一、一个错误操作
在生产环境中,
假如我们要清空一个正在写入的文件, 比如 “清空 2020020501.log”
我见过许多同学会这样操作:
rm -f 2020020501.log && touch 2020020501.log
二、为什么这个操作错误?
这样操作后会发现 2020020501.log 不再有新的写入了,或者说那些本来好好往 2020020501.log 写着日志的进程,并不能往新 touch 的 2020020501.log 写入日志:
tail -f 2020020501.log
.
此时执行 lsof | grep delete | grep 2020020501.log
还会发现,那些写日志的进程,
还 hold 着旧的 2020020501.log 文件句柄没释放:
testpro 27168 root 4u REG 252,17 124055696 54801882 /testlog/2020020501.log (deleted)
testpro 27169 root 4u REG 252,17 124055696 54801882 /testlog/2020020501.log (deleted)
testpro2 30035 root 4u REG 252,17 124064390 54801882 /testlog/2020020501.log (deleted)
testpro2 30035 30045 root 4u REG 252,17 124064390 54801882 /testlog/2020020501.log (deleted)
... ...
三、怎么解决这个错误操作带来的问题?
为了让新 touch 的 2020020501.log 能继续写入log,
需要重启所有正在写入 2020020501.log 的进程。
在这个测试 case 里面,需要重启 testpro 和 testpro2 。
由此可见,
如果不小心错误地将一个被许多进程读写中的热文件 rm
删除了,
那就需要重启所有相关进程,才能恢复正常读写。
这就非常麻烦了,因此强烈不建议通过 rm
删除进程读写中的热文件。
四、正确的操作是怎样的?
> 2020020501.log
或者
echo > 2020020501.log