{T}

磁盘数据恢复:rm -rf 误删数据,如何进行数据恢复

0. 引言

rm -rf 是 Linux 上最危险的命令之一,误删文件后第一反应往往是大惊失色。但**"删除"不等于"消失"**:Linux 的删除本质是摘除 inode 链接,数据块的物理内容依旧存在。本章先讲清两种误删场景与可恢复的原理(i_count/i_nlink、inode/block),再分别演示进程占用中删除与无进程占用删除的恢复方法,并给出防止二次覆盖的关键操作。


1. 两种误删场景

场景状态恢复手段
场景一文件正在被进程使用/proc/<pid>/fd 直接找回
场景二文件未被任何进程使用分析 block 数据块(extundelete)

2. 为什么数据可以恢复

Linux 中每个文件有两个链接计数器:

  • i_count:文件被进程引用的次数(进程打开文件时 +1);
  • i_nlink:文件的硬链接个数。

只有两个计数器都归零,文件才被系统真正判定删除。

  • 场景一:执行 rm -rf 时进程还在使用文件,i_count 不为 0——文件"看似被删",实际仍可通过进程的文件描述符找回;
  • 场景二:两个计数器都为 0,inode 链接被摘除,但数据仍在 block 中。

2.2 inode 与 block 的存储结构

文件内容由两个单元支撑:

  • inode:存放文件元数据(大小、权限、时间戳),内含索引指向数据块;
  • block:实际存放文件数据的数据块。

rm 只是删除了 inode 的链接,block 数据块并未被清除——理论上可完整找回。

2.3 唯一风险:block 覆盖

删除后若有进程持续向磁盘写入数据,操作系统可能把已删除文件的 block 分配给新数据,覆盖后数据将永久丢失。因此误删后的第一动作是:立即 umount 目录所在磁盘设备umount /test -l),阻止新的写入。

图表渲染中…

3. 场景一:进程占用中删除的恢复

  1. 模拟场景:echo "Delete file" > deletefile.txt,用 tail -f deletefile.txt 让进程持续占用该文件;
  2. 执行 rm -rf deletefile.txt 制造误删;
  3. lsof | grep deletefile.txt 找到正在使用该文件的进程(如 tail,PID 为 4701);
  4. 通过进程的文件描述符找回:
bash
ls -l /proc/4701/fd/           # 找到指向已删除文件的描述符(标记为 deleted)
cp /proc/4701/fd/3 /opt/recovertest/deletefile.txt_bak

恢复出的文件内容与删除前完全一致——因为进程仍持有该文件,数据从未真正消失。


4. 场景二:无进程占用删除的恢复(extundelete)

4.1 安装 extundelete

基于 ext3/ext4 的已删文件分析恢复工具:

bash
yum -y install bzip2 e2fsprogs e2fsprogs-devel gcc-c++
wget https://nchc.dl.sourceforge.net/project/extundelete/extundelete/0.2.4/extundelete-0.2.4.tar.bz2
tar jxvf extundelete-0.2.4.tar.bz2 && cd extundelete-0.2.4
./configure && make && make install

4.2 恢复步骤

  1. 先卸载误删目录所在设备:umount /test -l(防止新写入覆盖 block);
  2. 分析设备上的已删除文件:
bash
extundelete /dev/sdb --inode 2
  1. 恢复:
bash
extundelete /dev/sdb --restore-file file            # 恢复单个文件
extundelete /dev/sdb --restore-directory testdir    # 恢复单个目录
extundelete /dev/sdb --restore-all                  # 恢复全部已删文件

恢复命令需在其他目录下执行(如 /opt/recovertest),恢复结果输出到当前目录的 RECOVERED_FILES/ 下;同名文件多次恢复会自动生成 .v1.v2 版本。


5. 小结

  • 两大原理:i_count/i_nlink 双计数器归零才算删除;删除只摘 inode 链接,block 数据仍在;
  • 第一原则:误删后立即 umount,阻止新写入覆盖 block——这是恢复成功与否的分水岭;
  • 场景一(进程占用)lsof 找进程 → /proc/<pid>/fd 复制找回,恢复零成本;
  • 场景二(无占用):extundelete 分析 inode → --restore-file / --restore-all 恢复;
  • 预防重于恢复:谨慎使用 rm -rf,重要数据走备份与回收站机制,恢复操作本身对业务有影响与数据风险。

下一章讲解典型网络故障:长连接与短连接的选择,以及大量 TIME_WAIT 的产生原因与内核优化方案。