參數innodb_force_recovery影響了整個InnoDB存儲引擎的恢復狀況


參數innodb_force_recovery影響了整個InnoDB存儲引擎的恢復狀況。該值默認為0,表示當需要恢復時執行所有的恢復操作。當不能進行有效恢復時,如數據頁發生了corruption,MySQL數據庫可能會宕機,並把錯誤寫入錯誤日志中。

但是,在某些情況下,我們可能並不需要執行完整的恢復操作,我們自己知道如何進行恢復。比如正在對一個表執行alter table操作,這時意外發生了,數據庫重啟時會對InnoDB表執行回滾操作。對於一個大表,這需要很長時間,甚至可能是幾個小時。這時我們可以自行進行恢復,例如可以把表刪除,從備份中重新將數據導入表中,這些操作的速度可能要遠遠快於回滾操作。

innodb_force_recovery還可以設置為6個非零值: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):不查看撤銷日志(Undo Log),InnoDB存儲引擎會將未提交的事務視為已提交。
  • 6(SRV_FORCE_NO_LOG_REDO):不執行前滾的操作。

需要注意的是,當設置參數innodb_force_recovery大於0后,可以對表進行select、create、drop操作,但insert、update或者delete這類操作是不允許的。

模擬故障

我們來做個實驗,模擬故障的發生。在第一會話中,對一張接近1 000W行的InnoDB存儲引擎表執行更新操作,但是完成后不要馬上提交:

start transaction;

update Profile set password='';

--start transaction語句開啟了事務,同時防止了自動提交的發生,update操作則會產生大量的回滾日志。這時,我們人為地kill掉MySQL數據庫服務器。

ps-ef|grep mysqld

kill-9 pid

通過kill命令,我們人為地模擬了一次數據庫宕機故障,當MySQL數據庫下次啟動時會對update的這個事務執行回滾操作,而這些信息都會記錄在錯誤日志文件中,默認后綴名為err。如果查看錯誤日志文件,可得到如下結果:

090922 13:40:20 InnoDB:Started;log sequence number 6 2530474615
InnoDB:Starting in background the rollback of uncommitted transactions
090922 13:40:20 InnoDB:Rolling back trx with id 0 5281035,8867280 rows to undo
InnoDB:Progress in percents:1090922 13:40:20
090922 13:40:20[Note]/usr/local/mysql/bin/mysqld:ready for connections.
Version:'5.0.45-log'socket:'/tmp/mysql.sock'port:3306 MySQL Community
Server(GPL)
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
InnoDB:Rolling back of trx id 0 5281035 completed
090922 13:49:21 InnoDB:Rollback of non-prepared transactions completed

可以看到,如果采用默認的策略,即把innodb_force_recovery設為0,InnoDB會在每次啟動后對發生問題的表執行恢復操作,通過錯誤日志文件,可知這次回滾操作需要回滾8 867 280行記錄,總共耗時約9分多鍾。

我們做再做一次同樣的測試,只不過在啟動MySQL數據庫前將參數innodb_force_recovery設為3,然后觀察InnoDB存儲引擎是否還會執行回滾操作,查看錯誤日志文件,可看到:

090922 14:26:23 InnoDB:Started;log sequence number 7 2253251193
InnoDB:!innodb_force_recovery is set to 3!
090922 14:26:23[Note]/usr/local/mysql/bin/mysqld:ready for connections.
Version:'5.0.45-log'socket:'/tmp/mysql.sock'port:3306 MySQL Community
Server(GPL)

這里出現了“!”,InnoDB警告你已經將innodb_force_recovery設置為3,不會進行undo的回滾操作了。因此數據庫很快啟動完成,但是你應該很小心當前數據庫的狀態,並仔細確認是否不需要回滾操作。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM