faq_2026-09-26_st_4


title: “logrotate设置了按大小切割日志为什么不生效” description: “logrotate 配了 size 档日志却迟迟不切:size 与时间档在同一配置块里互斥、应用抱着句柄不放需要 copytruncate、定时任务一天才驱动一次。本文用 debug 干跑定位问题,按三查逐步修复并验证空间真的释放。” slug: logrotate-size-rotation-not-working date: 2026-09-26 categories: [“常见问答”] draft: false

Linux 服务器上的 catalina.out 眼看着涨到几十 GB,于是给 logrotate 配了按大小切割,指望它到量就切。几天过去再看,文件还是一个囫囵的大块头,配置检查了几遍“看着也没写错”。轮转工具明明在跑,为什么就是不切?这类不生效多半不是玄学,是配置语义和预期对不上。

原因分析

排在前面的原因是档位互斥。logrotate 的配置里,按时间切(daily、weekly)和按大小切(size 100M)属于两套触发档,写在同一个配置块里并不叠加,各版本各有取舍——常见结果就是时间档在场、size 档被晾在一边。想要“到量就切”,这个块里就只留 size;想“时间到了也切、中途超量也切”,对应的是 maxsize 参数;minsize 则是“时间到了且超量才切”。几个词的语义差别必须分清。

第二个是句柄问题。Tomcat 这类应用自己抱着日志文件的句柄不撒手,logrotate 常规做法只是把旧文件改名、再建新文件,应用却仍往旧句柄里写——表面上切了一次,实际数据照旧灌进改名后的文件,新文件空转,磁盘占用纹丝不动。对付这类应用要用 copytruncate(先复制旧文件、再把原文件原地清空),或者在 postrotate 里给进程发信号让它重开日志,两条路二选一,用串了反而不生效。

第三是触发时机。logrotate 不是常驻服务,靠系统每天一次的定时任务驱动——上午超标,也要等下一轮运行才可能切;状态文件记录着每个日志的处理进度,测试机上改过系统时间,状态就会错乱。

分步解决

  1. 干跑看诊断。用 logrotate -d 模式跑一遍主配置,输出会逐条说明每个日志“需要轮转”还是“不需要”、命中的是哪个配置块——卡在哪一步,一眼可辨。
  2. 修档位。确认配置块里 size 与时间档没有混写;纯按大小就只留 size 一行,对照需求把 maxsize 与 minsize 的语义用对。
  3. 对付抱句柄的应用。catalina.out 这类加上 copytruncate,并去掉与之冲突的重开句柄动作;改完强制切一次(-f 参数),验证文件真的变小、磁盘空间真的回来了。
  4. 确认驱动在跑。systemd 系统用 list-timers 查 logrotate 定时器的下次运行时间;cron 系统看每日任务与状态文件时间戳是否正常推进。
  5. 切完对账。du 看日志目录、df 看文件系统,两边一致才算真释放;不一致就是还有进程攥着旧句柄没放。
  6. 观察一个周期。配置改好后让它自然触发一两轮,确认按预期尺寸切割、保留代数正确,再收工。

预防

新应用上线时把日志策略一并配齐——路径、切割档位、保留代数,用干跑模式验收通过再投产;日志目录纳入占用监控,超阈值就告警。磁盘告警里先爆的十有八九是日志分区,把“日志也是数据”记进巡检清单,比每次满了再倒查省心得多。