分布式事務
下面一個事務 里面有兩個更新,分別將id=1的Tom改為Jack,將id=2的zhangsan 改為 lisi。在MySQL中這個事務很普通,但是在分布式數據庫TiDB 中的會遇到什么問題呢?
begin;
(1,'Tom') --> (1,'Jack')
(2,'zhangsan') --> (2,'lisi')
commit;
比如(1,‘Tom’)? 存儲在一個TiKV中 ,(2,'zhangsan')存儲在另一個TiKV中,
當我完成修改操作(1,‘Tom’) --> (1,‘Jack’) 數據所在的TiKV并提交后,存儲(2,'zhangsan')的TiKV不可用了,這樣就出現了一個事務中一部分提交修改持久化,一部分未提交的狀況,破壞了事務的原子性。
TiDB采用Google的模型解決這個問題?
分布式事務在TiKV的存儲
通過一個只修改一行的事務了解事務是如何存儲在TiKV中的 。
事務流程
begin;? 從PD中獲取事務開始的時間戳 start_ts
接下來會把修改的數據讀取到內存中,
commit;兩階段提交 ;第一階段?prewrite階段,寫兩個CF, 分別為default CF? 和 Lock CF。將內存中修改的數據寫入到TiKV節點中 ,將鎖信息寫入到TiKV節點中。第二階段 commit階段,從PD中獲取事務結束的時間戳commit_ts。
樂觀鎖:在提交commit的時候將鎖信息寫入到TiKV ,其他會話感知不到
悲觀鎖:將鎖信息提前寫入到TiKV中,其他會話可以感知到。
目前討論的按樂觀鎖討論
事務是如何存儲在TiKV上?
事務中,TiKV節點會有三個CF?分別存儲為
① default? CF 存儲修改的數據,put? <3_100,Frank > 在 (ID_時間戳,修改的新值),只存儲修改的新值,因為新數據永遠在上面
put? <3_100,Frank > 修改
put? <3_100,Frank > 插入
delete? <3_100,Frank > 刪除
② Lock CF 存儲鎖信息 ,只給事務修改的第一行加一把主鎖 ,其他修改的行指向主鎖。
鎖結構<3,(w,pk,3,100,...)>? w代表寫鎖,pk代表主鍵,3 代表key? ,100代表開始時間戳
③ 在Write CF中 寫入 提交信息 ,commit 之后 兩階段提交的第二階段,
<3_110,100>? <業務ID_提交時間,事務開始時間>
然后寫入 鎖信息的清理,不是刪除 LOCK CF中數據,而是插入一條數據 例如
<3,(D,pk,3,100,...)>? D 代表刪除
write CF 不單單會記錄提交信息 ,當這一行的數據長度小于255字節時 ,還能寫數據的修改。
分布式事務在TiKV的實現
分布式事務解決的關鍵點:只給修改的第一行加一把主鎖 ,其他行加的是鎖的指向?,指向第主鎖 。分布式事務原子性,取決于主鎖。
put <1_100,Jack> 業務id_事物開始的時間戳 ,
<1,(W,pk,1,100...)>?只給修改的第一行加一把主鎖 ,其他行加的是鎖的指向?,指向第主鎖?
put<2_100,Candy>
<2,(w,@1,2,100...)> 存儲的是鎖的指向,指向的是主鎖。
MVCC
如果需要修改很多數據,這些數據在修改期間都不能讀寫,那嚴重影響了數據庫系統的并發性。
解決上面的方法 :寫確實不能再寫了,因為這些數據在修改。但是可以讀。
其他數據庫也有MVCC。