MySQL Forcing InnoDB Recovery
MySQL非正常重啟或者磁碟故障可能導致MySQL資料檔案損壞。這種情況下,如果沒有可用的備份檔案則可使用innodb_force_recovery選項強制InnoDB引擎啟動。這時一些後臺操作不會執行,可以較為安全的dump出資料庫中的表。
innodb_force_recovery選項可選的值為0-6,預設也即正常情況下值為0,在發生故障需要強制啟動時可在MySQL配置檔案[mysqld]節新增innodb_force_recovery = 1配置(或者其他值)。3或者以下的值對於強制重啟後dump資料來說相對安全,可能個別損壞的頁上的一些資料會丟失。4或者以上的值相對危險因為資料檔案可能永久性的損壞。6這個值最為危險。
當innodb_force_recovery值大於0時InnoDB會阻止INSERT、UPDATE、DELETE操作。MySQL5.6.15以後4及以上的值使InnoDB為只讀模式。
幾個取值的意義:
1 (SRV_FORCE_IGNORE_CORRUPT)
儘管檢測到了損壞的頁扔強制伺服器執行。一本情況設定為該值即可,然後dump出庫表進行重建。
2 (SRV_FORCE_NO_BACKGROUND)
阻止master thread和任何purge thread執行。若崩潰發生在purge環節則使用該值
3 (SRV_FORCE_NO_TRX_UNDO)
崩潰恢復後不執行事務回滾
4 (SRV_FORCE_NO_IBUF_MERGE)
阻止插入緩衝合併操作。如果可能導致崩潰則不要做這些操作。不要進行統計操作。該值可能永久損壞資料檔案。若使用了該值,則將來要刪除和重建輔助索引。
5 (SRV_FORCE_NO_UNDO_LOG_SCAN)
啟動資料庫時不檢視undo日誌。此時InnoDB甚至把未完成的事務按照提交處理。該值可能永久性的損壞資料檔案。
6 (SRV_FORCE_NO_LOG_REDO)
恢復時不做redo log roll-forward。使資料庫頁處於廢止狀態,繼而可能引起B樹或者其他資料庫結構更多的損壞。
在值小於等於3時可以通過SELECT來dump表,可以drop或者create表。MySQL5.6.27後大於3的值也支援DROP TABLE;
如果事先知道哪個表導致了崩潰則可drop掉這個表。如果碰到了由失敗的大規模匯入或大量ALTER TABLE操作引起的runaway rollback,則可kill掉mysqld執行緒然後設定 innodb_force_recovery為3使資料庫重啟後不進行rollback。然後刪除導致runaway rollback的表;
如果表內的資料損毀導致不能dump整個表內容。那麼附帶ORDER BY primary_key DESC 從句的查詢或許能夠dump出損毀部分之後的部分資料;
若使用更高的innodb_force_recovery值,那麼一些損壞的資料結構可能引起復雜的查詢無法執行。此時可能只能執行最基本的SELECT * FROM T語句。
需要注意的是,這僅是緊急情況下的一種補救,不能依賴於這個辦法,最好的辦好還是做好資料備份工作,包括全備份和日誌備份。確定要使用該方案是要確保有原始損壞資料的副本。4以上的值可能永久導致資料檔案損壞。務必在測試環境測試通過後再在生產環境使用。