日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQLite数据库损坏与修复

發布時間:2025/3/15 数据库 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQLite数据库损坏与修复 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【引子】

平時用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數據庫損壞的原因可以看官網
How To Corrupt An SQLite Database File。

  • File overwrite by a rogue thread or process
    1.1. Continuing to use a file descriptor after it has been closed
    1.2. Backup or restore while a transaction is active
    1.3. Deleting a hot journal
    1.4. Mispairing database files and hot journals
  • File locking problems
    2.1. Filesystems with broken or missing lock implementations
    2.2. Posix advisory locks canceled by a separate thread doing close()
    2.2.1. Multiple copies of SQLite linked into the same application
    2.3. Two processes using different locking protocols
    2.4. Unlinking or renaming a database file while in use
    2.5. Multiple links to the same file
    2.6. Carrying an open database connection across a fork()
  • Failure to sync
    3.1. Disk drives that do not honor sync requests
    3.2. Disabling sync using PRAGMAs
  • Disk Drive and Flash Memory Failures
    4.1. Non-powersafe flash memory controllers
    4.2. Fake capacity USB sticks
  • Memory corruption
  • Other operating system problems
    6.1. Linux Threads
    6.2. Failures of mmap() on QNX
    6.3. Filesystem Corruption
  • SQLite Configuration Errors
  • Bugs in SQLite
    8.1. False corruption reports due to database shrinkage
    8.2. Corruption following switches between rollback and WAL modes
    8.3. I/O error while obtaining a lock leads to corruption
    8.4. Database pages leak from the free page list
    8.5. Corruption following alternating writes from 3.6 and 3.7.
    8.6. Race condition in recovery on windows system.
  • 修復損壞的SQLite數據庫

    前陣子由于分區空間滿出現了sqlite3數據庫文件損壞的現象,操作的時候報錯:

    Error: database disk image is malformed

    這里記錄一下修復的操作過程:

    1.將數據庫中的數據導出為sql語句文件

    sqlite3 test_file.db #打開損壞的數據庫文件 .output recovery.sql #設置輸出文件 .dump # 導出文件 .q

    2.將導出的recovery.sql文件最后一行ROLLBACK改為COMMIT;

    vim recovery.sql

    3.導入到一個新庫中

    sqlite3 fix.db #打開用于導入修復后的數據庫數據 .read recovery.sql #讀取數據文件 .q

    SQLite使用建議

    這里有4點建議:

  • 減少多進程或多線程操作,盡可能單線程寫。
  • 減少事務操作,減小事務復雜度,減少檢查點
  • 減少數據庫的大小
  • 避免使用PRAGMA synchronous=OFF

  • 引經據典

    https://blog.csdn.net/jieshibendan/article/details/90678036
    https://blog.csdn.net/qq_35241071/article/details/111247142
    https://blog.csdn.net/mycwq/article/details/45541409

    總結

    以上是生活随笔為你收集整理的SQLite数据库损坏与修复的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。