Linux服务器磁盘空间告急怎么办?从排查到扩容的完整处置流程

磁盘空间写满是服务器最常见的故障之一,轻则网站报500错误,重则数据库损坏、系统无法写入日志。本文给出从发现问题到彻底解决的完整流程,包括临时释放空间和长期扩容两条路径。

一、快速确认磁盘状态

# 查看各分区使用情况
df -h

# 典型输出(Use% 达到100%即告警)
# Filesystem      Size  Used Avail Use% Mounted on
# /dev/sda1        40G   40G     0 100% /
# tmpfs           1.9G     0  1.9G   0% /dev/shm
# 查看inode使用情况(小文件过多会耗尽inode)
df -i

# 若inode Use%接近100%,即使磁盘有空间也无法创建新文件

二、定位占用空间的大文件

# 从根目录开始逐层排查(-x不跨越文件系统)
du -sh /* 2>/dev/null | sort -rh | head -20

# 进入占用最大的目录继续排查
du -sh /var/* 2>/dev/null | sort -rh | head -10

# 找出超过100MB的单个文件
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null | sort -k5 -rh | head -20

常见磁盘空间大户

位置内容典型占用
/var/log/系统和应用日志几百MB到几十GB
/var/lib/docker/Docker镜像、容器、卷几GB到几十GB
/tmp/临时文件通常较小,偶有异常
/var/www/html/网站上传文件视业务而定
/var/lib/mysql/MySQL数据库文件几GB到几百GB
~/.pm2/logs/PM2应用日志长期运行后可达数GB

三、快速释放空间(应急处理)

1. 清理系统日志

# 清理journald日志(保留最近3天)
journalctl --vacuum-time=3d

# 查看journald日志占用
journalctl --disk-usage

# 清理/var/log下的压缩旧日志
find /var/log -name "*.gz" -delete
find /var/log -name "*.old" -delete

# 清空Nginx访问日志(不影响运行)
> /var/log/nginx/access.log
> /var/log/nginx/error.log

2. Docker清理

# 一键清理所有未使用的Docker资源
docker system prune -a --volumes

# 查看Docker占用详情
docker system df

# 只清理悬空镜像(更安全)
docker image prune

# 清理已停止的容器
docker container prune

3. 清理APT缓存

# 清理已下载的安装包缓存
apt clean
apt autoremove -y

# 查看清理效果
du -sh /var/cache/apt/

4. 清理MySQL binlog

# 查看binlog占用
ls -lh /var/lib/mysql/mysql-bin.*

# 删除7天前的binlog
mysql -u root -p -e "PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY);"

# 或在my.cnf中限制binlog保留天数
echo "expire_logs_days = 7" >> /etc/mysql/mysql.conf.d/mysqld.cnf
systemctl restart mysql

5. 清理PM2日志

# 安装pm2-logrotate
pm2 install pm2-logrotate

# 配置日志轮转(保留7天)
pm2 set pm2-logrotate:retain 7
pm2 set pm2-logrotate:max_size 50M

# 立即清空当前日志
pm2 flush

四、长期扩容方案

方案A:挂载额外块存储(推荐)

在IDC.Net控制台购买额外的块存储盘,挂载到服务器:

# 查看新磁盘(通常是/dev/sdb)
lsblk

# 创建分区
fdisk /dev/sdb
# 依次按:n → p → 1 → 回车 → 回车 → w

# 格式化为ext4
mkfs.ext4 /dev/sdb1

# 创建挂载点并挂载
mkdir -p /data
mount /dev/sdb1 /data

# 设置开机自动挂载
echo "/dev/sdb1 /data ext4 defaults 0 2" >> /etc/fstab

# 验证
df -h /data

方案B:LVM逻辑卷扩容

若原磁盘使用LVM管理,可以在线扩容而无需重启:

# 查看当前LVM状态
pvs && vgs && lvs

# 假设新增了/dev/sdb,初始化为PV
pvcreate /dev/sdb

# 将新PV加入现有VG(假设VG名为ubuntu-vg)
vgextend ubuntu-vg /dev/sdb

# 扩展LV并同步文件系统
lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv
resize2fs /dev/ubuntu-vg/ubuntu-lv

# 确认扩容成功
df -h /

方案C:迁移大目录到新挂载点

# 将/var/www迁移到新磁盘
rsync -av /var/www/ /data/www/
mv /var/www /var/www.bak

# 创建软链接
ln -s /data/www /var/www

# 验证正常后删除备份
rm -rf /var/www.bak

五、预防磁盘告急的最佳实践

  • 配置Prometheus告警:磁盘使用率超过80%时发送告警通知(参见第25篇)
  • 配置logrotate定期轮转日志:logrotate -f /etc/logrotate.conf
  • 定期运行 docker system prune 清理无用镜像
  • 购买服务器时预留足够的磁盘余量(建议实际使用量的2倍)
  • 将数据库、上传文件、日志分离到独立的块存储,与系统盘隔离

六、总结

磁盘空间告急时,优先清理日志和Docker缓存,通常可以释放几GB到几十GB的空间。长期来看,挂载额外块存储是最灵活的扩容方案。IDC.Net的香港VPS支持弹性块存储扩展,在控制台购买后几分钟即可挂载使用,无需重启服务器。

THE END