第 1 篇 给出了 Session → Cache → Reconcile → HS → Checkpoint 的坐标系。落到 API 层,第一批必须钉死的不变量是:谁打开数据库、谁持有事务、谁能动 cursor。把 MongoDB 连接池或「每线程一个 DB 连接」的心智原样套到 WiredTiger,会在并发与资源生命周期上踩坑。
本文只回答:
- Connection / Session / Cursor 各自管什么、生命周期怎么走。
- 线程模型与「一 session 一事务」边界。
- 与 MongoDB 嵌入、后续 Cache 章节的衔接点。
本文是「WiredTiger 内核」系列第 2 篇(共 17 篇)。→ 系列目录
先修:第 1 篇 · 全景。续读:第 3–4 篇(Cache / Eviction)。
版本锚定:Architecture Guide Version 12.0.0 /
develop的 Connection、Session、Cursor、Multithreading;源码路径以mongodb-8.0的src/include/connection.h、session.h、src/conn/为准。Guide 不与发版锁步。
一、三层句柄:一张表
| 句柄 | Guide 定义 | 关键不变量 | 典型 API |
|---|---|---|---|
| Connection | 数据库实例句柄 | 文件锁独占;进程内通常一个;持有全局 cache 与内部线程 | wiredtiger_open /
WT_CONNECTION::close /
reconfigure |
| Session | 几乎所有操作的上下文 | 隶属一个 connection;单线程使用;同时最多一个运行中事务 | open_session /
begin_transaction / close |
| Cursor | 定位、迭代、读写入口 | 由创建 session 拥有;同 session 多 cursor 共享事务上下文 | open_cursor / search /
insert / close |
flowchart TB
app["Application / MongoDB"] --> conn["WT_CONNECTION"]
conn --> s1["WT_SESSION 1"]
conn --> s2["WT_SESSION 2"]
conn --> workers["Internal threads<br/>evict / checkpoint / log"]
s1 --> c1a["WT_CURSOR A"]
s1 --> c1b["WT_CURSOR B"]
s2 --> c2["WT_CURSOR C"]
Architecture Guide Connection:connection
通过文件锁对数据库拥有排他访问,因此同一数据库同一时刻只能打开一个
connection。这与「多个 mongod 写同一
dbPath」被操作系统/部署禁止是同一类约束在库内的投影。
二、Connection:打开、运行、关闭
2.1
初始化(wiredtiger_open)
Guide Connection · Initialization 的顺序可收成:
- 解析配置(eviction、logging、checkpoint、cache、statistics 等)。
- 按
create决定建库或打开已有库;检查 turtle / 元数据等必需文件;损坏时返回WT_RUN_RECOVERY或WT_TRY_SALVAGE,不建成 connection。 - 启动内部工作线程:statistics、logging、eviction、checkpoint、cache 管理,以及管理 dhandle 活跃度的 sweep server。
- 在 connection 完全就绪前跑 rollback to stable,把库收到一致状态。
MongoDB 启动 mongod
时完成上述嵌入;运维看到的 cacheSizeGB
等最终落到 connection 配置(第 14
篇)。本篇不展开每个配置项词典。
2.2 运行期
- 数据库级操作走 connection 接口(例如
reconfigure,无需先 close 再 open)。 - 几乎所有 CRUD 在 session
上下文中执行(
open_session)。 - 全局状态在
WT_CONNECTION_IMPL(connection.h);connection 句柄可以在线程间共享(Multithreading),但具体 session 不行。
2.3 关闭
WT_CONNECTION::close 释放所持资源(含
sessions,除非另行配置),必要时再次 rollback to
stable——Guide 提醒这一步可能耗时。
源码目录入口(mongodb-8.0):src/conn/(打开/关闭与连接级服务)、src/include/connection.h。
三、Session:事务与操作的容器
3.1 创建与配额
Session 只能通过已有 connection 的
WT_CONNECTION::open_session 创建;一个
connection 可有多个 session,一个 session 只属于一个
connection。上限由 wiredtiger_open 配置项
session_max 约束(Session)。
两类 session:
| 类型 | 来源 | 用途 |
|---|---|---|
| User session | 应用 / MongoDB | 用户读写与显式事务 |
| Internal session | WiredTiger 自建 | Eviction 等内部操作 |
Guide 写明:二者使用规则相同,差别只在创建来源。
3.2 事务边界
- 可把多个操作收成一个原子事务。
- 一个 session 在任意时刻最多持有一个运行中事务,且该事务只属于该 session。
这直接决定 API 形状:不要指望「同一 session 上并行两个独立事务」;要并行就开多个 session(并遵守每 session 单线程)。
3.3 Cursor 与 dhandle
- 同一 session 可对一张或多张表打开多个 cursor;所有 cursor 共享该 session 的事务上下文。
cache_cursors(open_session 或wiredtiger_open)可缓存 cursor,减少反复 open/close 开销。- 首次访问某表时获取并缓存 data handle;不再使用时标 idle,由 sweep server 回收不活跃 dhandle(Data Handles;细节不在本篇展开)。
3.4 关闭与错误
WT_SESSION::close
回滚仍活跃的事务并关闭仍打开的 cursor。关闭 connection
也会关闭全部 session。
WT_SESSION::get_last_error 返回最近一次
session API 的错误码、子级错误码与消息;外部 session
默认保存错误,内部 session 默认不保存——除非由带
WT_SESSION_SAVE_ERRORS 的外部 session
打开并继承(schema 类路径需要把内部错误传回外部)。
3.5 线程模型(硬约束)
A session is always executed as a single thread.(Architecture Guide Session · Multithreading)
工程含义:
- 同一
WT_SESSION*不得被多线程并发调用。 - 多线程应:共享 connection,每线程(或每逻辑工作者)持有自己的 session。
- MongoDB 侧线程如何映射到 WT session,属于嵌入层调度;本系列只钉 WT 不变量,避免把「一个 TCP 连接」等同于「一个 WT session」而不查源码。
四、Cursor:读写的实际入口
4.1 种类与创建
WT_SESSION::open_cursor 按
URI/配置创建不同类型 cursor。Guide
Cursor:典型用途是访问 B-Tree
中的键值;也可用于索引、statistics、log、metadata,以及
backup 管理。
文件(B-Tree)cursor 的实现结构是
WT_CURSOR_BTREE:方法多是对 B-Tree
层的薄包装;定位与原始键值传递由 B-Tree 层完成。
4.2 所有权
- File cursor 由 session 拥有,只能被该 session 使用。
- 某 session 首次打开某文件时创建 file cursor;即使其他 session 已打开同一文件,本 session 仍有自己的 cursor 实例。
- Open cursor 会增加 data handle 引用计数,阻止 drop /
rename / verify / salvage;
WT_CURSOR::close释放(或按缓存策略保留)cursor 内存并递减引用。
4.3 与后续章节的接口
| 操作直觉 | 落到的机制(后续篇) |
|---|---|
search / next 未命中内存 |
经 WT_REF 按需读页进 Cache(第 3 篇) |
insert / update |
挂 WT_INSERT / WT_UPDATE
链(第 5 篇) |
| 读旧快照 | 链 → on-disk → History Store(第 7–8 篇) |
| 长时间持有 cursor | 可能拖住 oldest / 历史回收(第 15 篇) |
本篇不展开 cursor 方法表;完整列表以 WT API 文档为准。
五、常见误解与工程间隙
「多线程共用一个 session 能提升吞吐。」
违反 Guide 单线程契约,属于未定义用法,不是性能技巧。「Connection 与 Session 一一对应。」
正确模型是 1 connection : N sessions : 每 session 若干 cursors。「打开 cursor 就算进了 cache_size。」
Cache 章:dhandle、cursor、session 不计入 cache 计量;它们仍占进程堆,只是不计cache_size配额。工程间隙:Architecture Guide 与具体 MongoDB 小版本的线程命名、内部 session 数量可能不一致;排障以对应二进制符号与
mongodb-8.0源码为准。本篇无本地线程转储实测。
开放问题(系列后部回收): MongoDB 在复制/prepared 路径上如何把逻辑会话映射到 WT session 与时间戳,是否放大「长游标拖住 HS」——第 14–15 篇结合手册写边界,不在此编造映射表。
六、收束
记住三句:
- Connection 独占数据库实例并拉起全局服务线程;CRUD 几乎都在 Session 里做。
- Session 单线程、同时一事务;其下多个 Cursor 共享该事务上下文,且不可跨 session 借用。
- 下一篇进入 Cache /
WT_REF:cursor 读写最终碰到的是按需加载的页与 clean/dirty 计量——那才是 eviction 与 reconcile 的舞台。
参考资料
规范 / 官方文档
- WiredTiger Architecture Guide, Connection:https://source.wiredtiger.com/develop/arch-connection.html
- WiredTiger Architecture Guide, Session:https://source.wiredtiger.com/develop/arch-session.html
- WiredTiger Architecture Guide, Cursor:https://source.wiredtiger.com/develop/arch-cursor.html
- WiredTiger Architecture Guide, Multithreading(session 单线程契约)
源码
wiredtiger/wiredtigermongodb-8.0:src/include/connection.h、session.h;src/conn/
站内
- 第 1 篇 · 全景
- 系列索引
- 第 08 篇 · History Store(读路径与长游标后果)
上一篇:文档库存储引擎全景
下一篇:Cache 与
WT_REF
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【WiredTiger 内核】运维与排障:HS 膨胀、cache 压力与长游标
给出 WiredTigerHS.wt 膨胀、cache dirty/eviction 压力、长游标与备份窗口的可复现排查口径;强调禁止手工删除 HS/日志文件,并把现象映射回本系列机制篇。
【WiredTiger 内核】文档库存储引擎全景:MongoDB 默认引擎的生态位
定位文档库默认引擎 WiredTiger 相对 PG/InnoDB/SQLite/RocksDB 的生态位;钉住 Session→Cache→Reconcile→HS→Checkpoint 主线、站内分工与 17 篇阅读路线,并以 Berenson 隔离词汇与 Durable History 为学术/工程锚点。
【WiredTiger 内核】Cache 与 WT_REF:clean/dirty 计量与按需读页
拆解 WiredTiger Cache 的 clean/dirty 计量、WT_REF/WT_PAGE 按需加载,以及 update chain / insert list 如何挂在页上;说明 cache_size 不计 session/cursor,并为 Eviction 章节铺垫 dirty 必须先 reconcile。
【WiredTiger 内核】Eviction:脏页必须先 reconcile
拆解 WiredTiger Eviction 的 server/worker/队列、target/trigger 阈值,以及 dirty eviction 经 reconciliation 把最新值写入用户表、旧版本写入 History Store;说明应用线程被迫协助驱逐的条件。