极客进化岛
技术自由路

循序渐进学运维-误删除文件修复实战

  1. 删根 真的可以删掉吗
root@zmkjedu71 ~]# rm -rf /
rm: 在"/" 进行递归操作十分危险
rm: 使用 --no-preserve-root 选项跳过安全模式
[root@zmkjedu71 ~]# rm -rf  . /*

企业中常见的关于删除文件的运维规范,简洁版

  1. 进入目录当中
  2. 尽可能使用mv 代替rm
  3. 不要通配符
  4. 不要使用 -rf
  5. 写一个脚本 (脚本思路)
    • 提示你是否确认删除
    • 自动备份
    • 发邮件去确认
    • 30天之内提示还在冷静期,自动清除

面试:

  1. 你们公司是以运维主导,开发为主导
  2. 你们公司是否有明确运维规范

如果我们不小心删除了文件如何恢复:

ext4文件系统上删除文件,可以恢复: extundelete ,ext3恢复使用:ext3grep

XFS 有自动备份恢复工具

文件系统由几个部分组成:

文件名 inode block

结论:

  • 删除文件其实删除的inode
  • inode号一旦释放就容易被覆盖

测试inode号是否容易被覆盖?

[root@zmkjedu71 d]# cd
[root@zmkjedu71 ~]# mkdir test
[root@zmkjedu71 ~]# touch a.txt
[root@zmkjedu71 ~]# ls -i a.txt
34503763 a.txt
[root@zmkjedu71 ~]# rm -rf a.txt
[root@zmkjedu71 ~]# touch a.txt
[root@zmkjedu71 ~]# ls -i a.txt
33803902 a.txt
[root@zmkjedu71 ~]# rm -rf a.txt
[root@zmkjedu71 ~]# touch a.txt
[root@zmkjedu71 ~]# ls -i a.txt
33803902 a.txt
[root@zmkjedu71 ~]# touch b.txt
[root@zmkjedu71 ~]# ls -i b.txt
33803903 b.txt
[root@zmkjedu71 ~]# rm -rf b.txt 
[root@zmkjedu71 ~]# touch b.txt
[root@zmkjedu71 ~]# ls -i b.txt
33803903 b.txt
创建文件名不同,占用inode是相同的吗?
[root@zmkjedu71 ~]# rm -rf b.txt 
[root@zmkjedu71 ~]# touch c.txt
[root@zmkjedu71 ~]# touch b.txt
[root@zmkjedu71 ~]# ls -i b.txt
33803903 b.txt
[root@zmkjedu71 ~]# ls -i c.txt
33803901 c.txt
[root@zmkjedu71 ~]# rm -rf c.txt
[root@zmkjedu71 ~]# touch d.txt
[root@zmkjedu71 ~]# ls -i d.txt
33803901 d.txt
​

总结:

  • inode生成是随机的,优先补全释放
  • inode指向block (真正存放数据的地方)

可以通过inode号来恢复

删除文件VS 复制文件 ,速度上哪个快?

当然是删除快,因为删除其实是删除inode号 ,而复制是copy了block中的数据。

问题: 误删除文件,第一件事做的是什么?

答案: 卸载分区,设置为只读,目的是防止文件被覆盖。

误删除文件实验思路:(todolist)

  1. 新增加一块硬盘
  2. 分区 fdisk
  3. 格式化
  4. 挂载 /dev/sdb1 /tmp/sdb1
  5. 创建一堆文件
    • 普通文件
    • 空文件
    • 空目录
    • 目录
  6. 删除文件
  7. 卸载分区
  8. 恢复文件
    • extundelete 工具
    • 找到inode号

实验环境:

[root@zmkjedu71 ~]# cat /etc/redhat-release 
CentOS release 6.7 (Final)
[root@zmkjedu71 ~]#

新增一块硬盘:

image-20220518151437271
image-20220518151527399
image-20220518151629177

新增磁盘结束之后,开启虚拟机

[root@zmkjedu71 ~]# ll /dev/sdb* brw-rw----. 1 root disk 8, 16 5月 18 23:16 /dev/sdb [root@zmkjedu71 ~]#

分区(使用fdisk分区)

