1. 磁盘空间管理的四大神器
刚接手一台Linux服务器时,最让人头疼的就是突然弹出的"no space left on device"警告。上周我就遇到个典型案例:某台生产环境的Nginx服务器突然无法写入日志,紧急排查时发现根分区被占满。这时候df、du、fdisk、lsblk这四个命令就像手术刀组合,能快速定位问题。
df命令像是系统的体检报告,用df -h查看时,重点关注Use%列。有次我发现/var分区显示100%使用率,但实际文件加起来不到分区容量的一半——原来是某个进程删除文件后未释放句柄,用lsof | grep deleted找到了罪魁祸首。
du命令则是精准的病灶探测器。当/home分区告急时,用sudo du -sh /home/* | sort -rh快速锁定占用50G空间的用户目录。更精细的排查可以用--max-depth控制扫描深度,比如du -h --max-depth=2 /var/log。
fdisk和lsblk这对搭档负责理清磁盘的"解剖结构"。有次扩容磁盘后,lsblk清晰显示出新增的/dev/sdb未分区,而fdisk -l则详细列出了每个分区的起止扇区。特别提醒:操作fdisk时千万注意设备名,误操作可能导致数据灾难。
经验之谈:生产环境操作前先用
lsblk -f确认文件系统类型,EXT4/XFS/Btrfs等文件系统的管理命令各有不同
2. 从报警到解决的全流程实战
去年处理过一起典型故障:监控系统报警显示/data分区剩余不足10%。以下是完整的排查过程:
第一阶段:宏观诊断
$ df -hT /data Filesystem Type Size Used Avail Use% Mounted on /dev/nvme0n1p1 ext4 100G 92G 3.2G 97% /data发现是ext4文件系统,使用率已达97%。但du -sh /data统计只有60G,这30G的差值可能是隐藏文件或已删除未释放的空间。
第二阶段:定位大文件
$ sudo find /data -type f -size +1G -exec ls -lh {} + -rw-r----- 1 mysql mysql 12G Jun 15 03:00 /data/mysql/slow.log -rw-r--r-- 1 root root 8G Jun 14 18:00 /data/backups/old.tar.gz找到MySQL的慢查询日志和过期备份文件,用truncate -s 0清空日志文件(注意不要直接rm,避免影响正在写入的进程)。
第三阶段:分析分区结构
$ lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT NAME FSTYPE SIZE MOUNTPOINT nvme0n1 200G ├─nvme0n1p1 ext4 100G /data └─nvme0n1p2 xfs 100G /home发现该NVMe硬盘还有100G未分配空间,于是用fdisk /dev/nvme0n1创建新分区,通过resize2fs在线扩展了/data分区。
3. 那些容易踩的坑
inode耗尽陷阱:有次df -h显示磁盘还有空间,但系统报"no space"。执行df -i发现inode用尽,原因是/tmp下有数百万个小文件。解决方法:
$ find /tmp -type f -name "*.tmp" -delete $ tune2fs -i 0 /dev/sda1 # 禁用inode时间检查提升性能LVM的障眼法:用lsblk看到的是物理视图,而LVM逻辑卷需要额外命令:
$ pvs; vgs; lvs # 查看物理卷/卷组/逻辑卷 $ vgdisplay # 查看剩余可分配空间网络文件系统的特殊性:NFS挂载点用df可能显示不准确,实际应该用du -s统计。曾遇到NAS存储配额满但本地df显示有空间的案例。
容器带来的复杂度:Docker的overlay2存储驱动会占用大量空间,用docker system df查看专属统计:
$ docker system prune --volumes # 清理无用容器数据4. 高级技巧与自动化方案
实时监控方案:
# 每5分钟记录磁盘使用情况 (crontab -l 2>/dev/null; echo "*/5 * * * * df -h >> /var/log/disk_usage.log") | crontab -安全删除大文件:
$ shred -n 3 -z -v sensitive_file # 多次覆盖后删除 $ rm -f sensitive_file自动化清理脚本:
#!/bin/bash THRESHOLD=90 CURRENT=$(df / | awk '{print $5}' | tail -1 | sed 's/%//') if [ "$CURRENT" -gt "$THRESHOLD" ]; then find /var/log -name "*.log" -mtime +30 -exec rm {} \; journalctl --vacuum-size=200M fiBtrfs/ZFS特例:这些现代文件系统需要专用命令:
$ btrfs filesystem show # Btrfs空间统计 $ zpool list # ZFS存储池状态实际运维中,我习惯将这几个命令组合使用。比如lsblk -f | grep -v snap可以过滤掉快照设备,du --exclude="*.iso"可以跳过特定文件类型。记住:任何删除操作前先用ls确认文件列表,避免误删关键数据。