01 mysql
內存中的資料庫數據何時持久化到磁碟?
因為redo log已經持久化,因此資料庫數據寫入磁碟與否影響不大,不過為了避免出現髒數據(內存中與磁碟不一致),事務提交後也會將內存數據刷入磁碟(也可以按照固設定的頻率刷新內存數據到磁碟中)。
redo log何時寫入磁碟
redo log會在事務提交之前,或者redo log buffer滿了的時候寫入磁碟
這裡存在兩個問題:
問題1:之前是寫undo和資料庫數據到硬碟,現在是寫undo和redo到磁碟,似乎沒有減少IO次數
- 資料庫數據寫入是隨機IO,性能很差
- redo log在初始化時會開闢一段連續的空間,寫入是順序IO,性能很好
- 實際上undo log並不是直接寫入磁碟,而是先寫入到redo log buffer中,當redo log持久化時,undo log就同時持久化到硬碟了。
因此事務提交前,只需要對redo log持久化即可。
另外,redo log並不是寫入一次就持久化一次,redo log在內存中也有自己的緩衝池:`redo log buffer`。每次寫redo log都是寫入到buffer,在提交時一次性持久化到磁碟,減少IO次數。
問題2:redo log 數據是寫入內存buffer中,當buffer滿或者事務提交時,將buffer數據寫入磁碟。
redo log中記錄的數據,有可能包含尚未提交事務,如果此時資料庫崩潰,那麼如何完成數據恢復?
數據恢復有兩種策略:
- 恢復時,只重做已經提交了的事務
- 恢復時,重做所有事務包括未提交的事務和回滾了的事務。然後通過Undo Log回滾那些未提交的事務
Inodb引擎採用的是第二種方案,因此undo log要在 redo log前持久化
02總結
最後總結一下:
- undo log 記錄更新前數據,用於保證事務原子性
- redo log 記錄更新後數據,用於保證事務的持久性
- redo log有自己的內存buffer,先寫入到buffer,事務提交時寫入磁碟
- redo log持久化之後,意味著事務是**可提交**的
業務發展瓶頸,解決業務系統的高耦合、可伸縮問題的需求越來越強烈。
03Seata支持的事務模型
Seata 會有 4 種分布式事務解決方案,分別是 AT 模式、TCC 模式、Saga 模式和 XA 模式。
Seata中比較常用的是AT模式。
訂單服務在下單時,同時調用庫存服務和用戶服務,此時就會發生跨服務和跨數據源的分布式事務問題。
在 Seata 中,將 Storage 服務看成一個本地事務,Business 服務看成一個本地事務,將 Order 服務看成一個本地事務,將 Account 服務看成一個本地事務,其構成了一個 Distributed Transaction,由 TC 統一協調。在 Seata 中稱之為 「Global Transaction」
在 Seata 中有三個基礎組件:
Transaction Coordinator(TC)(協調者):維護全局和分支事務的狀態,驅動全局提交或回滾。
Transaction Manager(TM)(事務管理):定義全局事務的範圍,開啟全局事務,提交 或 回滾一個全局事務。
Resource Manager(RM)(資源管理):管理分支事務資源。與 TC 通訊並報告分支事務狀態,管理本地事務的提交與回滾。
在 Seata 中,一個典型的生命周期如下所示:
TM 要求 TC 生成一個全局事務,並由 TC 生成一個全局事務XID 返回。
XID 通過微服務調用鏈傳播。
RM 向 TC 註冊本地事務,將其註冊到 ID 為 XID 的全局事務中。
TM 要求 TC 提交或回滾XID 對應的全局事務。
TC 驅動 XID 對應的全局事務對應的所有的分支事務提交或回滾。