binlog和redoLog在崩潰恢復上的作用


what:

  崩潰恢復:即使在數據庫宕機的情況下,也會出現操作一半的情況;

  bin log :是server層的歸檔日志,不足以實現崩潰恢復(crash-safe);

  redo log :是物理日志,具有崩潰恢復的能力;

 

diff:

  1、適用對象:

    bin log: 是 MySQL 的 Server 層實現的,所有引擎都可以使用;

    redo log :是 InnoDB 引擎特有的;

  2、寫入內容:

    bin log:是邏輯日志。記錄的是這個語句的原始邏輯,比如 “給 id = 1 這一行的 age 字段加 1”;

    redo log :是物理日志。記錄的是 “在某個數據頁上做了什么修改”;

  3、寫入方式:

    bin log:是追加寫入。“追加寫” 是指 bin log 文件寫到一定大小后會切換到下一個,並不會覆蓋以前的日志。那么就會出現“沒有標志能讓 InnoDB 從 bin log 中判斷哪些數據已經刷入磁盤了,哪些數據還沒有”;

    redo log :是循環寫入。即空間固定會被用完;那么“會記錄未刷入磁盤的日志,已經刷入磁盤的數據就會刪掉”;

 

how:

  核心方案:redo log采用兩階段提交。即redo log的寫入拆分為了2個步驟:preparecommit

 

   SQL 查詢語句的執行過程:(具體流程入下圖)

    1、MySQL 客戶端與服務器間建立連接,客戶端發送一條查詢給服務器

    2、服務器檢查查詢緩存,如果命中了緩存,則立刻返回存儲在緩存中的結果;否則進入下一階段;

    3、服務器端進行 SQL 解析、預處理,生成合法的解析樹;

    4、由優化器生成對應的執行計划

    5、執行器根據執行計划(優化器生成),調用相應的存儲引擎的 API 來執行,並將執行結果返回給客戶端;

      

 

  SQL更新語句的執行過程:相對查詢多了,兩日志模塊 bin log 和 redo log的操作。

    以“update tablese tage=age+1 where id=1;”為栗子:

    注意:以下操作和查詢的前4步相同。

    1、執行器:找存儲引擎取到 id = 1 這一行記錄;

    2、存儲引擎:根據主鍵索引到這一行,如果 id = 1 這一行所在的數據頁本來就在內存池(Buffer Pool)中,就直接返回給執行器;否則,需要先從磁盤讀入內存池,然后再返回;

    3、執行器:拿到存儲引擎返回的行記錄,把 age 字段加上 1,得到一行的記錄,然后再調用存儲引擎的接口寫入這行新記錄;

    4、存儲引擎:將這行新數據更新到內存中,同時將這個更新操作記錄到 redo log 里面,此時 redo log 處於 prepare 狀態。然后告知執行器執行完成了,隨時可以提交事務

          注意:此處的“事務”是提交過程中的一個小步驟,也是最后一步,而非 sql 語句中的提交事務 commit 命令

    5、執行器生成這個操作的 bin log,並把 bin log 寫入磁盤;

    6、執行器:調用存儲引擎的提交事務接口;

    7、存儲引擎:把剛剛寫入的 redo log 狀態改成提交(commit)狀態,更新完成

    具體如下圖:

    

 

 

 why():

   怎么判斷bin log 是不是完整的?

    1、statement 格式的 bin log,最后會有 COMMIT;

    2、row 格式的 bin log,最后會有 XID event;

    3、對於 bin log 可能會在中間出錯的情況,MySQL 5.6.2 版本以后引入了 binlog-checksum 參數,用來驗證 bin log 內容的正確性;

 

  為何redo log有崩潰恢復能力?

    1、如果 redo log 里面的事務是完整的,也就是已經有了 commit 標識,則直接提交;

    2、如果 redo log 里面的事務處於 prepare 狀態,則判斷對應的事務 binlog 是否存在並完整

      a、如果 binlog 存在並完整,則提交事務;

      b、否則,回滾事務;

 

  栗子1:“數據庫在寫入 redo log(prepare) 階段之后、寫入 binlog 之前,發生了崩潰”。

    分析:此時,redo log處於prepare狀態,但是binlog沒有完成,事務就需要回歸。

    原因:binlog 還沒有寫入,之后從庫進行同步的時候,就會缺少數據,但是主庫中已經有數據了,結果就是“主從不一致”,所以主庫的操作需要回滾。

 

  栗子2:“數據庫在寫入 binlog 之后,redo log在commit之前發生了崩潰”。圖如下:

    分析:redo log處於prepare狀態,binlog完整了,事務直接提交。

    原因: binlog 寫入成功,從庫能夠同步過去。此時主庫並沒有完成這個操作,所以主備就不一致了。那么在主庫上需要提交這個事務。

              

 

 

  

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM