故障現象
- 從庫 MySQL 不斷重啟
- 錯誤日誌:
InnoDB: Database page corruption ... page 30506 ... index "PRIMARY" of table "maitem"."email_status"
- 建議查閱:Forcing InnoDB Recovery
核心參數:innodb_force_recovery
| 值 | 常數 | 行為 |
| 1 | SRV_FORCE_IGNORE_CORRUPT | 忽略損壞頁,允許 SELECT/CREATE/DROP |
| 2 | SRV_FORCE_NO_BACKGROUND | 阻止主執行緒 (含 purge) |
| 3 | SRV_FORCE_NO_TRX_UNDO | 不執行事務回滾 |
| 4 | SRV_FORCE_NO_IBUF_MERGE | 不合併 Insert Buffer |
| 5 | SRV_FORCE_NO_UNDO_LOG_SCAN | 視未提交事務為已提交 |
| 6 | SRV_FORCE_NO_LOG_REDO | 不執行 Redo Log 前滾 |
值越大包含前面所有行為,生產環境建議從 1 開始嘗試。
修復實戰步驟 (主鍵索引損壞)
- 編輯配置:
innodb_force_recovery = 1 → 重啟 MySQL
- 驗證穩定:不再重啟,可正常 SELECT
- 建立新表 (同結構,引擎改 MyISAM 避開 InnoDB 損壞頁):
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 → 重啟 MySQL
- 重命名並轉回 InnoDB:
RENAME TABLE email_status_bak TO email_status;
ALTER TABLE email_status ENGINE = InnoDB;
關鍵避坑指南
REPAIR TABLE / CHECK TABLE 對 InnoDB 無效
ALTER TABLE ... ENGINE=MyISAM 在 innodb_force_recovery > 0 會報錯 ERROR 1025 (HY000),故採用「新建+導入+刪除+重命名」繞過
- 若為二級索引損壞,可直接
OPTIMIZE TABLE 或 ALTER TABLE ... ENGINE=InnoDB 重建
- 若資料字典 損壞,需從備份還原或
mysqldump 導出導入
事後建議
- 啟用
innodb_checksum_algorithm=crc32 (5.6.6+)
- 定期
CHECKSUM TABLE 掃描
- 備份策略:
xtrabackup 熱備 + Binlog 時間點恢復
- 上一篇文章: MySQL 常見錯誤代碼 1005-1045 完整對照表與解決方案
- 下一篇文章: Java 連線 MySQL 亂碼終極解決方案:五層編碼鏈路完整配置
Copyright ©
程式碼之家 All Rights Reserved