标签: Linux磁盘管理 | 文件系统修复 | 日志清理 | 空间优化 | 运维技巧
凌晨3点,监控系统突然报警:No space left on device。你揉着惺忪的睡眼登录服务器,df -h 显示磁盘使用率100%,服务开始拒绝写入,数据库连接池爆满,用户投诉电话接踵而至。
别慌。磁盘空间不足就像衣柜塞满了衣服——不是没地方了,是该扔的没扔,该叠好的乱堆着。
本文将带你从快速诊断到深度清理,再到预防措施,系统性地解决Linux磁盘空间问题。
第1层:快速诊断——先搞清楚"谁吃了我的空间"
在动手清理之前,你需要像医生问诊一样,先诊断病因。
1.1 查看磁盘整体使用情况
# 查看所有文件系统的磁盘使用情况(人类可读格式)
df -h
输出示例:
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 50G 48G 2.0G 96% /
devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs 3.9G 8.0K 3.9G 1% /dev/shm
关键结论:如果 Use% 接近100%,说明磁盘空间确实不足。但如果 Avail 还有空间却提示 No space left,可能是 inode 耗尽。
1.2 检查 inode 使用情况
# 查看 inode 使用情况
df -i
输出示例:
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda1 3276800 3276800 0 100% /
关键结论:inode 耗尽时,即使磁盘还有空间,也无法创建新文件。 这通常是小文件过多导致的(比如缓存目录、日志碎片)。
1.3 定位大文件/目录
# 查看当前目录下各子目录的大小(从大到小排序)
du -sh /* 2>/dev/null | sort -rh | head -20
# 查看指定目录下文件大小
du -sh /var/log/* 2>/dev/null | sort -rh | head -10
# 查找大于100MB的文件
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null
关键结论:du 命令是磁盘空间的"照妖镜",能快速定位"空间大户"。
第2层:日志清理与轮转——别让日志成为"空间杀手"
日志文件是磁盘空间的头号杀手。我见过太多服务器因为日志失控而宕机。
2.1 使用 journalctl 清理系统日志
# 查看日志占用的磁盘空间
journalctl --disk-usage
# 只保留最近500MB的日志
journalctl --vacuum-size=500M
# 只保留最近7天的日志
journalctl --vacuum-time=7d
# 查看当前日志保留配置
cat /etc/systemd/journald.conf
配置持久化(/etc/systemd/journald.conf):
[Journal]
# 限制日志最大占用空间
SystemMaxUse=500M
# 单个日志文件大小限制
SystemMaxFileSize=50M
# 保留日志的最大时间
MaxRetentionSec=7day
关键结论:journalctl --vacuum-size 是应急清理的神器,但修改配置文件才能根治。
2.2 配置 logrotate 自动轮转
logrotate 是 Linux 系统自带的日志轮转工具,能自动压缩、删除旧日志。
查看 logrotate 配置:
# 查看主配置文件
cat /etc/logrotate.conf
# 查看各服务的日志配置
ls /etc/logrotate.d/
自定义配置示例(/etc/logrotate.d/myapp):
/var/log/myapp/*.log {
daily # 每天轮转
rotate 7 # 保留7个备份
compress # 压缩旧日志
delaycompress # 延迟压缩(保留最近一个未压缩)
missingok # 日志不存在不报错
notifempty # 空日志不轮转
create 0644 root root # 创建新日志的权限
dateext # 使用日期作为后缀
}
手动测试配置:
# 测试配置是否正确(不实际执行)
logrotate -d /etc/logrotate.d/myapp
# 强制立即执行一次
logrotate -f /etc/logrotate.conf
关键结论:logrotate 是运维的"自动保洁员",配置好了就能一劳永逸。
2.3 常见日志清理命令速查
| 场景 | 命令 | 说明 |
|---|---|---|
| 清空单个日志文件 | > /var/log/big.log | 快速释放空间,保留文件句柄 |
| 删除7天前的日志 | find /var/log -name "*.log" -mtime +7 -delete | 清理过期日志 |
| 压缩旧日志 | find /var/log -name "*.log" -mtime +1 -exec gzip {} \; | 节省空间 |
第3层:已删除文件空间释放——"幽灵文件"的清理
这是最容易被忽视的问题。文件删除了,但空间没释放?
3.1 理解"已删除但未释放"的文件
在 Linux 中,文件被删除后,如果还有进程持有该文件的句柄,磁盘空间并不会立即释放。这就像你把衣柜里的衣服扔了,但室友还抓着衣服不放,衣柜空间还是占着。
3.2 使用 lsof 查找 deleted 文件
# 查找所有已删除但仍被占用的文件
lsof | grep deleted
# 按大小排序,找出占用空间最大的
lsof | grep deleted | awk '{print $7, $1, $2, $NF}' | sort -rn | head -20
# 查看特定进程占用的已删除文件
lsof -p <PID> | grep deleted
输出示例:
nginx 1234 www-data 3w REG 8,1 10737418240 0 /var/log/nginx/access.log (deleted)
关键结论:lsof | grep deleted 是排查"幽灵文件"的终极武器。
3.3 释放已删除文件占用的空间
方法一:重启进程(推荐)
# 优雅重启 nginx
systemctl restart nginx
# 或者发送 HUP 信号重新加载
kill -HUP <PID>
方法二:清空文件内容(无需重启)
# 找到占用文件的进程ID和文件描述符
# 假设 PID=1234,文件描述符=3
# 使用 truncate 清空内容
> /proc/1234/fd/3
# 或者使用 echo
echo > /proc/1234/fd/3
关键结论:> /proc/<PID>/fd/<FD> 是无需重启服务就能释放空间的黑科技。
3.4 实战脚本:一键清理 deleted 文件
#!/bin/bash
# 一键清理已删除但仍占用的文件
echo "正在查找已删除但仍占用的文件..."
# 获取所有 deleted 文件的 PID 和 FD
lsof | grep deleted | awk '{print $2, $4}' | sed 's/[^0-9]*$//' | while read pid fd; do
if [ -n "$pid" ] && [ -n "$fd" ]; then
echo "清理进程 $pid 的文件描述符 $fd"
> /proc/$pid/fd/$fd
fi
done
echo "清理完成!"
df -h
第4层:文件系统修复——当磁盘"生病"了
如果以上方法都无效,可能是文件系统本身出了问题。
4.1 使用 fsck 检查修复文件系统
# 查看文件系统类型
df -Th
# 卸载分区后检查(必须卸载!)
umount /dev/sdb1
fsck -y /dev/sdb1
# 对于 ext4 文件系统
e2fsck -y /dev/sdb1
fsck 参数说明:
| 参数 | 说明 |
|---|---|
-y | 自动回答 yes,无需交互 |
-n | 只检查不修复(模拟运行) |
-v | 显示详细信息 |
-f | 强制检查(即使文件系统标记为 clean) |
关键结论:fsck 必须在卸载的分区上运行,否则可能损坏数据。
4.2 根文件系统修复方法
根文件系统无法卸载,需要进入救援模式:
方法一:使用 Live CD/USB
- 插入 Live 介质,从介质启动
- 选择 “Try Ubuntu” 或类似选项
- 找到根分区并挂载检查
# 查看分区
fdisk -l
# 挂载根分区(假设是 /dev/sda1)
mount /dev/sda1 /mnt
# 检查文件系统
fsck -y /dev/sda1
方法二:使用恢复模式
- 重启系统,在 GRUB 菜单选择 “Advanced options”
- 选择 “Recovery mode”
- 选择 “fsck” 选项
方法三:强制开机检查
# 在正常运行时设置下次启动检查
tune2fs -c 1 /dev/sda1
# 或者创建 forcefsck 文件
touch /forcefsck
reboot
关键结论:根文件系统修复需要谨慎操作,建议先备份重要数据。
4.3 文件系统健康监控
# 查看文件系统状态
tune2fs -l /dev/sda1
# 查看挂载选项
mount | grep /dev/sda1
# 查看磁盘 SMART 信息(需要安装 smartmontools)
smartctl -a /dev/sda
预防措施——让磁盘问题不再发生
5.1 配置 fstab 自动监控
编辑 /etc/fstab,为关键分区添加监控选项:
# 示例:启用磁盘配额和错误报告
/dev/sda1 / ext4 errors=remount-ro,usrquota,grpquota 0 1
5.2 使用 smartctl 监控磁盘健康
# 安装 smartmontools
apt-get install smartmontools # Debian/Ubuntu
yum install smartmontools # CentOS/RHEL
# 启用 SMART 监控
smartctl -s on /dev/sda
# 查看磁盘健康状态
smartctl -H /dev/sda
# 运行完整自检
smartctl -t long /dev/sda
# 查看自检结果
smartctl -l selftest /dev/sda
关键结论:smartctl 是磁盘的"体检报告",能提前发现潜在故障。
5.3 设置磁盘空间告警脚本
#!/bin/bash
# 磁盘空间监控脚本
THRESHOLD=80
EMAIL="admin@example.com"
# 检查磁盘使用率
df -H | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $5 " " $1 }' | while read output; do
usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1)
partition=$(echo $output | awk '{ print $2 }')
if [ $usep -ge $THRESHOLD ]; then
echo "警告: 分区 $partition 使用率已达 $usep%" | mail -s "磁盘空间告警" $EMAIL
fi
done
添加到 crontab 定时执行:
# 每30分钟检查一次
*/30 * * * * /path/to/disk-monitor.sh
方案对比总结
| 清理层级 | 适用场景 | 风险等级 | 执行难度 | 效果持久性 |
|---|---|---|---|---|
| 第1层:诊断 | 所有场景 | ⭐ 无 | ⭐ 简单 | - |
| 第2层:日志清理 | 日志过大 | ⭐ 低 | ⭐ 简单 | ⭐⭐⭐ 配置后可持久 |
| 第3层:deleted文件 | 空间未释放 | ⭐⭐ 中 | ⭐⭐ 中等 | ⭐ 临时解决 |
| 第4层:文件系统修复 | 文件系统损坏 | ⭐⭐⭐ 高 | ⭐⭐⭐ 复杂 | ⭐⭐⭐ 根治问题 |
立即可做的3件事
-
运行诊断命令:执行
df -h和df -i,确认是磁盘空间不足还是 inode 耗尽 -
清理日志:执行
journalctl --vacuum-size=500M和find /var/log -name "*.log" -mtime +7 -delete,快速释放空间 -
检查幽灵文件:执行
lsof | grep deleted,如果有结果,考虑重启相关服务或清空文件描述符
结语
磁盘空间管理是 Linux 运维的基本功。记住这个口诀:先诊断、再清理、后修复、终预防。
磁盘空间就像时间,总是不够用,但总是可以优化。掌握这4层清理策略,下次再遇到 No space left,你就能从容应对了。
如果这篇文章帮到了你,欢迎点赞、收藏、转发。有任何问题,欢迎在评论区留言讨论!
标签: Linux磁盘管理 | 文件系统修复 | 日志清理 | 空间优化 | 运维技巧
1736



被折叠的 条评论
为什么被折叠?



