2010-08-27 36 views
5

在版本3.7中引入的write-ahead-log功能的SQLite documentation中,有一些評論讓我困惑了一下。SQLite WAL在電源故障時安全性如何?

鏈接頁面顯示「只要應用程序願意犧牲掉電後的持久性,就不需要將內容同步到磁盤上」。然後幾段落,它說:「檢查點確實需要同步操作,以避免在斷電或硬重啓後出現數據庫損壞的可能性」「。

因此,我的數據庫在更大的損失功率損失風險如果我使用WAL?

回答

4

腐敗行爲的無風險增加與沃爾瑪(因爲檢查點時,使用同步操作)。

但是,如果有崩潰(斷電或硬重啓),你將失去任何自上一次檢查點以來的交易;這就是「犧牲耐用性」的意思。

+3

我知道這個答案是舊的,但它有一個相當重要的錯誤。從上一個檢查點開始,您將不會丟失事務,您將失去尚未完全寫入WAL的事務。如果synchronous = NORMAL,那麼在將事務寫入WAL時不會等待fsync(),因此如果在完全寫入之前斷電,則可能會丟失該事務。一旦進入WAL,不管檢查點是什麼,它都不會丟失。 – 2013-02-05 22:07:19

+1

直到2016-02-17 https://www.sqlite.org/docsrc/info/3540d671bcc4835c SQLite文檔中提到,在WAL模式下,synchronous = NORMAL默認情況下...它現在說同步= FULL - 更安全的默認設置。因此,只有在設置了synchronous = NORMAL模式時,您纔會在檢查點之前丟失事務 – 2016-03-11 00:21:25

5

爲了充分回答,我們需要知道您設置爲PRAGMA synchronous,因爲這會影響fdatasync()的調用時間,從而在物理驅動器上刷新緩衝區時。

當您引用「只要應用程序願意犧牲掉電後的耐久性」,這是指synchronous=NORMAL。這裏WAL僅在檢查點發生時與磁盤同步(一個fdatasync()用於WAL,另一個用於合併後的主DB)。你應該受到保護,以防止腐敗,但可能有一些寫入從未將其寫入盤片,因此丟失:因此失去了耐用性。儘管如此,上升的幅度要遠低於實際同步數據的慢速fdatasync()。

要想最好地防止數據丟失,您可能需要synchronous=FULL。這重新獲得耐久性,但每次寫入交易的成本是一個fdatasync()。但是,這仍然比非WAL模式更好,其中將有兩個fdatasync()調用 - 一個用於事務日誌,另一個用於主DB。

0

只要同步調用到您的操作系統工作完美,你沒有損壞分貝的風險。但是,這可能會也可能不是這樣 - 請參閱sqlite文檔以獲取關於此的更長時間的解釋。

要更正Doug Currie(請參閱MattR的帖子):如果@ synchronous = NORMAL @,您只會冒失去交易的風險。如果@ synchronous = FULL @(這是默認值),則不會犧牲耐久性。有關詳細信息,請參閱http://www.sqlite.org/draft/wal.html。我認爲WAL日誌實際上比'經典'日誌(在系統同步不完善的情況下)更安全,因爲在我理解WAL日誌的情況下,db在給定時刻執行關鍵任務的機會較低。但是,我目前沒有硬數據來支持這一點。