首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 核心源碼解析:InnoDB Redo Log 崩潰恢復機制深度剖析

     編輯:MySQL 綜合教學

MySQL 核心源碼解析:InnoDB Redo Log 崩潰恢復機制深度剖析

1. 核心結構體:recv_sys_t

InnoDB 啟動時透過 recv_sys_t 結構協調 Redo Log 恢復:

struct recv_sys_struct {
  mutex_t mutex;                    // 保護鎖
  ibool apply_log_recs;             // 正在應用 log record 到頁面
  ibool apply_batch_on;             // 批量應用標誌
  dulint lsn;                       // 當前 LSN
  ulint last_log_buf_size;
  byte* last_block;                 // 恢復時最後塊緩衝區
  byte* last_block_buf_start;       // 緩衝區起始位址(512 位元組對齊)
  byte* buf;                        // 從日誌塊讀取的 redo 資料
  ulint len;                        // buf 有效資料長度
  dulint parse_start_lsn;           // 開始解析的 LSN
  dulint scanned_lsn;               // 已掃描 LSN
  ulint scanned_checkpoint_no;      // 恢復 checkpoint 序號
  ulint recovered_offset;           // 恢復位置偏移
  dulint recovered_lsn;             // 已恢復 LSN 位置
  dulint limit_lsn;                 // 最大恢復 LSN(暫未使用)
  ibool found_corrupt_log;          // 是否發現損壞日誌
  log_group_t* archive_group;       // 歸檔日誌組
  mem_heap_t* heap;                 // 記憶體堆管理恢復過程記憶體
  hash_table_t* addr_hash;          // 雜湊表:key=space_id+page_no
  ulint n_addrs;                    // addr_hash 中 recv_addr 數量
};

關鍵設計:addr_hash 以 (space_id, page_no) 為 key,收集同一頁面的所有 redo record,批量寫入減少隨機 I/O。

2. 相關輔助結構

// 頁面級恢復操作集合
struct recv_addr_struct {
  ulint state;              // RECV_NOT_PROCESSED / BEING_PROCESSED / PROCESSED
  ulint space;              // 表空間 ID
  ulint page_no;            // 頁號
  UT_LIST_BASE_NODE_T(recv_t) rec_list;  // 該頁面的 redo record 鏈表
  hash_node_t addr_hash;    // 雜湊節點
};

// 單條 redo record 操作
struct recv_struct {
  byte type;                // log 類型
  ulint len;                // 資料長度
  recv_data_t* data;        // 記錄資料鏈表
  dulint start_lsn;         // MTR 起始 LSN
  dulint end_lsn;           // MTR 結束 LSN
  UT_LIST_NODE_T(recv_t) rec_list;
};

// 實際資料載體
struct recv_data_struct {
  recv_data_t* next;        // 下一個節點,後接大塊記憶體存儲 record body
};

3. 恢復過程 LSN 關係

  • parse_start_lsn:本次恢復起始 LSN(通常為 checkpoint LSN)
  • scanned_lsn:已從 log buffer 掃描解析至 buf 的 LSN
  • recovered_lsn:已應用至頁面或存入 addr_hash 的 LSN

關係:parse_start_lsn ≤ scanned_lsn ≤ recovered_lsn ≤ log_sys->lsn

4. 核心介面與流程

  • recv_recovery_from_checkpoint_start:從最近 checkpoint 開始恢復
  • recv_recovery_from_checkpoint_finish:結束恢復、釋放記憶體、處理事務與 binlog
  • recv_recovery_from_archive_start/finish:從歸檔日誌恢復
  • recv_reset_logs:截斷重做日誌(可能丟失資料)

Checkpoint 恢復流程:

  1. 讀取資料庫檔案中最大 LSN
  2. 呼叫 recv_recovery_from_checkpoint_start(max_lsn)
  3. 定位最近 checkpoint 的日誌組與資訊
  4. 對比 checkpoint LSN 與 max_lsn,相等則無需恢復
  5. 同步各日誌組歸檔狀態
  6. 循環:讀 2MB 日誌到 log_sys->buf → 掃描驗證 → 去除 block header 存入 recv_sys->buf(更新 scanned_lsn) → MTR 解析 → 合法記錄按 (space,page_no) 存入 addr_hash → recv_apply_hashed_log_recs 掃描 hash 表批量應用至頁面(更新 recovered_lsn) → 直到無待恢復日誌
  7. 呼叫 recv_recovery_from_checkpoint_finish 收尾

5. 記憶體關係圖解

recv_sys->addr_hash → recv_addr_t (per page) → rec_t 鏈表 → recv_data_t 鏈表(含 record body)

此設計實現「按頁面聚合、批量應用」,極大降低恢復期隨機 I/O,是 InnoDB 高可用核心基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved