如何启用 Turso 的 multiprocess_wal 让多个进程读写同一数据库文件?
2026/9/13 7:37:36 网站建设 项目流程

如何启用 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 部署时建议以当前版本的实际行为和发布说明为准。
  • 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-tshmTurso 共享内存。内存映射的协调器,跟踪 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——这与单进程内跨连接的行为相同。

验证:确认多进程模式真正生效

文档给出的判断方式有以下几种:

  1. .tshm侧车文件出现。启用后打开数据库,数据库目录中会多出mydb.db-tshm。这是 multiprocess 模式实际启用的直接产物。

  2. 混用模式会快速失败,报错文本可区分两种方向。数据库不能一边以单进程模式、另一边以多进程模式同时打开,打开路径会探测不兼容的现存 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

    这两条报错可以作为检查手段:如果漏给某个进程传了标志,打开会直接失败并命中其中一条,而不是静默降级(只读打开除外,见下)。

  3. 切换模式的正确操作:关闭到该库的所有现有连接,再用目标配置重新打开。.tshm文件可以留在原地——Turso 在下一次 multiprocess 打开时复用它,必要时从 WAL 重建状态。另有一个只读回退行为:对只读打开请求multiprocess_wal.tshm不存在时,Turso 回退到旧式只读 WAL 路径而不是失败,这让只读工具可以安全地读一个被单进程写者干净关闭的库。

  4. 正确性压测(可选路径):仓库中的确定性并发模拟器支持 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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询