最近更新|軟件分類|軟件專題|軟件排行|手機版|軟件發(fā)布SQLiteDoctor(sqlite數(shù)據(jù)庫修復工具) v1.4.1 最新版
您的位置:首頁>系統(tǒng)工具 > 數(shù)據(jù)恢復>SQLiteDoctor(sqlite數(shù)據(jù)庫修復工具) v1.4.1 最新版

SQLiteDoctor(sqlite數(shù)據(jù)庫修復工具) v1.4.1 最新版數(shù)據(jù)庫修復軟件

網(wǎng)友評分:

相關軟件

軟件介紹

SQLiteDoctor最新版是一款很實用的數(shù)據(jù)庫修復軟件,它使用起來很簡單,你只需選擇要恢復的sqlite數(shù)據(jù)庫和輸出數(shù)據(jù)庫文件。歡迎下載!

SQLiteDoctor(sqlite數(shù)據(jù)庫修復工具)

軟件功能

易于使用的向導

要開始,只需選擇要恢復的sqlite數(shù)據(jù)庫和輸出數(shù)據(jù)庫文件。如果損壞的數(shù)據(jù)庫已加密,您可以選擇設置加密密鑰。

SQLiteDoctor支持所有標準的SEE sqlite加密:AES128,AES192和AES256。

SQLiteDoctor(sqlite數(shù)據(jù)庫修復工具)

表格面板

掃描數(shù)據(jù)庫以查找所有表和所有rowid值。如果無法找到特定表的最大RowID值,則使用N / A值,您可以手動將該值設置為高于您知道在該數(shù)據(jù)庫中為該表使用的最大rowid值的數(shù)值(如果不是輸入的值超過使用的默認值100000)。

SQLiteDoctor(sqlite數(shù)據(jù)庫修復工具)

詳細日志

恢復開始后,會生成詳細的日志輸出,以便讓您了解當前執(zhí)行的步驟。如果出現(xiàn)不可恢復的錯誤,將顯示紅色消息(帶有總錯誤計數(shù)標簽)。

SQLiteDoctor(sqlite數(shù)據(jù)庫修復工具)

要求

MacOS 10.10.5或更高版本

Windows 7SP1 / 8.1 / 10或更高版本

如何破壞sqlite數(shù)據(jù)庫

SQLite數(shù)據(jù)庫對腐敗具有很強的抵抗力。如果應用程序崩潰,操作系統(tǒng)崩潰,甚至在事務中發(fā)生電源故障,則部分寫入的事務應在下次訪問數(shù)據(jù)庫文件時自動回滾。恢復過程是完全自動的,不需要用戶或應用程序的任何操作。雖然SQLite可以抵御數(shù)據(jù)庫損壞,但它并不是免疫的。本文檔描述了SQLite數(shù)據(jù)庫可能損壞的各種方法。

1.文件被流氓線程或進程覆蓋

SQLite數(shù)據(jù)庫文件是普通的磁盤文件。這意味著任何進程都可以打開文件并用垃圾覆蓋它。SQLite庫沒有什么能夠防范這種情況。

1.1。關閉后繼續(xù)使用文件描述符

我們已經(jīng)看到多個文件描述符在文件上打開的情況,然后該文件描述符被關閉并在SQLite數(shù)據(jù)庫上重新打開。后來,其他一些線程繼續(xù)寫入舊文件描述符,沒有意識到原始文件已經(jīng)關閉。但是因為SQLite重新打開了文件描述符,所以打算進入原始文件的信息最終會覆蓋部分SQLite數(shù)據(jù)庫,從而導致數(shù)據(jù)庫損壞。

其中一個例子發(fā)生在大約2013-08-30,在Fossil DVCS的規(guī)范存儲庫中。在那種情況下,文件描述符2(標準錯誤)在sqlite3_open_v2()之前被錯誤地關閉(我們懷疑 是 stunnel ),因此用于存儲庫數(shù)據(jù)庫文件的文件描述符是2.稍后,應用程序錯誤導致斷言( )通過調(diào)用write(2,...)發(fā)出錯誤消息的語句。但由于文件描述符2現(xiàn)在已連接到數(shù)據(jù)庫文件,因此錯誤消息覆蓋了數(shù)據(jù)庫的一部分。為防止出現(xiàn)此類問題,SQLite 版本3.8.1(2013-10-17)及以后拒絕對數(shù)據(jù)庫文件使用低編號文件描述符。(請參閱SQLITE_MINIMUM_FILE_DESCRIPTOR 了解更多信息。)

Facebook工程師在2014-08-12的博客文章中報告了使用封閉文件描述符導致?lián)p壞的另一個例子 。

1.2。事務處于活動狀態(tài)時備份或還原

在后臺運行自動備份的系統(tǒng)可能會嘗試在事務處理過程中制作SQLite數(shù)據(jù)庫文件的備份副本。然后,備份副本可能包含一些舊內(nèi)容和一些新內(nèi)容,因此會損壞。

制作SQLite數(shù)據(jù)庫的可靠備份副本的最佳方法是使用作為SQLite庫一部分的備份API。如果不這樣做,只要任何進程沒有正在進行的事務,就可以安全地復制SQLite數(shù)據(jù)庫文件。如果先前的事務失敗,那么將任何回滾日志(* -journal文件)或預寫日志(* -wal文件)與數(shù)據(jù)庫文件本身一起復制是很重要的。

1.3。刪除熱門日記

SQLite通常將所有內(nèi)容存儲在單個磁盤文件中。但是,在執(zhí)行事務時,在崩潰或電源故障后恢復數(shù)據(jù)庫所需的信息存儲在輔助日志文件中。這種日志文件被描述為“熱門”。日志文件與原始數(shù)據(jù)庫文件具有相同的名稱,并添加了-journal或-wal后綴。

SQLite必須查看日志文件才能從崩潰或電源故障中恢復。如果在崩潰或電源故障后移動,刪除或重命名熱日志文件,則自動恢復將不起作用,并且數(shù)據(jù)庫可能會損壞。

此問題的另一個表現(xiàn)是 由于使用不一致的8 + 3文件名而導致的數(shù)據(jù)庫損壞。

1.4。錯誤配對數(shù)據(jù)庫文件和熱門期刊

前面的示例是更一般問題的特定情況:SQLite數(shù)據(jù)庫的狀態(tài)由數(shù)據(jù)庫文件和日志文件控制。在靜止狀態(tài)下,日志文件不存在,只有數(shù)據(jù)庫文件才對。但是,如果日志文件確實存在,則必須將其與數(shù)據(jù)庫保持在一起以避免損壞。以下行為都可能導致腐?。?/p>

在兩個不同的數(shù)據(jù)庫之間交換日志文件。

使用不同的日志文件覆蓋日志文件。

將日志文件從一個數(shù)據(jù)庫移動到另一個數(shù)據(jù)庫

復制數(shù)據(jù)庫文件而不復制其日志。

用另一個數(shù)據(jù)覆蓋數(shù)據(jù)庫文件而不刪除與原始數(shù)據(jù)庫關聯(lián)的任何熱日志。

2.文件鎖定問題

SQLite在數(shù)據(jù)庫文件和預寫日志或WAL文件上使用文件鎖 來協(xié)調(diào)并發(fā)進程之間的訪問。如果沒有協(xié)調(diào),兩個線程或進程可能會嘗試同時對數(shù)據(jù)庫文件進行不兼容的更改,從而導致數(shù)據(jù)庫損壞。

2.1。鎖實現(xiàn)損壞或丟失的文件系統(tǒng)

SQLite依賴于底層文件系統(tǒng)來進行鎖定,正如文檔所說的那樣。但是一些文件系統(tǒng)在其鎖定邏輯中包含錯誤,因此鎖定并不總是像宣傳的那樣。特別是網(wǎng)絡文件系統(tǒng)和NFS尤其如此。如果在鎖定原語包含錯誤的文件系統(tǒng)上使用SQLite,并且如果兩個或多個線程或進程同時嘗試訪問同一數(shù)據(jù)庫,則可能導致數(shù)據(jù)庫損壞。

2.2。Posix咨詢鎖由一個單獨的線程取消close()

SQLite在unix平臺上使用的默認鎖定機制是POSIX咨詢鎖定。不幸的是,POSIX咨詢鎖定具有設計怪癖,使其容易被濫用和失敗。特別是,同一進程中具有持有POSIX顧問鎖的文件描述符的任何線程都可以使用不同的文件描述符覆蓋該鎖。一個特別有害的問題是close()系統(tǒng)調(diào)用將取消所有線程和進程中所有文件描述符的同一文件上的所有POSIX顧問鎖。

因此,例如,假設一個多線程進程有兩個或多個線程,它們與同一個數(shù)據(jù)庫文件有不同的SQLite數(shù)據(jù)庫連接。然后出現(xiàn)第三個線程,并希望自己從同一個數(shù)據(jù)庫文件中讀取內(nèi)容,而不使用SQLite庫。第三個線程執(zhí)行open(),read()然后close()。人們會認為這將是無害的。但是關閉()系統(tǒng)調(diào)用導致所有其他線程刪除數(shù)據(jù)庫中的鎖。那些其他線程無法知道他們的鎖剛剛被破壞(POSIX沒有提供任何機制來確定這一點),所以他們繼續(xù)運行,假設他們的鎖仍然有效。這可能導致兩個或多個線程或進程同時嘗試寫入數(shù)據(jù)庫,從而導致數(shù)據(jù)庫損壞。

請注意,兩個或多個線程使用SQLite庫訪問同一SQLite數(shù)據(jù)庫文件是完全安全的。SQLite的unix驅動程序知道POSIX咨詢鎖定怪癖并解決它們。只有當線程試圖繞過SQLite庫并直接讀取數(shù)據(jù)庫文件時,才會出現(xiàn)此問題。

2.2.1。SQLite的多個副本鏈接到同一個應用程序

正如前一段所指出的,SQLite采取措施解決POSIX顧問鎖定的怪癖。部分解決方法涉及保持開放SQLite數(shù)據(jù)庫文件的全局列表(互斥保護)。但是,如果SQLite的多個副本鏈接到同一個應用程序,那么這個全局列表將有多個實例。使用SQLite庫的一個副本打開的數(shù)據(jù)庫連接將不知道使用另一個副本打開的數(shù)據(jù)庫連接,并且將無法解決POSIX顧問鎖定問題。一個close()方法的一個連接操作可能在不知不覺中清除不同的數(shù)據(jù)庫連接上的鎖,導致數(shù)據(jù)庫損壞。

上面的場景聽起來很牽強。但是,SQLite開發(fā)人員已經(jīng)知道至少有一個商業(yè)產(chǎn)品正好發(fā)布了這個錯誤。供應商來到SQLite開發(fā)人員尋求幫助,以追蹤他們在Linux和Mac上看到的一些不常見的數(shù)據(jù)庫損壞問題。這個問題最終被追溯到這樣一個事實,即應用程序是連接兩個單獨的SQLite副本。解決方案是將應用程序構建過程更改為僅鏈接一個SQLite副本而不是兩個副本。

2.3。兩個進程使用不同的鎖定協(xié)議

SQLite在unix平臺上使用的默認鎖定機制是POSIX建議鎖定,但還有其他選項。通過使用sqlite3_open_v2()接口選擇備用sqlite3_vfs,應用程序可以使用可能更適合某些文件系統(tǒng)的其他鎖定協(xié)議。例如,可以選擇在必須在不支持POSIX建議鎖定的NFS文件系統(tǒng)上運行的應用程序中使用點文件鎖定。

與同一數(shù)據(jù)庫文件的所有連接使用相同的鎖定協(xié)議非常重要。如果一個應用程序正在使用POSIX顧問鎖,而另一個應用程序正在使用點文件鎖定,則這兩個應用程序將不會看到彼此的鎖定,并且無法協(xié)調(diào)數(shù)據(jù)庫訪問,從而可能導致數(shù)據(jù)庫損壞。

2.4。在使用時取消鏈接或重命名數(shù)據(jù)庫文件

如果兩個進程具有到同一數(shù)據(jù)庫文件的打開連接,并且一個進程關閉其連接,則取消鏈接該文件,然后在其位置創(chuàng)建一個具有相同名稱的新數(shù)據(jù)庫文件并重新打開新文件,然后這兩個進程將與不同的進程通信具有相同名稱的數(shù)據(jù)庫文件。(請注意,這僅適用于Posix和Posix類系統(tǒng),它允許文件在讀取和寫入時仍然打開時取消鏈接.Windows不允許這樣做。)由于回滾日志和WAL文件基于數(shù)據(jù)庫文件的名稱,兩個不同的數(shù)據(jù)庫文件將共享相同的回滾日志或WAL文件。其中一個數(shù)據(jù)庫的回滾或恢復可能會使用其他數(shù)據(jù)庫中的內(nèi)容,從而導致?lián)p壞。

換句話說,取消鏈接或重命名打開的數(shù)據(jù)庫文件會導致行為未定義且可能不合需要。

從SQLite 版本3.7.17(2013-05-20)開始,如果數(shù)據(jù)庫文件在仍在使用時取消鏈接,則unix OS接口將向錯誤日志發(fā)送SQLITE_WARNING消息。

2.5。指向同一文件的多個鏈接

如果單個數(shù)據(jù)庫文件有多個鏈接(硬鏈接或軟鏈接),那么這只是說該文件有多個名稱的另一種方式。如果兩個或多個進程使用不同的名稱打開數(shù)據(jù)庫,那么它們將使用不同的回滾日志和WAL文件。這意味著如果一個進程崩潰,另一個進程將無法恢復正在進行的事務,因為它將查找適當日志的錯誤位置。

換句話說,打開和使用具有兩個或多個名稱的數(shù)據(jù)庫文件會導致行為未定義且可能不合需要。

從SQLite 版本3.7.17(2013-05-20)開始,如果數(shù)據(jù)庫文件有多個硬鏈接,則unix OS界面將向錯誤日志發(fā)送SQLITE_WARNING消息。

從SQLite 版本3.10.0(2016-01-06)開始,unix OS界面將嘗試解析符號鏈接并按其規(guī)范名稱打開數(shù)據(jù)庫文件。在3.10.0版之前,通過符號鏈接打開數(shù)據(jù)庫文件類似于打開具有多個硬鏈接的數(shù)據(jù)庫文件并導致未定義的行為。

2.6??鏵ork()進行打開的數(shù)據(jù)庫連接

不要打開SQLite數(shù)據(jù)庫連接,然后fork(),然后嘗試在子進程中使用該數(shù)據(jù)庫連接。將導致各種鎖定問題,您很容易就會遇到損壞的數(shù)據(jù)庫。SQLite不是為支持這種行為而設計的。必須在子進程中打開子進程中使用的任何數(shù)據(jù)庫連接,而不是從父進程繼承。

如果在父進程中打開了連接,甚至不要在子進程的數(shù)據(jù)庫連接上調(diào)用sqlite3_close()。關閉底層文件描述符是安全的,但sqlite3_close() 接口可能會調(diào)用清除活動,這些活動將從父項下刪除內(nèi)容,從而導致錯誤甚至數(shù)據(jù)庫損壞。

3.未能同步

為了保證數(shù)據(jù)庫文件始終保持一致,SQLite偶爾會要求操作系統(tǒng)將所有掛起的寫入刷新到持久存儲,然后等待該刷新完成。這是使用Windows 下的unix和FlushFileBuffers()下的fsync()系統(tǒng)調(diào)用 完成的。我們將此備用寫入的刷新稱為“同步”。

實際上,如果只關注原子和一致寫入并且愿意放棄持久寫入,則同步操作不需要等到內(nèi)容完全存儲在持久性介質上。相反,同步操作可以被認為是I / O障礙。只要在同步之前發(fā)生的所有寫入在同步之后發(fā)生的任何寫入之前完成,就不會發(fā)生數(shù)據(jù)庫損壞。如果同步作為I / O屏障運行而不是真正的同步,則電源故障或系統(tǒng)崩潰可能導致一個或多個先前提交的事務回滾(違反“ACID”的“持久”屬性)但數(shù)據(jù)庫至少會繼續(xù)保持一致,這就是大多數(shù)人關心的問題。

SQLiteDoctor(sqlite數(shù)據(jù)庫修復工具)

3.1。不支持同步請求的磁盤驅動器

不幸的是,大多數(shù)消費級大容量存儲設備都在于同步。磁盤驅動器一旦到達軌道緩沖區(qū)并且在實際寫入氧化物之前就會報告內(nèi)容在安全介質上是安全的。這使得磁盤驅動器似乎運行得更快(這對于制造商來說非常重要,因此他們可以在貿(mào)易雜志中顯示出良好的基準數(shù)據(jù))。并且公平地說,只要在軌道緩沖器實際寫入氧化物之前沒有功率損耗或硬復位,謊言通常不會造成傷害。但是,如果確實發(fā)生了斷電或硬復位,并且如果這導致在同步到達氧化物之后寫入的內(nèi)容而在同步之前寫入的內(nèi)容仍在軌道緩沖區(qū)中,則可能發(fā)生數(shù)據(jù)庫損壞。

USB閃存棒似乎是關于同步請求的特別惡毒的騙子。通過將大型事務提交到USB記憶棒上的SQLite數(shù)據(jù)庫,可以很容易地看到這一點。COMMIT命令將相對快速地返回,表明記憶棒告訴操作系統(tǒng)并且操作系統(tǒng)告訴SQLite所有內(nèi)容都安全地存在于持久存儲中,但記憶棒末端的LED將繼續(xù)閃爍幾個更多秒。在LED仍在閃爍時拔出記憶棒會經(jīng)常導致數(shù)據(jù)庫損壞。

請注意,SQLite必須相信操作系統(tǒng)和硬件告訴它有關同步請求狀態(tài)的任何信息。SQLite無法檢測到任何一個正在撒謊并且寫入可能無序發(fā)生。但是,WAL模式下的 SQLite對于無序寫入比對默認回滾日志模式要寬松得多。在WAL模式下,失敗的同步操作可能導致數(shù)據(jù)庫損壞的唯一時間是在檢查點操作期間。COMMIT期間的同步失敗可能導致耐久性丟失,但不會導致?lián)p壞的數(shù)據(jù)庫文件。因此,由于同步操作失敗導致數(shù)據(jù)庫損壞的一條防線是在WAL模式下使用SQLite并盡可能不頻繁地檢查點。

3.2。使用PRAGMA禁用同步

可以使用同步編譯指示在運行時禁用SQLite執(zhí)行以幫助確保完整性的同步操作。通過設置PRAGMA synchronous = OFF,省略所有同步操作。這使得SQLite似乎運行得更快,但它也允許操作系統(tǒng)自由地重新排序寫入,如果在所有內(nèi)容到達持久存儲之前發(fā)生電源故障或硬重置,則可能導致數(shù)據(jù)庫損壞。

為了獲得最大的可靠性和針對數(shù)據(jù)庫損壞的穩(wěn)健性,SQLite應始終以其默認同步設置FULL運行。

4.磁盤驅動器和閃存故障

如果文件內(nèi)容因磁盤驅動器或閃存故障而發(fā)生更改,則SQLite數(shù)據(jù)庫可能會損壞。這是非常罕見的,但磁盤偶爾會在扇區(qū)中間翻轉一下。

4.1。非電源安全閃存控制器

我們被告知,在一些閃存控制器中,如果在寫入期間電源中斷,則耗損均衡邏輯可能導致隨機文件系統(tǒng)損壞。例如,這可以表現(xiàn)為在斷電時甚至沒有打開的文件中間的隨機變化。因此,例如,當發(fā)生斷電時,設備會將內(nèi)容寫入閃存中的MP3文件,這可能導致SQLite數(shù)據(jù)庫損壞,即使數(shù)據(jù)庫在斷電時甚至沒有使用。

4.2。假容量USB棒

有許多流通的USB棒在報告中具有高容量(例如:8GB),但實際上只能存儲少量(例如:1GB)。嘗試在這些設備上寫入通常會導致不相關的文件被覆蓋。因此,任何使用欺詐性閃存設備都很容易導致數(shù)據(jù)庫損壞。諸如“假容量usb”之類的互聯(lián)網(wǎng)搜索將會發(fā)現(xiàn)許多有關此問題的令人不安的信息。

5.記憶腐敗

SQLite是一個C庫,它在與它所服務的應用程序相同的地址空間中運行。這意味著應用程序中的雜散指針,緩沖區(qū)溢出,堆損壞或其他故障可能會破壞內(nèi)部SQLite數(shù)據(jù)結構,并最終導致?lián)p壞的數(shù)據(jù)庫文件。通常情況下,這些類型的問題在任何數(shù)據(jù)庫損壞發(fā)生之前都表現(xiàn)為段錯誤,但是有些情況下應用程序代碼錯誤導致SQLite發(fā)生故障,從而破壞數(shù)據(jù)庫文件而不是恐慌。

使用內(nèi)存映射I / O時,內(nèi)存損壞問題變得更加嚴重。當全部或部分數(shù)據(jù)庫文件映射到應用程序的地址空間時,覆蓋該映射空間的任何部分的雜散指針將立即破壞數(shù)據(jù)庫文件,而不需要應用程序執(zhí)行后續(xù)的write()系統(tǒng)調(diào)用。

6.其他操作系統(tǒng)問題

有時,操作系統(tǒng)會出現(xiàn)可能導致問題的非標準行為。有時這種非標準行為是故意的,有時在實施中是錯誤的。但無論如何,如果操作的執(zhí)行方式與SQLite期望執(zhí)行的方式不同,則存在數(shù)據(jù)庫損壞的可能性。

6.1。Linux線程

一些舊版本的Linux使用LinuxThreads庫來提供線程支持。LinuxThreads類似于Pthreads,但在處理POSIX顧問鎖方面略有不同。SQLite版本2.2.3到3.6.23認識到LinuxThreads正在運行時使用,并采取適當?shù)拇胧﹣斫鉀QLinuxThreads的非標準行為。但是大多數(shù)現(xiàn)代Linux實現(xiàn)都使用了Pthreads的更新,更正確的NPTL實現(xiàn)。從SQLite 版本3.7.0(2010-07-21)開始,假設使用NPTL。沒有檢查。因此,如果在使用LinuxThreads的舊Linux系統(tǒng)上運行的多線程應用程序中使用,SQLite的最新版本將巧妙地出現(xiàn)故障并可能損壞數(shù)據(jù)庫文件。

6.2。QNX上的mmap()失敗

在QNX上存在mmap()的一些微妙問題,使得對單個文件描述符進行第二次mmap()調(diào)用可以使得從第一個mmap()調(diào)用獲得的內(nèi)存歸零。unix上的SQLite使用mmap()為WAL模式下的事務協(xié)調(diào)創(chuàng)建共享內(nèi)存區(qū)域,并且它將為大事務多次調(diào)用mmap()。已證明QNX mmap()在該場景下?lián)p壞了數(shù)據(jù)庫文件。QNX工程師意識到了這個問題,正在研究解決方案; 你讀這篇文章時可能已經(jīng)解決了這個問題。

當QNX運行,建議內(nèi)存映射I / O永遠不會被使用。此外,要使用WAL模式,建議應用程序采用獨占鎖定模式,以便在沒有共享內(nèi)存的情況下使用WAL。

