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。
// 頁面級恢復操作集合
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
};
parse_start_lsn:本次恢復起始 LSN(通常為 checkpoint LSN)scanned_lsn:已從 log buffer 掃描解析至 buf 的 LSNrecovered_lsn:已應用至頁面或存入 addr_hash 的 LSN關係:parse_start_lsn ≤ scanned_lsn ≤ recovered_lsn ≤ log_sys->lsn
recv_recovery_from_checkpoint_start:從最近 checkpoint 開始恢復recv_recovery_from_checkpoint_finish:結束恢復、釋放記憶體、處理事務與 binlogrecv_recovery_from_archive_start/finish:從歸檔日誌恢復recv_reset_logs:截斷重做日誌(可能丟失資料)Checkpoint 恢復流程:
recv_recovery_from_checkpoint_start(max_lsn)log_sys->buf → 掃描驗證 → 去除 block header 存入 recv_sys->buf(更新 scanned_lsn) → MTR 解析 → 合法記錄按 (space,page_no) 存入 addr_hash → recv_apply_hashed_log_recs 掃描 hash 表批量應用至頁面(更新 recovered_lsn) → 直到無待恢復日誌recv_recovery_from_checkpoint_finish 收尾recv_sys->addr_hash → recv_addr_t (per page) → rec_t 鏈表 → recv_data_t 鏈表(含 record body)
此設計實現「按頁面聚合、批量應用」,極大降低恢復期隨機 I/O,是 InnoDB 高可用核心基石。