date: 2019-05-22 10:39:31
redo log innodb的“語(yǔ)音便簽”
我早上上班路上一邊開(kāi)車一邊聽(tīng)專欄偶洋,聽(tīng)到需要記錄的東西會(huì)在等紅燈的時(shí)候用語(yǔ)音便簽記錄下,晚上睡覺(jué)前才會(huì)整理成博客。這個(gè)過(guò)程中,邊開(kāi)車邊整理博客我是做不到的右核,所以我先用語(yǔ)音便簽做了一個(gè)簡(jiǎn)單記錄渤昌,等我空閑的時(shí)候才會(huì)把語(yǔ)音便簽整理到博客上。
MySQL也一樣脸侥,如果每次更新、刪除操作都去直接更新磁盤文件盈厘,那能容忍的并發(fā)恐怕極其有限了睁枕。在innodb中采用了redo log的方式先把操作記錄下來(lái),等空閑的時(shí)候再把redo log批量更新到磁盤中沸手。
redo log的文件數(shù)量和大小可以配置外遇,當(dāng)達(dá)到配置的值時(shí),會(huì)觸發(fā)批量寫入磁盤操作契吉,清空redo log跳仿。
名詞
- WAL技術(shù) Write-Ahead Logging 先寫日志,再寫磁盤
- crash-safe 有了redo log捐晶,可以保證即使服務(wù)突然異常菲语,也不會(huì)丟失數(shù)據(jù)
binlog Server層的“語(yǔ)音便簽”
上面的redo log是引擎層的日志,server層也有自己的日志惑灵,稱為binlog(歸檔日志)
問(wèn)題
- 為什么有兩份日志山上?
- binlog只有歸檔能力,沒(méi)有crash-safe能力英支;innodb為了crash-safe能力引入了redo log
- binlog和redo log有啥不同佩憾?
- redo log是innodb特有的,binlog是MySQL的server層的日志干花,所有引擎都可以使用
- redo log是物理日志妄帘,記錄的是“在某個(gè)數(shù)據(jù)頁(yè)上做了什么修改”;binlog是邏輯日志池凄,記錄的是這個(gè)語(yǔ)句的原始邏輯抡驼,比如“給ID=2這一行的c字段加1 ”
- redo log是循環(huán)寫的,空間固定會(huì)用完肿仑;binlog是可以追加寫入的婶恼∩=祝“追加寫”是指binlog文件寫到一定大小后會(huì)切換到下一個(gè),并不會(huì)覆蓋以前的日志勾邦。
兩階段提交
一次更新操作的流程
- 執(zhí)行器找引擎取到要修改的記錄
- 引擎查看記錄是否在內(nèi)存中蚣录,如果在內(nèi)存中,直接返回給執(zhí)行器眷篇;否則需要從磁盤讀入內(nèi)存萎河,然后再返回
- 執(zhí)行器拿到數(shù)據(jù)后計(jì)算新的數(shù)值,再調(diào)用引擎寫入這行新數(shù)據(jù)
- 引擎將這行數(shù)據(jù)更新到內(nèi)存中蕉饼,同時(shí)寫入redo log(prepare狀態(tài))虐杯;然后告知執(zhí)行器執(zhí)行完了,隨時(shí)可以提交事務(wù)
- 執(zhí)行器把這個(gè)操作的binlog寫入磁盤中
-
執(zhí)行器通知引擎昧港,引擎把剛剛寫入的redo log狀態(tài)更新為commit
為什么需要兩階段提交擎椰?
如果MySQL服務(wù)異常宕機(jī),我們需要使用定時(shí)鏡像+binlog來(lái)恢復(fù)數(shù)據(jù)创肥。
如果沒(méi)有兩階段提交达舒,要么先寫binlog,要么先寫redo log叹侄,考慮只寫了一個(gè)日志的情況巩搏,即寫完一個(gè)日志就宕機(jī)的情況。
-
先寫redo log后寫binlog
- redo log恢復(fù)后的數(shù)據(jù)是更新后的
- binlog恢復(fù)的數(shù)據(jù)是更新前的
-
先寫binlog后寫redo log
- binlog恢復(fù)的數(shù)據(jù)是更新后的
- redo log恢復(fù)的數(shù)據(jù)是更新前的
如果沒(méi)有兩階段提交趾代,上述情況下就出現(xiàn)了引擎狀態(tài)(庫(kù)的實(shí)際狀態(tài))和用binlog恢復(fù)出來(lái)的庫(kù)狀態(tài)不一致的問(wèn)題贯底;不只有數(shù)據(jù)庫(kù),兩階段提交也是跨系統(tǒng)維持?jǐn)?shù)據(jù)邏輯一致性時(shí)常用的一個(gè)方案撒强。