【MySQL】崩潰恢復問題解決:Forcing InnoDB Recovery
背景:
MySQL page corruption通常會導致查詢或者後臺執行緒crash或者是甚至會導致innodb前滾恢復crash,這樣的page corruption產生通常是由於資料庫的意外事件,如:斷電、強行kill等。在這種情況下,我們可以使用innodb_force_recovery選項強制InnoDB儲存引擎啟動,並阻止後臺操作執行,以便我們匯出表的資料。
引數值分析:
innodb_force_recovery共有七個值0-6
0(normal startup without forced recovery ):這是預設值,即正常啟動
1(SRV_FORCE_IGNORE_CORRUPT):即使檢測到髒頁,仍然啟動,啟動後,在select * from table_name時,會嘗試跳過損壞的索引頁與資料頁,方便我們dump;值得注意的是,該dump通常能保證資料的完整性,因為這裡的損壞的頁通常是我們不需要的。
2 (SRV_FORCE_NO_BACKGROUND):阻止master thread和purge thread的執行,如果mysql崩潰的原因是purge pages失敗,那麼設定為2會阻止purge執行緒啟動,從而讓mysqld啟動;值得注意的是設定為innodb_force_recovery較高的值包含了較低值的所有功能,其實目的只有一個,就是要啟動,dump出資料。
3 (SRV_FORCE_NO_TRX_UNDO) :阻止事物回滾,(innodb崩潰恢復過程中,要將active狀態的事物回滾),同樣這裡包括了2、1的所有功能。
4 (SRV_FORCE_NO_IBUF_MERGE):阻止insert buffer merge操作,即阻止merge執行緒(這會產生永久的髒資料檔案,當然insert buffer是對於二級索引而言的,我們當然可以重建索引),同樣這裡也會包括3、2、1的功能,從5.7.3開始,還會設定innodb為read_only。
5 (SRV_FORCE_NO_UNDO_LOG_SCAN) :終止undo log的掃描,把未提交的事物當成提交(innodb崩潰恢復過程中,要遍歷undo log以便於重構事物),該操作會對資料檔案做永久性改變,同樣該操作也會包含4、3、2、1的功能,從5.7.3開始,還會設定innodb為read_only。
6 (SRV_FORCE_NO_LOG_REDO) :阻止redo的前滾操作,該操作會對資料檔案做永久性改變,同樣改操作包含5、4、3、2、1的功能,從5.7.3開始,還會設定innodb為read_only。
看了以上7個值的,或許你還不清楚,我們先來了解下MySQL的崩潰恢復流程,這裡簡單概括下:
1.獲取MySQL的LSN,如果MySQL有多個日誌檔案,那就取檔案中的最大值LSN
2.從LSN開始,APPLY BATCH redo;
3.遍歷系統所有的Rollback Segment Header Page,讀取其中的Undo Slot指向的Undo Log Header Page來重構事物(recreate transaction)
4.刪除未建立完成的索引,對於active狀態的事物進行回滾
從這個恢復流程,我們可以看出,innodb_force_recovery是從崩潰恢復流程的四個階段(注意順序4->1)來阻止相關執行緒的動作來防止資料庫起不來,最終的目的是為了讓我們能匯出資料。
恢復步驟:
1.透過遞增設定innodb_force_recovery的值,直到能啟動mysql。
為什麼要遞增設定?
從引數分析部分,我們可以看出來4-6對資料的完整性是有很大損壞的,值越小,完整性越能保證。
1-3我們基本能保證資料一致性,4我們可以透過重建索引,來保證一致性,而5-6則不行
2.用select * from table_name outfile...匯出資料。
3.drop table table_name;
4.設定innodb_force_recovery=0,重新啟動。
5.重新匯入資料。
實戰:
在一個資料庫中,我模擬刪除t12.ibd檔案(這種情況在真事情況下也是存在,當trucate table 時,恰好mysql掛了,就會有.idb檔案被刪除的情況)
1.看一段啟動日誌
2017-03-29 23:37:40 7121 [Note] InnoDB: Reading tablespace information from the .ibd files...
2017-03-29 23:37:40 7121 [ERROR] InnoDB: Attempted to open a previously opened tablespace. Previous tablespace test/playerdiamond uses space ID: 1 at filepath: ./test/playerdiamond.ibd. Cannot open tablespace test/t12 which uses space ID: 1 at filepath: /datatest/test/t12.ibd
2017-03-29 23:37:40 7fa8e7c6f840 InnoDB: Operating system error number 2 in a file operation.
InnoDB: The error means the system cannot find the path specified.
InnoDB: If you are installing InnoDB, remember that you must create
InnoDB: directories yourself, InnoDB does not create them.
InnoDB: Error: could not open single-table tablespace file ./test/t12.ibd
InnoDB: We do not continue the crash recovery, because the table may become
InnoDB: corrupt if we cannot apply the log records in the InnoDB log to it.
InnoDB: To fix the problem and start mysqld:
InnoDB: 1) If there is a permission problem in the file and mysqld cannot
InnoDB: open the file, you should modify the permissions.
InnoDB: 2) If the table is not needed, or you can restore it from a backup,
InnoDB: then you can remove the .ibd file, and InnoDB will do a normal
InnoDB: crash recovery and ignore that table.
InnoDB: 3) If the file system or the disk is broken, and you cannot remove
InnoDB: the .ibd file, you can set innodb_force_recovery > 0 in my.cnf
InnoDB: and force InnoDB to continue crash recovery here.
170329 23:37:41 mysqld_safe mysqld from pid file /usr/local/mysql56/data/mysql.pid ended
170329 23:41:05 mysqld_safe Starting mysqld daemon with databases from /usr/local/mysql56/data
2017-03-29 23:41:06 0 [Note] /usr/local/mysql56/bin/mysqld (mysqld 5.6.32-log) starting as process 9155 ...
從這裡可以看出t12.ibd被刪除了,導致mysql起不來
2.設定innodb_force_recovery=1,啟動
InnoDB: Last MySQL binlog file position 0 160166, file name mysql-bin.000095
2017-03-30 04:35:46 7f7351aaf840 InnoDB: Error: table 'test/t12'
InnoDB: in InnoDB data dictionary has tablespace id 1,
InnoDB: but the tablespace with that id has name test/playerdiamond.
InnoDB: Have you deleted or moved .ibd files?
InnoDB: Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.6/en/innodb-troubleshooting-datadict.html
InnoDB: for how to resolve the issue.
2017-03-30 04:35:46 15193 [Note] InnoDB: 128 rollback segment(s) are active.
2017-03-30 04:35:46 15193 [Note] InnoDB: Waiting for purge to start
2017-03-30 04:35:46 15193 [Note] InnoDB: 5.6.32 started; log sequence number 431731693
2017-03-30 04:35:46 15193 [Note] InnoDB: !!! innodb_force_recovery is set to 1 !!!
2017-03-30 04:35:46 15193 [Note] Recovering after a crash using /usr/local/logdir/mysql-bin
2017-03-30 04:35:46 15193 [Note] Starting crash recovery...
2017-03-30 04:35:46 15193 [Note] Crash recovery finished.
從日誌可以看書mysql Crash recovery完成了,如果還是還是沒啟動你就可以將值設定為2,3,4依次遞增
3.進入mysql,然後drop table t12;
mysql> show create table t12;
ERROR 1146 (42S02): Table 'test.t12' doesn't exist
mysql>
mysql>
mysql> drop table t12;
Query OK, 0 rows affected (0.03 sec)
mysql>
mysql>
由於這裡我是模擬刪除.ibd檔案,所以就沒法恢復資料了,所以也就沒必要匯出,匯入這個這個步驟
4.設定innodb_force_recovery=0,重新啟動
[root@localhost test]# vim /etc/my.cnf
[root@localhost test]# service mysqld restart
Shutting down MySQL... SUCCESS!
Starting MySQL............ SUCCESS!
[root@localhost test]#
由此看到MySQL重新啟動了
MySQL page corruption通常會導致查詢或者後臺執行緒crash或者是甚至會導致innodb前滾恢復crash,這樣的page corruption產生通常是由於資料庫的意外事件,如:斷電、強行kill等。在這種情況下,我們可以使用innodb_force_recovery選項強制InnoDB儲存引擎啟動,並阻止後臺操作執行,以便我們匯出表的資料。
引數值分析:
innodb_force_recovery共有七個值0-6
0(normal startup without forced recovery ):這是預設值,即正常啟動
1(SRV_FORCE_IGNORE_CORRUPT):即使檢測到髒頁,仍然啟動,啟動後,在select * from table_name時,會嘗試跳過損壞的索引頁與資料頁,方便我們dump;值得注意的是,該dump通常能保證資料的完整性,因為這裡的損壞的頁通常是我們不需要的。
2 (SRV_FORCE_NO_BACKGROUND):阻止master thread和purge thread的執行,如果mysql崩潰的原因是purge pages失敗,那麼設定為2會阻止purge執行緒啟動,從而讓mysqld啟動;值得注意的是設定為innodb_force_recovery較高的值包含了較低值的所有功能,其實目的只有一個,就是要啟動,dump出資料。
3 (SRV_FORCE_NO_TRX_UNDO) :阻止事物回滾,(innodb崩潰恢復過程中,要將active狀態的事物回滾),同樣這裡包括了2、1的所有功能。
4 (SRV_FORCE_NO_IBUF_MERGE):阻止insert buffer merge操作,即阻止merge執行緒(這會產生永久的髒資料檔案,當然insert buffer是對於二級索引而言的,我們當然可以重建索引),同樣這裡也會包括3、2、1的功能,從5.7.3開始,還會設定innodb為read_only。
5 (SRV_FORCE_NO_UNDO_LOG_SCAN) :終止undo log的掃描,把未提交的事物當成提交(innodb崩潰恢復過程中,要遍歷undo log以便於重構事物),該操作會對資料檔案做永久性改變,同樣該操作也會包含4、3、2、1的功能,從5.7.3開始,還會設定innodb為read_only。
6 (SRV_FORCE_NO_LOG_REDO) :阻止redo的前滾操作,該操作會對資料檔案做永久性改變,同樣改操作包含5、4、3、2、1的功能,從5.7.3開始,還會設定innodb為read_only。
看了以上7個值的,或許你還不清楚,我們先來了解下MySQL的崩潰恢復流程,這裡簡單概括下:
1.獲取MySQL的LSN,如果MySQL有多個日誌檔案,那就取檔案中的最大值LSN
2.從LSN開始,APPLY BATCH redo;
3.遍歷系統所有的Rollback Segment Header Page,讀取其中的Undo Slot指向的Undo Log Header Page來重構事物(recreate transaction)
4.刪除未建立完成的索引,對於active狀態的事物進行回滾
從這個恢復流程,我們可以看出,innodb_force_recovery是從崩潰恢復流程的四個階段(注意順序4->1)來阻止相關執行緒的動作來防止資料庫起不來,最終的目的是為了讓我們能匯出資料。
恢復步驟:
1.透過遞增設定innodb_force_recovery的值,直到能啟動mysql。
為什麼要遞增設定?
從引數分析部分,我們可以看出來4-6對資料的完整性是有很大損壞的,值越小,完整性越能保證。
1-3我們基本能保證資料一致性,4我們可以透過重建索引,來保證一致性,而5-6則不行
2.用select * from table_name outfile...匯出資料。
3.drop table table_name;
4.設定innodb_force_recovery=0,重新啟動。
5.重新匯入資料。
實戰:
在一個資料庫中,我模擬刪除t12.ibd檔案(這種情況在真事情況下也是存在,當trucate table 時,恰好mysql掛了,就會有.idb檔案被刪除的情況)
1.看一段啟動日誌
2017-03-29 23:37:40 7121 [Note] InnoDB: Reading tablespace information from the .ibd files...
2017-03-29 23:37:40 7121 [ERROR] InnoDB: Attempted to open a previously opened tablespace. Previous tablespace test/playerdiamond uses space ID: 1 at filepath: ./test/playerdiamond.ibd. Cannot open tablespace test/t12 which uses space ID: 1 at filepath: /datatest/test/t12.ibd
2017-03-29 23:37:40 7fa8e7c6f840 InnoDB: Operating system error number 2 in a file operation.
InnoDB: The error means the system cannot find the path specified.
InnoDB: If you are installing InnoDB, remember that you must create
InnoDB: directories yourself, InnoDB does not create them.
InnoDB: Error: could not open single-table tablespace file ./test/t12.ibd
InnoDB: We do not continue the crash recovery, because the table may become
InnoDB: corrupt if we cannot apply the log records in the InnoDB log to it.
InnoDB: To fix the problem and start mysqld:
InnoDB: 1) If there is a permission problem in the file and mysqld cannot
InnoDB: open the file, you should modify the permissions.
InnoDB: 2) If the table is not needed, or you can restore it from a backup,
InnoDB: then you can remove the .ibd file, and InnoDB will do a normal
InnoDB: crash recovery and ignore that table.
InnoDB: 3) If the file system or the disk is broken, and you cannot remove
InnoDB: the .ibd file, you can set innodb_force_recovery > 0 in my.cnf
InnoDB: and force InnoDB to continue crash recovery here.
170329 23:37:41 mysqld_safe mysqld from pid file /usr/local/mysql56/data/mysql.pid ended
170329 23:41:05 mysqld_safe Starting mysqld daemon with databases from /usr/local/mysql56/data
2017-03-29 23:41:06 0 [Note] /usr/local/mysql56/bin/mysqld (mysqld 5.6.32-log) starting as process 9155 ...
從這裡可以看出t12.ibd被刪除了,導致mysql起不來
2.設定innodb_force_recovery=1,啟動
InnoDB: Last MySQL binlog file position 0 160166, file name mysql-bin.000095
2017-03-30 04:35:46 7f7351aaf840 InnoDB: Error: table 'test/t12'
InnoDB: in InnoDB data dictionary has tablespace id 1,
InnoDB: but the tablespace with that id has name test/playerdiamond.
InnoDB: Have you deleted or moved .ibd files?
InnoDB: Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.6/en/innodb-troubleshooting-datadict.html
InnoDB: for how to resolve the issue.
2017-03-30 04:35:46 15193 [Note] InnoDB: 128 rollback segment(s) are active.
2017-03-30 04:35:46 15193 [Note] InnoDB: Waiting for purge to start
2017-03-30 04:35:46 15193 [Note] InnoDB: 5.6.32 started; log sequence number 431731693
2017-03-30 04:35:46 15193 [Note] InnoDB: !!! innodb_force_recovery is set to 1 !!!
2017-03-30 04:35:46 15193 [Note] Recovering after a crash using /usr/local/logdir/mysql-bin
2017-03-30 04:35:46 15193 [Note] Starting crash recovery...
2017-03-30 04:35:46 15193 [Note] Crash recovery finished.
從日誌可以看書mysql Crash recovery完成了,如果還是還是沒啟動你就可以將值設定為2,3,4依次遞增
3.進入mysql,然後drop table t12;
mysql> show create table t12;
ERROR 1146 (42S02): Table 'test.t12' doesn't exist
mysql>
mysql>
mysql> drop table t12;
Query OK, 0 rows affected (0.03 sec)
mysql>
mysql>
由於這裡我是模擬刪除.ibd檔案,所以就沒法恢復資料了,所以也就沒必要匯出,匯入這個這個步驟
4.設定innodb_force_recovery=0,重新啟動
[root@localhost test]# vim /etc/my.cnf
[root@localhost test]# service mysqld restart
Shutting down MySQL... SUCCESS!
Starting MySQL............ SUCCESS!
[root@localhost test]#
由此看到MySQL重新啟動了
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30221425/viewspace-2136469/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL 引擎特性:InnoDB崩潰恢復MySql
- InnoDB 崩潰恢復機制
- MySQL 崩潰恢復過程分析MySql
- AI|經常崩潰的問題解決AI
- Backup And Recovery User's Guide-介質恢復問題解決GUIIDE
- Backup And Recovery User's Guide-介質恢復問題解決-執行試驗恢復GUIIDE
- Linux崩潰恢復工具--CRK(轉)Linux
- 記錄一次解決App崩潰問題的解決方案APP
- Backup And Recovery User's Guide-介質恢復問題解決-調查介質恢復問題:階段1GUIIDE
- 基於Redo Log和Undo Log的MySQL崩潰恢復流程MySql
- 分享:MySQL資料庫崩潰解決過程MySql資料庫
- 儲存崩潰資料恢復過程;資料恢復案例資料恢復
- 【案例】利用innodb_force_recovery解決MySQL伺服器crash無法重啟問題MySql伺服器
- 【案例】利用innodb_force_recovery 解決MySQL伺服器crash無法重啟問題MySql伺服器
- ## 【分散式事務】面試官問我:MySQL中的XA事務崩潰瞭如何恢復??分散式面試MySql
- UIPikerView 省市區三聯滑動,解決滑動崩潰問題UIView
- windows10桌面崩潰怎麼修復_win10桌面無限崩潰解決方法WindowsWin10
- MySQL crash recovery恢復慢分析MySql
- 一起看下MySQL的崩潰恢復到底是怎麼回事MySql
- 使用Percona Data Recovery Tool for InnoDB恢復資料
- 【MySQL】Innodb 恢復工具介紹MySql
- 解決實名軟體造成的 XP系統崩潰問題(轉)
- 某品牌儲存raid崩潰解決方案/raid5資料恢復案例AI資料恢復
- MySQL修復壞塊引數innodb_force_recovery的解釋MySql
- 資料庫崩潰恢復表結構的方法資料庫
- 伺服器崩潰硬碟壞道資料恢復伺服器硬碟資料恢復
- win10 pr崩潰怎麼解決_win10 pr崩潰解決辦法Win10
- 解決跨海高併發崩潰難題?so easy
- win10經常網頁崩潰怎麼解決 win10網頁崩潰如何修復Win10網頁
- 【MySQL】二、Innodb 恢復工具介紹MySql
- 大型網站如何防止崩潰,解決高併發帶來的問題網站
- 全面解決amule容易崩潰和中文顯示、輸入的問題(轉)
- mysql 5.5 索引建設(表rebuild)過程中的系統崩潰的恢復MySql索引Rebuild
- qq遊戲崩潰w10解決方法_w10系統玩qq遊戲老崩潰如何修復遊戲
- win10工作管理員崩潰怎麼解決_win10工作管理員崩潰黑屏修復方法Win10
- win10 qq影片崩潰怎麼修復_win10系統qq影片老是崩潰解決方法Win10
- 360瀏覽器總是崩潰是為什麼 360經常崩潰解決修復方法介紹瀏覽器
- 惠普塔式伺服器崩潰資料恢復成功案例伺服器資料恢復