[root@zmkjedu71 ~]# ll /dev/sdb*
brw-rw----. 1 root disk 8, 16 5月 18 23:16 /dev/sdb
[root@zmkjedu71 ~]# fdisk /dev/sdb
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0x95ad17d7.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
switch off the mode (command 'c') and change display units to
sectors (command 'u').

Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-2610, default 1):
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-2610, default 2610): +5G

Command (m for help): p

Disk /dev/sdb: 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: 0x95ad17d7

Device Boot Start End Blocks Id System
/dev/sdb1 1 654 5253223+ 83 Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
[root@zmkjedu71 ~]# ll /dev/sdb*
brw-rw----. 1 root disk 8, 16 5月 18 23:19 /dev/sdb
brw-rw----. 1 root disk 8, 17 5月 18 23:19 /dev/sdb1
[root@zmkjedu71 ~]#

格式化,创建目录挂载

[root@zmkjedu71 ~]# mkdir /tmp/sdb1

格式化
[root@zmkjedu71 ~]# mkfs.ext4 /dev/sdb1
mke2fs 1.41.12 (17-May-2010)
文件系统标签=
操作系统:Linux
块大小=4096 (log=2)
分块大小=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
328656 inodes, 1313305 blocks
65665 blocks (5.00%) reserved for the super user
第一个数据块=0
Maximum filesystem blocks=1346371584
41 block groups
32768 blocks per group, 32768 fragments per group
8016 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736

正在写入inode表: 完成
Creating journal (32768 blocks): 完成
Writing superblocks and filesystem accounting information: 完成

This filesystem will be automatically checked every 36 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.

