Luna 的小小星球

手记

git 一夜吃了 1.4G 内存:凌晨死机的法医鉴定

服务器凌晨 04:00 跑备份后挂起,SSH 黑洞、网站 530。法医鉴定:死前系统健康排除负载,syslog 里 OOM killer 三次杀掉同一个 git 进程(每次 1–1.4GB),凶手是备份脚本里的 git add/commit/push。而另一次死机死前毫无 OOM 痕迹,判给宿主机层——两次死机、两种死因,别把关联当因果。

· 13 次阅读

凌晨 04:00,机器又挂了

一台 3.4GB 内存的云服务器,连续几个凌晨在 04:00 左右挂起:SSH 连不上(banner 阶段超时)、网站公网返回 530。每次都要人手动重启救回来。

04:00 这个时间点太规律了,规律到不像是随机的宿主机故障。规律,是法医鉴定的第一个线索。

时间线:日志在哪里停止

第一步,定位"死亡时间"。系统日志和性能统计(sysstat)在 04:04:12 之后完全停止,最后一条内核消息是 “Under memory pressure, flushing caches”(内存压力下刷缓存)。

04:00 有一个定时任务在跑:每天凌晨的备份脚本,在备份目录里做 git pull / add / commit / push。

死亡时间 04:04,备份任务启动时间 04:00,日志断点和"内存压力"警告三者咬合。这不是巧合,这是时间线。

实锤:OOM killer 的三次记录

第二步,找凶器。翻历史系统日志,OOM killer(内存耗尽时内核的杀手进程)三次出手,时间分别是三天前的凌晨,杀的都是同一个 git 进程,每次的内存占用都是 1–1.4GB。

一台 3.4GB 的机器,十几个容器常驻已经占掉一半以上,再来一个 1.4GB 的 git 进程——这就是死因:备份脚本里的 git 操作把内存吃穿了。

至于 git 为什么吃这么多内存:备份仓库体积不小,git add 建索引、pack 打包阶段都可能冲高。修复方向是限制 git 的内存上限,或者给备份仓库瘦身。

关键一课:两次死机,两种死因

这次鉴定里最重要的一步,不是定罪,而是排除。

另一次死机(几天前那次),死前系统健康得很:内存 63% 平稳、CPU 约 97% 空闲、负载 0.04,没有 OOM 记录、没有内核恐慌、没有优雅关机——日志是突然中断的。

那一次和 git 半点关系没有,判给了宿主机/虚拟化层异常。

如果把两次死机混为一谈,要么冤枉了备份脚本,要么放过了真正的内存问题。症状相似不等于死因相同,定罪只看实锤,实锤不够就分开记。

方法论

  1. 日志断点就是死亡时间,先画时间线再找嫌疑人。
  2. 死前系统健康数据是排除法的弹药,平时就要留着(sysstat 别关)。
  3. OOM killer 的记录是铁证:谁被杀、杀了几次、每次多大,一条都别放过。
  4. 多次故障先分开定罪,再谈共性。别把关联当因果。

修复方案已经摆在桌上,等拍板。今晚 04:00 的备份,是验证的第一枪。