討論SQLite資料庫損壞與修復

2021-07-05 18:58:25 字數 2205 閱讀 4485

昨晚,朋友和我反饋sqlite資料庫發生損壞有沒有辦法恢復。大致的情況是這樣的,當資料庫在使用時不小心用了新的檔案覆蓋資料庫,導致了sqlite資料庫出現了損壞,開啟的時候出現要輸入密碼,而且不能把sql語句dump下來。所以,文章這裡整理sqlite資料庫出現損壞的所有情況,以及如何修復損壞的sqlite資料庫檔案。

sqlite算是非常穩定的資料庫,不容易出現損壞,就算應用程式崩潰,或者作業系統崩潰,甚至是執行事務時出現斷電,都能在下一次使用資料庫時自動修復。但是,還是不能避免不出現損壞的情況。

導致sqlite資料庫損壞的情況

導致sqlite資料庫損壞的情況大致可歸結為4類:檔案覆蓋問題、檔案鎖問題、資料同步問題、記憶體問題

檔案覆蓋問題

sqlite資料庫檔案被覆蓋是可能的,畢竟是乙個普通的磁碟檔案,意味著所有的程序都可以開啟和覆蓋,所以不可能完全避免檔案覆蓋的情況。1. 多執行緒寫資料庫問題。 sqlite資料庫是支援多程序併發讀寫,但是如果這時候關閉和重新開啟資料庫,就很可能出現一些執行緒還在寫資料到資料庫,出現部分資料被覆蓋的情況。

2. 執行事務時備份或恢復資料 事務都是乙個過程性的操作,需要一定時間,而資料備份是原子操作,如果在事務執行過程時備份,可能導致複製的內容包含了部分新的內容和部分舊的內容,就出現資料庫損壞。恢復也是一樣。

3. 刪除日誌檔案 sqlite資料庫通常都是儲存所有內容到乙個檔案,但執行事務時,為了實現程式崩潰,斷電時可以回滾日誌,就伴隨著一些附加的日誌檔案。如果日誌被刪除了,就會導致恢復出現異常。

檔案鎖問題

為了實現sqlite資料庫併發讀寫,sqlite會使用檔案鎖來保證資料安全。1. 系統檔案鎖問題sqlite依賴於底層的檔案系統對檔案鎖的實現,但是,一些檔案系統存在鎖邏輯錯誤,使得鎖並不可靠,這在網路檔案系統和nfs情況比較常見。

2. posix協同鎖(advisory lock)在

linux

或者unix下,sqlite 預設鎖是協同鎖。當程序使用協同鎖,如果其中有乙個執行緒執行 close() 就可能導致鎖被取消。如果已經有兩個執行緒同時連線到同乙個資料庫,再來乙個執行緒不以sqlite api的形式,就是以系統檔案形式讀取資料庫( open(), read() , 然後close()),就會導致這個程序的資料庫鎖被取消,而兩個執行緒同時運算元據庫就會導致資料覆蓋引起錯亂。

3. 不同的連線協議不同的連線協議鎖也可能會不同,也就導致鎖沒有發揮錯誤引起錯誤。

4.當資料庫正在使用時刪除或重新命名資料庫檔案出現這種情況往往是在linux等類posix系統,

windows

下不會出現這個情況,而且同時有事務執行就會放大這個問題。

資料同步問題

為了保證資料一致性,sqlite有時候會請求作業系統將所有等待持久化的資料刷入磁碟,然後等待這個操作完成。1.磁碟驅動器的同步請求可能是不可靠的 現有普通消費級別的磁碟驅動器多數都會謊報資料同步結果,以期望得到更高的寫入速度。當資料剛到達磁碟緩衝區,還沒真正寫入氧化物介質,磁碟驅動器就報告內容已經安全寫入。但是這時候斷電、硬體復位就會導致資料同步失敗。這種情況主要出現在快閃儲存器介質。

2.使用pragmas會影響同步通過設定pragma synchronous=off, sqlite所有的同步操作都會被忽略。這使得sqlite執行得更快,但如果出現電源故障或硬體復位就會前面儲存的所有資料。如果單純為了獲得最大的資料可靠性和健壯性,sqlite可設定synchronous = full

記憶體問題

sqlite作為乙個c執行庫,和使用它的應用程式執行在同乙個記憶體位址空間。這意味著,任何野指標,緩衝區溢位,堆損壞等都有可能損壞了sqlite的資料結構,並最終導致資料庫檔案損壞。另外,使用記憶體對映i/o模型(如mmap)的時候,記憶體問題會變得更加嚴重。當資料庫檔案的一部分或全部被對映到應用程式的位址空間,雖然減少了檔案io操作,但是野指標可能訪問並修改到任何部分的對映空間資料。

更多sqlite資料庫損壞的原因可以看這裡。

修復損壞的sqlite資料庫

linux下:$ sqlite3 mydata.db ".dump" | sqlite3 new.dbwin下:d:\>sqlite3 mydata.db .dump > mydata.sqld:\>sqlite3 new.db < mydata.sqld:\>sqlite3 aa.db "pragma integrity_check"

sqlite使用建議

這裡有4點建議:1. 減少多程序或多執行緒操作,盡可能單執行緒寫。2. 減少事務操作,減小事務複雜度,減少檢查點3. 減少資料庫的大小4. 避免使用pragma synchronous=off

SQLite資料庫損壞與修復

導致sqlite資料庫損壞的情況大致可歸結為4類 檔案覆蓋問題 檔案鎖問題 資料同步問題 記憶體問題 sqlite資料庫檔案被覆蓋是可能的,畢竟是乙個普通的磁碟檔案,意味著所有的程序都可以開啟和覆蓋,所以不可能完全避免檔案覆蓋的情況。1.多執行緒寫資料庫問題。sqlite資料庫是支援多程序併發讀寫,...

SQLite資料庫損壞修復

the database disk image is malformed 進入到sqlite3操作指定的資料庫 或者直接 sqlite3 e item.db 操作此資料庫 sqlite databases main e item.db sqlite tables 顯示列表 檢查資料庫是否損壞 sql...

sqlite3資料庫損壞修復

前陣子由於分割槽空間滿出現了sqlite3資料庫檔案損壞的現象,操作的時候報錯 error database disk image is malformed 這裡記錄一下修復的操作過程 sqlite3 test file.db 開啟損壞的資料庫檔案 output recovery.sql 設定輸出檔...