meta 快照回滚前,我先用 du 摸了一遍目录
上周在测试环境回滚一次 meta 快照,版本是 2024.3 的内网构建,数据量不大,目录 6.8GB、约 1.9 万个文件,主体是 JSON 描述文件和一堆按天切分的校验日志。现象是:回滚脚本跑了 4 分钟没结束,磁盘 IO 一直打满,最后 rsync 报了个空间不足退出,但 df 看还有 12GB。
我先没动脚本,只做了一件事——把目录按大小摸一遍:
du -sh ./* | sort -h | tail -20
find . -type f -size +50M -printf '%s\t%p\n' | sort -n | tail -20
结果很直接:6.8GB 里有 5.4GB 是 logs/ 下的历史校验日志,其中当天的 verify.log 单个就 2.1GB,而且还在被写入。回滚脚本用的是 rsync -a --delete,它会把源端没有的日志也删掉,但删除前要先把目标端内容读一遍做比对,于是这 2.1GB 的活跃文件被反复读,速度和空间都卡在这里。
我的做法是拆成两步,先排除日志,再回滚数据:
rsync -a --delete \
--exclude='logs/' \
--exclude='*.tmp' \
/snapshot/meta-2024.3/ ./meta/
日志单独处理,只做增量追加,不参与删除比对:
rsync -a --ignore-existing /snapshot/meta-2024.3/logs/ ./meta/logs/
改完回滚从 4 分钟降到 40 秒左右,空间也没再报错。
为什么这样有效:--delete 的代价不在删除本身,而在于 rsync 要为目标端每个文件建立比对项,文件越大、越活跃,读取代价越高。把高频写的大文件排除出去,等于把比对集合从 1.9 万降到 1.2 万左右,而且剩下的都是小文件,元数据操作占主导,反而快。代价是日志目录不再被快照“纠正”,如果源端删过日志,目标端会留着,需要人肉确认。
失效的地方我也踩过:一是 --exclude 写 logs 不带斜杠时,会连 meta/logs-archive/ 这种同前缀目录一起排掉,我第一次就漏了归档目录;二是如果回滚目标本身是软链接,-a 会保留链接而不是跟进去,--delete 的行为会变得很难预期,我当时是先 ls -l 确认了目录实体才敢跑;三是活跃日志被排除后,回滚完成的那一刻日志内容是新旧混合的,不能拿它当回滚是否成功的判据。
现在每次回滚前我都会先跑一遍 du 和 find,把大文件列出来再决定排除清单。你们那边 meta 目录里通常哪个子目录最占空间,是日志还是校验产物?
0 条评论
还没有评论,写下第一条。