如何启用 Turso 的 multiprocess_wal 让多个进程读写同一数据库文件?
【免费下载链接】tursoA SQL database in Rust: SQLite-compatible, now also speaking Postgres (experimental). The LLVM of databases.项目地址: https://gitcode.com/GitHub_Trending/tu/turso
Turso 默认规定一个数据库文件只能被单个 OS 进程打开:同一进程内的多个线程和连接可以安全共享数据库,但从第二个进程打开同一文件时会收到 locking error。如果你的部署形态是"多个独立进程读写同一份.db文件而不经过 server 层"(worker + sidecar、CLI 与嵌入式应用共用数据库、新旧进程短暂重叠的零停机发布、按连接拆进程部署),就需要启用实验特性multiprocess_wal。启用后,多个进程可以同时打开同一个.db文件,通过一个共享内存文件协调 WAL 读写与 checkpoint。
注意:multiprocess access 是experimental状态,磁盘协调格式和公开 API 可能在版本之间变化,文档明确提示不要依赖该格式跨版本做长期存储(见 docs/sql-reference/multiprocess-access.mdx)。
启用前核对适用条件
以下条件全部满足时 multiprocess WAL 才可用,任何一条不满足都应先处理再启用:
- 平台:64 位类 Unix 系统(Linux、macOS、Android 等)。在 Windows、WASM 和 32 位目标上,
multiprocess_wal标志会被接受但没有效果,数据库按单进程模式打开。- 这里两份文档的说法需要留意:SQL 参考文档 multiprocess-access.mdx 称 Windows 上标志无效;而 CLI 手册 docs/manual.md 中
--experimental-multiprocess-wal一条的说明是"支持 64 位 Unix,以及配合--vfs experimental_win_iocp使用时支持 64 位 Windows"。两处对 Windows 的支持口径不一致,涉及 Windows 部署时建议以当前版本的实际行为和发布说明为准。
- 这里两份文档的说法需要留意:SQL 参考文档 multiprocess-access.mdx 称 Windows 上标志无效;而 CLI 手册 docs/manual.md 中
- IO 后端:当前 IO 后端必须实现共享 WAL 协调。默认的文件后端支持;纯内存后端和部分自定义 VFS 不支持。
- 文件系统:数据库必须位于正确实现 POSIX byte-range lock 和 mmap 的本地文件系统。以下文件系统会被明确拒绝(返回
InvalidArgument),因为共享 mmap 协调在它们上面不安全:NFS、CIFS/SMB2、CephFS、GFS2、Lustre、OCFS2,以及 AFS、CODA、NCP、9P (v9fs)。 - 非内存库:
:memory:和file::memory:路径会被拒绝,共享协调需要落盘文件。
第一步:为每个打开该库的进程传递 multiprocess_wal
最短主路径是 CLI。tursodb通过--experimental-multiprocess-wal标志开启(该标志同时列在 docs/sql-reference/cli/command-line-options.mdx 的 Experimental Feature Flags 表中):
tursodb --experimental-multiprocess-wal mydb.db关键约束:同一时刻打开mydb.db的每一个tursodb(或 SDK)进程都必须传该标志,混用模式会被拒绝(下文"验证"一节给出具体报错)。
如果你用 SDK 而不是 CLI,各语言对应写法如下(取自 docs/sql-reference/multiprocess-access.mdx):
Rust:
use turso::Builder; let db = Builder::new_local("mydb.db") .experimental_multiprocess_wal(true) .build()?;JavaScript / Node.js:
import { Database } from "@tursodatabase/libsql"; const db = new Database("file:mydb.db", { experimental: ["multiprocess_wal"], });Python:
import turso conn = turso.connect( "mydb.db", experimental_features="multiprocess_wal", )Go(配置结构或 DSN 二选一):
db, err := turso.NewDatabase(turso.TursoDatabaseConfig{ Path: "mydb.db", ExperimentalFeatures: "multiprocess_wal", })db, err := sql.Open("turso", "mydb.db?experimental=multiprocess_wal")multiprocess_wal是实验特性清单中的正式条目,完整清单见 docs/sql-reference/experimental-features.mdx。
理解 .tshm 侧车文件:多进程如何协调
启用后,Turso 会在数据库旁边多创建一个同级文件,各进程共同 mmap 它来协调:
| 文件 | 用途 |
|---|---|
mydb.db | 数据库文件(不变)。 |
mydb.db-wal | 预写日志(不变)。 |
mydb.db-tshm | Turso 共享内存。内存映射的协调器,跟踪 WAL 状态、当前 writer、当前 checkpointer、reader slot 和共享的 page-to-frame 索引。 |
协调机制的要点:
- 单 writer 槽位:任意时刻至多一个进程持有 writer 锁,其余进程的写者阻塞等待。
- 单 checkpointer 槽位:checkpoint 跨进程串行化。
- 有界 reader 槽位:每个活动读事务 pin 住一个 WAL frame,防止它被并发写者覆盖或被 checkpointer 回收。
- 共享 frame 索引:任意进程中的读者都能把页号解析到最新 WAL frame,不必从头扫 WAL。
跨进程的.tshm字节范围锁(Linux 上用 OFD 锁,macOS 上用fcntl)控制所有权切换;mmap 区域提供元数据查询的快路径。
并发语义保持与单进程 WAL 一致:读者永不阻塞写者;快照稳定,并发进程提交新 frame 不影响已开始的读事务;一个进程做的 DDL 变更通过既有的 schema 刷新路径被其他进程在下一条语句时发现,兄弟进程中的 prepared statement 可能收到SchemaUpdated并重新 prepare——这与单进程内跨连接的行为相同。
验证:确认多进程模式真正生效
文档给出的判断方式有以下几种:
.tshm侧车文件出现。启用后打开数据库,数据库目录中会多出mydb.db-tshm。这是 multiprocess 模式实际启用的直接产物。混用模式会快速失败,报错文本可区分两种方向。数据库不能一边以单进程模式、另一边以多进程模式同时打开,打开路径会探测不兼容的现存 opener 并立即报错(引自 docs/sql-reference/multiprocess-access.mdx 的"Mixing Modes"一节):
- 不带
multiprocess_wal打开,而另一进程持有存活的.tshm权限:Database is already open with experimental multiprocess WAL in another process
- 带
multiprocess_wal打开,而另一进程持有旧式独占 DB 文件锁:Database is already open without experimental multiprocess WAL in another process
这两条报错可以作为检查手段:如果漏给某个进程传了标志,打开会直接失败并命中其中一条,而不是静默降级(只读打开除外,见下)。
- 不带
切换模式的正确操作:关闭到该库的所有现有连接,再用目标配置重新打开。
.tshm文件可以留在原地——Turso 在下一次 multiprocess 打开时复用它,必要时从 WAL 重建状态。另有一个只读回退行为:对只读打开请求multiprocess_wal但.tshm不存在时,Turso 回退到旧式只读 WAL 路径而不是失败,这让只读工具可以安全地读一个被单进程写者干净关闭的库。正确性压测(可选路径):仓库中的确定性并发模拟器支持 multiprocess 模式,见 testing/concurrent-simulator/README.md。该命令在
testing/concurrent-simulator内收集覆盖并运行多进程场景,副作用是写入.coverage/whopper/下的报告文件,需要本地具备 Rust 工具链:
make whopper-coverage WHOPPER_RUNS=10 \ WHOPPER_ARGS="--mode fast --max-steps 10000 --multiprocess --processes 2 --connections-per-process 2"报告输出到.coverage/whopper/report.txt与.coverage/whopper/html/index.html。文档说明 multiprocess 的 concurrent-simulator 与 stress 测试只在 64 位 Unix 目标上运行。
限制与边界
- 不与 MVCC 同用:该特性尚不支持 MVCC(
BEGIN CONCURRENT)。单进程内用 MVCC,或多进程 WAL + 默认隔离模型,二选一,不能同时。 .tshm格式带版本号,不迁移:格式升级会使已有.tshm失效,Turso 在打开时重建,不做跨版本迁移。- ATTACH 继承主连接设置:通过
ATTACH DATABASE附加的数据库继承主连接的 multiprocess 设置。 - 生产警示:docs/manual.md 对该 CLI 标志的说明中标注"该特性未生产就绪,当前不要用于关键数据"。
完成上述步骤后,判断标准是:数据库目录出现mydb.db-tshm、所有参与进程都带了标志、漏传标志的进程会收到上面两条报错之一而不是锁定错误,即说明多进程读写路径已经建立。
【免费下载链接】tursoA SQL database in Rust: SQLite-compatible, now also speaking Postgres (experimental). The LLVM of databases.项目地址: https://gitcode.com/GitHub_Trending/tu/turso
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考