一、Linux磁盘空间优化的重要性
1.1 磁盘空间不足的危害
当Linux服务器磁盘空间不足时,会引发一系列严重问题:
– 系统崩溃:无法写入日志和临时文件,导致服务异常
– 数据库故障:MySQL/PostgreSQL无法写入数据,导致数据丢失
– 性能下降:文件系统碎片增多,IO性能显著下降
– 安全风险:日志无法正常记录,安全事件难以追溯
1.2 优化策略总览
Linux磁盘空间优化可以分为三个层次:
– 即时清理:快速释放已占用的空间
– 定期维护:建立自动化清理机制
– 架构优化:从系统设计层面减少空间浪费
二、磁盘空间分析工具
2.1 基础分析命令
# 查看文件系统使用情况
df -hT
# 查看目录大小(排序)
du -sh /* | sort -rh
# 查看指定目录下最大的10个子目录
du -sh /var/* | sort -rh | head -10
# 查看inode使用率
df -i
2.2 高级分析工具
# 安装ncdu(交互式磁盘分析)
sudo apt install -y ncdu
ncdu /var
# 安装tdu(磁盘使用趋势分析)
sudo apt install -y tdu
# 使用find查找大文件
find / -type f -size +500M -exec ls -lh {} \; 2>/dev/null | sort -k5 -rh
# 查找最近修改的大文件
find / -type f -mtime -1 -size +100M -exec ls -lh {} \; 2>/dev/null
2.3 磁盘使用趋势报告
#!/bin/bash
# 生成磁盘使用报告
echo "=== 磁盘使用报告 - $(date) ===" > /tmp/disk_report.txt
echo "" >> /tmp/disk_report.txt
echo "文件系统使用情况:" >> /tmp/disk_report.txt
df -h >> /tmp/disk_report.txt
echo "" >> /tmp/disk_report.txt
echo "最大的目录(前10):" >> /tmp/disk_report.txt
du -sh /* 2>/dev/null | sort -rh | head -10 >> /tmp/disk_report.txt
cat /tmp/disk_report.txt
三、日志文件优化
3.1 日志文件分析
# 查看日志目录总大小
du -sh /var/log
# 按大小排序日志文件
ls -lhS /var/log/ | head -20
# 统计各应用日志大小
du -sh /var/log/* | sort -rh
3.2 logrotate高级配置
logrotate是Linux系统自带的日志轮转工具,合理配置可以自动管理日志文件大小。
全局配置文件 /etc/logrotate.conf:
# 全局默认配置
weekly # 每周轮转
rotate 4 # 保留4个旧文件
create # 轮转后创建新文件
compress # 压缩旧文件
delaycompress # 延迟一个周期再压缩
missingok # 文件不存在不报错
notifempty # 空文件不轮转
应用级配置示例 /etc/logrotate.d/nginx:
/var/log/nginx/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 nginx adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}
3.3 journald日志管理
# 查看journal日志占用
journalctl --disk-usage
# 设置日志最大容量
sudo nano /etc/systemd/journald.conf
# SystemMaxUse=500M
# 立即清理
sudo journalctl --vacuum-size=200M
sudo journalctl --vacuum-time=7d
# 重启journald
sudo systemctl restart systemd-journald
四、软件包管理优化
4.1 APT缓存优化(Debian/Ubuntu)
# 查看缓存大小
du -sh /var/cache/apt/archives
# 清理所有缓存
sudo apt clean
# 仅清理不再可下载的包
sudo apt autoclean
# 移除不再需要的依赖
sudo apt autoremove --purge -y
# 清理残留配置文件
dpkg -l | grep "^rc" | awk '{print $2}' | xargs sudo dpkg --purge
4.2 YUM/DNF缓存优化(RHEL/CentOS/Fedora)
# 清理所有缓存
sudo yum clean all # 或 sudo dnf clean all
# 清理缓存和元数据
sudo dnf clean all --enablerepo="*"
# 移除孤立的依赖包
sudo dnf autoremove
# 查看缓存大小
du -sh /var/cache/yum # 或 /var/cache/dnf
4.3 Snap包优化
# 查看snap占用空间
du -h /var/lib/snapd/snaps
# 删除旧版本snap包
sudo snap list --all | awk '/disabled/{print $1, $3}' | while read name rev; do sudo snap remove "$name" --revision="$rev"; done
# 清理snap缓存
sudo rm -rf /var/lib/snapd/cache/*
五、内核管理优化
5.1 查看内核信息
# 当前运行的内核
uname -r
# 已安装的所有内核
dpkg -l | grep linux-image # Debian/Ubuntu
rpm -qa | grep kernel # RHEL/CentOS
# /boot分区使用情况
du -sh /boot
ls -lh /boot
5.2 安全清理旧内核
# Debian/Ubuntu - 保留当前内核
CURRENT=$(uname -r | sed 's/-generic//')
sudo apt purge -y $(dpkg -l | grep linux-image | grep -v $CURRENT | grep -v "linux-image-generic" | awk '{print $2}')
sudo apt purge -y $(dpkg -l | grep linux-headers | grep -v $CURRENT | awk '{print $2}')
# 清理后更新grub
sudo update-grub
5.3 防止boot分区满
# 修改/etc/apt/apt.conf.d/50unattended-upgrades
# 只保留当前和上一个内核
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
六、容器与虚拟化优化
6.1 Docker空间优化
# 查看Docker磁盘使用详情
docker system df -v
# 一键清理所有未使用资源
docker system prune -a --volumes
# 仅清理悬空镜像
docker image prune -f
# 仅清理停止的容器
docker container prune -f
# 仅清理未使用的网络
docker network prune -f
# 查看镜像层详情
docker history --no-trunc image_name
6.2 Podman空间优化
# 查看磁盘使用
podman system df
# 清理未使用资源
podman system prune -a -f
# 清理悬空镜像
podman image prune -f
6.3 LXC/LXD容器优化
# 查看容器存储使用
lxc storage info default
# 清理未使用的镜像
lxc image list -c f
lxc image delete <fingerprint>
# 清理快照
lxc snapshot <container> <snapshot_name>
lxc delete <container>/<snapshot_name>
七、数据库空间优化
7.1 MySQL/MariaDB
# 查看数据库大小
mysql -e "SELECT table_schema, ROUND(SUM(data_length+index_length)/1024/1024,2) AS 'MB' FROM information_schema.tables GROUP BY table_schema;"
# 清理二进制日志
mysql -e "PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY);"
# 优化碎片表
mysql -e "SELECT CONCAT('OPTIMIZE TABLE ',table_schema,'.',table_name,';') FROM information_schema.tables WHERE DATA_FREE > 0;" | mysql
7.2 PostgreSQL
# 全库VACUUM
sudo -u postgres vacuumdb --all --full --analyze
# 查看膨胀表
sudo -u postgres psql -c "SELECT schemaname, relname, n_dead_tup FROM pg_stat_user_tables WHERE n_dead_tup > 1000 ORDER BY n_dead_tup DESC;"
# 清理WAL日志
sudo -u postgres pg_archivecleanup /var/lib/postgresql/15/main/pg_wal
八、自动化维护体系
8.1 综合清理脚本
#!/bin/bash
# /usr/local/bin/auto-cleanup.sh
LOG="/var/log/auto-cleanup.log"
DATE=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$DATE] === 开始自动清理 ===" >> $LOG
# 1. APT缓存
apt clean >> $LOG 2>&1
apt autoremove --purge -y >> $LOG 2>&1
# 2. 旧日志
find /var/log -name "*.gz" -mtime +30 -delete >> $LOG 2>&1
find /var/log -name "*.[0-9]" -mtime +30 -delete >> $LOG 2>&1
# 3. Journal日志
journalctl --vacuum-size=200M >> $LOG 2>&1
# 4. 临时文件
find /tmp -type f -atime +7 -delete >> $LOG 2>&1
# 5. 旧内核(保留2个)
apt purge -y $(dpkg -l | grep linux-image | grep -v $(uname -r) | grep -v "generic" | tail -n +3 | awk '{print $2}') >> $LOG 2>&1
echo "[$DATE] === 清理完成 ===" >> $LOG
df -h / >> $LOG
8.2 Crontab定时配置
# 编辑定时任务
sudo crontab -e
# 每周日凌晨2点执行清理
0 2 * * 0 /usr/local/bin/auto-cleanup.sh
# 每天凌晨3点检查磁盘空间
0 3 * * * /usr/local/bin/disk-alert.sh
8.3 Systemd Timer方式
创建 /etc/systemd/system/auto-cleanup.timer:
[Unit]
Description=Weekly auto cleanup
[Timer]
OnCalendar=Sun 02:00
Persistent=true
[Install]
WantedBy=timers.target
创建 /etc/systemd/system/auto-cleanup.service:
[Unit]
Description=Auto cleanup service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/auto-cleanup.sh
启用定时器:
sudo systemctl daemon-reload
sudo systemctl enable auto-cleanup.timer
sudo systemctl start auto-cleanup.timer
九、监控与告警
9.1 磁盘告警脚本
#!/bin/bash
THRESHOLD=80
HOSTNAME=$(hostname)
for PART in $(df -h | awk '{print $6}' | tail -n +2); do
USAGE=$(df -h $PART | tail -1 | awk '{print $5}' | sed 's/%//')
if [ $USAGE -gt $THRESHOLD ]; then
echo "${HOSTNAME}: ${PART} 使用率 ${USAGE}% 超过阈值 ${THRESHOLD}%"
fi
done
9.2 Prometheus + Grafana监控
推荐使用Prometheus的node_exporter采集磁盘指标,配合Grafana面板实时可视化:
– node_filesystem_avail_bytes – 可用空间
– node_filesystem_size_bytes – 总空间
– node_filesystem_files_free – 可用inode
总结
Linux系统磁盘空间优化是一项系统性的工作,核心原则:
- 监控优先:建立完善的监控告警机制
- 自动清理:使用cron或systemd timer定期执行
- 按需分配:合理规划分区大小和挂载策略
- 架构优化:从设计层面减少空间浪费(如使用对象存储替代本地存储)
通过以上最佳实践,可以确保Linux系统长期稳定运行,避免因磁盘空间不足导致的服务中断。
注:本文基于Ubuntu 22.04/CentOS Stream 9编写,部分命令可能因发行版不同而有所差异。