Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

PingCAP-Japan
September 13, 2022

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

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

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

アーカイブ動画:
https://youtu.be/eSWWvJdz6Tw

PingCAP-Japan

September 13, 2022
Tweet

More Decks by PingCAP-Japan

Other Decks in Technology

Transcript

  1. 本日の位置づけ 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によるデータ整合性の実現 

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


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

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

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

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

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

  5. 分散型データベース特有の課題
 ❓トランザクション(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 > 
 ❌
 ❌

  6. 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
  7. 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
  8. 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
  9. 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
  10. 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>

  11. トランザクション~動作まとめ(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) 

  12. トランザクション~動作まとめ(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 に更新する
 楽観トランザクションモード 

  13. プライマリ・ロック(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??

  14. プライマリ・ロック(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 にロック情報を書き込む 

  15. 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)

  16. トランザクションの原子性(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)

  17. トランザクションの原子性(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)

  18. 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 データベース 
 コミットされていないため 

  19. 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=?

  20. 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 >

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

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