2013-01-14 66 views
1

我正在考慮應用程序在程序或操作系統崩潰後檢測部分寫入記錄的方式。由於記錄只有追加到一個文件(從未覆蓋),寫入時崩潰保證產生比它應該是短的文件大小?即使文件以讀寫模式而不是附加模式打開,只要寫入文件總是在文件末尾,這是否保證了這一點?這將大大簡化故障恢復,因爲將最後一條記錄的預期大小和位置與實際文件大小進行比較足以檢測部分寫入。可以使用文件大小來檢測部分追加嗎?

我知道隨機訪問寫入可以由文件系統重新排序,但我無法找到追加時是否會發生這種情況的信息。我想象一個亂序追加需要文件系統在(稀疏)文件的尾部創建一個「洞」,在塊之外寫入塊,然後填充塊之間的塊,但是我希望這樣的方法效率太低,以至於沒有人會以這種方式實現他們的文件系統。

我想另一個問題可能是文件系統在將新塊附加到文件之前更新目錄條目的文件大小字段,並且操作系統崩潰。這是否在實踐中發生過? (ext4,也許?)有沒有一種快速檢測它的方法? (當試圖讀取根據文件大小應該存在的未寫入塊時會發生什麼?)

是否還有其他任何內容,例如由磁盤/閃存驅動器執行的寫入重新排序,這會妨礙使用文件大小作爲檢測部分追加的方法?我不希望在我的應用程序中能夠彌補這種驅動器欺騙,但是瞭解它會很好。

+0

爲什麼不簡單地在追加前備份「記錄」文件?並在追加結束或程序正確退出後刪除它?這比檢查文件大小要好得多。 – KurzedMetal

+0

因爲在某些情況下記錄的大小可能是千兆字節。我試圖避免不必要的複製。 –

回答

2

如果你想確保你永遠不會失去記錄,你需要一個一致的日記或交易系統爲您的文件。

除非您設置了O_DIRECT [您可能不想這麼做],或者您使用標記來指示「這已完全提交」,這是絕對不能保證的。當文件關閉時寫入。您可以在mainfile中執行該操作,或者,例如,有一個文件可以在外部記錄「上次寫入記錄」。如果你打開&關閉該文件,只要APP崩潰就應該是安全的 - 如果操作系統崩潰[或者突然停止 - 例如斷電,拔下盤子等],所有投注都關閉。

寫入重新排序和寫入緩存是/可以在所有級別完成 - C庫,操作系統,文件系統模塊和硬盤/控制器本身都可以重新排序寫入。

+0

我不需要保證記錄寫入已經完成;我只是在尋找一種方式來告訴他們什麼時候沒有。 (目標是避免文件損壞,而不是確保沒有記錄丟失。) 關於您的標記建議,我打算將最後寫入的記錄的位置和大小保存在單獨的(小)文件中,使用newfile /同步/重命名習慣使其保持原子狀態。但是,只有當我能夠檢測到主數據文件不是它應該的大小時纔有用。 –

+0

首先,我的意思是「保證它們已經實現」,正是你所描述的 - 一種告訴已寫入內容的方式。當然,如果你錄製「我已經寫了1234條記錄」,而你的文件只有1230條記錄長,那麼很清楚,有些記錄是錯過的。您還可以通過臨時的「標記文件」檢測到「應用程序沒有正確關閉」,當您正確使用應用程序時,該標記文件會被刪除/重命名。 –

+0

如果文件系統按照應用程序請求的順序執行操作,那麼您的「標記文件」的想法顯然會起作用。然而,有時候事情不會那樣。例如,ext4文件系統(直到它用新的默認行爲進行修補)有一個習慣,即在文件完成先前寫入之前重命名文件,導致0字節文件在壞的時候發生崩潰時替換完美的文件。 –

相關問題