logrotate的olddir参数必须与日志文件位于同一物理设备,因其依赖rename()系统调用,而该调用不支持跨文件系统;正确做法是先用olddir在同设备建临时目录,再通过postrotate脚本mv到目标磁盘。

logrotate 的 olddir 参数本身不支持跨物理设备移动日志,它强制要求目标目录与原始日志文件必须位于同一文件系统(即同一挂载点)。这是内核级限制——因为 logrotate 使用 rename() 系统调用完成移动,而该调用无法跨设备。所以不能直接靠 olddir /mnt/backup(假设 /mnt/backup 是另一块磁盘)来实现。
为什么 olddir 必须在同一物理设备上
logrotate 手册明确说明:“The directory must be on the same physical device as the log file being rotated”。本质是原子重命名操作的限制:不同挂载点属于不同文件系统,rename() 无法跨越。若强行指定跨设备路径,logrotate 会报错或静默失败,旧日志仍留在原处。
正确做法:olddir + postrotate 移动组合
核心思路是分两步走:先用 olddir 在本地创建临时归档区(满足同设备要求),再通过 postrotate 脚本把内容搬走。这是生产环境通用解法。
- 在原始日志所在分区下建一个临时目录,例如
/var/log/app/olddir - 配置
olddir /var/log/app/olddir - 在
postrotate块中执行mv或rsync把/var/log/app/olddir/*同步到目标磁盘(如/mnt/logs-backup/) - 建议加
|| true防止移动失败导致整个轮转中断
实际配置示例
以 Nginx 日志为例,假设目标磁盘挂载在 /mnt/logs-arch:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
/var/log/nginx/*.log {
daily
rotate 30
missingok
compress
delaycompress
copytruncate
olddir /var/log/nginx/olddir
sharedscripts
postrotate
mkdir -p /mnt/logs-arch/nginx
mv /var/log/nginx/olddir/* /mnt/logs-arch/nginx/ 2>/dev/null || true
find /mnt/logs-arch/nginx -name "*-$(date -d 'yesterday' +\%Y\%m\%d).gz" -delete
endscript
}
注意:mkdir -p 确保目标路径存在;find ... -delete 可选,用于清理过期归档,避免备份盘也被撑满。
验证与调试建议
配置写完不要直接上线,先做两件事:
- 运行
logrotate -d -f /etc/logrotate.d/nginx查看 debug 输出,确认olddir被识别、postrotate脚本被触发 - 手动执行一遍
postrotate里的命令,检查权限(logrotate 默认以 root 运行,但目标磁盘挂载用户/组需允许写入)和路径是否可达
如果目标磁盘是 NFS 或 CIFS 挂载,还需确认网络稳定性及挂载选项(如 soft vs hard)是否影响移动可靠性。










