SQLITE 問題整理

前言

用過 sqlite 的朋友都知道,在數據庫目錄會有 xxx.db 文件,你可能看到過,其實數據庫不只有 xxx.db,有時候還會有 xxx.db-shm、xxx.db-wal、xxx.db-journal 等文件,你有想過這些文件的作用是什麼嗎?還有使用數據庫時,偶爾會報 SQLITE_BUSY 或者 SQLITE_LOCKED 的錯誤,你知道是因爲什麼導致的嗎?請看正文。

知識點

db-shm、db-wal、db-journal 文件,這些是什麼?

db 文件:db 文件就是我們理解的常規的數據庫文件

db-journal 文件:一般數據庫事務中會用到,在數據回滾時,用作回滾日誌

db-wal 文件:需要手動開啓 wal 模式,開啓 wal 模式後,數據庫修改日誌會先寫在 wal 文件中,事務提交後,會寫在 db 文件中,主要用作協調併發訪問。

db-shm 文件:用於共享內存和協調併發訪問,存儲了數據庫連接中的鎖信息和同步機制,數據庫啓用 WAL 模式後創建,數據庫關閉時刪除。

WAL 模式是什麼?

WAL 需要手動開啓,它是 sqlite 的一種日誌模式,會將寫操作記錄到一個單獨的日誌文件(db-wal)中實現高效的併發讀寫操作。

它主要有兩個特點:

寫操作:寫操作首先記錄到 db-wal 文件中宏,不是直接寫入主數據庫文件。

併發讀寫:wal 模式允許多個讀操作和和一個寫操作同時執行。

SQLITE_BUSY 原因

一般是不同的數據庫連接(通常是不同的進程)之間存在衝突纔會導致 SQLITE_BUSY,注意一般是多進程操作一個數據庫纔會出現此問題。

例如:一個進程在一個連接上讀,另一個進程在不同的連接上讀或者寫,會 SQLITE_BUSY。

詳見:

https://www.sqlite.org/rescode.html#busy

SQLITE_LOCKED 原因

一般是同一個數據庫連接內,或使用共享內存的不同連接之間存在衝突,注意一般是一個進程內的多線程操作導致此問題。

例如:同一個連接上,一個線程讀表,一個線程刪表,會 SQLITE_LOCKED

詳見:

https://www.sqlite.org/rescode.html#locked

總結

本文主要介紹了 db-shm, db-wal, db-journal 文件的作用, SQLITE_BUSY 和 SQLITE_LOCKED 錯誤的原因,以及 WAL 模式的概念和特點。希望你能有所收穫。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/Z_x0oY6ux1RLbVbfvlxZOw