MySQL日志系統(tǒng):一條SQL更新語句是如何執(zhí)行的

日志系統(tǒng): redo log(重做日志)和binlog(歸檔日志)。

重要的日志模塊:redo log

MySQL WAL(Write-Ahead-Logging)關(guān)鍵點(diǎn)是先寫日志,再寫磁盤。
當(dāng)更新數(shù)據(jù)時(shí),InnoDB引擎就會(huì)先把記錄寫到redo log里面,并更新內(nèi)存,這個(gè)是否更新就算完成,在合適的時(shí)候,將記錄寫入到磁盤里面。
redo log的標(biāo)記:write pos 是當(dāng)前記錄的位置,一邊寫一邊后羿;checkpoint是當(dāng)前要擦出的位置,也是往后移動(dòng)推移并且循環(huán)的,擦除記錄前要把記錄更新到數(shù)據(jù)文件。有了redo log,InnoDB就可以保證即使數(shù)據(jù)庫(kù)發(fā)生異常重啟,之前提交的記錄都不會(huì)丟失,這個(gè)能力成為crash-safe。

重要的日志模塊:binlog

Server層有自己的日志,稱為binlog。redo log是InnoDB引擎特有的日志。
剛開始時(shí),MySQL自帶的引擎是MyISAM,但是MyISAM沒有crash-safe的能力,binlog日志只能用于歸檔。
redo log與binlog的區(qū)別:

  • redo log是InnoDB引擎特有的;binlog是MySQL Server層實(shí)現(xiàn)的,所有引擎都可以使用。
  • redo log是物理日志,記錄的是在某個(gè)數(shù)據(jù)頁(yè)上做了什么修改;binlog是邏輯日志,記錄的是這個(gè)語句的原始邏輯。
  • redo log是循環(huán)寫的,空間固定會(huì)用完;binlog是可以追加寫入的。追加寫入是指binlog文件寫到一定大小后會(huì)切換到下一個(gè),并不會(huì)覆蓋以前的日志。

更新流程:

  • 執(zhí)行器先找引擎得到修改的記錄,如果在內(nèi)存中,直接返回;如果沒有在內(nèi)存中,從磁盤讀取內(nèi)存,然后在返回。
  • 執(zhí)行器拿到數(shù)據(jù)后,修改之后,然后通過引擎將數(shù)據(jù)寫入內(nèi)存。
  • 引擎將數(shù)據(jù)更新到內(nèi)存中,同時(shí)將這個(gè)更新操作記錄到redo log里面,此時(shí)redo log處于prepare狀態(tài),然后告知執(zhí)行器執(zhí)行完成了,隨時(shí)可以提交事務(wù)。
  • 執(zhí)行器生成這個(gè)操作的binlog,并把binlog寫入磁盤。
  • 執(zhí)行器調(diào)用引擎的提交事務(wù)接口,引擎把剛剛寫入的redo log改成commit狀態(tài),更新完成。

兩階段

binlog會(huì)記錄所有的邏輯操作,并且是采用"追加寫"的形式。

由于redo log和binlog是兩個(gè)獨(dú)立的邏輯,如果不用兩階段,就會(huì)出現(xiàn)問題

  • 先寫redo log后寫binlog:redo log寫完,binlog沒有寫完,MySQL進(jìn)程異常重啟。系統(tǒng)崩潰之后,恢復(fù)的數(shù)據(jù)為更新后的數(shù)據(jù),binlog恢復(fù)的數(shù)據(jù)是原先的數(shù)據(jù)。
  • 先寫binlog 后寫redo:binglog寫完之后crash,事務(wù)無效,值沒有變化,由于redo log還沒寫,通過binlog恢復(fù)的數(shù)據(jù)就多一個(gè)事務(wù)出來,與原庫(kù)不同。

redo log用于保證crash-safe能力。innodb_flush_log_at_trx_commit這個(gè)參數(shù)設(shè)置為1的時(shí)候,表示每次事務(wù)的redo log都直接持久化到磁盤。
這樣可以保證MySQL異常重啟之后數(shù)據(jù)不丟失。

sync_binlog這個(gè)參數(shù)設(shè)置為1時(shí),表示每次事務(wù)的binlog都持久化到磁盤。這樣保證MySQL異常重啟之后binlog不丟失。

binlog有兩種模式,statement格式的記sql語句,row格式會(huì)記錄行的內(nèi)容,記兩條,更新前和更新后都有。

redo只是完成了prepare,binlog失敗,事務(wù)本身就會(huì)回滾,所以這個(gè)庫(kù)里面status的值是0。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容