标准答案
- rename 只改变目录项名称,已有 fd 仍指向原 inode;unlink 后空间也可能直到最后一个 fd 关闭才释放。
- copytruncate 可以让路径继续存在,但复制期间可能丢日志或产生截断竞争,适用边界不如应用主动 reopen 清晰。
- 更稳妥的方式是应用接收信号重新打开日志,或写标准输出交给 journald/容器日志系统管理。
- 排查磁盘未释放时要查看 deleted 但仍被进程持有的文件,并确认轮转、压缩、权限和采集端策略。
题目解析
常见轮转方式是 rename 后创建新文件,或 copytruncate 复制后截断原文件。rename 后,已经打开旧文件描述符的进程仍会继续写旧 inode,只有应用重新打开日志或使用支持 reopen 的日志库,内容才会进入新文件;copytruncate 则可能在复制和截断之间丢失少量日志。
删除一个仍被进程打开的文件名只会减少目录引用,磁盘空间要等最后一个 fd 关闭才释放。排查应同时查看文件名、inode、进程 fd、轮转配置和采集器状态,并用一条测试日志验证新旧文件和采集链路是否一致。
常见误区
- 误区:rm 掉日志文件后空间一定立刻释放。改正:用 lsof 检查是否仍有进程持有 deleted inode,并让进程关闭或 reopen。
- 误区:看到新文件存在就认为应用已经切换。改正:写入带时间或请求 ID 的测试日志,确认实际落到新文件并被采集。