SQLite WAL 模式可能锁住短命读者
来源:hynek.me — 2026-07-24
📋 概述
SQLite 的 "database is locked" 错误通常被认为是写操作的问题,标准建议是使用 WAL 模式。但在一个写极少、读极频繁的非典型工作负载中——每月写不到一次,但每秒读数十到数百次——WAL 模式反而引入了罕见的 `SQLITE_BUSY` 错误。根源在于 WAL 模式下,即使只是读取也需要写-shm 文件:连接通过 -shm 文件协调,打开或关闭空 WAL 数据库时可能短暂需要排他锁。对于打开→SELECT→关闭的短命读者来说,这造成了"读也需要锁"的诡异现象。
🔑 核心要点
- WAL 模式下,读取也可能需要写入 -shm 文件,因此短命读者偶尔会收到 SQLITE_BUSY。
- 即使数据库多日未被写入,-wal 和 -shm 文件的修改时间仍会更新——因为每次打开/关闭连接都需要协调。
- SQLite C 库的默认连接超时为 0,意味着任何短暂的锁冲突立即导致失败。
- 这种问题出现在无连接池的独立进程模式中——每个进程打开只读连接、执行一次 SELECT、立刻关闭。
- 对于写极少的场景,不使用 WAL 模式可能反而是更合适的选择。
💡 金句
数据库文件本身自 7 月 21 日以来未被触碰,但 -wal 和 -shm 文件在 7 月 24 日仍被修改——因为每次打开或关闭连接都需要协调。
👍 0
👎 0
← 返回 Lobsters 首页