我正在研究Linux的數據庫引擎,並且對於將一個系統調用寫入內核的許多塊有一致性問題。我用O_DIRECT打開設備。使用O_DIRECT一致地寫入很多塊
設備寫入數據塊,具體取決於它可能是512,2048或4096的硬件。比方說,我會在一次系統調用中寫入2個512字節的塊。如果在磁盤寫入1個塊後系統完全關閉,會發生什麼情況?在正常操作期間,write()系統調用將返回所寫入數據的大小,因此當2個值(被詢問vs返回)不匹配時,我可以比較並生成一個錯誤,但電源關閉會變得複雜。它更復雜,因爲內核可能會向設備發送寫請求,而不是按照您的要求發送請求,所以請求的尾部可能會寫在磁頭之前,然後關閉電源。
請考慮數據庫引擎寫入事務日誌。假設一個事務約爲4096個字節,引擎將需要寫入8個512字節的塊。突然之間,我們停電並且只有一半的請求被寫入。數據庫如何處理這些問題?我想要解決這個問題,你首先需要寫出你打算寫入磁盤上另一個位置的塊的數量。一旦您收到正確的返回值,您可以編寫數據。然後,在收到確認信息後,您必須發送另一個寫入磁盤,以更新所有您想要寫入的塊實際上已成功寫入的信息。所以,這需要3次寫入操作,如果內核正在從另一個進程寫入磁盤,這很可能會導致3次查找。效率太低。
我正在尋找一種方法來實現只有一次寫操作到磁盤的許多塊的一致寫入。 (一個write()系統調用)這可能嗎?
爲什麼不只是有足夠的電池或電容器充電,你有時間檢測電源故障,並停止服務器乾淨? – 2012-02-04 02:19:09
@R,其實這是個好主意。只需要一臺UPS,我就可以緩存輔助磁盤塊,並用一次尋道寫入實際數據。不適用於所有人,但這是一個很好的解決方案,可以在緊急情況下提供快速的日常操作並提供備份。 – Nulik 2012-02-04 13:36:15