序言:ACID 是一組數據庫設計原則,他是業務數據和關鍵業務程序的可靠性保障。
1、atomicity(原子性)
依賴如下能力
autocommit
commit
rollback
2、一致性
2.1 double write buffer
1、定義:double write buffer 是一塊空間,mysql 將緩沖池的數據寫入到此空間,然后 flush 到 mysql 數據存儲空間。當 mysql 發生異常退出時,會從這個空間恢復數據。
2、可能問題:double write buffer 會造成兩倍磁盤IO 嗎?
不會,寫入double write buffer 使用OS 調用 fsync()方法,每次寫入一塊大的 chunk 數據。(順序 IO)
2.2 crash recovery
mysql 異常恢復分為如下幾步進行
2.2.1 tablespace discovery
mysql 啟動時會掃描tablespace空間,看是否有表需要 recovery。
2.2.1 redo log application
重要知識:checkpoint(檢查點) 是 redo log 管理的核心機制之一。它的核心作用是 標記哪些數據修改已經持久化到磁盤,從而優化崩潰恢復的效率并回收 redo log 空間
1、redo log 存儲方式:redo log,存儲物理日志 記錄數據頁的變化(即第幾頁第幾行變動),用于 mysql 程序異常退出后恢復。
redo log 在磁盤中是一系列文件,在事務成功提交并且寫入后會被清理,此空間會重復使用
2、redo log 的寫入:寫入 redo log buffer,默認事務提交時強制刷盤 innodb_flush_log_at_trx_commit。(可每秒刷盤 0 ,OS 異步刷盤)
2.2.2 回滾未提交事務
2.2.3 change buffer merge
redo log 中會存儲buffer pool 和 change buffer 中的數據,在 redo log 重放時,會根據 checkpoint 位置恢復對應的 change buffer
2.2.4 purge
清除被標記刪除的,并且在所有事務中不可見的數據。
3、隔離性
3.1 隔離級別
1、REPEATABLE READ:事務開啟時read snapshot,snapshot 在事務執行中不會變化,除非本事務使用 DML語句。 在執行 DQL,DML 語句時會使用 gap lock。這也是REPEATABLE READ減少幻讀的核心。
2、READ COMMITTED:每次 read 都是讀取最新的 snapshot,在 select,update delete 時根據 where 條件匹配到 row,然后使用 primary key 或者隱藏主鍵鎖住 row,而不會使用 gap lock 鎖住間隙。READ COMMITTED確保最終一致性,且會有更好的并發性能。
3、READ UNCOMMITTED:產生臟讀,幻讀,一般不用。
4、SERIALIZABLE:禁用并發。
3.2 data lock
4、持久性
mysql數據持久性主要和 redo log,double write buffer,bin log 相關聯,除此之外,還與 mysq 服務所在的機器相關,如 CPU,OS,hardware。下面從 mysql 自身支持持久性分析:
1、如圖可知 Redo Log 和 double write buffer的數據都來自 buffer pool 中的臟頁,這兩類數據都是以磁盤存儲,buffer pool 是內存存儲。
2、Redo log 和 double write buffer 都是 mysql 的恢復機制,當 mysql recovery 時首先從 double write buffer 恢復,如果恢復失敗或者部分恢復,則會從 redo log 恢復。
3、innodb_flush_log_at_trx 參數的配置會影響 mysql 數據持久性,默認配置 1,Redo log 同步刷盤才返回客戶端成功,其他兩種情況均可能導致 mysql 丟失數據。
4、mysql server 層還有 bin log,它存儲 mysql 事務提交后的每一條邏輯數據(SQL),常用做主從復制和數據同步。
下圖是 mysql 寫入數據時的流程圖