我聽說過有傳言說,如果在資料庫和郵件伺服器運行時更改系統時間,它們會發生不好的事情。然而,我很難找到有關實際風險的任何具體資訊。
我有一個在 Debian Wheezy 主機上運行的生產 Postgres 9.3 伺服器,時間晚了 367 秒。我可以ntpdate
在 Postgres 運行時運行或啟動 openntp,還是可能會導致問題?如果是這樣,校正時間的更安全方法是什麼?
是否有其他服務對系統時間的變化更敏感?也許是郵件伺服器(exim、sendmail 等)或訊息佇列(activemq、rabbitmq、zeromq 等)?
答案1
資料庫不喜歡時間上的倒退,因此您不想從跳躍時間的預設行為開始。如果偏移量小於 600 秒(10 分鐘),則將選項新增-x
至命令列將縮短時間。在最大轉換速率下,將時鐘調整一分鐘大約需要一天半的時間。這是一種緩慢但安全的調整時間的方法。
在執行ntp
調整時間之前,您可能需要先選擇ntp
一個選項,例如-g 2
驗證它偵測到的偏移量有多大。這會將恐慌偏移量設定為 2 秒,這應該是相對安全的。
在此選項可用之前,我使用的另一個選項是編寫一個循環,每分鐘左右重置秒的時鐘部分。如果您檢查以確保重置不會改變第二次,這可能是安全的。如果大量使用時間戳,則可能會出現無序記錄。
一個常見的選擇是關閉伺服器足夠長的時間,以免時鐘向後移動。 ntp
或者ntpdate
可以設定為在啟動時將時鐘跳到正確的時間。這應該在資料庫啟動之前完成。
答案2
如果資料庫非常活躍且內部記錄上有時間戳,那麼它們特別容易受到系統時間變更的影響。一般來說,如果你的時間落後了,那麼你突然向前跳躍所遇到的問題會比你領先並突然向後跳躍時遇到的問題要少得多。
正如 Joffrey 指出的那樣,與資料庫本身相比,應用程式更容易出現時間突然跳躍的問題。更正時間的最安全方法是關閉應用程式 N+1 分鐘(其中 N 是系統時鐘提前的分鐘數),然後同步時間、啟動 NTP 並重新啟動應用程式。如果你不能在應用程式中承受那麼多的停機時間,我只能建議你在同步時間之前備份資料庫,然後向電腦界的上帝獻上一隻死松鼠,然後扣動扳機。好吧,我有點開玩笑,但除了應用程式中斷之外,我想不出任何其他「安全」的方法。
答案3
當發生即時時間跳躍時,通常不是資料庫伺服器容易出錯:而是使用該時間的應用程式。
追蹤時間通常有兩種方式:追蹤自己的時間或比較系統時間。兩者都有一些積極和消極的權衡。
自己的時間追蹤
我看到這在一些嵌入式程式和系統中使用,其中精確的時序並不那麼重要。在主應用程式循環中,會採用一種追蹤「tick」的方法。這可能是由內核、睡眠或選擇發出的警報,指示經過的時間量。當您知道已經過去了多少時間時,您就知道可以在計數器上添加或減去該時間。這個計數器是使您的計時應用程式發生的原因。例如,如果計數器高於 10 秒,您可以丟棄某些內容,或者您需要執行某些操作。
如果應用程式不記錄時間,計數器將不會改變。根據您的應用程式的設計,這可能是需要的。例如,使用計數器比開始/停止時間戳列表更容易追蹤長時間運行的進程處理某事需要多長時間。
專業人士:
- 不依賴系統時鐘
- 不會因時間偏差較大而中斷
- 無需昂貴的系統調用
- 小計數器比完整時間戳消耗更少的內存
缺點:
- 時間不是很準確
- 系統時間的變更可能會使其更加不準確
- 計時與運行應用程式相關,不持久
比較系統時間
這是更常用的系統:儲存時間戳並使用系統時間呼叫將其與時間戳進行比較。系統時間的巨大偏差可能會威脅應用程式的完整性,幾秒鐘的任務可能需要幾個小時或立即結束,具體取決於時鐘的方向。
專業人士:
- 準確的時間比較
- 在重新啟動和長時間中斷後仍然存在
缺點:
- 進行系統呼叫以取得新的時間戳以與其他時間戳進行比較
- 應用程式需要注意傾斜或可能中斷
受影響的系統
與計劃任務相比,大多數應用程式都會使用時間戳記。對於資料庫系統來說,可以進行快取清理。
如果應用程式沒有進行相應的檢測和處理,則所有使用資料庫並以查詢語言呼叫時間函數的應用程式都將受到偏差的影響。應用程式永遠不會停止運行或允許無限期的登入期限,具體取決於其目的。
郵件系統將使用時間戳記和/或逾時來處理陳舊或未送達的郵件。時鐘偏差可能會影響這一點,但影響要小得多。關於重新連接到伺服器的退避計時器可能會被錯過,導致連接伺服器受到處罰。
我不認為(尚未研究)更改系統時間時內核警報會響起。使用這些的系統可能是安全的。
解決方案
輕輕地移動時間。這可以在您最喜歡的時間解決方案的文檔中找到。