1. 误删 /usr 之后,系统到底变成了什么样
先把最坏的情况说清楚:在 CentOS 这类系统上,/usr不是“可选目录”,它装着绝大多数用户态程序、库文件、共享资源。/bin、/sbin、/lib、/lib64在现代发行版里通常都是指向/usr下对应目录的符号链接。也就是说,你敲的ls、cp、bash、yum、systemctl,底层二进制和依赖库基本都在/usr里。
所以一旦/usr被删,典型表现是这样的:
- 当前已经打开的 shell 可能还能用,因为进程已经加载进内存,但新开一个终端大概率直接报错,提示找不到
bash或找不到共享库。 - 大部分命令失效,
ls、vi、cp全部报command not found或者error while loading shared libraries。 yum、rpm、dnf这类包管理工具基本瘫痪,因为它们本身也依赖/usr下的 Python 和库。- 系统可能还能勉强运行已启动的服务,但一旦重启,大概率卡在启动阶段,因为 init 系统要调用的东西也缺了。
这里有个很多人会误判的点:误删/usr和误删/home、/data完全不是一个量级。后者是数据丢失,前者是系统级“半身不遂”。你没法靠yum reinstall修,因为yum自己都跑不起来。这也是为什么这个场景下,最稳的思路不是“在坏系统里修”,而是“用外部环境挂载后修复,或者直接重装 + 数据抢救”。
我先把结论摆在这,方便你判断走哪条路:
| 场景 | 推荐方案 | 数据风险 | 耗时 |
|---|---|---|---|
| 系统盘独立,数据在别的盘 | 直接重装系统,挂载数据盘 | 低 | 30-60 分钟 |
| 系统和数据在同一块盘,且有重要数据 | 用 U 盘启动进救援环境,先备份数据再重装 | 中 | 1-3 小时 |
| 有完整系统备份/快照 | 回滚快照 | 低 | 视平台而定 |
| 只是想恢复部分配置 | 救援模式下从备份或同版本机器拷贝 | 中 | 视情况 |
注意:误删之后第一件事是停止对这块盘的一切写操作。你每多写一点数据,被删文件块被覆盖的概率就高一分。如果数据极其重要,正确做法是关机、拔盘、做镜像,再在镜像上操作。下面讲的是常规可操作路径。
2. 为什么“在原系统里修”基本走不通
2.1 包管理器的自举困境
很多人第一反应是“我yum reinstall一下不就行了”。问题在于,yum是个 Python 程序,它的解释器在/usr/bin/python,依赖库在/usr/lib64/python*。/usr没了,yum这个命令本身就不存在了。就算你从别处拷一个yum二进制过来,它一运行就去找 Python 库,照样崩。
这就像你家的工具箱锁在保险柜里,而保险柜的钥匙也在保险柜里——自举链条断了。
2.2 动态链接器的依赖链
Linux 程序分静态链接和动态链接。绝大多数系统命令是动态链接的,运行时需要/lib64/ld-linux-x86-64.so.2这个动态链接器,以及一堆.so库。这些库在 CentOS 7/8 上大多位于/usr/lib64。/usr一删,动态链接器找不到库,任何新启动的程序都会报:
error while loading shared libraries: libc.so.6: cannot open shared object file你甚至没法用cp把备份拷回来,因为cp自己也起不来。
2.3 唯一还能用的“救命通道”
有几个东西在极端情况下可能还活着:
- 已经运行的 shell 进程:如果删之前就开着终端,这个 shell 的内存映像还在,内建命令(
cd、echo、export)还能用。但外部命令基本废了。 - 静态编译的 busybox:如果你系统里恰好有静态 busybox,它能提供一套精简命令。但 CentOS 默认不带。
/proc和/sys:这两个是内核虚拟文件系统,不依赖/usr,还能读。但光能读没用,你没法执行恢复动作。
所以现实就是:坏系统里没有可用的修复工具链。必须借助外部环境。这就引出了两条主流路线——U 盘救援和重装。
3. 制作一个能救命的 CentOS 启动 U 盘
3.1 选 ISO:最小化版还是完整版
制作救援 U 盘,ISO 的选择有讲究:
- Minimal ISO:体积小(几百 MB),启动后是个精简安装环境,带基本 shell 和部分工具。适合网络好、只需要进救援模式拷数据的场景。
- DVD/Everything ISO:体积大(几个 GB),但自带完整安装源和更多工具。如果你网络受限,或者需要
rpm离线装包,选它更稳。 - NetInstall ISO:最小,但安装时全程依赖网络。
我的建议:做救援盘优先用 Minimal 或 DVD ISO,因为它们的安装环境本身就带rescue模式,进去后能挂载原系统、能读写磁盘、能拷数据。版本尽量和原系统一致(比如原来 CentOS 7.9,就用 7 系列的 ISO),避免库版本对不上导致挂载后操作别扭。
3.2 写盘工具与操作
写盘这件事,Windows、Linux、macOS 各有各的做法。核心原则只有一个:把 ISO 以“原始镜像”方式写入 U 盘,而不是简单复制文件。
在 Linux 下最直接:
# 先确认 U 盘设备名,千万别写错,写错就是抹掉别的盘 lsblk # 假设 U 盘是 /dev/sdb,用 dd 写入 sudo dd if=CentOS-7-x86_64-Minimal-2009.iso of=/dev/sdb bs=4M status=progress oflag=sync几个关键点:
of=后面是整块设备(/dev/sdb),不是分区(/dev/sdb1)。写分区是常见错误,写出来不能启动。bs=4M是块大小,兼顾速度和稳定。太小慢,太大在某些 U 盘上容易出错。status=progress让你看到进度,不然 dd 一声不吭,你会怀疑它卡死。oflag=sync强制同步写入,避免拔盘时数据还在缓存里没落盘。
在 Windows 下,常用的是 Rufus 或 balenaEtcher。Rufus 里选“DD 模式”写入,不要选“ISO 模式”,否则可能做出一个只能读不能启动的盘。balenaEtcher 默认就是镜像写入,比较省心。
在 macOS 下:
# 找到 U 盘,通常是 /dev/disk2 之类 diskutil list # 先卸载(不是弹出) diskutil unmountDisk /dev/disk2 # 写入,注意用 rdisk 更快 sudo dd if=CentOS-7-x86_64-Minimal-2009.iso of=/dev/rdisk2 bs=4m3.3 写完之后必须验证的两件事
第一,确认 U 盘真的可启动。有条件的话找台测试机或虚拟机试一下,别等到生产机前才发现盘做废了。第二,确认 BIOS/UEFI 启动模式。老机器多是 Legacy BIOS,新机器多是 UEFI。ISO 一般两种都支持,但你要在开机时选对启动项,否则可能看到黑屏或“no bootable device”。
提示:有些服务器默认关闭了从 USB 启动,需要在 BIOS 里手动打开,或者用带外管理(如 IPMI、iDRAC、iLO)挂载 ISO 远程启动。这个在机房场景下比跑现场插 U 盘高效得多。
4. 进救援模式:挂载、备份、抢救数据
4.1 从 U 盘启动到 rescue 环境
插上 U 盘,开机狂按启动菜单键(常见是 F12、F11、F9、Esc,视品牌而定),选 U 盘启动。进入 CentOS 安装界面后,不要点“Install”,而是选Troubleshooting → Rescue a CentOS system。
救援模式会做几件事:
- 尝试自动探测并挂载你原来的系统到
/mnt/sysimage。 - 给你一个 shell,通常提示你
chroot /mnt/sysimage进入原系统环境。
但注意:如果/usr被删,自动挂载可能失败或挂载后不完整。这时候不要慌,手动挂载。
4.2 手动挂载原系统分区
先看磁盘布局:
lsblk fdisk -l假设原系统根分区是/dev/sda2,/boot是/dev/sda1,数据盘是/dev/sdb1。手动挂载:
mkdir -p /mnt/root mount /dev/sda2 /mnt/root # 如果 /boot 独立,也挂上 mount /dev/sda1 /mnt/root/boot # 数据盘单独挂,方便备份 mkdir -p /mnt/data mount /dev/sdb1 /mnt/data挂载后ls /mnt/root,你会看到/usr目录要么不存在,要么是空的。这时候你的目标很明确:把/mnt/root下还重要的东西(/etc、/home、/var、/root、/opt等)拷到数据盘或外部存储。
4.3 备份时最容易忽略的目录
很多人备份只盯着/home,其实这些目录同样关键:
/etc:所有配置文件,包括网络、用户、服务配置。丢了重建很痛苦。/var:数据库数据、日志、Web 内容、邮件队列常在这里。/root:root 用户的脚本、密钥、历史。/opt:第三方软件常装在这。/srv:部分服务的站点数据。/usr/local:如果你手动编译安装过东西,这里可能有你的心血。
备份命令示例:
# 用 tar 打包,保留权限 tar czpPf /mnt/data/etc-backup.tar.gz /mnt/root/etc tar czpPf /mnt/data/var-backup.tar.gz /mnt/root/var tar czpPf /mnt/data/home-backup.tar.gz /mnt/root/home-p保留权限,-P保留绝对路径(注意这会记录/mnt/root/...路径,恢复时要注意)。如果数据量大,用rsync更灵活:
rsync -aAXv /mnt/root/etc/ /mnt/data/etc/-a归档模式,-A保留 ACL,-X保留扩展属性,-v显示进度。
注意:备份前先确认目标盘空间够。用
df -h看一眼,别拷到一半空间满了,前功尽弃。
5. 修复路线一:从同版本机器补齐 /usr
如果你不想重装,且手头有另一台完全相同版本的 CentOS 机器,理论上可以从它那里把/usr拷过来。但这条路坑很多,我把它讲透,你自己判断值不值得走。
5.1 为什么“同版本”是硬性前提
/usr里的二进制和库是跟发行版版本、架构、甚至补丁级别强绑定的。CentOS 7.6 的glibc和 7.9 的版本可能不同,混用会导致动态链接失败。架构更不用说,x86_64 和 aarch64 的二进制完全不通用。
所以源机器必须满足:
- 同发行版(都是 CentOS 7 或都是 CentOS 8)
- 同小版本(最好
cat /etc/centos-release完全一致) - 同架构(
uname -m一致) - 补丁级别接近(
rpm -qa对比差异不要太大)
5.2 拷贝的具体做法
在救援环境下,把源机器的/usr打包,传到目标机,解包到/mnt/root/usr:
# 在源机器上打包(假设能登录) tar czpPf /tmp/usr-backup.tar.gz /usr # 传到救援环境后解包 mkdir -p /mnt/root/usr tar xzpPf /tmp/usr-backup.tar.gz -C /mnt/root但这里有个致命问题:源机器的/usr里包含它自己的配置和状态,比如/usr/lib/systemd下的单元文件、/usr/share下的文档、某些软件的数据。直接覆盖可能引入不一致。更稳妥的是只拷核心运行库和二进制,但那样又很难界定范围。
5.3 这条路我不推荐的原因
说实话,从同版本机器拷/usr属于“看起来可行、实际很脆”的方案。原因有三:
- 依赖关系复杂:
/usr里成千上万个文件,你很难保证拷全。漏一个库,某个服务就起不来。 - SELinux 上下文:CentOS 默认开 SELinux,直接
tar拷贝可能丢失安全上下文,导致服务被拒绝。需要restorecon修复,但restorecon本身也可能在/usr里。 - 包数据库不一致:
rpm数据库记录的文件和实际文件对不上,后续yum操作会报各种诡异错误。
所以我的实际建议是:除非你有非常特殊的理由不能重装,否则直接重装更省心。重装半小时,修/usr可能折腾一整天还留隐患。
6. 修复路线二:重装系统 + 数据回迁的完整流程
6.1 重装前的最后确认
重装会格式化系统盘,所以动手前必须确认:
- 重要数据已经备份到另一块物理盘或外部存储。别备份在同一块盘的其他分区,因为重装可能重新分区。
- 记下原系统的关键配置:网络(IP、网关、DNS)、主机名、用户列表、服务列表、定时任务、防火墙规则。这些可以从备份的
/etc里翻。 - 确认安装介质的版本和原系统一致或兼容,避免应用跑不起来。
6.2 安装时的分区策略
重装时分区有个经验:系统和数据分开。如果原来没分,这次借机会分好:
/boot:1G 左右,放内核和引导。/:50-100G,放系统和软件。/home或/data:剩余空间,放数据。swap:按内存大小定,一般 4-16G。
这样以后再出系统级问题,数据盘不受影响,重装只需格式化/和/boot。
6.3 数据回迁与配置恢复
系统装好后,挂载数据盘,把之前备份的/etc、/home、/var等按需恢复。注意:
/etc不要整个覆盖,而是按文件对比恢复。新系统的/etc有它自己的默认配置,直接覆盖可能把新系统的网络、引导配置搞坏。用diff或vimdiff逐个对比。- 用户和组要先建好,再恢复
/home,否则文件属主会变成数字 UID。 - 数据库类数据(MySQL、PostgreSQL)恢复前先停服务,恢复后检查权限和属主。
# 对比新旧配置 diff -r /mnt/data/etc-backup/etc /etc # 恢复用户 useradd -u 1001 -g 1001 -d /home/appuser appuser # 恢复 home 并修正属主 rsync -aAXv /mnt/data/home-backup/ /home/ chown -R appuser:appuser /home/appuser7. 几个真实踩过的坑和应对技巧
7.1 救援模式认不到硬盘控制器
有些服务器用了 RAID 卡或 NVMe,救援模式的默认内核可能没带对应驱动,导致lsblk看不到盘。这时候要么在启动时加驱动参数,要么用厂商提供的专用救援镜像。带外管理挂载 ISO 时,注意选对驱动版本。
7.2 chroot 之后命令还是不能用
chroot /mnt/sysimage后如果/usr是空的,chroot 进去也没用,因为 shell 和命令都在/usr里。这时候不要 chroot,直接在救援环境里操作/mnt/sysimage下的文件。救援环境自己有完整的/usr,工具齐全。
7.3 备份时权限丢失
用cp不带-a,或者用某些图形工具拖拽,会导致权限、属主、时间戳全丢。恢复后服务起不来,排查半天发现是权限问题。记住:系统文件备份一律用tar -p或rsync -aAX。
7.4 忘了记录原分区 UUID
/etc/fstab里常用 UUID 挂载分区。重装后如果数据盘的 UUID 变了(重新格式化会变),fstab对不上,开机进紧急模式。恢复前用blkid查新 UUID,更新fstab。
blkid # 输出示例:/dev/sdb1: UUID="xxxx-xxxx" TYPE="ext4"7.5 SELinux 导致的“莫名其妙”拒绝
恢复文件后如果服务起不来,看/var/log/audit/audit.log或dmesg,如果有avc: denied,多半是 SELinux 上下文不对。用:
restorecon -Rv /path/to/restored/files如果restorecon不可用(因为/usr问题),可以临时setenforce 0验证是不是 SELinux 的锅,但生产环境不要长期关闭。
8. 防患于未然:比恢复更重要的几件事
误删/usr这种事,恢复一次就够了,谁也不想有第二次。几个低成本高回报的习惯:
- 命令别名加确认:给
rm加-i,或者用trash-cli代替直接删。alias rm='rm -i'写进/etc/profile.d/。 - 关键操作前打快照:虚拟机、云主机都有快照功能,改系统前打一个,出事回滚几分钟。
- 定期备份
/etc:/etc不大,但价值极高。用etckeeper把它纳入版本控制,每次改动都有记录。 - 分离系统和数据:前面说过,分区时就把
/和/data分开,系统坏了数据还在。 - 保留一份救援 U 盘:做好的 CentOS 救援盘放机房或随身带,关键时刻能省几小时。
我个人在实际操作中的体会是:误删/usr之后,最贵的不是修复技术,而是时间和数据。技术方案就那几条,但如果你平时没备份、没分盘、没快照,恢复过程就会非常被动。反过来,如果平时做好了这些,真出事时也就是重装半小时、回迁数据一小时的功夫。所以与其研究怎么花式修复,不如把功夫下在平时——这话听起来像老生常谈,但每次踩坑之后都会重新认同一次。