Linux 文件系统故障排查:从磁盘告警到快速定位
Linux 服务器运行过程中,文件系统问题非常常见,例如:
这类问题看似复杂,但只要建立固定的排查顺序,通常可以快速定位。
一、总体排查思路
建议按照以下顺序检查:
确认故障现象 ↓检查磁盘空间 ↓检查 inode ↓定位大目录和大文件 ↓检查已删除但仍被占用的文件 ↓检查挂载状态 ↓检查内核和磁盘错误 ↓必要时离线修复文件系统
核心是判断三个问题:
二、检查磁盘空间
首先执行:
重点关注:
示例:
Filesystem Size Used Avail Use% Mounted on/dev/sda2 80G 76G 1.2G 99% //dev/sdb1 500G 210G 290G 43% /data
当磁盘使用率超过 90% 时,就应开始排查。达到 100% 后,应用通常会出现日志写入失败、数据库异常或服务无法启动等问题。
按使用率排序:
需要注意,df 只能查看文件系统整体使用情况,不能直接告诉你具体哪个目录占用了空间。
三、定位大目录和大文件
1. 分析目录占用
查看根目录下各一级目录大小:
sudo du -xhd1 / 2>/dev/null | sort -h
如果发现 /var 占用较大,可继续排查:
sudo du -xhd1 /var 2>/dev/null | sort -h
逐层进入占用最大的目录,直到找到具体位置。
常见高占用目录包括:
其中 -x 表示不跨文件系统,避免统计其他挂载盘。
2. 查找大文件
查找大于 1GB 的文件:
sudo find / -xdev -type f -size +1G -printf '%s %p\n' 2>/dev/null \ | sort -nr \ | head -20
常见大文件来源:
不要看到大文件就直接删除,应先确认文件是否仍在使用,以及是否属于业务数据。
四、磁盘未满,却无法创建文件
有时 df -h 显示磁盘还有空间,但创建文件时报错:
此时可能不是磁盘容量耗尽,而是 inode 用完了。
检查 inode:
示例:
Filesystem Inodes IUsed IFree IUse% Mounted on/dev/sda2 5242880 5242880 0 100% /
inode 用于保存文件的元数据信息。每个普通文件、目录、软链接通常都会占用一个 inode。
因此,即使磁盘还有大量空间,只要小文件数量过多,也可能无法再创建文件。
查找文件数量较多的目录:
sudo find /var -xdev -type f -printf '%h\n' 2>/dev/null \ | sort \ | uniq -c \ | sort -nr \ | head -20
常见原因包括:
处理时不仅要删除无用文件,还应修复应用的清理策略,否则问题会再次出现。
五、文件删除后空间没有释放
这是 Linux 中非常典型的问题。
假设应用正在写入日志:
管理员直接执行:
rm -f /var/log/app/service.log
虽然文件名已经消失,但如果应用进程仍然持有该文件的文件描述符,磁盘空间并不会立即释放。
此时通常会出现:
检查命令:
或者:
示例:
java 1824 app 15w REG 8,2 21474836480 0 12345 /var/log/app.log (deleted)
这表示 Java 进程仍占用一个已经删除的 20GB 日志文件。
最稳妥的处理方式是重启对应服务:
sudo systemctl restart app.service
然后重新检查:
生产环境中不要直接重启未知进程,应先确认业务影响。
六、df 和 du 结果不一致
如果:
显示已使用 70GB,而:
只统计出 40GB,通常有以下原因。
1. 已删除文件仍被进程占用
检查:
2. 挂载点覆盖了原目录
例如 /data 目录原来已有文件,之后又挂载了新磁盘:
原目录中的文件并未删除,只是被新的挂载内容遮住。
检查挂载关系:
生产环境不要直接卸载,应先确认是否有业务正在使用该目录。
3. ext4 保留空间
ext4 通常会为 root 保留一部分空间,避免磁盘完全占满后系统无法正常运行。
查看保留空间:
sudo tune2fs -l /dev/sda2 | grep -E 'Reserved block count|Block size'
系统分区上的保留空间不建议随意取消。
七、文件系统变成只读
应用可能出现:
检查挂载状态:
findmnt -no TARGET,SOURCE,FSTYPE,OPTIONS /
如果挂载参数中出现 ro,说明文件系统当前为只读。
Linux 在检测到严重文件系统错误或磁盘 I/O 异常时,可能会自动将文件系统重新挂载为只读,以防止损坏继续扩大。
查看内核日志:
或:
journalctl -k -p err..alert
重点关注:
EXT4-fs errorBuffer I/O errorI/O errorRemounting filesystem read-only
此时不要急于强制恢复读写:
如果底层磁盘仍存在错误,强制写入可能进一步破坏数据。
正确顺序是:
八、检查磁盘健康状态
文件系统错误不一定是文件系统本身的问题,也可能来自硬盘、控制器或存储链路。
安装工具:
sudo apt install smartmontools
查看磁盘健康状态:
sudo smartctl -a /dev/sda
重点关注:
NVMe 磁盘可以执行:
sudo smartctl -a /dev/nvme0
如果出现持续增长的坏块、不可校正错误或大量介质错误,应优先备份数据并更换磁盘,而不是反复执行修复。
九、正确使用 fsck
fsck 用于检查和修复文件系统,但不能随意对正在挂载读写的文件系统执行。
先确认设备和挂载关系:
对于非根分区,可先卸载:
sudo umount /dev/sdb1sudo fsck -f /dev/sdb1
ext4 可使用:
根文件系统通常需要在以下环境中修复:
XFS 通常使用:
sudo xfs_repair /dev/sdb1
同样应在文件系统卸载后执行。
十、典型案例:删除日志后磁盘仍然 100%
故障现象
显示:
Filesystem Size Used Avail Use% Mounted on/dev/sda3 50G 50G 0 100% /var
但执行:
只统计出 18GB。
排查
由于 df 和 du 差异很大,执行:
发现:
java 2658 app 12w REG 8,3 32212254720 0 88192 /var/log/app.log (deleted)
Java 进程仍然占用一个已删除的 30GB 日志文件。
处理
确认业务允许后重启服务:
sudo systemctl restart app.service
再次执行:
磁盘空间恢复正常。
根因
管理员直接删除了正在写入的日志文件,但应用进程没有关闭对应文件描述符。
后续应使用应用自身的日志滚动功能或 logrotate 管理日志,避免问题再次发生。
十一、常用命令速查
# 查看磁盘空间df -h# 查看 inodedf -i# 查看目录占用sudo du -xhd1 /var 2>/dev/null | sort -h# 查找大文件sudo find / -xdev -type f -size +1G -exec ls -lh {} \; 2>/dev/null# 检查删除后仍被占用的文件sudo lsof +L1# 查看挂载关系findmnt# 查看块设备和文件系统lsblk -f# 查看内核错误dmesg -T | grep -Ei 'error|fail|ext4|xfs|i/o'# 查看磁盘健康状态sudo smartctl -a /dev/sda
十二、总结
Linux 文件系统故障主要可以分为四类:
推荐记住以下排查顺序:
df -h→ df -i→ du / find→ lsof +L1→ findmnt / lsblk→ dmesg / smartctl→ 卸载后执行 fsck
处理文件系统故障时,最重要的原则是:
先收集信息,再执行操作;先保护数据,再进行修复。
大多数“磁盘满了”“无法写入”“删除文件空间不释放”“文件系统只读”等问题,都可以较快缩小范围并找到根因。