記一次刪庫到數據恢復

熟悉的朋友可能知道,進入架構組後,今年一直在爲團隊作各類開發輔助工具,其中包括一個服務器。node

最近這個服務器也上線有三月多了,也不斷收集了不少數據,包括用戶的各類行爲操做、API 調用數據等等。linux

在最近的一次升級中,我調整了源碼的目錄結構,腦子一抽刪除了數據庫。sql

因而就開始爲期一天的數據恢復過程,最後的結果是很悲劇,好在影響不大,能夠放到後面講。shell

文件找回

須要說明的是,由於是小微服務,採用的是最簡單的 SQLite 數據庫。SQLite 區分其餘的數據庫的明顯地方是,它只提供最基本的數據服務,但並不啓用端口監聽,能夠簡單的認爲這就是個文件,若是刪除了,就和普通文件從系統中消失是同樣的。因此一般若是使用 SQLite 保存數據須要自行按期備份。數據庫

因此此次的博文雖然叫『刪庫』,但實際上能夠簡單的理解成文件找回後端

rm -rf

我在誤刪時,是使用 rm -rf 命令,這固然是個耳熟能詳的惡名遠揚的命令(以致於我當時請教後端大佬的時候,後端大佬的反應是『哦,你也終於刪一次庫啦』)bash

rm 是 linux 系統的用於『刪除文件或目錄』的命令服務器

-f 標識表示 force,即:架構

在除去有寫保護的文件前不提示。微服務

-r 標識表示:

當 File 參數爲目錄時容許循環的刪除目錄及其內容

FYI: 更多參考

extundelete 與磁盤存儲

extundelete 是 linux 系統下一個有力的數據恢復工具。extundelete使用存儲在分區日誌中的信息來嘗試恢復已從分區中刪除的文件。

咱們稍微複習一下計算機基礎知識:

硬盤

硬盤是一種採用磁介質的數據存儲設備,數據『物理意義上的』存儲在若干個磁盤片上。在磁盤片的每一面上,以轉動軸爲軸心、以必定的磁密度爲間隔的若干個同心圓就被劃分紅磁道(track),每一個磁道又被劃分爲若干個扇區(sector)。

主引導扇區和分區表

硬盤的0磁道0柱面1扇區是主引導扇區位,包括硬盤主引導記錄MBR(Main Boot Record)和分區表DPT(Disk Partition Table)。操做系統經過分區表把硬盤劃分爲若干個分區,而後再在每一個分區裏面建立文件系統,寫入數據文件。

分區日誌

分區日誌系統是一個文件系統,用於修復因爲計算機關閉不當而致使的任何不一致。這種關閉一般是因爲電源中斷或軟件問題形成的。即記錄了分區的數據讀寫操做。

經過這些日誌,能夠知道分區中的歷史操做。

數據存儲

具體的數據存儲原理內容比較多,這裏不作贅述。爲了便於理解,我在此理解爲:

操做系統中的文件在硬盤的表現形式是在硬盤一片數據區域記錄二進制信息,並由操做系統的一個指針指向該物理地址 而操做系統級別的『刪除文件』,即刪除這個『指針』 原來的物理地址內沒有『指針』指向後,至關於被釋放,當操做系統須要時,能夠被複寫上新的數據。

由此觀得,extundelete 經過查閱分區日誌,找到被刪除的指針,告訴用戶,能夠嘗試恢復哪些數據。

但因爲操做系統隨時能夠複寫空餘磁盤,因此若是要恢復的物理地址已經被改寫,數據將沒法找回。

DEMO

爲了脫敏,我使用我本身的服務器,具體記錄一下文件恢復的過程。

環境

  • CentOS 7.4 64位
  • 文件目錄: /root/Sparrow/db.sqlite3

刪除文件

# rm -rf db.sqlite3
複製代碼

安裝 extundelete

# yum install extundelete -y
複製代碼

掛載磁盤

首先咱們去查詢這個文件或上級文件夾所處的磁盤

# df /root/Sparrow/
文件系統          1K-塊    已用     可用 已用% 掛載點
/dev/vda1      41151808 2614640 36423736    7% /
複製代碼

找到後首要的是掛載磁盤,掛載後磁盤將不會被繼續寫入,保護現場

umount /dev/vda1
複製代碼

/dev/vda1 就是文件所在的磁盤。

不掛載也是能夠的,這樣會致使磁盤可能會被其餘的進程寫入數據,從而抹掉原來的數據,因此我最後沒有找回文件就是由於沒有及時掛載。

inode

inode 是 linux 系統下文件或者文件夾的標識。經過 ls –id 就能夠看到。

讀取根目錄的 inode 值:

# ls -id /
2 /
複製代碼

如今咱們知道磁盤根目錄的 inode 是 2。

extundelete 查詢可恢復的數據信息

先查詢磁盤根目錄下的可恢復信息

# extundelete /dev/vda1 --inode 2
複製代碼

執行時,若是沒有掛載磁盤,會提示。

獲得結果:

重點盤紅圈內,看到 root 的 inode 是 131073,繼續查詢 /dev 的信息:

# extundelete /dev/vda1 --inode 131073
複製代碼

看到 /Sparrow 是 262194,繼續查詢 /dev 的信息:

# extundelete /dev/vda1 --inode 262194
複製代碼

最終找到了刪除信息:

能夠看到 db.sqlite3 被標識爲 Deleted

extundelete 恢復數據

執行 --restore-directory 恢復指定目錄

# extundelete /dev/vda1 --restore-directory /root/Sparrow/db.sqlite3
複製代碼

或執行 --restore-all 恢復全部可恢復的數據

# extundelete /dev/vda1 --restore-all
複製代碼

執行結束後,會在當前路徑下,生成一個 RECOVERED_FILES 文件夾,裏面有全部被恢復的文件。

若是磁盤已經被讀寫,沒法恢復,會提示相似信息:

Loading filesystem metadata ... 320 groups loaded.
Loading journal descriptors ... 27896 descriptors loaded.
Searching for recoverable inodes in directory /root/Sparrow/db.sqlite3 ...
120 recoverable inodes found.
Looking through the directory structure for deleted files ...
120 recoverable inodes still lost.
No files were undeleted.
複製代碼

後記

這一次的『刪庫』事件,給我了一個很好的教訓。服務器的數據必定要及時備份或作好容災,防止丟失。同時,此次也藉此機會進行學習了文件恢復。

固然,但願你們都不會出現我這樣的悲劇 😂。


有什麼問題均可以在博文後面留言,或者微博上私信我,或者郵件我 coderfish@163.com

博主是 iOS 妹子一枚。

但願你們一塊兒進步。

個人微博:周小魚

相關文章
相關標籤/搜索