轉自:http://github.tiankonguse.com/blog/2015/09/13/linux-remove-recovery/
下午, DBA找我說有些SQL執行了兩個小時了,導致主從同步延遲很多.
晚上, 一個同事要走了, 做了一個月的項目要整理一下好交接出去.結果刪除沒有用的文件時, 路徑多了一個空格, 導致整個項目的代碼被刪除, 坑爹的是他從來沒提交過SVN.
奮斗到天亮
對於打點那個項目, 編輯說出問題那一刻, 我就知道是哪里的問題了.
當時那位同事做那塊邏輯時, 我給他交代了兩個注意點: 1.注意修改時間 2.批量操作時,參考能量瓶打點的批量操作邏輯.
我拉取SVN, 看了看相關代碼, 我心里面無話可說, 我交代的注意點他都沒有按我說的來做.
不管那么多, 先修復問題再說, 然后找測試, leader, 總監, 運維一層層的審批, 最后發布, 浪費不少精力和時間.
DBA找我得時候, 我猜想是autodata出問題了, 畢竟autodata里面全是各種like, 左值, 子查詢等sql語句.
但是我稍微觀察了一下, 發現sql來源竟然不是autodata, 於是趕緊查看來源ip, 再查查ip所在機器屬於誰負責.
結果發現是搜索小組負責的, 於是拉取那個組的運維, 組長等人.
后來, 問題嚴重到主從同步延遲兩個小時了, 於是搜索小組把相關任務停止, DBA手動殺死相關SQL, 才得到緩解.
后來, 慢慢的恢復正常了.
那位同事誤刪項目時, 我以為是清除cmake的臨時文件時誤操作的, 結果是管理項目時誤操作導致的.比如有個 bulid 目錄, 你想刪除 bulid 下的東西, 一般是進入bulid目錄, 然后刪除即可.
kyyuan@skyyuan-PC3:test $ tree . ├── bulid │ └── tml └── file 1 directory, 2 files skyyuan@skyyuan-PC3:test $ cd bulid/ skyyuan@skyyuan-PC3:bulid $ rm -rf * skyyuan@skyyuan-PC3:bulid $ cd .. skyyuan@skyyuan-PC3:test $ tree . ├── bulid └── file 1 directory, 1 file
但是這位同事沒有進入到相關目錄, 然后通過路徑來刪除的.
skyyuan@skyyuan-PC3:test $ touch bulid/tmp skyyuan@skyyuan-PC3:test $ tree . ├── bulid │ └── tmp └── file 1 directory, 2 files skyyuan@skyyuan-PC3:test $ rm -rf bulid/* skyyuan@skyyuan-PC3:test $ tree . ├── bulid └── file 1 directory, 1 file
那樣雖然可以做到刪除文件, 但是如果不小心在星號前面多打了一個空格, 后果不堪設想.
skyyuan@skyyuan-PC3:test $ touch bulid/tmp skyyuan@skyyuan-PC3:test $ tree . ├── bulid │ └── tmp └── file 1 directory, 2 files skyyuan@skyyuan-PC3:test $ rm -rf bulid/ * skyyuan@skyyuan-PC3:test $ tree . 0 directories, 0 files
大概這位同事在管理項目時, 就是類似的發生悲劇的.
不過幸運的是, 這台機器有兩個磁盤, 系統在小磁盤上, 數據在大磁盤上.這里可以把大磁盤卸載了, 來慢慢恢復數據.
root@10.123.10.23:[~]: parted --list Disk /dev/vda: 19.3GB Number Start End Size Type File system 標志 1 32.3kB 9994MB 9994MB primary ext3 啟動 2 9994MB 12.1GB 2147MB primary 3 12.1GB 19.3GB 7181MB primary Disk /dev/vdb: 195GB Number Start End Size Type File system 標志 1 32.3kB 195GB 195GB primary ext3
網上搜索linux文件恢復, 搜到的都是foremost, extundelete, scalpel, testdisk, phtorec 等相關教程.
試了之后發現都不理想, 后來加上 ext3 這個關鍵字, 搜到了 ext3grep 這個工具.
然后下載源碼安裝.
wget https://ext3grep.googlecode.com/files/ext3grep-0.10.2.tar.gz tar zxvf ext3grep-0.10.1.tar.gz cd ext3grep-0.10.1 ./configure make make install
然后卸載磁盤.
root@10.123.10.23:[/]: df -k 文件系統 1K-塊 已用 可用 已用% 掛載點 /dev/vda1 9606084 5634124 3483988 62% / tmpfs 8085312 880 8084432 1% /dev/shm /dev/vdb1 187846260 88430136 89874096 50% /data root@10.123.10.23:[/]: fuser -k /data root@10.123.10.23:[/]: umount /data
然后掃描磁盤上的所有節點.大概會跑幾十分鍾吧.
root@10.123.10.23:[/]: ext3grep /dev/vdb1 --ls --inode 2 Running ext3grep version 0.10.2 WARNING: I don't know what EXT3_FEATURE_COMPAT_EXT_ATTR is. WARNING: EXT3_FEATURE_INCOMPAT_RECOVER is set. This either means that your partition is still mounted, and/or the file system is in an unclean state. Number of groups: 1456 Loading group metadata... done Minimum / maximum journal block: 23790082 / 23823397 Loading journal descriptors... sorting... done ... ...
看着節點一個一個的掃描, 心里面逐漸的穩定下來.
突然發現這樣一個錯誤:
WARNING: Failed to open file 'locate_output'. See locate.cc ERROR: dir_inode_to_block(1589385) returned -1. ext3grep: init_directories.cc:82: bool init_directories_action(const ext3_dir_entry_2&, const Inode&, bool, bool, bool, bool, bool, bool, Parent*, void*): Assertion . 已放棄
心里面一驚, 趕緊google怎么回事, 在 google group 上發現需要加上 --accept-all
參數.
加上后發現還是存在這樣的問題, 有人說先把舊的文件刪除, 於是刪除重新來, 不報這個錯誤了.
root@10.123.10.23:[/recovery]: ll 總用量 2808 -rw-r--r-- 1 root root 124904 9月 13 18:08 scan.log -rw-r--r-- 1 root root 2737031 9月 13 17:27 vdb1.ext3grep.stage1 root@10.123.10.23:[/recovery]: mv vdb1.ext3grep.stage1 vdb1.ext3grep.stage1.bak01 root@10.123.10.23:[/recovery]: ll 總用量 2808 -rw-r--r-- 1 root root 124904 9月 13 18:08 scan.log -rw-r--r-- 1 root root 2737031 9月 13 17:27 vdb1.ext3grep.stage1.bak01 root@10.123.10.23:[/recovery]: ext3grep /dev/vdb1 --accept-all --ls --inode 2 > scan.log WARNING: Failed to open file 'locate_output'. See locate.cc root@10.123.10.23:[/recovery]:
然后一般我們是根據名字來恢復文件的, 所以我們需要先找到我們的文件.
root@10.123.10.23:[/home/skyyuan/test]: ll screenshot_hash.cpp -rwxr--r-- 1 skyyuan users 730 9月 9 11:01 screenshot_hash.cpp root@10.123.10.23:[/recovery]: ext3grep /dev/vdb1 --dump-names | grep screenshot_hash.cpp skyyuan/skyyuan/.vim/view/~=+test=+screenshot_hash.cpp= skyyuan/test/screenshot_hash.cpp skyyuan/test/screenshot_hash.cpp~
這個時候我們可以搜索可以恢復的文件路徑, 然后恢復之.
root@10.123.10.23:[/recovery]: ext3grep /dev/vdb1 --restore-file skyyuan/test/screenshot_hash.cpp Running ext3grep version 0.10.2 WARNING: I don't know what EXT3_FEATURE_COMPAT_EXT_ATTR is. WARNING: EXT3_FEATURE_INCOMPAT_RECOVER is set. This either means that your partition is still mounted, and/or the file system is in an unclean state. Number of groups: 1456 Minimum / maximum journal block: 23790082 / 23823397 Loading journal descriptors... sorting... done The oldest inode block that is still in the journal, appears to be from 13246709 = Wed Jun 3 15:38:29 1970 Journal transaction 884563 wraps around, some data blocks might have been lost of this transaction. Number of descriptors in journal: 31536; min / max sequence numbers: 883887 / 885058 Writing output to directory RESTORED_FILES/ Loading vdb1.ext3grep.stage2.........................................................................................................................................e Restoring skyyuan/test/screenshot_hash.cpp root@10.123.10.23:[/recovery]: ll 總用量 16992 drwxr-xr-x 3 root root 4096 9月 13 18:23 RESTORED_FILES -rw-r--r-- 1 root root 325248 9月 13 18:19 scan.log -rw-r--r-- 1 root root 2737059 9月 13 18:18 vdb1.ext3grep.stage1 -rw-r--r-- 1 root root 2737031 9月 13 17:27 vdb1.ext3grep.stage1.bak01 -rw-r--r-- 1 root root 11554133 9月 13 18:19 vdb1.ext3grep.stage2 root@10.123.10.23:[/recovery]: ll RESTORED_FILES 總用量 4 drwxr-x--- 3 root root 4096 9月 13 18:23 skyyuan root@10.123.10.23:[/recovery]: tree RESTORED_FILES/ RESTORED_FILES/ └── skyyuan └── test └── screenshot_hash.cpp 2 directories, 1 file
恢復完了, 我們再把磁盤掛上去.
mount /dev/vdb1 /data
最后, 在編譯程序, 運行之后發現正常, 什么也不管, 趕緊提交SVN.
尾記
這個周五, 一直忙到半夜2點多才回去, 這些事故與問題實際上和我都沒有關系, 但是加入進來學到不少東西.
ext3grep 的源碼我已經在我的github上存了一份, 對源碼感興趣的可以來看看.