一條查詢語句的執(zhí)行過程一般是經(jīng)過連接器、分析器、優(yōu)化器、執(zhí)行器等功能模塊,最后到達存儲引擎。
首先,可以確定的說,查詢語句的那一套流程,更新語句也是同樣會走一遍。與查詢流程不一樣的是,更新流程還涉及兩個重要的日志模塊:redo log(重做日志)和 binlog(歸檔日志)。
重要的日志模塊:redo log
具體來說,當(dāng)有一條記錄需要更新的時候,InnoDB 引擎就會先把記錄寫到 redo log里面,并更新內(nèi)存,這個時候更新就算完成了。同時,InnoDB 引擎會在適當(dāng)?shù)臅r候,將這個操作記錄更新到磁盤里面,而這個更新往往是在系統(tǒng)比較空閑的時候做。
與此類似,InnoDB 的 redo log 是固定大小的,比如可以配置為一組 4 個文件,每個文件的大小是 1GB。從頭開始寫,寫到末尾就又回到開頭循環(huán)寫,如下面這個圖所示:

write pos 是當(dāng)前記錄的位置,一邊寫一邊后移,寫到第 3 號文件末尾后就回到 0 號文件開頭。checkpoint 是當(dāng)前要擦除的位置,也是往后推移并且循環(huán)的,擦除記錄前要把記錄更新到數(shù)據(jù)文件。
有了 redo log,InnoDB 就可以保證即使數(shù)據(jù)庫發(fā)生異常重啟,之前提交的記錄都不會丟失,這個能力稱為crash-safe。
重要的日志模塊:binlog
redo log 是 InnoDB 引擎特有的日志,而 Server 層也有自己的日志,稱為 binlog(歸檔日志)。
最開始 MySQL 里并沒有 InnoDB 引擎。MySQL 自帶的引擎是 MyISAM,但是 MyISAM 沒有 crash-safe 的能力,binlog 日志只能用于歸檔。而 InnoDB 是另一個公司以插件形式引入 MySQL 的,既然只依靠 binlog 是沒有 crash-safe 能力的,所以 InnoDB 使用另外一套日志系統(tǒng)——也就是 redo log 來實現(xiàn) crash-safe 能力。
這兩種日志有以下三點不同:
1. redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 層實現(xiàn)的,所有引擎都可以使用。
2. redo log 是物理日志,記錄的是“在某個數(shù)據(jù)頁上做了什么修改”;binlog 是邏輯日志,記錄的是這個語句的原始邏輯,比如“給 ID=2 這一行的 c 字段加 1 ”。
3. redo log 是循環(huán)寫的,空間固定會用完;binlog 是可以追加寫入的?!白芳訉憽笔侵?binlog 文件寫到一定大小后會切換到下一個,并不會覆蓋以前的日志。