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

MySQL 崩潰無法重啟?innodb_force_recovery 緊急搶救實戰指南

     編輯:MySQL 綜合教學

故障現場

某創業公司磁碟陣列損壞導致主機 Crash,MySQL 重啟報錯:

InnoDB: Doing recovery: scanned up to log sequence number 9120034833
[ERROR] mysqld got signal 11  -- 訪問違規,核心轉儲

分析:機器異常斷電導致重做日誌損壞,InnoDB 恢復過程中遇到壞頁觸發 Segfault,無法完成 Crash Recovery。

搶救原理:innodb_force_recovery 參數詳解

該參數讓 InnoDB 跳過特定恢復步驟,以唯讀模式啟動實例,導出資料後重建。等級 1-6,高等級包含低等級所有限制:

等級常數名行為風險
1SRV_FORCE_IGNORE_CORRUPT忽略損壞頁可能讀到髒資料
2SRV_FORCE_NO_BACKGROUND禁用主線程(purge、merge 等)防止背景線程觸發二次 Crash
3SRV_FORCE_NO_TRX_UNDO不執行事務回滾未提交事務視同提交
4SRV_FORCE_NO_IBUF_MERGE不合併插入緩衝二級索引可能不完整
5SRV_FORCE_NO_UNDO_LOG_SCAN不掃描 Undo Log同等級 3,更激進
6SRV_FORCE_NO_LOG_REDO不執行 Redo Log 前滾資料最可能不一致,最後手段

實戰操作步驟

  1. 修改配置(my.cnf):
    [mysqld]
    innodb_force_recovery = 6
    innodb_purge_threads = 0  -- 關鍵!避免 5.5-5.6 版本背景線程循環等待
  2. 重啟 MySQL:觀察錯誤日誌出現 ready for connections 即成功。
  3. 唯讀導出資料:
    mysqldump --single-transaction --all-databases > /backup/full.sql
    禁止執行 INSERT/UPDATE/DELETE/DDL。
  4. 重建實例:將參數恢復為 0,初始化新實例,導入備份。

避坑指南:innodb_purge_threads 陷阱

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 模式)。

事後總結

  • Crash Safe Replication (MySQL 5.6+ GTID + relay-log-info-repository=TABLE + sync_relay_log=1) 可最大程度避免 Error 1594/1236。
  • 定期驗證備份可用性,建立 RTO/RPO 指標演練。
  • 硬體層面:RAID 卡 BBU、磁碟健康監控、雙機熱備。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved