CentOS服务器硬盘爆满卡死?十几TB日志用rsync空目录完美清除

李洋博客09-23882阅读0评论

哎妈呀我貌似好久没有写笔记了,嗯嗯,最近优化主题模板,在加上写新的主题没有时间折腾其他内容了,这不今天就来活了,怎么个事呢?是这样的公司之前的项目产生了大量的无用日志文件,有多少大呢?这么说吧十几个TB,是的TB不是GB,我最初没以为这是一个棘手的活,心想着用宝塔面板右键删除然后清空回收站就完了呗,顺手把TP框架的代码优化下不写log文件了,但是我还是小看了这个十几个TB,无论是宝塔面板的右键还是命令符的 rm 命令直接干死机,导致主机直接崩溃,啥也干不了,有时间点开文件夹都进不去,更别说右键删除了,好一顿头疼。

CentOS服务器硬盘爆满卡死?十几TB日志用rsync空目录完美清除 第1张

趁着有闲赶紧提升日程,把这个烫手山芋扔了,不然中秋、国庆就得加班了,,,我可不想这样。先说下服务器环境:

适用场景:宝塔面板 + CentOS / RHEL 系服务器,

程序:ThinkPHP 站点日志目录,/runtime/log。

当然也可以是其他目录堆积了海量文件,只要是因 rm 卡死、进目录 ls 卡死、宝塔文件管理器也卡死,此文都能解决,而且是后台跑、不影响业务数据,就是有一丢丢的慢。

故障现象

本地宝塔服务器,数据盘 /data 58T,被一个站点的日志目录吃掉了十几 TB,内网路径:

/data/wwwroot/192.168.0.5/runtime/log

这是宝塔里「内网IP」命名的站点根目录下的 ThinkPHP 运行日志目录,你的路径按实际替换即可。

如果你想直接删除,有如下表现出来的症状

  • 直接 rm -rf 或 rm -rf * —— 服务器卡死,像死机;

  • 进目录后 ls —— 卡死,命令行失去响应;

  • 宝塔面板「文件」管理器右键删除 —— 同样卡死;

  • 磁盘一直满,业务随时可能写入失败。

这些不是硬盘垃圾本身的问题,而是删除方式 + 海量小文件叠加,要知道进入文件夹都能崩溃,这得多少文件啊?我粗略看了下100条/也,大概3000多页,这还只是一个文件夹下的所以直接rm -rf / rm -rf * 等于直接卡死。rm 动手前会把整棵目录树(或通配符 * 展开)先生成成参数列表。成千上万个 .log 文件会让这个过程吃光内存、占满磁盘 IO,看起来就是死机,严重时还能触发 OOM(内存耗尽)。这还是纯命令符的状态,更别提宝塔文件管理器了,它是用 PHP 扫描目录再逐个删,比命令行还要慢,海量文件必崩。所以从"进目录就卡死"可以判断,这是海量小文件,而不是几个大文件。小文件的删除本质是文件系统元数据操作(unlink),比删大文件慢得多。

错误示范(避雷清单)

