Linux

copytruncate 實際是如何工作的?

  • July 7, 2021

在使用以下配置copytruncate旋轉文件之前, 我們想了解一下:logrotate

/app/syslog-ng/custom/output/all_devices.log { 
size 200M 
copytruncate
dateext 
dateformat -%Y%m%d-%s 
rotate 365 
sharedscripts 
compress
postrotate 
   /app/syslog-ng/sbin/syslog-ng-ctl reload 
endscript 
}

RHEL 7.x,8GB 記憶體,4 個 VCpu

問題:

logrotate當 syslog-NG 已經打開文件進行日誌記錄時,如何截斷文件?不是資源爭奪嗎?syslog-NG 是否會在沒有任何要記錄的內容時立即關閉文件?

截斷日誌文件實際上是有效的,因為編寫者使用 O_APPEND 打開要寫入的文件。

open(2)手冊頁:

O_APPEND:文件以追加模式打開。在每次 write(2) 之前,文件偏移量位於文件末尾,就像使用 lseek(2) 一樣。文件偏移量的修改和寫入操作作為單個原子步驟執行。

如前所述,操作是原子的,因此每當發出寫入操作時,它將附加到與文件末尾匹配的目前偏移量,而不是在前一個寫入操作完成之前保存的偏移量。

這使得在截斷操作之後追加工作,將下一個日誌行再次寫入文件的開頭,而無需重新打開文件。

(O_APPEND 的相同功能還可以讓多個寫入者附加到同一個文件,而不會破壞彼此的更新。)

記錄器還使用單個 write(2) 操作寫入日誌行,以防止在截斷或併發寫入操作期間將日誌行分成兩部分。

請注意,像 syslog、syslog-ng 或 rsyslog 這樣的記錄器通常不需要使用copytruncate,因為它們支持重新打開日誌文件,通常通過向它們發送 SIGHUP。logrotate 對存在的支持copytruncate是為了迎合其他記錄器,這些記錄器通常附加到日誌文件,但不一定有重新打開日誌文件的好方法(因此在這些情況下通過重命名進行輪換不起作用。)

另請注意,它copyrotate具有固有的競爭條件,因為在 logrotate 完成複制之後和發出截斷操作之前,作者可能會在日誌文件中附加一行。這種競爭條件會導致它永遠失去那些日誌行。copytruncate這就是為什麼通常不推薦使用旋轉日誌的原因,除非這是唯一可行的方法。

引用自:https://unix.stackexchange.com/questions/475524