6.3。文件系統(tǒng)腐敗

由于SQLite數(shù)據(jù)庫是普通的磁盤文件,因此文件系統(tǒng)中的任何故障都可能破壞數(shù)據(jù)庫?,F(xiàn)代操作系統(tǒng)中的文件系統(tǒng)非??煽浚匀粫l(fā)生錯誤。例如,在2013-10-01,持有Wiki for Tcl / Tk的SQLite數(shù)據(jù)庫 在主機被轉移到文件系統(tǒng)層中存在問題的(linux)內(nèi)核的狡猾版本后幾天就被破壞了。在那種情況下,文件系統(tǒng)最終變得如此嚴重損壞,以至于機器無法使用,但最早出現(xiàn)問題的癥狀是SQLite數(shù)據(jù)庫損壞。

SQLiteDoctor(sqlite數(shù)據(jù)庫修復工具)

7. SQLite配置錯誤

SQLite有許多針對數(shù)據(jù)庫損壞的內(nèi)置保護。但是配置選項可以禁用許多這些保護。如果禁用保護,則可能會發(fā)生數(shù)據(jù)庫損壞。

以下是禁用SQLite內(nèi)置保護機制的示例:

如果出現(xiàn)操作系統(tǒng)崩潰或電源故障,設置PRAGMA synchronous = OFF會導致數(shù)據(jù)庫損壞,但此設置可以避免因應用程序崩潰而造成的損壞。

在打開其他數(shù)據(jù)庫連接時更改PRAGMA schema_version。

使用PRAGMA journal_mode = OFF或PRAGMA journal_mode = MEMORY 并在寫入事務中使應用程序崩潰。

設置PRAGMA writable_schema = ON然后使用DML語句更改數(shù)據(jù)庫模式可能會使數(shù)據(jù)庫完全不可讀,如果不仔細完成的話。

8. SQLite中的錯誤

SQLite經(jīng)過了非常仔細的測試,以幫助確保它盡可能沒有錯誤。在為每個SQLite版本執(zhí)行的許多測試中,有一些模擬電源故障,I / O錯誤和內(nèi)存不足(OOM)錯誤的測試,并驗證在任何這些事件期間都沒有發(fā)生數(shù)據(jù)庫損壞。SQLite也經(jīng)過現(xiàn)場驗證,大約有20億次活動部署,沒有嚴重問題。

然而,沒有軟件100%完美。SQLite(現(xiàn)已修復)中存在一些可能導致數(shù)據(jù)庫損壞的歷史錯誤。還有一些還未被發(fā)現(xiàn)。由于SQLite的廣泛測試和廣泛使用,導致數(shù)據(jù)庫損壞的錯誤往往非常模糊。應用程序遇到SQLite錯誤的可能性很小。為了說明這一點,下面給出了一個帳戶,其中列出了在2009-04-01至2013-04-15四年期間SQLite中發(fā)現(xiàn)的所有數(shù)據(jù)庫損壞錯誤。這個帳戶應該讓讀者直觀地了解SQLite中存在的各種錯誤,這些錯誤可以通過測試程序完成,并使其成為一個版本。

8.1。由于數(shù)據(jù)庫收縮導致的虛假損壞報告

如果數(shù)據(jù)庫是由SQLite版本3.7.0或更高版本編寫的,然后由SQLite版本3.6.23或更早版本再次編寫,以使數(shù)據(jù)庫文件的大小減小,那么下一次SQLite版本3.7.0訪問數(shù)據(jù)庫文件,它可能會報告數(shù)據(jù)庫文件已損壞。但是,數(shù)據(jù)庫文件并沒有真正損壞。版本3.7.0在腐敗檢測中過于熱心。

問題已在2011-02-20修復。該修復程序首先出現(xiàn)在SQLite 版本3.7.6(2011-04-12)中。

8.2。在回滾和WAL模式之間切換后出現(xiàn)損壞

在一個進程或線程中反復切換進出WAL模式的SQLite數(shù)據(jù)庫并在交換機之間 運行VACUUM命令會導致另一個打開數(shù)據(jù)庫文件的進程或線程錯過數(shù)據(jù)庫已更改的事實。然后,第二個進程或線程可能會嘗試使用陳舊緩存修改數(shù)據(jù)庫并導致數(shù)據(jù)庫損壞。

這個問題是在內(nèi)部測試中發(fā)現(xiàn)的,從未在野外觀察到過。問題已在2011-01-27和3.7.5版本中修復。

8.3。獲取鎖定時的I / O錯誤會導致?lián)p壞

如果操作系統(tǒng)在嘗試在WAL模式下獲得對共享內(nèi)存的某個鎖定時返回I / O錯誤,則SQLite可能無法重置其緩存,如果嘗試后續(xù)寫入,則可能導致數(shù)據(jù)庫損壞。

請注意,只有在嘗試獲取鎖定導致I / O錯誤時才會出現(xiàn)此問題。如果沒有授予鎖定(因為某些其他線程或進程已經(jīng)存在沖突鎖定),則不會發(fā)生任何損壞。我們不知道在嘗試獲取共享內(nèi)存上的文件鎖時,任何操作系統(tǒng)都會因I / O錯誤而失敗。所以這是一個理論問題,而不是一個真正的問題。不用說,在野外從未觀察到這個問題。在模擬I / O錯誤的測試工具中對SQLite進行壓力測試時發(fā)現(xiàn)了這個問題。

對于SQLite版本3.7.3,此問題已于2010-09-20修復。

8.4。數(shù)據(jù)庫頁面從空閑頁面列表中泄漏

從SQLite數(shù)據(jù)庫中刪除內(nèi)容時,不再使用的頁面將添加到空閑列表中,并重新用于保存后續(xù)插入添加的內(nèi)容。在使用incremental_vacuum時,版本3.6.16到3.7.2中存在的SQLite中的錯誤可能會導致頁面丟失在空閑列表之外。這不會導致數(shù)據(jù)丟失。但是這會導致數(shù)據(jù)庫文件超出必要的范圍。并且它會導致integrity_check編譯指示報告空閑列表中缺少的頁面。

對于SQLite版本3.7.2,此問題已在2010-08-23修復。

8.5。從3.6和3.7交替寫入后的腐敗。

SQLite版本3.7.0引入了許多SQLite數(shù)據(jù)庫文件格式的新增強功能(例如但不限于WAL)。3.7.0版本是這些新功能的震撼發(fā)布。我們期待找到問題并且沒有失望。

如果最初使用SQLite版本3.7.0創(chuàng)建數(shù)據(jù)庫,然后由SQLite版本3.6.23.1編寫,使得數(shù)據(jù)庫文件的大小增加,然后由SQLite版本3.7.0再次編寫,則數(shù)據(jù)庫文件可能會損壞。

對于SQLite版本3.7.1,此問題已在2010-08-04修復。

8.6。Windows系統(tǒng)恢復中的競爭條件。

SQLite版本3.7.16.2修復了Windows系統(tǒng)上鎖定邏輯中的細微競爭條件。當數(shù)據(jù)庫文件需要恢復時,因為寫入它的先前進程在事務中間崩潰并且兩個或多個進程嘗試同時打開該數(shù)據(jù)庫,那么競爭條件可能導致其中一個進程獲得錯誤指示已完成恢復,允許該進程繼續(xù)使用數(shù)據(jù)庫文件而不先運行恢復。如果該進程寫入文件,則該文件可能會損壞。這種競爭條件顯然存在于SQLite for Windows的所有早期版本中,可追溯到2004年。但競爭非常緊張。實際上,您需要一臺快速的多核計算機,在該計算機中啟動兩個進程以在兩個單獨的核心上同時運行恢復。此缺陷僅在Windows系統(tǒng)上,并不影響posix OS界面。

  • 下載地址

點擊報錯軟件無法下載或下載后無法使用,請點擊報錯,謝謝!