MySql 一條更新語(yǔ)句是如何執(zhí)行的? MySql雜談、MySql WAL 技術(shù)

1 前言
如下所示,一條普通的更新語(yǔ)句
當(dāng)你點(diǎn)擊執(zhí)行這條查詢指令時(shí),你看到的結(jié)果是:

你知道發(fā)生了什么嗎 ???
如下圖所示是一條查詢語(yǔ)句的執(zhí)行過(guò)程【一條SQL查詢語(yǔ)句是如何執(zhí)行的? MySql雜談】

更新語(yǔ)句在執(zhí)行過(guò)程中,也必然要走發(fā)上圖所示的基本流程,
2 一條更新指令的執(zhí)行過(guò)程
第一步 執(zhí)行器先找引擎取 user_id='760’這一行。這里的 user_id 是主鍵,引擎直接用樹(shù)搜索找到這一行。如果 user_id=‘760’ 這一行所在的數(shù)據(jù)頁(yè)本來(lái)就在內(nèi)存中,就直接返回給執(zhí)行器;否則,需要先從磁盤 讀入內(nèi)存,然后再返回。
第二步 執(zhí)行器拿到引擎給的行數(shù)據(jù),將這個(gè)對(duì)應(yīng)的列的值進(jìn)行修改,然后得到新的一行數(shù)據(jù),再調(diào)用引擎接口寫入這行新數(shù)據(jù)。
第三步 引擎將這行新數(shù)據(jù)更新到內(nèi)存中,同時(shí)將這個(gè)更新操作記錄到 redo log日志中。
第四步 執(zhí)行器生成這個(gè)操作的 binlog,并把 binlog 寫入磁盤。
第五步 執(zhí)行器調(diào)用引擎的提交事務(wù)接口,引擎把剛剛寫入的 redo log 改成提交(commit)狀態(tài),更新完成。
3 MySql WAL 技術(shù)
3.1 redo log 日志
當(dāng)有一條記錄需要更新的時(shí)候,InnoDB 引擎就會(huì)先把記錄寫到 redo log日志中,并更新數(shù)據(jù)庫(kù)操作引擎內(nèi)存,然后當(dāng)系統(tǒng)比較空閑的時(shí)候再更新到磁盤里面,這個(gè)過(guò)程可描述為WAL。
WAL 的全稱 是 Write-Ahead Logging,關(guān)鍵點(diǎn)就是先寫日志,再寫磁盤。
redo log日志記錄功能,使得 InnoDB 可以保證在數(shù)據(jù)庫(kù)發(fā)生異常重啟后,之前提交的記錄都不會(huì)丟失,這個(gè)能力可稱為crash-safe。
3.2 binlog 日志
MySQL 整體來(lái)看,包括兩部分, 一部分是Service層:

另一部分是引擎層,負(fù)責(zé)存儲(chǔ)相關(guān)的功能,redo log 是 InnoDB 數(shù)據(jù)存儲(chǔ)引擎特有的日志,binlog 歸檔日志是Server層持有的日志。
3.3 redo log 日志 與 binlog 日志的不同
持有對(duì)象不同,redo log 是InnoDB 持有,binlog是Server層持有
作用不同,redo log 是物理日志,記錄的是“在某個(gè)數(shù)據(jù)頁(yè)上做了什么修改”;binlog 是邏輯日 志,記錄的是這個(gè)語(yǔ)句的原始邏輯,如這里的更新語(yǔ)句
redo log 是循環(huán)寫入,binlog 是可以追加寫入, binlog 文件寫到一定大小后會(huì)切換到下一個(gè),并不會(huì)覆蓋以前的日志。
完畢
不局限于思維,不局限語(yǔ)言限制,才是編程的最高境界。