某創業公司磁碟陣列損壞導致主機 Crash,MySQL 重啟報錯:
InnoDB: Doing recovery: scanned up to log sequence number 9120034833
[ERROR] mysqld got signal 11 -- 訪問違規,核心轉儲
分析:機器異常斷電導致重做日誌損壞,InnoDB 恢復過程中遇到壞頁觸發 Segfault,無法完成 Crash Recovery。
該參數讓 InnoDB 跳過特定恢復步驟,以唯讀模式啟動實例,導出資料後重建。等級 1-6,高等級包含低等級所有限制:
| 等級 | 常數名 | 行為 | 風險 |
|---|---|---|---|
| 1 | SRV_FORCE_IGNORE_CORRUPT | 忽略損壞頁 | 可能讀到髒資料 |
| 2 | SRV_FORCE_NO_BACKGROUND | 禁用主線程(purge、merge 等) | 防止背景線程觸發二次 Crash |
| 3 | SRV_FORCE_NO_TRX_UNDO | 不執行事務回滾 | 未提交事務視同提交 |
| 4 | SRV_FORCE_NO_IBUF_MERGE | 不合併插入緩衝 | 二級索引可能不完整 |
| 5 | SRV_FORCE_NO_UNDO_LOG_SCAN | 不掃描 Undo Log | 同等級 3,更激進 |
| 6 | SRV_FORCE_NO_LOG_REDO | 不執行 Redo Log 前滾 | 資料最可能不一致,最後手段 |
[mysqld]
innodb_force_recovery = 6
innodb_purge_threads = 0 -- 關鍵!避免 5.5-5.6 版本背景線程循環等待
ready for connections 即成功。mysqldump --single-transaction --all-databases > /backup/full.sql
禁止執行 INSERT/UPDATE/DELETE/DDL。MySQL 5.5/5.6 當 innodb_purge_threads=1 且 innodb_force_recovery>1 時,主線程會陷入 Waiting for the background threads to start 無限循環。源碼邏輯:
while (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
if (srv_thread_has_reserved_slot(SRV_MASTER) == ULINT_UNDEFINED ||
(srv_n_purge_threads == 1 && srv_thread_has_reserved_slot(SRV_WORKER) == ULINT_UNDEFINED)) {
os_thread_sleep(1000000); // 1秒睡眠,無限循環
} else break;
}
解法:強制設定 innodb_purge_threads=0(單線程 purge 模式)。