在代码更新服务器上写更新脚本,测试的时候脑子一短路,直接 `rm -rf /opt/fabric/*`,导致/opt/fabric下十几个代码更新脚本被删除,并且都没有备份,重新写这些脚本会要人命的。以前只在windows下恢复过删除的文件,windows下删除文件只是将文件标记为删除,数据所在的磁盘可以被写入,并没有真正的删除数据,所以有很多软件可以恢复删除的windows文件。但在我印象中linux用rm删除是很难恢复的,但是重写的工作量实在太大,于是谷歌了一下,发现了extundelete这个软件,成功恢复了目录。

我的服务器是centos6.5,文件系统是ext4,一但文件被删除,应马上停止所有写文件的进程或服务,最好将文件系统挂载文只读,以免数据文件被破坏无法恢复。开始恢复!

一、将文件系统挂载为只读或杀掉有写入和打开文件的进程

首先看一下根文件系统挂载的位置,因为我只有一块硬盘并且启用了lvm

fdisk -l

[root@localhost tmp]# fdisk -l
Disk /dev/sda: 21.5 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000e4832

Device Boot Start End Blocks Id System
/dev/sda1 * 1 64 512000 83 Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2 64 2611 20458496 8e Linux LVM

Disk /dev/mapper/VolGroup-lv_root: 18.8 GB, 18798870528 bytes
255 heads, 63 sectors/track, 2285 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

我的sda2是lvm分区,根文件系统是挂在 /dev/mapper/VolGroup-lv_root上,重新mount成只读,使用命令:

mount -o remount,ro /dev/mapper/VolGroup-lv_root

可能会提示:

mount: / is busy

这是因为还有进程在打开根分区的文件或者写根分区造成的,需要关闭所有打开文件的或写的进程或者系统服务,例如:sshd服务关闭后并不会踢掉连接,还要手动kill一下,其它有这种情况有rsyslogd、dhclinet、postfix等。

service  network stop
service rsyslog stop
service sshd stop  && killall sshd
service postfix stop 

以home分区为例,可以用下面命令查看打开或写home分区进程的ID:

lsof /home | awk '$4 ~ /[0-9].*w/'   

或者:

lsof -F pa /home | awk '/^p/ {pid = substr($0, 2)} /^a.*w/ {print pid}'

查出进程号后kill掉即可,或者用fuser命令直接干掉所有写入操作的进程:

fuser -kuc  /home

如果只要恢复某一分区的数据,可以只将该分区挂载成只读,无需将根文件系统只读,因为我这里因为系统安装时偷懒分区不合理,所以只能将根文件系统只读。

二、安装软件 extundelete

我为省事直接将文件系统挂成读写,来安装extundelete,注意不要写要恢复文件的分区。编译安装很简单了,需要的依赖包: gcc gcc-c++ e2fsprogs-devel
一条命令搞定:

yum install gcc gcc-c++ e2fsprogs-devel

如果不安装e2fsprogs-devel会提示:

configure: error: Can't find ext2fs library

编译安装 :

./configure && make && make install

三、恢复文件

1.查看文件或文件夹的inode

我要恢复的文件是/opt/fabric下的所有目录,首先查看一下/opt/fabric文件夹的inode :

ls -i /opt/fabirc
784683 test

2.查询可恢复的数据信息

extundelete /dev/mapper/VolGroup-lv_root --inode 784683

3.用inode恢复文件或文件夹

extundelete /dev/mapper/VolGroup-lv_root --restore-inode 784683

之后输入y,会将恢复成功的文件存储在当前目录下的RECOVERED_FILES中

4.恢复单个文件

extundelete /dev/mapper/volGroup-lv_root --restore-file opt/fabric/update_web.py 

5.恢复文件夹

extundelete /dev/mapper/volGroup-lv_root --restore-path /opt/fabric

6.尝试恢复所有删除文件

extundelete /dev/mapper/volGroup-lv_root --restore-all 

如果用extundelete恢复不出来,就节哀顺便吧

用debugfs也能恢复,但是比较难玩。testdisk倒是简单,但是恢复时间长,能恢复是数据有限

参考文章:
http://unix.stackexchange.com/questions/42015/mount-is-busy-when-trying-to-mount-as-read-only-so-that-i-can-run-zerofree
http://book.51cto.com/art/201409/452475.htm