1. Linux磁盘问题排查全景指南
当Linux服务器突然提示"No space left on device"或者遭遇无法写入的尴尬情况时,作为运维老手,我通常会按照这套经过实战检验的排查流程来解决问题。以下是我在500+台服务器维护中总结的完整解决方案,涵盖从快速应急到深度优化的全链路操作。
1.1 磁盘空间告急的典型症状
最常见的两种磁盘问题表现形式:
- 空间耗尽型:
df -h显示使用率100%,报错"No space left on device" - 写入异常型:有剩余空间但无法创建/修改文件,报错"Read-only file system"或"I/O error"
重要提示:当磁盘使用率超过90%时就应开始清理,许多服务(如MySQL)在空间不足时会出现不可预知的异常行为
2. 八步诊断与修复流程
2.1 第一步:快速定位空间占用
使用改良版df命令获取更直观的空间信息:
bash复制df -hT -x tmpfs -x devtmpfs | sort -hrk5
参数解析:
-h:人类可读格式-T:显示文件系统类型-x:排除临时文件系统sort -hrk5:按使用率降序排序
典型输出示例:
code复制Filesystem Type Size Used Avail Use% Mounted on
/dev/nvme0n1p1 ext4 100G 96G 3.7G 97% /
/dev/sdb1 xfs 2.0T 1.8T 200G 90% /data
2.2 第二步:深度分析目录占用
du命令的进阶用法:
bash复制du -h --max-depth=1 / 2>/dev/null | sort -hr
如果遇到"Permission denied"干扰统计,改用:
bash复制sudo du -h --max-depth=1 --time / | grep -v "Permission denied" | sort -hr
对于超大型文件系统,推荐更高效的ncdu工具:
bash复制sudo apt install ncdu # Debian/Ubuntu
sudo yum install ncdu # CentOS/RHEL
ncdu / --exclude /mnt # 交互式分析界面
2.3 第三步:处理日志文件爆炸
日志管理黄金组合:
bash复制# 查看最大的10个日志文件
find /var/log -type f -name "*.log" -exec du -h {} + | sort -hr | head -n10
# 清空而不删除日志文件(保持inode不变)
truncate -s 0 /var/log/syslog
# 配置logrotate自动管理(示例配置)
cat > /etc/logrotate.d/myapp <<EOF
/var/log/myapp/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 640 root adm
sharedscripts
postrotate
systemctl reload myapp >/dev/null
endscript
}
EOF
2.4 第四步:追踪磁盘写入进程
使用iotop实时监控:
bash复制sudo iotop -o -b -d 10 -n 5
输出字段解读:
- DISK READ:每秒读取量
- DISK WRITE:每秒写入量
- SWAPIN:交换内存使用率
- IO>:I/O优先级
对于没有iotop的环境,可用内核提供的统计接口:
bash复制watch -n1 "cat /proc/diskstats | grep -E 'nvme0n1|sda'"
2.5 第五步:处理僵尸文件与挂载异常
当文件已删除但进程仍占用空间时:
bash复制# 查找被删除但仍被占用的文件
sudo lsof +L1 | grep deleted
# 释放空间方法(任选其一):
# 1. 重启持有文件的进程
# 2. 清空文件描述符(危险!)
sudo truncate -s 0 /proc/[pid]/fd/[fd_num]
挂载点异常检测:
bash复制mount | grep -E '(ro,|remount)' # 检查只读挂载
dmesg | grep -i error # 查看磁盘错误日志
smartctl -a /dev/sda # 检查磁盘健康状态
2.6 第六步:清理APT/YUM缓存
包管理器缓存清理:
bash复制# Debian/Ubuntu
sudo apt clean
sudo apt autoremove --purge
# CentOS/RHEL
sudo yum clean all
sudo package-cleanup --oldkernels --count=2
2.7 第七步:处理Docker磁盘泄漏
容器相关空间回收:
bash复制# 查看docker磁盘使用
docker system df -v
# 彻底清理(谨慎使用)
docker system prune -a --volumes
# 限制日志大小(daemon.json配置示例)
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
2.8 第八步:文件系统修复与扩容
当遇到文件系统错误时:
bash复制# 卸载后检查ext4文件系统
sudo umount /dev/sdb1
sudo fsck -y /dev/sdb1
# XFS文件系统修复
xfs_repair /dev/sdb1
在线扩容LVM磁盘:
bash复制# 查看PV/VG/LV信息
sudo pvdisplay
sudo vgdisplay
sudo lvdisplay
# 扩展逻辑卷(示例)
sudo lvextend -L +20G /dev/vg00/lv_root
sudo resize2fs /dev/vg00/lv_root # ext4文件系统
# 或对xfs:
sudo xfs_growfs /dev/vg00/lv_root
3. 高级诊断工具集
3.1 性能分析工具链
bash复制# 安装诊断工具包
sudo apt install sysstat iotop dstat ltrace strace # Debian
sudo yum install sysstat iotop dstat ltrace strace # RHEL
# 实时IO监控(dstat)
dstat -tdl --disk-util --disk-tps 5
# 块设备级监控(iostat)
iostat -xmdz 5
3.2 自动化清理脚本
创建/usr/local/bin/disk-cleaner:
bash复制#!/bin/bash
LOG_FILE="/var/log/disk-cleaner.log"
{
echo "==== $(date) ===="
echo "### 清理APT缓存 ###"
apt clean
apt autoremove -y
echo "### 清理日志 ###"
find /var/log -name "*.log" -type f -size +100M -exec truncate -s 50M {} \;
journalctl --vacuum-size=200M
echo "### 清理临时文件 ###"
find /tmp -type f -atime +7 -delete
find /var/tmp -type f -atime +30 -delete
echo "### 当前磁盘状态 ###"
df -hT
} >> "$LOG_FILE" 2>&1
设置定时任务:
bash复制sudo chmod +x /usr/local/bin/disk-cleaner
sudo crontab -e
# 添加:
0 3 * * * /usr/local/bin/disk-cleaner
4. 防患于未然的配置建议
4.1 文件系统选择建议
根据使用场景选择:
- Ext4:通用场景,稳定性优先
- XFS:大文件处理(如数据库、视频存储)
- Btrfs:需要快照功能的场景
挂载参数优化(/etc/fstab示例):
code复制UUID=xxxx /data xfs defaults,noatime,nodiratime,allocsize=8m 0 2
4.2 监控告警配置
Prometheus监控规则示例:
yaml复制groups:
- name: disk.rules
rules:
- alert: DiskSpaceCritical
expr: 100 - (node_filesystem_avail_bytes{mountpoint="/"} * 100 / node_filesystem_size_bytes{mountpoint="/"}) > 90
for: 10m
labels:
severity: critical
annotations:
summary: "Disk space critical on {{ $labels.instance }}"
description: "{{ $labels.mountpoint }} on {{ $labels.instance }} has only {{ $value | humanize }}% free space"
4.3 特殊场景处理
案例1:NFS挂载点卡死
bash复制# 强制卸载
umount -f -l /mnt/nfs
# 安全挂载参数
mount -t nfs -o soft,timeo=30,retrans=3 server:/path /mnt/nfs
案例2:磁盘I/O性能骤降
bash复制# 检查调度器
cat /sys/block/sda/queue/scheduler
# 临时切换为deadline(机械硬盘)
echo deadline > /sys/block/sda/queue/scheduler
# 永久生效(GRUB配置)
GRUB_CMDLINE_LINUX_DEFAULT="... elevator=deadline"
