SQLite 开启 WAL 模式提高并发读写能力
SQLite 开启 WAL 模式提高并发读写能力
SQLite 默认就很好用。
但如果你的程序有较多并发读写,就应该了解:
1 | WAL 模式 |
WAL 全称:
1 | Write-Ahead Logging |
简单理解:
1 | 写入先进入 WAL 日志文件,读请求仍然可以继续读取旧的数据快照。 |
这样可以减少读写互相阻塞的情况。

一、SQLite 默认模式的问题
SQLite 默认 journal 模式通常是:
1 | DELETE |
在这种模式下,写事务可能会阻塞读事务。
如果你的程序是:
- 单用户脚本
- 小工具
- 偶尔写入
- 主要读数据
默认模式够用。
但如果是:
- Web API
- 多线程读写
- 后台任务持续写入
- 前端频繁查询
- 日志/任务表高频更新
就可以考虑开启 WAL。
二、开启 WAL 模式
进入 SQLite:
1 | sqlite3 app.db |
执行:
1 | PRAGMA journal_mode=WAL; |
查看当前模式:
1 | PRAGMA journal_mode; |
如果返回:
1 | wal |
说明已经开启。
也可以直接命令行执行:
1 | sqlite3 app.db "PRAGMA journal_mode=WAL;" |
三、设置 busy_timeout
WAL 不是让 SQLite 变成无限并发数据库。
如果多个写操作同时发生,仍然可能竞争写锁。
建议设置:
1 | PRAGMA busy_timeout=5000; |
意思是:
1 | 遇到锁等待时,最多等 5000 毫秒。 |
命令行:
1 | sqlite3 app.db "PRAGMA busy_timeout=5000;" |
在 Python 里:
1 | import sqlite3 |
四、设置 synchronous
常见搭配:
1 | PRAGMA synchronous=NORMAL; |
完整初始化:
1 | PRAGMA journal_mode=WAL; |
说明:
FULL:更保守,安全性更高NORMAL:WAL 下常用,性能更好OFF:不建议生产使用
一般 Web 小项目可以用:
1 | WAL + synchronous=NORMAL + busy_timeout |
五、Node.js 中开启 WAL
如果你使用 better-sqlite3:
1 | pnpm add better-sqlite3 |
示例:
1 | import Database from 'better-sqlite3' |
六、Python 中开启 WAL
Python 示例:
1 | import sqlite3 |
注意:
1 | check_same_thread=False 不是让连接天然线程安全。 |
它只是允许连接跨线程使用。
真实项目里,更推荐:
1 | 每个线程/请求使用独立连接 |
七、WAL 会生成哪些文件
开启 WAL 后,你会看到:
1 | app.db |
含义:
| 文件 | 作用 |
|---|---|
app.db |
主数据库 |
app.db-wal |
写前日志 |
app.db-shm |
共享内存索引 |
不要随便只复制 app.db。
如果数据库正在运行,最好先 checkpoint 或停服务后备份。
八、手动 checkpoint
WAL 文件可能会变大。
可以执行:
1 | PRAGMA wal_checkpoint(TRUNCATE); |
命令行:
1 | sqlite3 app.db "PRAGMA wal_checkpoint(TRUNCATE);" |
这会尝试把 WAL 里的内容写回主库,并截断 WAL 文件。
九、什么时候不适合 WAL
WAL 不是万能的。
不适合:
- 数据库放在不可靠网络文件系统
- 写入并发极高
- 多进程疯狂写
- 需要复杂事务隔离
- 数据规模持续扩大到超出 SQLite 适合范围
如果你已经有大量并发写入,应该考虑:
1 | PostgreSQL |
而不是硬扛 SQLite。
十、推荐配置
小型 Web 项目推荐:
1 | PRAGMA journal_mode=WAL; |
如果使用 Node.js:
1 | db.pragma('journal_mode = WAL') |
如果使用 Python:
1 | conn.execute("PRAGMA journal_mode=WAL;") |
总结
SQLite 开启 WAL 后,最大的收益是:
1 | 读写并发体验更好。 |
它不会让 SQLite 变成大型数据库。
但对于个人项目、小后台、轻量 API、本地工具来说,WAL 非常值得开启。
推荐记住这一组:
1 | PRAGMA journal_mode=WAL; |