記錄一次刪了開發環境數據庫文件恢復的過程!(大部分恢復)

是的,我一不小心把開發環境下數據庫的data刪除了

show variables like '%datadir%';

對的,就是上面這個路徑下的全刪了,恐怖。。。。。 當時腦子一片空白,想想還好是開發環境,後面趕快找運維恢復。。

 

刪了這些文件之後,mysql進程還在(這是最好的結果),服務已經掛了。

 

在看完運維噼裏啪啦一頓操作數據庫終於恢復好了(有驚無險。。),趕緊抓着這個機會向大佬學習了一波,後來我自己又試着恢復了日誌文件,下面就用恢復日誌來舉例,恢復數據庫文件也是一樣的過程(但是複雜多了,考慮的東西也多多了)。

 

注意:這種恢復方法只能恢復那些被進程調用並存在於內存中的文件,如服務的日誌文件,數據庫的數據等,對於日誌和數據庫的恢復來說非常有用

 

恢復過程:

1、首先先查到我們刪除的文件會被哪個關聯的進程調用(這個是恢復前提,沒有這個就不能恢復),我們可以看到這時運行着redis服務,端口是6380, 這時開着aof 每秒追加的模式。如果對redis持久化不熟悉的可以查 redis學習日記(二):redis 小工具及持久化

 

在這裏我們可以看着這個名爲  appendonly-6380.log 日誌文件,這個就是和redis進程有關的文件,下面我們將刪除這個文件再恢復。

 

 

2、好的,現在這個文件被刪除,首先我們使用 lsof 命令查看這個文件與哪個進程有關, 通過這個文件的路徑grep 查詢即可,我們可以發現這個進程號就是redis服務的進程號。

 

3、在確定這個進程號之後,我們進入linux   /proc/pid/fd 路徑下,這裏我們pid是15120, 所以我們進入  cd  /proc/15120/fd ,打印裏面的內容看看。 我們可以看到這個文件後面被標了 (deleted) 標記。

4、 打印這個文件發現內容和原來一樣,所以我們重定向生成原來的文件即可 。 

root@czx:/proc/15120/fd# cat 5 > /data/soft/redis-5.0.0/data/appendonly-6380.aof

5、 這樣我們就把一個日誌文件重新恢復了。數據庫文件也是一樣,加載的數據庫數據都會被mysql進程可視,這時最後一道可以找到這個文件的入口,如果這個進程沒了就也找不到了。

 

總結:

1、通過 lsof  結合grep 找到和刪除文件相關的pid。

root@czx:/data/soft/redis-5.0.0/data# lsof | grep /data/soft/redis-5.0.0/data/appendonly-6380.aof

2、拿着這個pid 進入 /proc/pid/fd  文件夾,找到被刪除的文件,在文件後面會有 deleted 標記。

root@czx:/proc/15120/fd# pwd
/proc/15120/fd

3、通過重定向或者複製這個文件到原來的路徑就可以了。

root@czx:/proc/15120/fd# cat 5 > /data/soft/redis-5.0.0/data/appendonly-6380.aof

 

看了恢復的過程,我又去了解了下爲什麼linux下可以這麼做。

恢復的原理:

1、首先 linux 操作系統下文件實際上是一個指向inode的鏈接, inode鏈接包含了文件的所有屬性, 比如權限和所有者, 數據塊地址(文件存儲在磁盤的這些數據塊中). 當你刪除(rm)一個文件, 實際刪除了指向inode的鏈接, 並沒有刪除inode的內容. 進程可能還在使用. 只有當inode的所有鏈接完全移去, 這些數據纔算真正刪除,這也是之前爲什麼一直強調要有指向這個文件的進程就是這個道理,當我們rm刪除一個文件時,我們就只剩下進程這個指向這個文件的鏈接了,也就是說這時如果我們把這個進程kill掉,那這個文件就用這個方法恢復不了了。

2、既然這時實際文件沒有被刪除,那它就還存在於磁盤中,準確說應該是內存中,那它存在哪裏呢?

答案就是在這個 /proc 文件夾下,這個proc文件夾下存放了各種以進程號命名的文件(如上面的 15120 文件夾)和 如 stat 這些 linux 內核相關的文件(stat文件就寫着當前cpu的一些信息)。而 /proc/15120/fd 下就是存放這個進程放在內存中的一些文件,我們可以看到這裏就有刪除的文件。

3、有了這個即將刪除的文件我們就能隨意操作了。
 

 

回到主題:

我們用上述方式恢復了部分數據庫文件,對的,只能恢復部分,悲劇。。。。只能接着又去請教了運維

 

那爲什麼只能恢復部分呢?

按照上述講的內容,只有進程正在使用的文件會被加載到內存中來,即使全部文件正在使用好了,可能也會被計算機本身的內存所限制而只存放部分文件,更何況有些數據根本沒人使用。

 

還有一個問題,有些數據庫文件被恢復了但是仍然不能訪問或者沒數據的情況

這時就牽扯到mysql數據庫的存儲方式了。

1、首先數據庫有個存放數據的路徑 ,叫【datadir】 。在配置文件中如  datadir = /var/lib/mysql 就指定存放位置,這下面就存放MySQL 數據庫文件,包括 MySQL 所建數據庫文件和 MySQL 所用存儲引擎創建的數據庫文件

我們知道現在主流的數據庫存儲的兩個引擎是 MyISAM 和InnoDB。那在這兩個引擎模式下它又是以怎麼樣的方式存放的呢?

我這裏畫了一個圖方便理解。

我們可以看到無論是什麼引擎,【.frm文件】都是存在的,我們可以理解爲這個是定義一張表的表結構的文件,每個表對應一個同名frm文件。

而對於MyISAM存儲引擎來說,它的表索引和表數據是單獨分開的,所以一張表對應一個 【MYD表數據文件】 和 一個 【MYI表索引文件】。

對於InnoDB存儲引擎來說,它的表索引和表數據是存放在一起的,所以一張表對應一個 【MYD表數據文件】 和 一個 【MYI表索引文件】,默認使用一個表一個 【IDB文件】。

2、所以要恢復數據庫的一張表,如果是 InnoDB 存儲引擎,除了 IDB文件外還要有 FRM文件,這裏的 FRM 文件和 IDB 文件必須是一一對應,如果FRM對應的表結構和 IDB 存儲的數據格式不一致 恢復也不能成功,反正就是這兩個的文件缺失或者格式不對都不能正常使用,一定得是同時存在並且格式一致。

 

最後

說下恢復結果 ,昨天下午不小心刪了數據,晚上按照之前的方法大致恢復了一部分,基本的數據都恢復了,以爲沒事了。

結果第二天反應說有些表不能使用(100多張表),後來發現少了frm文件,然後從測試庫複製了缺失的文件到開發,還剩30多張不能使用(不能使用的原因大概就是frm文件和數據文件不對應)。。。黔驢技窮。。。把這30多張表刪了,直接把測試環境的表結構和數據都導入到了開發環境。。

 

雖然最後大部分恢復了,但還是有點小難受,吃一塹長一智,使用  rm 命令前一定要千萬小心,小心再小心。。。

 

最後的最後。。。大佬們如果有什麼恢復數據的好方法,一定虛心求教!寫的有什麼不對的,下方評論留言我也好學習學習

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章