首页/系统/Linux 运维命令速查/场景:不重启服务切割日志
进程与作业69 条

场景:不重启服务切割日志

应用把日志写进单文件越滚越大:mv 后让应用重开句柄(kill -USR1 或应用自带 reopen),或用 copytruncate 兜底。

Linux 运维命令速查系统更新于 2026-10-13

不重启服务切割日志是什么场景

应用把日志写进单个文件,文件越滚越大,磁盘压力随之上升。手工切割的难点不在移动文件,而在让应用重新打开一个新的日志句柄:文件改名后进程仍会把内容写进已被移动的旧文件。如果应用支持重新打开日志的信号,改名后发一次信号即可;不支持的应用只能用「复制后清空」的兜底方式,代价是中间有一小段日志可能丢失。

基本信息

适用平台GNU/Linux、macOS(进程信号与文件工具)
场景不重启服务的日志切割
标准流程改名、发信号让应用重开、确认句柄、压缩归档
兜底流程复制内容后清空原文件
关键前提确认应用对信号的真实语义
生产做法交给日志轮转工具配置脚本自动执行

典型使用场景

  • 单文件日志过大导致磁盘告警,需要立刻切割并压缩归档。
  • 应用不支持自动轮转,需要外部工具定期处理。
  • 变更前后需要保留完整日志用于审计。
  • 切割后确认应用已切换到新文件,避免写入丢失。
  • 应急时先切分释放空间,再排查日志增长原因。

标准流程

标准流程
cd /var/log/app                                  # 进入应用日志目录
pid=$(cat /run/app.pid)                          # 读取进程号
mv app.log app.log.$(date +%F)                   # 1 改名,句柄仍指向旧文件
kill -USR1 "$pid"                                # 2 通知应用重新打开日志文件
ls -l /proc/$pid/fd | grep app.log               # 3 确认句柄指向新文件
gzip app.log.$(date +%F)                         # 4 压缩归档旧日志
df -h /var/log                                   # 5 确认空间已释放
cp app.log app.log.bak && truncate -s 0 app.log  # 兜底:复制后清空,可能丢少量日志

步骤读法

步骤作用使用要点
改名让旧文件与新文件分离改名后句柄仍指向旧文件,必须继续处理
发送信号让应用重开日志信号语义要以应用文档为准
确认句柄验证切换成功查看进程的文件描述符指向
压缩归档回收磁盘空间先确认压缩成功再删除原文件
复制清空兜底方案复制与清空之间存在丢失窗口
轮转配置自动化生产环境应固化到轮转工具配置
必须确认应用对信号的真实行为:同一编号的信号在不同程序里语义完全不同,发错信号可能触发重载配置甚至直接退出。
复制后清空的兜底方式存在丢失窗口:复制与清空之间写入的日志会随清空一起消失,只适合能接受少量丢失的场景。
生产环境应把整套动作写进日志轮转工具的配置脚本,让切割、压缩、清理按策略自动执行,手工操作只用于应急。

易错点

  • 只改名不通知应用:进程继续写已被移动的旧文件,磁盘空间没有释放,日志看起来不再更新。
  • 发错信号导致应用重载配置或退出,日志问题升级成服务故障。
  • 兜底方案里先清空后复制,或复制过程中有持续写入,导致这段日志永久丢失。
  • 归档后直接删除原文件而不验证压缩结果,压缩损坏时日志无法恢复。

数据来源与参考

  • man 1 logrotate(logrotate 官方手册)

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