上篇文章 學習了 mysql的基礎架構,理清了一條查詢sql在mysql中的執行過程,其實update語句的執行過程也是大致相同的。
以下面的一條sql為例 (ID為主鍵)
update T set b=b+1 where ID = 2
- 客戶端通過連接器與mysql建立連接
- 刪除要update表的緩存
- 分析器解析sql並判斷是否含有語句錯誤
- 優化器確定查詢索引
- 執行器調用Innodb存儲引擎接口獲取ID=2的數據行。
- Innodb存儲引擎掃描主鍵索引查找到ID=2的行返回給server層。
- 執行器將B+1 調用存儲引擎接口寫入該行數據。
- Innodb存儲引擎將數據保存在內存中(WAL)。
- Innodb存儲引擎寫redo日志,prepare狀態,通知Server層。
- server層 提交Binlog后通知Innodb存儲引擎。
- Innodb存儲引擎將redo日志commit。
至此一條update語句就執行完成了。
redo日志:Innodb存儲引擎特有的機制,可以用來應對異常恢復,Crash-safe,redo可以保證mysql異常重啟時,將未提交的事務回滾,已提交的事務安全落庫。
二階段提交:redo(perpare)--->binlog-->redo(commit) 保證了mysql在異常重啟的時候,數據的一致性,在任意環節出錯,都可以保證redo日志和binlog的一致性。
WAL:第8個步驟,innodb沒有直接將數據落盤,而是存在內存中,並記錄日志,這里用到的技術就是WAL(Write-Ahead Logging)。數據在持久化硬盤前,如果mysql異常重啟,innodb可以根據redo日志將未持久化的數據恢復。redo日志是有大小限制的,循環寫,當redo快要寫滿時,將redo日志頭部的記錄清理,擦除記錄前要把內存記錄更新到數據文件。
binLog: binlog 記錄的是邏輯日志,是mysql的歸檔日志,支持所有引擎使用。與redo不同的是,binlog是不限制大小,文件追加寫。
這里將老師的圖貼上(對應的5--11的步驟)

