從庫 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 崩潰循環重啟。
修改 my.cnf,啟用強制恢復模式:
[mysqld]
innodb_force_recovery = 1
級別說明:
| 值 | 常量 | 效果 |
|---|---|---|
| 1 | SRV_FORCE_IGNORE_CORRUPT | 忽略損壞頁,允許 SELECT/CREATE/DROP,禁止 DML |
| 2 | SRV_FORCE_NO_BACKGROUND | 阻止主線程(purge 等) |
| 3 | SRV_FORCE_NO_TRX_UNDO | 不執行事務回滾 |
| 4 | SRV_FORCE_NO_IBUF_MERGE | 不合併插入緩衝 |
| 5 | SRV_FORCE_NO_UNDO_LOG_SCAN | 視未提交事務為已提交 |
| 6 | SRV_FORCE_NO_LOG_REDO | 不執行前滾 |
設為 1 後重啟,實例穩定,可正常讀取資料。
CREATE TABLE email_status_bak LIKE email_status;
ALTER TABLE email_status_bak ENGINE = MyISAM;
INSERT INTO email_status_bak SELECT * FROM email_status;
DROP TABLE email_status;
# 註釋掉 innodb_force_recovery
systemctl restart mysqld
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 定時掃描)。