挂载目录:
[root@zmkjedu71 ~]# mount /dev/sdb1 /tmp/sdb1
[root@zmkjedu71 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 20G 3.5G 15G 20% /
tmpfs 2.2G 72K 2.2G 1% /dev/shm
/dev/sda1 190M 40M 140M 23% /boot
/dev/sdb1 4.9G 11M 4.6G 1% /tmp/sdb1

创建文件:

[root@zmkjedu71 ~]# cp /etc/passwd /tmp/sdb1
[root@zmkjedu71 ~]# cp /etc/hosts /tmp/sdb1
[root@zmkjedu71 ~]# echo aaa > a.txt
[root@zmkjedu71 ~]# mkdir -p /tmp/sdb1/a/b/c
[root@zmkjedu71 ~]# cp a.txt /tmp/sdb1/a
[root@zmkjedu71 ~]# cp a.txt /tmp/sdb1/a/b
[root@zmkjedu71 ~]# touch !$/kong.txt
touch /tmp/sdb1/a/b/kong.txt
/etc/passwd

查看目录结构:

挂载镜像
[root@zmkjedu71 sdb1]# mount /dev/cdrom /mnt
mount: block device /dev/sr0 is write-protected, mounting read-only

安装tree命令
[root@zmkjedu71 sdb1]# yum install tree*
已加载插件:fastestmirror, refresh-packagekit, security
设置安装进程
Loading mirror speeds from cached hostfile
c6-media | 4.0 kB 00:00 ...
解决依赖关系
--> 执行事务检查
---> Package tree.x86_64 0:1.5.3-3.el6 will be 安装
--> 完成依赖关系计算

依赖关系解决

=========================================================
软件包 架构 版本 仓库 大小
=========================================================
正在安装:
tree x86_64 1.5.3-3.el6 c6-media 36 k

事务概要
=========================================================
Install 1 Package(s)

总下载量:36 k
Installed size: 65 k
确定吗?[y/N]:y
下载软件包:
运行 rpm_check_debug
执行事务测试
事务测试成功
执行事务
正在安装 : tree-1.5.3-3.el6.x86_64 1/1
Verifying : tree-1.5.3-3.el6.x86_64 1/1

已安装:
tree.x86_64 0:1.5.3-3.el6

完毕!
[root@zmkjedu71 sdb1]# tree
.
├── a
│   ├── a.txt
│   └── b
│   ├── a.txt
│   ├── c
│   └── kong.txt
├── hosts
├── lost+found
└── passwd

4 directories, 5 files

(误删)删除所有文件

[root@zmkjedu71 sdb1]# ls
a hosts lost+found passwd
[root@zmkjedu71 sdb1]# rm -rf ./*

卸载分区,或者设置为只读

[root@zmkjedu71 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 20G 3.5G 15G 20% /
tmpfs 2.2G 72K 2.2G 1% /dev/shm
/dev/sda1 190M 40M 140M 23% /boot
/dev/sdb1 4.9G 11M 4.6G 1% /tmp/sdb1
/dev/sr0 3.7G 3.7G 0 100% /mnt
[root@zmkjedu71 ~]# umount /dev/sdb1
[root@zmkjedu71 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 20G 3.5G 15G 20% /
tmpfs 2.2G 72K 2.2G 1% /dev/shm
/dev/sda1 190M 40M 140M 23% /boot
/dev/sr0 3.7G 3.7G 0 100% /mnt
[root@zmkjedu71 ~]#

工具正式出场: extundelete

链接:https://pan.baidu.com/s/1vJ_u43yD2AAuNgfoxhi-4w?pwd=4932 提取码:4932

上传工具

安装rz命令

[root@zmkjedu71 ~]# rz
-bash: rz: command not found
安装lrzsz
[root@zmkjedu71 ~]# yum install lr*
已加载插件:fastestmirror, refresh-packagekit, security
设置安装进程
Loading mirror speeds from cached hostfile
解决依赖关系
--> 执行事务检查
---> Package lrzsz.x86_64 0:0.12.20-27.1.el6 will be 安装
--> 完成依赖关系计算

依赖关系解决

=========================================================
软件包 架构 版本 仓库 大小
=========================================================
正在安装:
lrzsz x86_64 0.12.20-27.1.el6 c6-media 71 k

事务概要
=========================================================
Install 1 Package(s)

总下载量:71 k
Installed size: 159 k
确定吗?[y/N]:y
下载软件包:
运行 rpm_check_debug
执行事务测试
事务测试成功
执行事务
正在安装 : lrzsz-0.12.20-27.1.el6.x86_64 1/1
Verifying : lrzsz-0.12.20-27.1.el6.x86_64 1/1

已安装:
lrzsz.x86_64 0:0.12.20-27.1.el6

完毕!

查询一个命令它需要安装哪个包:

[root@zmkjedu71 ~]# yum search rz
已加载插件:fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
==================== N/S Matched: rz ====================
lrzsz.x86_64 : The lrz and lsz modem communications
: programs

Name and summary matches only, use "search all" for everything.
[root@zmkjedu71 ~]#

上传完成:

[root@zmkjedu71 ~]# ls extundelete-0.2.4.tar.bz2 extundelete-0.2.4.tar.bz2 [root@zmkjedu71 ~]#

安装extundelete

安装环境:
[root@zmkjedu71 ~]# yum install gcc*
[root@zmkjedu71 ~]# tar xf extundelete-0.2.4.tar.bz2
[root@zmkjedu71 ~]# cd extundelete-0.2.4
[root@zmkjedu71 extundelete-0.2.4]# ls
acinclude.m4 configure LICENSE README
aclocal.m4 configure.ac Makefile.am src
autogen.sh depcomp Makefile.in
config.h.in install-sh missing
[root@zmkjedu71 extundelete-0.2.4]#

小插曲:

编译报错:

[root@zmkjedu71 extundelete-0.2.4]# ./configure 
Configuring extundelete 0.2.4
configure: error: Can't find ext2fs library
[root@zmkjedu71 extundelete-0.2.4]#

解决方案:
[root@zmkjedu71 extundelete-0.2.4]# yum search ext2fs
已加载插件:fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
==================== Matched: ext2fs ====================
e2fsprogs.x86_64 : Utilities for managing ext2, ext3, and
: ext4 filesystems
e2fsprogs-libs.i686 : Ext2/3/4 filesystem-specific shared
: libraries
e2fsprogs-libs.x86_64 : Ext2/3/4 filesystem-specific
: shared libraries


[root@zmkjedu71 extundelete-0.2.4]# yum install e2fsprogs-devel

继续开始编译:

[root@zmkjedu71 extundelete-0.2.4]# ./configure 
Configuring extundelete 0.2.4
Writing generated files to disk
[root@zmkjedu71 extundelete-0.2.4]# make && make install

接下来,使用工具去恢复数据:

[root@zmkjedu71 test]# extundelete /dev/sdb1 --inode 2
NOTICE: Extended attributes are not restored.
Loading filesystem metadata ... 41 groups loaded.
Group: 0
Contents of inode 2:
................

Inode is Allocated
File mode: 16877
Low 16 bits of Owner Uid: 0
Size in bytes: 4096
Access time: 1652887582
Creation time: 1652887795
Modification time: 1652887795
Deletion Time: 0
Low 16 bits of Group Id: 0
Links count: 2
Blocks count: 8
File flags: 0
File version (for NFS): 0
File ACL: 0
Directory ACL: 0
Fragment address: 0
Direct blocks: 8370, 0, 0, 0, 0, 0, 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 Deleted
passwd 12 Deleted
hosts 13 Deleted
a 128257 Deleted
[root@zmkjedu71 test]#

通过inode号来恢复

目前inode 12 是passwd

[root@zmkjedu71 test]# extundelete /dev/sdb1  --restore-inode 12
NOTICE: Extended attributes are not restored.
Loading filesystem metadata ... 41 groups loaded.
Loading journal descriptors ... 62 descriptors loaded.
[root@zmkjedu71 test]# ls
RECOVERED_FILES
[root@zmkjedu71 test]# cd RECOVERED_FILES/
[root@zmkjedu71 RECOVERED_FILES]# ls
file.12
[root@zmkjedu71 RECOVERED_FILES]# md5sum file.12 /etc/passwd
53baee54724c650df260e45099a82100 file.12
53baee54724c650df260e45099a82100 /etc/passwd
[root@zmkjedu71 RECOVERED_FILES]#

通过文件名来恢复

[root@zmkjedu71 RECOVERED_FILES]# extundelete /dev/sdb1  --restore-file passwd
NOTICE: Extended attributes are not restored.
Loading filesystem metadata ... 41 groups loaded.
Loading journal descriptors ... 62 descriptors loaded.
Successfully restored file passwd
[root@zmkjedu71 RECOVERED_FILES]# cd RECOVERED_FILES/
[root@zmkjedu71 RECOVERED_FILES]# ls
passwd
[root@zmkjedu71 RECOVERED_FILES]# md5sum passwd /etc/passwd
53baee54724c650df260e45099a82100 passwd
53baee54724c650df260e45099a82100 /etc/passwd
[root@zmkjedu71 RECOVERED_FILES]#

通过目录名字来恢复

[root@zmkjedu71 RECOVERED_FILES]# extundelete /dev/sdb1  --restore-directory a
NOTICE: Extended attributes are not restored.
Loading filesystem metadata ... 41 groups loaded.
Loading journal descriptors ... 62 descriptors loaded.
Searching for recoverable inodes in directory a ...
8 recoverable inodes found.
Looking through the directory structure for deleted files ...
4 recoverable inodes still lost.
[root@zmkjedu71 RECOVERED_FILES]# cd RECOVERED_FILES/
[root@zmkjedu71 RECOVERED_FILES]# ls
a
[root@zmkjedu71 RECOVERED_FILES]# tree a
a
├── a.txt
└── b
└── a.txt

1 directory, 2 files
[root@zmkjedu71 RECOVERED_FILES]#

一次性恢复所有文件

[root@zmkjedu71 RECOVERED_FILES]# extundelete /dev/sdb1  --restore-all
NOTICE: Extended attributes are not restored.
Loading filesystem metadata ... 41 groups loaded.
Loading journal descriptors ... 62 descriptors loaded.
Searching for recoverable inodes in directory / ...
8 recoverable inodes found.
Looking through the directory structure for deleted files ...
0 recoverable inodes still lost.
[root@zmkjedu71 RECOVERED_FILES]# cd RECOVERED_FILES/
[root@zmkjedu71 RECOVERED_FILES]# ls
a hosts passwd
[root@zmkjedu71 RECOVERED_FILES]# tree
.
├── a
│   ├── a.txt
│   └── b
│   └── a.txt
├── hosts
└── passwd

2 directories, 4 files
[root@zmkjedu71 RECOVERED_FILES]#
image-20220518160434915

总结:

  1. ext4文件系统是没有办法恢复空文件,空目录
  2. XFS默认有备份机制
赞(2)
未经允许不得转载:极客进化岛 » 循序渐进学运维-误删除文件修复实战