一、清理前的诊断与评估
在遇到 Linux 服务器磁盘空间不足时,第一步是进行全面诊断与评估,明确哪些分区或目录最先触发告警。只有把问题的源头找清楚,后续的清理、分区与扩容才能有的放矢。
通过基线对比来判断占用趋势,结合应用的存储结构,尽量分清系统盘、数据盘、日志盘以及容器数据盘的占用比例,避免盲目清理造成业务波动。
常用的诊断思路包括查看根分区与目标分区的使用率、识别高占用目录、追踪最近新增的日志和缓存数据,以及确认是否存在历史残留的大文件。建立快照或备份点,确保清理前后可回滚。
示例命令用于快速获取基线信息:
df -h
du -h --max-depth=1 / | sort -hr
lsblk -f
快速诊断要点
根分区、/var、/home、/tmp、Docker 数据目录等分区的使用率是重点关注对象。结合应用日志、数据库日志、缓存目录,以及自动清理策略,判断哪些区域最需要清理。
系统日志和归档文件往往在短时间内产生海量数据,系统日志规模与保留策略直接影响磁盘可用空间,需要快速定位并评估清理可行性。
进一步的诊断包括检查最近时间段的写入模式,确认是否有异常进程持续写入大量数据。实时监控与历史趋势对比有助于判断是否需要永久调整分区结构,而不仅仅是短期清理。
备份与回滚点的确认同样重要:在进行清理前确保可用的最近备份或快照能在必要时回滚,以避免不可逆的误删。
备份与回滚点
在执行任何清理操作前,创建可用的备份或快照点是关键步骤。优先对 /var/log、数据库数据目录、容器数据卷等高价值数据进行备份,并记录当前分区的使用率和关键文件的指纹信息,以便回滚时能快速对照。
如果虚拟化环境提供了快照能力,可在清理前对整个系统或目标卷组创建快照,以便在清理导致异常时快速回滚。
示例命令用于备份与快照(具体命令需基于环境而定):
# 备份示例(把 /var/log 归档到备份目录)
tar czf /root/var_log_backup_$(date +%F).tgz /var/log# LVM 快照(假设根卷为 /dev/mapper/VolGroup-lv_root,创建名为 snap_before_cleanup 的快照)
lvcreate -s -n snap_before_cleanup -L 5G /dev/mapper/VolGroup-lv_root
二、清理阶段的具体操作
系统级清理与缓存清理
第一步通常是系统级清理,释放掉无用的缓存、临时文件和历史数据,以迅速释放空间并降低风险。

