分布式數(shù)據(jù)庫
事務
- 什么是事務?
- 事務就是并發(fā) + 鎖
- 事務就是為了保證數(shù)據(jù)的一致性,ACID保證事務的完整性
- 事務單元
- 商品要建立一個基于GMT_Modified的索引
- 從數(shù)據(jù)庫中寫入一行記錄,同時更新這行記錄的所有索引。
- 刪除整章表
- Etc
- 事務單元之間的Happen-before關系
- 讀寫 寫讀 讀讀 寫寫
- 如何以更快的速度完成?又能保證上面四種操作的邏輯順序?
- 排隊法 優(yōu)點: 不需要沖突控制,缺點:太慢
- 排他鎖
- 讀寫鎖 讀讀 和 讀寫做優(yōu)化
- MVCC 多版本并發(fā)控制 主流數(shù)據(jù)庫實現(xiàn)的方法
本質來說就是copy on write 能夠做到寫不阻塞讀。
在寫的時候可以做并發(fā)讀。讀讀,讀寫,寫讀都不沖突。
系統(tǒng)實現(xiàn)很復雜。
事務處理常見問題
- 多個事務,誰先誰后?
- 一個讀請求應該讀哪一個寫之后的數(shù)據(jù)?(MVCC)
- 解決方法: 邏輯時間戳數(shù)據(jù)的自增號,寫一次加一
SCN(Oracle)
Trx_id(Innodb)
Etc
- 如何恢復故障?
- 業(yè)務屬性不匹配 恢復: 記住執(zhí)行操作的反操作的log,然后進行回滾
系統(tǒng)崩潰 恢復: 數(shù)據(jù)恢復,系統(tǒng)沒有恢復完成時,不可以對外提供服務
- 碰到死鎖了怎么辦?
- 死鎖檢測和死鎖;死鎖產生的原因:兩個線程,不同方向,相同的資源
- 死鎖的解決方案:盡可能不死鎖,碰撞檢測,等鎖超時
深入單機事務
- 事務的ACID
- 原子性
一個事務要么同時成功,要么同時失敗
undo日志回滾到之前的版本
例子:ver1 Bob有100元,Smith有0元
ver2 Bob有0元,Smith有0元
(undo: Bob有100元,Smith有0元)
ver3 Bob有0元,Smith有100元
(undo: Bob有0元,Smith有0元)
一致性
Can(Happen before), 保證能看到系統(tǒng)內的所有更改。
兩個事務同時發(fā)生,處理不同事務的讀寫并行,就是處理一致性的重要問題。-
隔離性
以性能為理由,對一致性的破壞。
序列化讀寫(Serializable) 排他鎖 單位時間內只有一個事務可以執(zhí)行。
讀寫鎖:可重復讀(Repeatable Read)
讀鎖不能被寫鎖升級,只能做到讀讀并行讀已提交(Read Committed)
讀鎖可以被寫鎖升級,讀讀并行,讀寫并寫(寫讀不能)
出現(xiàn)了不可重復讀讀未提交(Read Uncommited)
只加寫鎖,讀不加鎖
讀讀并行,
讀寫并行
寫讀并行
問題:
可能讀到寫過程中的數(shù)據(jù)隔離性小結:
SQL92標準定義的隔離性
序列化,可重復讀,讀已提交,讀未提交
隔離性擴展:
快照(Snapshot Isolation)
多版本并發(fā)控制(MVCC)
核心思想:
copy on write + 無鎖編程。快照隔離性:
- 針對讀多寫少場景優(yōu)化
- 并行度能達到或超過讀未提交,而隔離級別很高
- 快照讀的情況能保證讀到一致性的同時實現(xiàn)讀未提交
- 實現(xiàn)了MVCC的系統(tǒng),快照讀幾乎等同于序列化讀
寫寫有沒有可能并行?
事務就是多個不同的命令組裝到一起的過程。
持久性
事務完成以后,該事務對數(shù)據(jù)庫所作的更改便持久的保存在數(shù)據(jù)庫之中。
RAID的持久性:
數(shù)據(jù)丟失的可能:1磁盤的物理損壞。2每一次commit都要fsync到磁盤中----->系統(tǒng)性能的下降。持久性 ---> 延遲
RAID Controller要保證同時成功和失敗。
1.提交請求到內存后返回(內存的數(shù)據(jù)容易丟失)
2.如何將內存的數(shù)據(jù)打包到磁盤(Group Commit提升系統(tǒng)的吞吐量)
持久性(擴展:持久性保證策略)
核心目的:提升并行度
- 單機事務的典型異常對應策略
業(yè)務屬性不匹配
回滾-
系統(tǒng)DOWN機
事務的原子性操作只有一個標記commit
commit完成時,之后的請求必須正常的完成
重啟后進入recovery模式:提交后事務單元繼續(xù)完成提交
未提交事務單元回滾
Recovery
- 過程是原子性操作,要保證ACID
- 進程掛掉,重啟recovery
- 記錄日志,保證不會出現(xiàn)數(shù)據(jù)丟失
- 事務的調優(yōu)原則
在不影響業(yè)務應用的前提下
- 減少鎖的覆蓋范圍
- Myisam表鎖 --> Innodb 行鎖
- 原位鎖 --> MVCC版本
- 增加鎖上可并行的線程數(shù)
- 讀鎖寫鎖分離、允許并行讀取數(shù)據(jù)
- 多線程并行讀取
- 允許更多人讀取
- 選擇正確鎖類型
- 悲觀鎖:使線程到blocking狀態(tài),通知信息Ok的狀態(tài)切換回等待狀態(tài),適合并發(fā)爭搶比較嚴重的場景
- 樂觀鎖:適合并發(fā)爭搶不太嚴重的場景
- 單機事務拾疑
-
事務單元擴展
事務單元商品要建立一個基于GMT_Modified的索引
從數(shù)據(jù)庫中讀取一行記錄
刪除整張表
向數(shù)據(jù)庫中寫入一行記錄,同時更新這行記錄
Etc
一組事務單元
Bob給Smith100
Joe領了100
Smith給了Bob100
Two Phase lock
BeginTrx Read from A(lockA) Read from B(lockB) A - 100 B + 100 Commit(unlockA,unlockB) -
死鎖擴展 - U鎖(更新鎖)
- 可重復讀隔離級別下:
Tx1 申請A讀鎖成功 Tx2 申請A讀鎖成功 Tx1 申請A讀鎖升級-等待Tx2讀鎖釋放 Tx2 申請A讀鎖升級為寫鎖-等待Tx1讀鎖釋放- Update set A = A-1 where id = 100 多個線程會死鎖
- U 鎖:
當探測到有寫操作的時候,自動將讀鎖升級為寫鎖。
-
MVCC拾遺
- 針對讀多寫少的場景優(yōu)化
- 并行度能達到或超過讀未提交,而隔離級別很高
分布式事務
目標:像傳統(tǒng)單機事務一樣的操作,可按需無限擴展
分布式數(shù)據(jù)庫的嘗試與問題
- 什么是事務
無論怎么偽裝:我們在玩的仍然是個圖靈機。 - 網絡帶來的,網絡失去的
- 基于鎖的事務實現(xiàn)中遇到的問題
- 從2PL到2PC
- 分布式事務異常處理
- 分布式日志記錄
- 分布式事務延遲變大問題
- 結合MVCC的事務實現(xiàn)中遇到的問題
- 分布式順序問題
本文為https://www.imooc.com/learn/272的課程筆記,如有侵權立刪。