nocopytruncate不保障原子性,而是放弃原子性、保留原始日志内容的保守模式:仅复制旧日志快照,不清空原文件,应用继续向原文件追加写入,备份不含轮转中新产生的日志。

nocopytruncate 的真实作用
当 logrotate 遇到一个正在被进程持续写入的日志文件(比如 nginx、java 应用未关闭日志句柄),nocopytruncate 表示:只复制一份旧日志,但不清空原文件。也就是说:
- 原日志文件保持打开、继续追加写入(内容不变)
- 备份文件是某个时间点的完整快照(不含轮转过程中新写入的内容)
- 不会执行
echo > logfile或truncate类操作
为什么它不提供原子性?
原子性在日志轮转中,通常指“旧日志停止写入 → 新日志立即接管 → 中间无丢失”,而 nocopytruncate 完全不干预原文件写入行为:
- 没有截断,意味着应用仍在往原文件末尾写,备份只是静态拷贝,必然存在时间差
- 备份期间新日志可能已写入几十或几百行,这部分内容既不在备份里,也不在“新日志”里(因为没 create 新文件)
- 若同时没配
create,轮转后就没有新日志文件,应用继续写原文件——等于没轮转
真正保障原子性的常用组合
要让轮转过程尽量无丢失、可预测,推荐以下两种更可靠的模式:
-
copytruncate + create(最常用):
先完整拷贝当前日志,再立即清空原文件;同时用create 0644 user group确保新日志文件存在。适合大多数守护进程(如 nginx、rsyslog),前提是应用能容忍日志文件被清空(绝大多数支持) -
create + postrotate 发送信号(最严谨):
用create建新文件,再在postrotate/endscript中向应用发信号(如kill -USR1),让应用主动 reopen 日志文件。这是与应用协同的原子切换,零丢失风险
nocopytruncate 的适用场景
它只在一种情况下合理使用:
- 你**明确不需要新日志文件**,只想归档当前状态(例如审计快照、临时取证)
- 你**无法中断或通知应用**,且担心
truncate导致应用异常(极少数老旧程序) - 你**自行管理日志写入逻辑**(比如脚本每次 open-write-close),此时原文件内容稳定,
nocopytruncate拷贝即准
总之,别为原子性选 nocopytruncate;要原子性,就用 copytruncate 配合权限控制,或用 create + postrotate 主动协同应用。


