做法结果
rm -rf /path/runtime/log通配/递归加载目录,吃内存占 IO,卡死甚至 OOM
rm -rf /path/runtime/log/** 展开成超长参数列表,同样卡死
宝塔文件管理器右键删除PHP 扫描目录,比命令行更慢,必崩
cd 进目录后 ls读取整目录 dentry,卡死

核心原则:不要 rm -rf、不要进目录 ls、不要用宝塔文件管理器删。用流式删除工具绕开"一次性加载整个目录"。

学会使用 rsync 空目录覆盖法

rsync --delete 的删除算法比 rm 高效得多,而且是流式处理,不会一次性把目录加载进内存,是清理百万级文件的首选。

# 1. 建一个空目录当"模板"
mkdir -p /tmp/empty_log

# 2. 用 idle IO 优先级 + 后台执行(SSH 断开也不中断)
nohup ionice -c 3 rsync -a --delete /tmp/empty_log/ /data/wwwroot/192.168.0.5/runtime/log/ > /tmp/cleanup.log 2>&1 &

# 3. 记下进程号,方便后续观察
echo "PID: $!"

如下图,为了更清楚和更直观的确定后台在运行,我们可以先【df -h /data】命令查看当前的使用情况,目前是已用40TB,还剩16T,一会看结果。

CentOS服务器硬盘爆满卡死?十几TB日志用rsync空目录完美清除 第2张


命令行解释:

  • 源路径 /tmp/empty_log/ 末尾的 / 不能省,它表示"同步该目录里的内容"。效果是:把目标目录清空(文件 + 子目录全删),但保留 runtime/log 目录本身(权限、所有者不变,最安全)。

  • ionice -c 3 = idle 级,删除只在磁盘空闲时进行,线上站点基本无感;代价是耗时更久。

  • nohup ... & 放后台,避免终端一关任务就中止。

这个可选哈,如果你不想这么慢的话,可以看后续非备选方案。

备选方案:find -delete(没装 rsync 时用)

CentOS 系统一般自带 rsync;若 which rsync 提示不存在,用 find 流式删:

# 同样 idle IO + 后台,保留目录本体
nohup ionice -c 3 find /data/wwwroot/192.168.0.5/runtime/log -mindepth 1 -delete > /tmp/cleanup_find.log 2>&1 &
  • -mindepth 1:不从 log 目录自身删起,只删里面的内容,目录本体保留。

  • 不要用 -type f -delete 只删文件——子目录还在,没清干净。

进度监控(别只看容量)

清理期间不要一直 tail -f cleanup.log——rsync 没加 -v,日志里基本只有 nohup: 忽略输入 一行,不会出新内容,那是正常的。

1)看真实进度,用 inode 用量(最灵敏)

海量小文件删起来,inode 会先于容量明显下降:

watch -n 30 'df -i /data'

只要"已用 inode"在下降,就说明 rsync 一直在干活。

2)确认进程还活着、没僵死

ps -o pid,etime,stat,time,cmd -p 166761

字段含义:

字段含义
pid进程号
etime真实已运行时间(关键)
stat状态
timeCPU 时间

⚠️ 误区:TIME 显示 00:00:00 是正常的!TIME 是 CPU 运行时间,不是"已经跑了多久"。rsync 删文件主要消耗的是 IO 等待,尤其加了 ionice -c 3(idle 模式)后,它几乎都在等磁盘空闲,几乎不占 CPU,所以 TIME 长期为 0 完全正常。只要 stat 不是 Z(僵死)或 T(暂停),就别动它。

3)看容量释放(粒度粗,配合参考)

watch -n 5 'df -h /data'

58T 的盘,1% 就约 0.58T,四舍五入看不出细节,所以容量只作辅助,主看 df -i。


想更快?三档策略任选

ionice -c 3 是为了不卡业务故意跑得慢。低峰期或维护窗口可提速:

策略命令改动速度业务影响
维持 idle(默认)不动最慢无感,推荐白天业务期
折中ionice -c 2 -n 7较快仍有限制,适合有空窗时
全速去掉ionice最快IO 高峰,站点可能短暂变慢

提速操作(先停旧的,避免两个 rsync 抢跑):

kill 166761   # 停掉当前 idle 进程

# 折中档:
nohup ionice -c 2 -n 7 rsync -a --delete /tmp/empty_log/ /data/wwwroot/192.168.0.5/runtime/log/ > /tmp/cleanup.log 2>&1 &

# 或全速档(维护窗口用,最快):
nohup rsync -a --delete /tmp/empty_log/ /data/wwwroot/192.168.0.5/runtime/log/ > /tmp/cleanup.log 2>&1 &

删完验证与重建

ps -p 166761                       # 无输出 = 删完了
df -i /data                        # 不再下降 = 删完了
df -h /data                        # 稳定在一个较低值
ls -1U /data/wwwroot/172.16.0.5_49240/runtime/log   # 现在能秒开且为空

rmdir /tmp/empty_log               # 清理临时空目录

如图,明显的能看出来可用空间在持续更加,这也就证明后台正在删除数据,而且没有影响业务的正常执行。隔段时间去宝塔文件管理查看删除情况就行。待全部删除之后在执行清理临时空目录。

CentOS服务器硬盘爆满卡死?十几TB日志用rsync空目录完美清除 第3张

重建: ThinkPHP 在下次有请求、需要写日志时会自动重建 runtime/log 目录,前提是父目录 runtime 对 PHP 进程(宝塔一般为 www 用户)可写。想保险就手动建一把。

mkdir -p /data/wwwroot/192.168.0.5/runtime/log
chown -R www:www /data/wwwroot/192.168.0.5/runtime/log
chmod 755 /data/wwwroot/192.168.0.5/runtime/log

彻底解决可以,避免几个月后又爆

删完是治标,建议马上做两件事:

1)宝塔计划任务定期清理(宝塔 → 计划任务 → Shell 脚本,每天凌晨):

# 删 7 天前的日志,只留最近一周
find /data/wwwroot/192.168.0.5/runtime/log -type f -name "*.log" -mtime +7 -delete

2)收敛 ThinkPHP 日志: 在站点 config/log.php 里开启按天 / 按大小切割、限制保留份数,或关闭 debug 全量日志,从源头减少堆积。

防坑速查表

  • ✅ 删除前先确认路径,且它不是软链接指向别处:readlink -f /你的/日志/路径

  • ✅ 用 rsync --delete 空目录法或 find -mindepth 1 -delete,避开 rm -rf

  • ✅ 用 ionice -c 3 后台跑,不拖垮业务

  • ✅ 用 df -i 看进度,比 df -h 灵敏

  • ✅ ps 里 TIME=00:00:00 是正常的,看 stat 是不是 Z/T 才要慌

  • ❌ 别用宝塔文件管理器删海量文件

  • ❌ 别进目录 ls 看(会卡)

  • ❌ 别 tail -f 等 rsync 日志(默认没输出)

海量文件清理,rm 必卡;用 rsync 空目录覆盖法 + ionice 限速后台跑,安全、不卡业务、还能随时提速。删完记得用计划任务定期轮转,别让历史重演。好了,记录完成,我去优化主题模板了,哦对了,还有一件事忘记说了哈,你的猜想没有错,这是AI辅助我解决的,不然我哪会这么高大上的东西哈,有问题留言反馈吧~~~

文章版权声明:除非注明,否则均为李洋博客原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
AddoilApplauseBadlaughBombCoffeeFabulousFacepalmFecesFrownHeyhaInsidiousKeepFightingNoProbPigHeadShockedSinistersmileSlapSocialSweatTolaughWatermelonWittyWowYeahYellowdog
评论列表 (暂无评论,882人围观)

还没有评论,来说两句吧...

取消
微信二维码
微信二维码
支付宝二维码