首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL InnoDB 表損壞修復實戰:從報警到恢復的完整流程

     編輯:MySQL 資料庫相關知識

故障現象

從庫 MySQL 持續重啟,錯誤日誌顯示:

InnoDB: Database page corruption on disk or a failed
InnoDB: file read of page 30506.
InnoDB: Page may be an index page where index id is 54
InnoDB: (index "PRIMARY" of table "maitem"."email_status")

判斷:表 maitem.email_status 的主鍵索引頁(page 30506)損壞,導致 InnoDB 崩潰循環重啟。

緊急處理:innodb_force_recovery

修改 my.cnf,啟用強制恢復模式:

[mysqld]
innodb_force_recovery = 1

級別說明:

值常量效果
1SRV_FORCE_IGNORE_CORRUPT忽略損壞頁,允許 SELECT/CREATE/DROP,禁止 DML
2SRV_FORCE_NO_BACKGROUND阻止主線程(purge 等)
3SRV_FORCE_NO_TRX_UNDO不執行事務回滾
4SRV_FORCE_NO_IBUF_MERGE不合併插入緩衝
5SRV_FORCE_NO_UNDO_LOG_SCAN視未提交事務為已提交
6SRV_FORCE_NO_LOG_REDO不執行前滾

設為 1 後重啟,實例穩定,可正常讀取資料。

資料搶救與重建

  1. 建立備份表(改用 MyISAM 繞過 InnoDB 損壞)
    CREATE TABLE email_status_bak LIKE email_status;
    ALTER TABLE email_status_bak ENGINE = MyISAM;
  2. 導入資料
    INSERT INTO email_status_bak SELECT * FROM email_status;
  3. 刪除損壞表
    DROP TABLE email_status;
  4. 關閉強制恢復,重啟實例
    # 註釋掉 innodb_force_recovery
    systemctl restart mysqld
  5. 重命名表並轉回 InnoDB
    RENAME TABLE email_status_bak TO email_status;
    ALTER TABLE email_status ENGINE = InnoDB;

關鍵經驗總結

  • 主鍵索引(聚簇索引)損壞比二級索引嚴重,無法用 OPTIMIZE TABLE 修復。
  • innodb_force_recovery=1 是最安全的起手式,僅跳過損壞頁檢查。
  • 若上述方法失效,可嘗試分塊導出:INSERT INTO ... SELECT * FROM ... LIMIT X,或用 mysqldump 導出再導入。
  • 平時務必建立定期備份與監控(如 CHECK TABLE 定時掃描)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved