【MySQL】 DB 回滾崩潰案例一則

楊奇龍發表於2013-05-31
背景
一個測試人員對效能資料庫進行效能壓測 ,由於儲存過程寫的有問題,對一個大表進行大量更新為及時提交 ,見proc hang 住就kill 掉程式,然後長時間等待未果直接重啟mysql 服務。之後錯誤日誌中報錯:
130516 20:47:36  InnoDB: Error: page 5 log sequence number 151 2771374516
InnoDB: is in the future! Current system log sequence number 131 3791365897.
InnoDB: Your database may be corrupt or you may have copied the InnoDB
InnoDB: tablespace but not the InnoDB log files. See
InnoDB: http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.html
InnoDB: for more information.
問題分析
根據錯誤提示:資料檔案的LSN比redo log的LSN要大,當系統嘗試使用Redo Log去修復資料頁面的時候,發現Redo Log LSN比資料頁面還小,所以導致錯誤。資料頁的LSN在一般情況下,都是小於Redo Log的,因為在事物提交或按照 innodb_trx_commit 設定的方式提交時,先將事物順序寫入Redo Log , 然後後臺執行緒按照 max_prt_dirty_page 引數設定的比例重新整理或當系統檢測到當10秒內系統會執行重新整理髒頁操作,所以,資料頁的LSN正常情況下永遠會比Redo Log 的LSN 小。
此次問題是正是由於資料庫在kill 掉程式之後執行回滾操作,但是未等回滾執行完畢就kill -9 mysql 導致回滾崩潰。
解決方法
上述問題的解決方法 是設定innodb_force_recovery=3 或者4 ,需要逐個嘗試。然後重啟資料庫服務 匯出重要的資料,重建資料庫。
 
innodb_force_recovery 可以設定為1-6,大的數字包含前面所有數字的影響。
1 (SRV_FORCE_IGNORE_CORRUPT):    忽略檢查到的corrupt頁。 
2 (SRV_FORCE_NO_BACKGROUND):     阻止主執行緒的執行,如主執行緒需要執行full purge操作,會導致crash。 
3 (SRV_FORCE_NO_TRX_UNDO):         不執行事務回滾操作。 
4 (SRV_FORCE_NO_IBUF_MERGE):       不執行插入緩衝的合併操作。 
5 (SRV_FORCE_NO_UNDO_LOG_SCAN):不檢視重做日誌,InnoDB儲存引擎會將未提交的事務視為已提交。 
6 (SRV_FORCE_NO_LOG_REDO):         不執行前滾的操作。 
當設定引數值大於0後,可以對錶進行select,create,drop操作,但insert,update或者delete這類操作是不允許的。當然即使innodb_force_recovery>0 ,你也可以DROP或CREATE表。如果某個表正在回滾而導致資料庫崩潰,設定innodb_force_recovery為3,重啟db 後,使得資料庫被掛起而不需要回滾,然後捨棄導致失控回滾的表。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22664653/viewspace-762668/,如需轉載,請註明出處,否則將追究法律責任。

相關文章