记一次误删除文件恢复过程:
前因:
因为是测试环境CentOS 7.9 x64,运行在linux下面,所以直接使用vscode的远程编辑功能,方便直观。在某一次修改后,执行命令,产生一些垃圾文件。就在vscode中,直接选中文件,删除。垃圾文件过多,使用ctrl+多选,手速过快。结果可想而知,可怕的墨菲定律发生了,将一个编写几天的还未提交版本库的文件删除,可怕,可怕,可怕!
过程:
程序报错后,发现误删除了文件。第一时间,百度+Google,找恢复文件的方法。
1、使用网上提供的 debugfs 方法
[root@ecs-e3e8-0927791 ~]# debugfs
debugfs 1.43-WIP (20-Jun-2013)
debugfs: open /dev/vda2
debugfs: ls -d /usr/local/openresty/nginx
2109951 (12) . 2109924 (12) .. 2109952 (12) conf
2109953 (12) html 2109954 (12) sbin 2108449 (12) logs
2109994 (24) client_body_temp 2238655 (20) proxy_temp
2238656 (20) fastcgi_temp 2238657 (20) uwsgi_temp
2238658 (20) scgi_temp 2238660 (3920) conf.d
debugfs: ls -d /usr/local/openresty/nginx/conf.d/
2238660 (12) . 2109951 (12) .. 2239024 (36) api.conf
<2238933> (20) cache.conf 2238972 (20) admin.conf
2238982 (20) douyin.conf 2228521 (28) lua
2238974 (24) upstream.conf 2238664 (24) www.cc098.com.conf
2238665 (56) header_set.conf <2238666> (32) filter.www.cc098.com.conf
2238666 (3864) www.cc098.com.filter.conf
debugfs: logdump -i <2238933>
Inode 2238933 is at group 273, block 8913518, offset 2560
Journal starts at block 10562, transaction 1300384
Found sequence 1280775 (not 1300930) at block 17456: end of journal.
debugfs: quit
[root@ecs-e3e8-0927791 ~]# dd if=/dev/vda2 of=/data/cache.conf bs=2560 count=1 skip=8913518
[root@ecs-e3e8-0927791 ~]# cat /data/cache.conf
[root@ecs-e3e8-0927791 ~]#
按照网上的方法,bs=offset,skip=blocks 满怀期望的按步骤执行了,结果,恢复的文件为空。一脸懵,还夹杂着无尽悔恨,悔不该没有早点提交版本库,悔不该删除时没有看清楚,一阵懊恼。日子要过,只能继续尝试
2、使用 lsof | grep deleted
lsof | grep deleted | grep cache.conf
没有查到占用的进程,心慌了,还夹杂着无尽悔恨,悔不该没有早点提交版本库,悔不该删除时没有看清楚,一阵懊恼。日子要过,只能继续尝试
3、使用 extundelete
#下载文件
wget http://nchc.dl.sourceforge.net/project/extundelete/extundelete/0.2.4/extundelete-0.2.4.tar.bz2
#转移
mv extundelete-0.2.4.tar.bz2 /data/
cd /data/
#解压
tar jxvf extundelete-0.2.4.tar.bz2
#编译
cd extundelete-0.2.4
./configure
#发现少了依赖,安装依赖
yum -y install gcc-c++ e2fsprogs.x86_64 e2fsprogs-devel.x86_64
#编译
./configure
make
make install
#见证奇迹
extundelete --inode 2 /dev/vda2
#傻眼了,结果如下
[root@ecs-e3e8-0927791 ~]# extundelete /dev/vda2 --inode 2
NOTICE: Extended attributes are not restored.
WARNING: EXT3_FEATURE_INCOMPAT_RECOVER is set.
The partition should be unmounted to undelete any files without further data loss.
If the partition is not currently mounted, this message indicates
it was improperly unmounted, and you should run fsck before continuing.
If you decide to continue, extundelete may overwrite some of the deleted
files and make recovering those files impossible. You should unmount the
file system and check it with fsck before using extundelete.
Would you like to continue? (y/n)
y
Loading filesystem metadata ... 288 groups loaded.
Group: 0
Contents of inode 2:
0000 | 6d 41 00 00 00 10 00 00 7a ec 8e 63 61 f8 8e 63 | mA......z..ca..c
0010 | 61 f8 8e 63 00 00 00 00 00 00 1f 00 08 00 00 00 | a..c............
0020 | 00 00 08 00 0e 01 00 00 0a f3 01 00 04 00 00 00 | ................
0030 | 00 00 00 00 00 00 00 00 01 00 00 00 21 24 00 00 | ............!$..
0040 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0050 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0060 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0070 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0080 | 1c 00 00 00 00 74 9d ac 00 74 9d ac 00 db 86 6b | .....t...t.....k
0090 | 5d 97 b8 59 00 00 00 00 00 00 00 00 00 00 02 ea | ]..Y............
00a0 | 07 06 44 00 00 00 00 00 1c 00 00 00 00 00 00 00 | ..D.............
00b0 | 73 65 6c 69 6e 75 78 00 00 00 00 00 00 00 00 00 | selinux.........
00c0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
00d0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
00e0 | 00 00 00 00 73 79 73 74 65 6d 5f 75 3a 6f 62 6a | ....system_u:obj
00f0 | 65 63 74 5f 72 3a 72 6f 6f 74 5f 74 3a 73 30 00 | ect_r:root_t:s0.
Inode is Allocated
File mode: 16749
Low 16 bits of Owner Uid: 0
Size in bytes: 4096
Access time: 1670311034
Creation time: 1670314081
Modification time: 1670314081
Deletion Time: 0
Low 16 bits of Group Id: 0
Links count: 31
Blocks count: 8
File flags: 524288
File version (for NFS): 0
File ACL: 0
Directory ACL: 0
Fragment address: 0
Direct blocks: 127754, 4, 0, 0, 1, 9249, 0, 0, 0, 0, 0, 0
Indirect block: 0
Double indirect block: 0
Triple indirect block: 0
File name | Inode number | Deleted status
. 2
.. 2
lost+found 11
dev 131073
proc 524289
sys 1179649
var 786433
tmp 2097153
etc 1310721
root 655361
selinux 917505
lib64 262145
usr 1835009
bin 1966081
boot 2228225
home 1441793
lib 1572865
media 1703937
mnt 393217
opt 1179650
sbin 2097155
srv 393218
cgroup 524290
misc 655364
net 917506
.autorelabel 5530
.dbus 1048577
run 1441794
.autofsck 3401
CloudResetPwdUpdateAgent 1048580
CloudrResetPwdAgent 1441813
data 1704223
p 1705227
#没有找到要恢复的文件,还不死心,仍要试试
[root@ecs-e3e8-0927791 ~]# extundelete /dev/vda2 --restore-file /usr/local/openresty/nginx/conf.d/cache.conf
NOTICE: Extended attributes are not restored.
WARNING: EXT3_FEATURE_INCOMPAT_RECOVER is set.
The partition should be unmounted to undelete any files without further data loss.
If the partition is not currently mounted, this message indicates
it was improperly unmounted, and you should run fsck before continuing.
If you decide to continue, extundelete may overwrite some of the deleted
files and make recovering those files impossible. You should unmount the
file system and check it with fsck before using extundelete.
Would you like to continue? (y/n)
y
Loading filesystem metadata ... 288 groups loaded.
Loading journal descriptors ... 30337 descriptors loaded.
Unable to restore inode 2238933 (usr/local/openresty/nginx/conf.d/cache.conf): No undeleted copies found in the journal.
Unable to restore file /usr/local/openresty/nginx/conf.d/cache.conf
extundelete: Operation not permitted while restoring file.
extundelete: Operation not permitted when trying to examine filesystem
一顿操作猛如虎,结果无地杵。 因为测试环境,并没有分区,所有文件都在【/】根目录下面。extundelete 执行,最好是要先umount 分区,再执行。而我这种情况,无法umount 。还是无法达到恢复的目的。咋办,心塞了,还夹杂着无尽悔恨,悔不该没有早点提交版本库,悔不该删除时没有看清楚,一阵懊恼。日子要过,只能继续百度,Google。
4、全网搜索相关资料,2小时后,并没有发现其他更好的方法。有点泄气了,突然觉得很久没有上厕所了,呵呵,先喝口水,就跑去放水了,还夹杂着无尽悔恨,悔不该没有早点提交版本库,悔不该删除时没有看清楚,一阵懊恼。日子要过,既然是文本文件,假如我使用dd 第一个字节开始读取,遍历整个磁盘,检索文件中的关键字,如果找到,就说明文件在blocks附近,有机会恢复。我自己写脚本试试
#!/bin/sh
bs=2560
max=30098880
skip=0
next=$(expr $max - $skip)
while true
do
if [ $skip -ge $max ];then
break;
fi
echo $bs $skip
dd if=/dev/vda2 of=/data/cache/$bs-$skip.conf bs=$bs count=1 skip=$skip 2>&1 >> /data/dd.log
cat /data/dd.log | grep "Invalid argument" -q
if [ $? -eq 0 ] ;then
break;
fi
cat /data/cache/$bs-$skip.conf | grep myproxy -q
if [ $? -eq 0 ] ; then
echo "found myproxy in $bs-$skip"
cat /data/cache/$bs-$skip.conf > /data/cache$bs-$skip-myproxy.conf
fi
cat /data/cache/$bs-$skip.conf | grep html5 -q
if [ $? -eq 0 ] ; then
echo "found html5 in $bs-$skip"
cat /data/cache/$bs-$skip.conf > /data/cache$bs-$skip-html5.conf
fi
cat /data/cache/$bs-$skip.conf | grep wxminicache -q
if [ $? -eq 0 ] ; then
echo "found wxminicache in $bs-$skip"
cat /data/cache/$bs-$skip.conf > /data/cache$bs-$skip-wxminicache.conf
fi
skip=$(expr $skip + $bs)
next=$(expr $max - $skip)
if [ $next -lt $bs ];then
bs = $next
fi
echo $next
done
结过n分钟,执行完成。查看 cache 目录下的文件,用 file 试下,看看有没有是文本文件的
for file in $(ls)
do
file $file | grep -q text
if [ $? -eq 0 ] ; then
echo $file >> ../textfile.txt
fi
done
还真能发现不少文件文件,惊喜,有戏,但遗憾的是,并没有发现我要恢复的文件相关内容。
是哪里的问题呢?bs设置太大了,我试试1024,实在不行,我再试256。按理来说,减少bs,颗粒度越细,切分的文件就越多,越容易发现我要的关键字。找到关键字后,再通过 bs,count,skip 来扩大范围。
有方向了,心不慌了,感觉天气都好了很多。修改脚本 bs = 1024,执行
结过 n分钟,发现关键字了。狂喜
[root@ecs-e3e8-0927791 cache]# ls ../ca*.conf
../cache1024-2674688-wxminicache.conf ../cache1024-52224-wxminicache.conf ../cache1024-53248-wxminicache.conf ../cache1024-9882624-wxminicache.conf
../cache1024-52224-html5.conf ../cache1024-53248-html5.conf ../cache1024-6462464-html5.conf ../cache.conf
[root@ecs-e3e8-0927791 cache]# ls ../ca*wxmi*.conf
../cache1024-2674688-wxminicache.conf ../cache1024-52224-wxminicache.conf ../cache1024-53248-wxminicache.conf ../cache1024-9882624-wxminicache.conf
[root@ecs-e3e8-0927791 cache]#
通过对结果文件的分析,发现 ../cache1024-9882624-wxminicache.conf 文件包括了删除文件的开头内容。 bs=1024,skip=9882624,耶耶耶,像中奖一样,舒坦。开始恢复
dd if=/dev/vda2 of=/data/cache.conf bs=1024 count=1 skip=9882624
可这样恢复的文件并不全,只有部分。修改count值为8,完美恢复
dd if=/dev/vda2 of=/data/cache.conf bs=1024 count=8 skip=9882624
此时已经深夜0点了,激动,一定要记录下恢复过程。
总结:
1、墨菲定律太可怕
2、及时备份代码,有版本库的,一定要养成良好的习惯
3、linux服务器分区,尽量多分几个区,mnt media data 这些单独分区。软件和配置文件,不要放在根分区上
4、不放弃,办法总比困难多