logrotate默认由anacron或systemd timer调度,执行时间不固定(如02:17、03:05),无法保证凌晨两点准时执行;必须改用root用户的crontab添加“0 2 *”定时任务,并禁用/etc/cron.daily/logrotate,同时配置中仅用daily而非size或hourly。

logrotate 默认由 /etc/cron.daily/logrotate 触发,但那是系统级 daily 任务,执行时间由发行版 cron 的 anacron 或 systemd timer 控制,**不保证固定在凌晨两点**。要精确到每天 2:00 执行日志切割,必须绕过默认机制,改用自定义 cron 条目。
为什么不能依赖 /etc/cron.daily/logrotate
Debian/Ubuntu 等系统中,/etc/cron.daily/logrotate 实际由 anacron 调度,可能延迟数小时;RHEL/CentOS 8+ 使用 systemd-timers(logrotate.timer),默认触发时间是随机偏移的,防止多机同时冲击服务器。这意味着即使配置了 daily,真实执行时间可能是 02:17、03:05 或更晚——无法满足“凌晨两点准时”这个硬性要求。
手动配置 crontab 强制 2:00 执行 logrotate
直接覆盖默认调度,用 root 用户添加精确定时任务:
- 运行
sudo crontab -e - 添加一行:
0 2 * * * /usr/sbin/logrotate /etc/logrotate.conf > /dev/null 2>&1 - 确保原
/etc/cron.daily/logrotate不再生效:重命名或注释掉其内容(如改名成/etc/cron.daily/logrotate.disabled)
注意:/usr/sbin/logrotate 路径需确认(可用 which logrotate 查),部分系统是 /usr/bin/logrotate;> /dev/null 2>&1 避免邮件堆积,如有告警需求可替换为邮件地址。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
logrotate 配置里必须用 daily,不能用 size 或 hourly
即使 cron 是 2:00 触发,logrotate 内部仍需靠规则判断是否该轮转。若配置中写的是 size 100M,它只检查文件大小,忽略时间;而 hourly 会强制每小时检查一次——这与你的“每天一次”目标冲突,且可能因 cron 只跑一次导致漏切。
-
daily是唯一与“每天凌晨两点”语义对齐的选项 - 不要混用
hourly或weekly,否则 logrotate 状态文件(/var/lib/logrotate/status)记录的时间戳会错乱,导致某天跳切、某天不切 - 如果服务日志增长极快,又想兼顾大小和时间,可用
daily+maxsize 100M(注意不是size):表示“每天至少切一次,但如果当天已超 100M 就提前切”
测试与验证要点
改完 cron 和配置后,别等明天——立刻验证是否真能按预期工作:
- 手动模拟时间:临时把系统时间设为前一天晚上 23:59,等一分钟看是否触发(
date -s "2026-09-07 23:59:00",切记之后hwclock -w同步硬件时钟) - 用调试模式验证配置语法:
logrotate -d /etc/logrotate.d/nginx,确认无error:行 - 检查状态文件更新:
grep nginx /var/lib/logrotate/status,应看到类似"2026-09-08-02:00:01"的时间戳(注意:logrotate 写入状态的时间 ≈ cron 执行时刻,非配置里的daily字面含义)
最易被忽略的是状态文件的时间精度——logrotate 不记录秒级时间,只存到分钟;如果你在 02:00:03 触发,状态里显示的仍是 02:00:01,但这不影响逻辑。真正要盯住的,是 cron 是否真的在 02:00:00±30s 内启动了进程(ps aux | grep logrotate 配合 date 观察)。










