$30 off During Our Annual Pro Sale. View Details »

TiKV - トランザクション& MVCC

PingCAP-Japan
September 13, 2022

TiKV - トランザクション& MVCC

このスライドでは、分散型データベースのTiDBが、どのようにトランザクションの原子性や読み取り一貫性を実現しているかを紹介します。また、Rocks DBのカラムファミリー(CF)を使ったTiDBの独自のLockロジック、悲観ロックと楽観ロック、ダーティ・リードを回避できるかの疑問について解説します。

トピック:
Rocks DBの振り返りと今回のテーマ紹介
トランザクションの実現
MVCCの仕組み

録画:https://youtu.be/U-NgRWVQyQk

PingCAP-Japan

September 13, 2022
Tweet

More Decks by PingCAP-Japan

Other Decks in Technology

Transcript

  1. PingCAP Education:
 TiKV- トランザクション&MVCC
 Xinke Qiao / 喬 心軻(キョウ シンカ) 


    Technical support engineer 
 PingCAP Japan
 PingCAP Education

  2. 本日の位置づけ https://pingcap.co.jp/event/ ※過去開催アーカイブ : https://www.youtube.com/channel/UCatxrGZANSnii2fe7FeEwvg/playlists 
 
 2022年6月16日(木) 14:00-15:00 
 PingCAP Education:TiKV-

    RocksDBについて 
 2022年7月28日(木) 14:00-15:00 
 PingCAP Education:TiDBでの表設計 
 2022年9月9日(金) 14:00-15:00 
 PingCAP Education:TiKV-トランザクション&MVCC 
 2022年9月30日(金) 14:00-15:00 
 PingCAP Education: TiDBでのSQL実行の仕組み 
 2022年10月21日(金) 14:00-15:00 
 PingCAP Education:TiKV - Raftによるデータ整合性の実現 

  3. Xinke Qiao / 喬 心軻(キョウ シンカ) 
 Technical support engineer 


    PingCAP Japan
 PingCAP Education
 PingCAP Education:
 TiKV- トランザクション&MVCC

  4. アジェンダ
 • Rocks DB の振り返り*と今回のテーマ紹介
 *2022/6/16 のウェビナーの内容の振り返り 
 ◦ Rocks

    DB の書き込み、読み込み、CF
 ◦ トランザクション
 ◦ MVCC
 
 • トランザクション
 ◦ 2-Phase Commit
 ◦ プライマリ・ロック
 ◦ 原子性
 
 • MVCC
 
 • まとめ&QA

  5. 振り返り


  6. 簡単な振り返り(1)
 1. データの永続化の実現
 2. 分散型データベースのデータ整合性の保証
 3. MVCC(Multi-Version Concurrency Control)
 4.

    トランザクションの実現
 5. Coprocessor
 ➔ Rocks DB for Raft log
 ➔ Rocks DB for KV 

  7. RocksDB の書き込む仕組み
 • 順序書き込み 
 例)削除:<del key=1233> 更新: <put key=2,value=”Lucy”>
 Background


    put key=1, value=”tom”
 del key=1233
 put key=2, value=”lucy”
 …
 …

  8. RocksDB-読み取る仕組み
 • 2分探索法
 min->
 max->
 New
 Old


  9. RocksDB-CF(Column Family)
 TiDB では、Default、Write、Lock の3つの CFによるトランザクション及びMVCCを実現しています。


  10. トランザクションの実現
 1. データの永続化の実現
 2. 分散型データベースのデータ整合性の保証
 3. MVCC(Multi-Version Concurrency Control)
 4.

    トランザクションの実現
 5. Coprocessor
 ➔ Google Percolator
 ➔ 2PC(2 Phase Commit)

  11. MVCC
 1. データの永続化の実現
 2. 分散型データベースのデータ整合性の保証
 3. MVCC(Multi-Version Concurrency Control)
 4.

    トランザクションの実現
 5. Coprocessor
 ➔ KV =>(key_version, value)
 例:t_12_p_1_<tso>,”Tom” )
 ➔ GC による古いバージョンデータのクリ ア
 ➔ …

  12. トランザクション


  13. 分散型データベース特有の課題
 ❓トランザクション(ACID)・原子性(Automicity)はどのように維持されるか❓
 
 「トランザクション」
 TiKV Node 1
 RocksDB KV 


    RocksDB Raft log TiKV Node 2
 RocksDB KV 
 RocksDB Raft log ① < 1, Tom> ➡ < 1, Jack > 
 ② < 2, Andy> ➡ < 2, Candy > 
 ❌
 ❌

  14. Cluster
 トランザクションの実行〜Begin
 • Default CF、Lock CF、Write CF
 • PD から

    start timestamp(start_ts) を取得する
 TiKV
 PD
 
 Begin:
 
 Client Default Lock Write start_ts=100
 TiDB Server
  15. Cluster
 トランザクションの実行〜DML
 • start_ts と表の id の組み合わせがキーにしたKV ペアを TiDB のメモリに格納する


    • Lock CF にロック情報を書き込む
 • 悲観トランザクション
 TiKV
 PD
 
 Begin:
 <3,xxx> -><3,Frank>
 Client 
 <3,(W,pk,3,100,…)>
 start_ts=100
 TiDB Server put <3_100, Frank>
 Default Lock Write
  16. Cluster
 トランザクションの実行〜2PC-Prewrite
 • Default CF に更新データを書き込む
 TiKV
 PD
 
 Begin:


    <3,xxx> -><3,Frank>
 Commit;
 Client put <3_100, Frank>
 
 <3,(W,pk,3,100,…)>
 start_ts=100
 TiDB Server put <3_100, Frank>
 Default Lock Write
  17. Cluster
 トランザクションの実行〜2PC-Commit
 1) PD からcommit_ts を取得する
 2) Write CF に

    Commit 情報を更新する
 3) Lock CF にロックが削除されたことを更新する
 start_ts=100
 TiKV
 PD
 TiDB Server 
 Begin:
 <3,xxx> -><3,Frank>
 Commit;
 Client put <3_100, Frank>
 <3,(D,pk,3,100…)>
 <3,(W,pk,3,100,…)>
 put <3_100, Frank>
 put <3_110,100>
 commit_ts=110
 Default Lock Write
  18. CF まとめ
 • Lock CF
 ロック情報を格納する
 • Write CF
 ◦

    トランザクション情報を格納する
 ◦ ユーザが行データを書き込む際、もし当該行デー タのサイズが 255 Bytes より小さい場合、 実際 の行データも格納する
 • Default CF
 255 Bytes より大きい場合、実際の行データを格納する
 TiKV
 Default Lock Write <3,(D,pk,3,100…)>
 <3,(W,pk,3,100,…)>
 put <3_100, Frank>
 put <3_110,100>

  19. トランザクション~動作まとめ(1)
 Client 側の操作
 Cluster 側の Background 操作
 begin
 TiDB Server

    によるPD から start_ts を獲得する
 < 1, Tom> ー> < 1, Jack > 
 < 2, Andy> ー> < 2, Candy >
 1. TiDB Server のメモリにデータを一時的に書き込む
 2. それぞれのTiKVノードの Lock CF にid=1,id=2 へのロック情報を書き込 む
 commit;
 <Prewrite>
 1. それぞれのTiKVノードの Default CF もしくは Write CF にid=1,id=2 にお ける実の行データを書き込む
 <Commit>
 1. PD から commit_ts を獲得する
 2. それぞれのTiKVノードの Write CF にcommit_ts を含めたid=1,id=2におけ るコミット情報を書き込む
 3. id=1,id=2 へのロックが削除された情報をそれぞれのTiKVノードの Lock CF に更新する
 悲観トランザクションモード(Default) 

  20. トランザクション~動作まとめ(2)
 Client 側の操作
 Cluster 側の Background 操作
 begin
 TiDB Server

    によるPD から start_ts を獲得する
 < 1, Tom> ー> < 1, Jack > 
 < 2, Andy> ー> < 2, Candy >
 TiDB Server のメモリにデータを一時的に書き込む
 commit;
 <Prewrite>
 1. それぞれのTiKVノードの Default CF もしくは Write CF にid=1,id=2 にお ける実の行データを書き込む
 2. それぞれのTiKVノードの Lock CF にid=1,id=2 へのロック情報を書き込 む
 <Commit>
 1. PD から commit_ts を獲得する
 2. それぞれのTiKVノードの Write CF にcommit_ts を含めたid=1,id=2におけ るコミット情報を書き込む
 3. id=1,id=2 へのロックが削除された情報をそれぞれのTiKVノードの Lock CF に更新する
 楽観トランザクションモード 

  21. プライマリ・ロック(pk)
 TiKV Node 1
 Default Lock Write <1,(W,pk,1,100,…)>
 pk:プライマリロック
 ➔

    トランザクションの中で最初に更新された行にかけるロック 
 ➔ 1トランザクションに1つのpk(プライマリロック) 
 @id:pkへのポインタ
 TiKV Node 2
 Default Lock Write <2,(W,@1,2,100,…)>
 トランザクション
 Begin(start_ts = 100)
 < 1,Tom > -> < 1,Jack >
 < 2,Andy > -> < 2, Candy > 
 id=2??

  22. プライマリ・ロック(Commit)
 TiKV Node 1
 Lock Write <1,(D,pk,1,100,…)>
 <1,(W,pk,1,100,…)>
 TiKV Node

    2
 Default Lock Write <2,(D,@1,2,100,…)>
 <2,(W,@1,2,100,…)>
 トランザクション
 Begin(start_ts = 100)
 < 1,Tom > -> < 1,Jack >
 < 2,Andy > -> < 2, Candy > 
 commit(commit_ts = 110)
 Default put <1_100, Jack>
 put <1_110,100>
 put <2_100, Candy>
 put <2_110,100>
 2PC:
 1. Prewrite: Default CF に更新データを書き込む(順序書き込む) 
 2. Commit: Write CF にコミット情報、Lock CF にロック情報を書き込む 

  23. TiKV Node 1
 Lock Write <1,(D,pk,1,100,…)>
 <1,(W,pk,1,100,…)>
 TiKV Node 2


    Default Lock Write <2,(D,@1,2,100,…)>
 <2,(W,@1,2,100,…)>
 Default put <1_100, Jack>
 put <1_110,100>
 put <2_100, Candy>
 put <2_110,100>
 トランザクションの原子性(1)
 • ノード2がダウンして、トランザクションの一部操作だけが成功された 場合
 トランザクション
 Begin(start_ts = 100)
 < 1,Tom > -> < 1,Jack >
 < 2,Andy > -> < 2, Candy > 
 commit(commit_ts = 110)

  24. トランザクションの原子性(2)
 • ノード2が回復した場合、プライマリ・ロックからロックのステータス を獲得する
 TiKV Node 1
 Lock Write <1,(D,pk,1,100,…)>


    <1,(W,pk,1,100,…)>
 TiKV Node 2
 Default Lock Write <2,(D,@1,2,100,…)>
 <2,(W,@1,2,100,…)>
 Default put <1_100, Jack>
 put <1_110,100>
 put <2_100, Candy>
 put <2_110,100>
 トランザクション
 Begin(start_ts = 100)
 < 1,Tom > -> < 1,Jack >
 < 2,Andy > -> < 2, Candy > 
 commit(commit_ts = 110)

  25. トランザクションの原子性(3)
 • 1トランザクションで何個の更新があっても 関係なく、pkといっ た1つのロックのみで管理をしている 
 TiKV Node 1
 Lock

    Write <1,(D,pk,1,100,…)>
 <1,(W,pk,1,100,…)>
 TiKV Node 2
 Default Lock Write <2,(D,@1,2,100,…)>
 <2,(W,@1,2,100,…)>
 Default put <1_100, Jack>
 put <1_110,100>
 put <2_100, Candy>
 put <2_110,100>
 トランザクション
 Begin(start_ts = 100)
 < 1,Tom > -> < 1,Jack >
 < 2,Andy > -> < 2, Candy > 
 commit(commit_ts = 110)

  26. MVCC


  27. MVCC〜更新中のデータの読み込み
 以下の例で、トランザクション②はコミットされていないため、Key=1と4のデータは読み込めないか❓
 トランザクション① Begin(start_ts = 100) < 1,Tom > ->

    < 1,Jack > < 2,Andy > -> < 2, Candy > Commit;(commit_ts = 110) トランザクション② Begin(start_ts = 115) < 1,Jack > -> < 1,Tim > < 4,Tony > -> < 4, Jerry > id=1&4
 <データのコピー>
 1,Jack > 1,Tim
 4,Tony > 4,Jerry 
 ❌
 <元データ>
 1,Jack
 4,Tony 
 多くの RDBMS データベース 
 コミットされていないため 

  28. MVCC〜更新中のデータの読み込み(続き)
 トランザクション②はコミットされていないため、Key=1と4のデータは読み込めないか❓
 トランザクション① Begin(start_ts = 100) < 1,Tom > ->

    < 1,Jack > < 2,Andy > -> < 2, Candy > Commit;(commit_ts = 110) トランザクション② Begin(start_ts = 115) < 1,Jack > -> < 1,Tim > < 4,Tony > -> < 4, Jerry > ❌
 TiDB データベース
 コミットされていないため 
 ts=120
 id=1,value=?
 id=2,value=?
 id=4,value=?

  29. MVCC
 悲観トランザクションモード(Default) 
 トランザクション①
 Begin(start_ts = 100)
 < 1,Tom >

    -> < 1,Jack >
 < 2,Andy > -> < 2, Candy > 
 Commit;(commit_ts = 110)
 
 トランザクション②
 Begin(start_ts = 115)
 < 1,Jack > -> < 1,Tim >
 < 4,Tony > -> < 4, Jerry >

  30. MVCC~Read&Write(1)
 Read
 ts=120
 id=1,value=?
 id=2,value=?
 id=4,value=?
 Write
 ts=120
 id=1,set value=new_value


  31. MVCC~Read&Write(2)
 Read
 ts=120
 id=1,value=?
 id=2,value=?
 id=4,value=?
 Write
 ts=120
 id=2,set value=new_value


  32. MVCC~Read&Write(3)
 Read
 ts=120
 id=1,value=?
 id=2,value=?
 id=4,value=?
 Write
 ts=120
 id=4,set value=new_value


  33. まとめ
 • Rocks DB の振り返りと今回のテーマ紹介
 ◦ Rocks DB の書き込み、読み込み、CF
 ◦

    トランザクション
 ◦ MVCC
 
 • トランザクション
 ◦ 2-Phase Commit
 ◦ プライマリ・ロック
 ◦ 原子性
 
 • MVCC

  34. Thank You!
 https://www.pingcap.com/
 info@pingcap.com