MySQL誤刪物理檔案的恢復(Linux)

lhrbest發表於2016-06-13
以前拜讀過一位Oracle大大的文章,結果自己在測試環境也遇到了,順手記下來
Oracle大大的文章連結http://blog.itpub.net/17203031/viewspace-1077770/
-------------------------------------------------------------------------------------正文------------------------------------------------------------------------------------
背景:DB的測試環境誤刪MySQL的日誌檔案ib_logfile1
環境:MySQL5.6.27
問題原因的分析:手滑了_(:з」∠)_
總體思路:
最重要的是冷靜,不要亂搞...
Linux下的檔案描述符的介紹,直接摘錄Oracle大大的描述


所以最重要的一點:冷靜,不要去隨便重啟資料庫,保持當時候的操作現場;

現場還原:測試環境中模擬誤刪ib_logfile1


然後發現資料依然在正常執行,可以插入新的資料

結合之前對Linux的檔案描述符的介紹,可以確定這個檔案還是存在的~
那麼動手找一下,先確定MySQL的程式ID:ps -ef | grep mysql
然後在/proc/fd裡面找到這個PID對應的資料夾(檔名=pid)看一下里面的內容

可以看到檔案還在,但是被標記成了deleted,既然檔案還在,那就好辦了~
趕緊把檔案拷貝回去?  No!
由於日誌也有buffer(innodb_log_buffer_size),拷回去之前,要確認這些日誌都重新整理到了磁碟,同時也要確認在拷貝的時候,沒有新的事務在操作MySQL資料庫;
所以先執行flush tables with readlock;再執行flush logs;

然後看一下新生成的幾個binlog,舊一點的binlog裡面能看到“誤刪”ib_logfile1之後執行的語句

在新生成的binlog裡面則什麼都沒有

確認了舊的redo log已經寫入到磁碟,也沒有新的事務在執行,那麼再把“誤刪”的檔案拷貝回去;


錯誤的場景:
假設最初出現問題的時候,關閉了資料庫,最終這個log沒了,那麼在啟動MySQL的時候就會有如下的報錯

或者是內容有問題,(這裡偷懶了,忘了在刷buffer前拷貝一個錯誤的logfile1,姑且就拿logfile0來湊數了,當成一個錯誤的logfile....._(:з」∠)_...本質上應該是一樣的效果)

那麼把之前處理好以後拷貝出來的logfile拷回去看看,修改檔案的所有者和許可權,啟動MySQL之後,噫!報錯了~
對比下之前拷貝一個內容有問題的logfile的錯誤資訊(模擬操作:沒有把log buffer的資料重新整理到磁碟,結果拷貝出來的logfile不對)

資料檔案和正確處理的logfile的LSN是恰好對應上的;
為什麼明明這個ib_logfile明明有問題,mysql還啟動了?
看看兩次替換日誌檔案後, mysql輸出的資訊(上面是沒有重新整理buffer的logfile,下面是重新整理過buff的)



可以看到資料庫根據重新整理到磁碟的資料檔案的為準,截斷了這些有問題的logfile,然後重新生成了新的logfile的LSN
推測:生成新的logfile的LSN之後,資料檔案中的標記位也發生了變更,從3117292814變成了3117292824,這也是為什麼第二次拷貝正確的logfile進去之後,還是列印出了錯誤日誌;
-------------------------------------------------------------------------------------結束------------------------------------------------------------------------------------
PS:不管是誤刪了資料檔案還是日誌檔案,切記不要關掉資料庫,且恢復的時候一定要確認快取資料全部重新整理到了磁碟~

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

相關文章