rm-rf误删数据,如何进⾏磁盘数据恢复
在⼯作中,我们知道⼀些操作命令危险性很⾼,如: rm -rf,它会造成数据的误删除。如果万⼀出现这样情况导致数据误删除时,我们应该如何对数据进⾏恢复呢?
删除数据的两种场景
通常有两种数据删除的场景是你需要清晰了解的。第 1 个是在执⾏ rm -rf 删除⽂件时,该⽂件正在被进程使⽤。第 2 个是这个⽂件并没有被其他进程所使⽤,⽽被误删除。本课时我将围绕这两种场景进⾏讲解并演⽰。
为什么数据可以恢复
既然我执⾏了 rm -rf 命令,不就是删除⽂件了吗,为什么⼜可以恢复数据呢?⾸先我来为你介绍⼀下其原由,对于第 1 种进程正在使⽤⽂件的场景,数据可以恢复是由因为 Linux ⾥,每个⽂件都有 2 个 link 计数器:i_count 和 i_nlink。
i_count 的作⽤是当⼀个⽂件被⼀个进程引⽤时,它的数值会加 1,也就是说它记录的是⽂件被进程引⽤的次数。i_nlink 的作⽤则是记录⽂件产⽣硬链接的个数。Linux 系统只有在两个数值都清零的时候,⽂件才被系统认为是删除的。如果我们执⾏了 rm -rf,却并没有把 i_count 删除,假设此时删除⽂件有进程
在使⽤,那么它(i_count)数值不为 0。这个时候就是⽂件看似被删除,但在操作系统还是能便捷的恢复回来。
这就是第 1 种场景删除数据能够被回的原因(由于 i_count 不为 0)。
第 2 种场景是将没有被进程使⽤的⽂件误删除,此时 i_count 和 i_nlink 都为 0。这个时候⽂件的 inode 连接信息已经被删除了,我们就需要通存放⽂件的 block 单元,做数据块的数据回。在系统上我们能看到的⽂件内容包括:⽂件名、⽂件⼤⼩、内容,但实际上它的存储依赖两个⾮常重要的单元,⼀个是 inode,它⽤于存放⽂件的相关元数据,它的元数据⾥会有⼀个类似于索引的值,能够索引到后⾯具体存放数据的 block 单元, block 是⼀个数据块,⽤来实际存放数据。我们在删除⽂件时,其实是把 inode 的链接删除了,但是 block 数据块,并没有删除。
所以这个时候我们依然可以通过分析后端的 block 块,对⽂件进⾏恢复。因为 block 块保存着真实的数据,理论上可以作完整的回数据,不过有⼀个风险:如果有进程在不断往磁盘写数据时,需要申请新的 block 块,如果操作系统分配已删除⽂件的 block 块时,那么新的写⼊数据就会覆盖 block 原来的数据,这时就会造成数据真正丢失的风险。
所以,如果出现这样场景造成数据误删除,需要第⼀时间 umount ⽬录所在的磁盘设备。如果没有其他进程在不断地往同⼀个磁盘块(block)⾥写数据,那么你的数据理论上还是在 block 块⾥⾯,依然
可以通过相关分析把数据回。
这就是我们为什么可以在这两个场景中把数据回的原因,那么接下来我将讲解如何来恢复数据。我会通过两个案例来进⾏演⽰。
案例演⽰
我们先演⽰第 1 种场景,第 1 种场景是⽂件在被进程使⽤过程中被删除,这种场景该如何去恢复⽂件呢?
⾸先我登录到测试环境的机器上,这⾥开启了两个窗⼝,第 1 个窗⼝我登录到了这台服务器上,cd /test ⽬录下,echo ⼀个测试⽂件(我把它命名为 DeleteFile),然后把这个内容("Delete file")重定向到本地的 。这个时候我的测试⽂件就已经⽣成了。接下来我要做的是开启⼀个进程,让它实时地使⽤这个⽂件。
这⾥我使⽤ tail 命令,持续地查看并且保持监听并使⽤这个⽂件。
接下来在另⼀个窗⼝,我同样到/test ⽬录下,⽽此时我要执⾏的是 rm -rf ./,这样就“彻底”把这个⽂件删除。接下来我们通过ls,可以看到本地已经没有这个⽂件了。
现在我们已经模拟出⽂件在进程使⽤过程中被删除的场景,那么接下来我们来演⽰恢复该⽂件。
⾸先需要到是哪个进程在使⽤这个⽂件,我们可以通过 lsof 命令,grep 刚刚删除的⽂件名称(),会列出当前使⽤⽂件的进程。我们会看到tail 命令正在使⽤,它(进程)的 pid 是 4701。
接下来我们要根据这条线索去恢复数据。我们知道该进程会有使⽤的⽂件句柄,那么我们对该进程的⽂件句柄⽬录进⾏查,cd 到
/proc/{pid}/fd ⽬录下(这⾥ pid 为4701),我们到这个⽬录下,输⼊ ls -l 命令,这个时候我们会看到,使⽤这个⽂件
(/)并且它的⽂件句柄为 3。
接下来我们要想办法把这个⽂件进⾏恢复,输⼊cp 3 /opt/_bak,这时我就把这 3 个⽂件做了⼀个拷贝,实现将数据恢复到 /opt/_bak ⽂件。
这个时候cd /opt/recovertest/,_bak 看⼀下⾥⾯的内容,可以发现这个⽂件的内容与刚刚⽣成的的测试⽂件内容⼀致,所以刚刚删除的⽂件恢复完毕。
接下来我来演⽰误删数据场景2(在没有进程使⽤⽂件的情况下,如何恢复误删的⽂件)。演⽰这种场景,保险起见我在本地多挂载了⼀块 SDB 的独⽴硬盘设备。
这种情况要如何恢复数据呢?我们需要安装 extundelete 这个⼯具。登录到我的测试机上,在这个演⽰场景⾥,挂载⼀块独⽴硬盘设备
/
怎样恢复数据
dev/sdb 并作数据格式化。完成格式化后。把单独的 sdb 设备,挂载到 test ⽬录下(mount /dev/sdb /test),接下来在 test ⽬录下⽣
成⼀个内容为“deletetest ”的测试⽂件file(echo 'deletetest'>file),这个时候本地⽬录会⽣成⼀个测试的⽂件:file,再新建⼀个叫 testdir 的⽬录(mkdir /test/testdir),那么这时本地既有⽂件⼜有⽬录,也就是我接下来要演⽰删除的这些⽂件。
我们可以通过 rm -rf ./*,直接把当前⽬录下的⽂件整体删除。然后我需要恢复这个⽂件,原理就是:通过分析它的 block 块,来恢复 inode 链接,要分析并恢复已删除⽂件的链接,我们要⽤到⼀些⼯具,这⾥推荐你使⽤⼀个叫 extundelete 的命令,它是在 Linux 下基于 ext3\ext4 的⽂件分析⼯具,可以对⽂件系统已删除的⽂件进⾏分析,并进⾏数据恢复。
在执⾏命令extundelete之前需要先做的是 umount,把我们刚刚误删的⽬录 umount 掉(umount  /test -l),避免有新的进程再往磁盘块⾥写数据,同时也便于执⾏⼯具进⾏接下来的分析。
附:extundelete 命令安装⽅式:
yum -y install bzip2 e2fsprogs e2fsprogs-devel gcc-c++
tar jxvf extundelete-0.2.4.tar.bz2
cd extundelete-0.2.4
./configure
make && make install
安装好这个⼯具(extundelete)后,执⾏:extundelete /dev/sdb --inode 2
我们可以在命令后⾯加⼊设备名称,然后加⼊上⾯的 inode 进⾏分析。完成之后我们会看到显⽰屏幕上已经出现了刚刚删除的⽂件、名称及⽬录,还会看到 inode 号以及当前的状态。
我们也可以选择恢复单独⽂件类型⽂件,执⾏:extundelete /dev/sdb --restore-file file
加⼊的选项是 --restore-file,后⾯加你想恢复的⽂件名称。
在执⾏以上恢复操作之前,我先要确保数据恢复的⽬录 /opt/recovertest 下,cd  /opt/recovertest ⽬录下,执⾏想恢复的⽂件
extundelete /dev/sdb --restore-file file。
执⾏完命令后,会有⼀个成功的提⽰。此时在当前⽬录的 RECOVERED_FILES ⽬录,有对应恢复好的⽂件,⼀个是 file,⼀个是 file.v1(这个为刚恢复的⽂件),为什么是 file.v1 呢?因为我在做操作的时候有操作过两遍,所以它恢复了两个⽂件。第 1 个 file 是我之前写⼊的内容,第2 个 file 则是由于我执⾏了第 2 次恢复,恢复的⽂件虽然也是 file,所以会⾃动命名成⼀个新的版本,叫作 file.v1(这个⽂件就是我们想要恢复的⽂件名称)。
刚刚讲到的选项是恢复单个⽂件,假设我们要恢复所有⽂件的话,就把选项改为 --restore-all,这样就把分析出来的已删除⽂件进⾏了恢复。如果件,只想恢复某⼀个⽬录,就可以把 "all" 改成 directory,然后⽤ restore-directory 这种⽅式恢复单个已删除的⽂件⽬录。
以上就是通过 extundelete 作场景 2 恢复演⽰。
平时⼯作中,你还是需要谨慎进⾏操作系统指令,以避免产⽣⽂件系统误删的情况,毕竟恢复起来对我们的业务影响,还有数据风险都是存在的。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。