Linux 误删除文件恢复

  • Post author:
  • Post category:linux

记一次误删除文件恢复过程:

前因:

因为是测试环境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、不放弃,办法总比困难多


版权声明:本文为booybooy原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。