常用的系统级清理包括清除包管理缓存、日志轮转积累、/tmp 及 /var/tmp 的无用临时文件,以及删除可回滚的历史缓存。
执行这些操作前,请确保不会影响正在运行的服务,必要时先停止相关服务再清理。下面给出常用清理命令示例:
# Debian/Ubuntu
apt-get clean
apt-get autoclean
apt-get autoremove -y# RedHat/CentOS/Fedora
yum clean all
# 或 dnf clean all(较新发行版)
dnf clean all# 清理 journal 日志容量(按需)
journalctl --vacuum-time=7d# 清理临时目录
rm -rf /tmp/*
rm -rf /var/tmp/*
释放缓存和日志缓存后,需重新检查分区使用情况,确保释放的容量达到预期。
若服务器启用了日志轮转策略,对 /var/log 的积累进行评估与配置,确保未来不会再次短时间内暴增。
应用与容器数据清理
应用日志、数据库日志、容器数据卷等往往容易成为磁盘压力的源头。对日志级别、保留策略以及历史日志的保留时长进行评估,必要时进行归档和清理。
容器化环境的镜像和未使用的容器、数据卷需要定期清理,避免长期占用磁盘空间。常用命令包括:
# 清理未使用的镜像、容器和数据卷
docker system prune -a -f
docker volume prune -f
# 如果没有改动过宿主机的 Docker 数据根目录,以上命令通常就足够
清理完成后,重新查看磁盘使用情况,确保关键分区有足够的缓冲空间。
若系统上有缓存性大数据结构(如缓存目录、NPM/Yarn 缓存、Python 虚拟环境等)需要定期维护,可结合应用重启流程来进行清理,以避免热重启后的重复写入。
三、分区与扩容的前提与策略
分区设计与容量规划
在扩容前,评估现有分区结构,确定数据盘和系统盘的分区布局是否合理,以及未来业务增长的容量需求。
常见策略包括将数据盘与日志、数据库、备份分区分离,避免单一分区过度增长对系统稳定性的影响。对于长期增长的环境,优先考虑使用 LVM 进行弹性扩容,以减少未来改动的复杂度。
容量规划还应考虑备份窗口、快照保存策略,以及跨磁盘的性能分布,以实现更稳定的 I/O 行为。
扩容方案与比较
扩容方案大致有两类:扩容现有分区(通常通过 LV/分区表调整)和新增数据分区(附加磁盘,重新分区并挂载)。前者对业务连续性影响较小,后者需要更周密的挂载与挂载点管理。
对于根分区或大容量数据盘,优先考虑使用 LVM 的扩展能力,以实现在线或近在线扩容,减少停机时间和风险。
扩容时需要关注的要点包括:卷组可用空间、逻辑卷大小、文件系统类型和在线扩展的支持情况,以及是否需要离线进入救援模式进行分区调整。
四、分区调整与扩容的全流程
准备工作与信息收集
在动手扩容前,务必完成完整的信息收集和风险评估,包括卷组信息、逻辑卷路径、文件系统类型以及当前挂载点状态。
收集的关键信息包括:卷组(VG)、逻辑卷(LV)、物理卷(PV)、当前容量、剩余可用容量、文件系统类型、挂载点等。
备份与快照仍然是前置条件:在执行扩容操作前确保最近的备份可用,如有可能,先创建卷组快照。
示例命令可用于信息收集:
vgdisplay
lvdisplay
pvdisplay
df -h
lsblk -f
使用 LVM 进行扩容的实际步骤
在 LVM 场景下,扩容流程通常包含:扩展物理卷、扩展卷组、扩展逻辑卷、以及扩展文件系统。以下以常见的 root 盘扩容为例给出示意步骤。
步骤要点包括:确认有可用的空闲物理容量、选择正确的卷路径、以及在线或离线扩展的可行性。
相关命令示例(请根据实际设备名称替换 /dev/sdb、VolGroup、lv_root 等):
# 1) 将新的磁盘分区并创建物理卷(示例设备 /dev/sdb)
parted /dev/sdb mklabel gpt
parted -a opt /dev/sdb mkpart primary ext4 0% 100%
partprobe /dev/sdb
pvcreate /dev/sdb1# 2) 将新 PV 添加到现有卷组
vgextend VolGroup /dev/sdb1# 3) 扩展逻辑卷(假设要扩展 root 卷)
lvextend -l +100%FREE /dev/VolGroup/lv_root# 4) 根据文件系统类型扩展文件系统
# 如果是 ext4
resize2fs /dev/VolGroup/lv_root
# 如果是 xfs(在线扩展)
xfs_growfs /dev/VolGroup/lv_root
扩容后的检查点:再次执行 df -h,确认新容量已经到位,并对关键应用进行干跑或简单压力测试,确保新容量被有效利用。
若扩容目标是非根分区(如数据分区),步骤类似,但需确保挂载点在扩容后的文件系统结构中正确生效,且不会影响到根分区的无障碍运行。
五、在线扩容与离线扩容的风险与注意
在线扩容的原则与适用场景
在线扩容在现代文件系统和 LVM 配合下可以极大降低停机时间,尤其适用于根分区使用 XFS 或者使用了扩展卷的场景。
在在线扩容时,确保文件系统类型对在线扩展的命令支持,如 XFS 可以通过 xfs_growfs 在线扩展,而 ext4 则需要 resize2fs,且在某些极端情况下需要卸载后扩展。
扩容前的风险控制包括:验证备份、确保写入工作负载可容忍的短暂变更、以及在维护窗口内执行,以降低业务影响。
在线扩容的典型操作流程:先扩展逻辑卷,再扩展文件系统,最后验证容量和性能。
离线扩容的场景与要点
在某些分区未提供在线扩展支持,或必须重新分区才能扩容的情况下,可能需要离线扩容。离线扩容通常涉及系统维护模式、服务停机、以及从备份中恢复数据,风险相对较高。
离线扩容的关键步骤包括:停机、卸载目标分区、修改分区表、调整逻辑卷和文件系统后再重新挂载,最后运行完整性检查与容量验证。
请确保在离线扩容前完成最近一次完整备份,并且有足够的时间窗口以完成完整流程。
六、扩容后验证与后续监控
扩容后的容量验证要点
扩容完成后立即进行容量和性能的验证,包括检查 df -h 的新容量、分区挂载情况、以及关键应用的写入吞吐是否恢复正常。
除了容量验证,还应进行简单的 I/O 测试,确保扩容没有引入挂载失败或者文件系统错误的风险。
重要的验证步骤包括:重新启动相关服务(如数据库、应用服务器),再进行一次写入测试,以验证数据路径的稳定性与一致性。
示例验证命令:
df -h
du -sh /path/to/bigdir
sysctl vm.drop_caches=3 # 如需清理缓存,谨慎执行
监控与告警的持续观测
扩容完成后,应将分区使用率纳入日常监控与告警策略,避免未来再次出现容量瓶颈。
常用监控领域包括:分区使用率、I/O 吞吐、写入速率、日志增长速率等,并结合阈值形成告警规则。
一个简易的持续监控示例(定期检查并输出当前根分区使用率):
#!/bin/bash
THRESH=85
USAGE=$(df / | awk 'NR==2 {print $5}' | tr -d '%')
if [ "$USAGE" -gt "$THRESH" ]; thenecho "Disk usage high: ${USAGE}% on /" | wall
fi


