1. 程式人生 > >一次修改資料庫物理檔案造成Mysql宕機的恢復記錄

一次修改資料庫物理檔案造成Mysql宕機的恢復記錄

事件起始

某夜,我正在床上冥想準備入睡,忽然同事向我求救:訊息內容如下:

Oh My Gold 改了些配置,啥都沒了!都沒了!沒了!了!

我仔細詢問,原來是她因為某些原因將某庫的物理資料夾改名後,發現數據庫找不到了。於是又將名稱改回來。結果仍然找不到。這讓她覺得資料可能被損壞了,於是趕忙來找我修復。

修復過程

我們資料庫用的版本是 MySQL5.7 ,放置在Linux伺服器上,在my.cnf 配置了資料庫物理檔案的存放地址。存放於 data 資料夾下。

表的儲存引擎全部使用 InnoDB,data 目錄的檔案依次如下

  • 用資料庫名命名的資料夾,資料夾記憶體放的 .ibd , .frm 檔案依次是資料庫表資料檔案和表結構檔案
  • ibdata1 (存放InnoDB表元資料、undo logs、the change buffer, and the doublewrite buffer) 檔案
  • ib_logfile0 ,ib_logfile1 事務日誌

這個時候我首先想到的是我本機用Navicat備份過一個檔案,立刻開啟Navicat嘗試還原備份,然而日誌全是 Err錯誤,顯示錶存在,但是我們是看不到的。這時候我就打算刪除該庫,直接使用備份恢復,然而資料庫刪除仍然報錯。我只得去備份了一下物理檔案然後刪除。刪除後再使用Navicat還原

經過一番操作,資料庫檔案是回來了。但是我電腦上的備份檔案他不是實時的,雖然恢復了資料庫,但仍然丟失了部分資料,我心有不甘。於是我想了一個“妙計”: 我把剛才備份的物理檔案裡面的 .frm .ibd 檔案替換到新建立的物理資料夾中。這樣狸貓換太子之後,我豈不是就擁有了最完整的資料?

說幹就幹,一通 cp -rf 過後,成功替換掉原來的檔案。開啟Navicat連線沒有問題,心裡竊喜。就在這時,陸續有同事反應資料庫連不上了,我的天吶。什麼鬼?我開啟MoBa檢視linux 程序,發現Mysql 服務已經宕掉了。我嘗試重啟,報出如下錯誤:

檢視Mysql 錯誤日誌:

This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
Attempting to collect some information that could help diagnose the problem.
As this is a crash and something is definitely wrong, the information
collection process might fail.

經過上網查詢,說是可以通過在 my.cnf 新增如下的配置來強制啟動資料庫官方文件對於該配置的解釋 ,同類問題的回答

[mysqld]
innodb_force_recovery = 1
  • 1SRV_FORCE_IGNORE_CORRUPT

    使伺服器即使檢測到損壞的頁也可以執行 。嘗試跳過損壞的索引記錄和頁,這有助於轉儲表。

  • 2SRV_FORCE_NO_BACKGROUND

    阻止主執行緒和任何清除執行緒執行。如果在清除操作期間發生崩潰,則此恢復值可防止崩潰。

  • 3SRV_FORCE_NO_TRX_UNDO

    崩潰恢復後 不執行事務回滾。

  • 4SRV_FORCE_NO_IBUF_MERGE

    防止插入緩衝區合併操作。如果它們會導致崩潰,請不要這樣做。不計算表 統計資訊。此值可能會永久損壞資料檔案。使用此值後,準備刪除並重新建立所有二級索引。設定 InnoDB為只讀。

  • 5SRV_FORCE_NO_UNDO_LOG_SCAN

    啟動資料庫時 不檢視撤消日誌: InnoDB甚至將未完成的事務也視為已提交。此值可能會永久損壞資料檔案。設定InnoDB為只讀。

  • 6SRV_FORCE_NO_LOG_REDO

    不進行與恢復有關的重做日誌前回滾。此值可能會永久損壞資料檔案。使資料庫頁面處於過時狀態,這又可能導致B樹和其他資料庫結構遭受更多破壞。設定 InnoDB為只讀。

官方文件特別說明:當級別 >= 4 時,可能會對資料庫檔案造成不可挽回的破壞。我嘗試從1 開始逐步修改該值啟動。直到 6 才正常啟動。啟動後,只能執行查詢語句,增刪改都不行。於是我將資料庫檔案全部備份後。關閉資料庫,刪除原來的 資料庫物理檔案、ibdata1 檔案、ib_logfile0 檔案。之後將 innodb_force_recovery 值還原為預設值0。重新恢復了資料庫檔案。解除了此次危機。

啟發

  1. 定時備份資料庫!即使是測試庫。測試庫可以調的時間間隔長一點
  2. 在不懂的情況下不要自作聰明亂動物理檔案!