MongoDB · 引擎特性 · 事务实现解析

本文涉及的产品
云原生多模数据库 Lindorm,多引擎 多规格 0-4节点
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 MongoDB,通用型 2核4GB
简介: MongoDB 4.0 引入的事务功能,支持多文档ACID特性,例如使用 mongo shell 进行事务操作> s = db.getMongo().startSession()session { "id" : UUID("3bf55e90-5e88-44aa-a59e-a30f777f1d89") }> s.

MongoDB 4.0 引入的事务功能,支持多文档ACID特性,例如使用 mongo shell 进行事务操作

> s = db.getMongo().startSession()
session { "id" : UUID("3bf55e90-5e88-44aa-a59e-a30f777f1d89") }
> s.startTransaction()
> db.coll01.insert({x: 1, y: 1})
WriteResult({ "nInserted" : 1 })
> db.coll02.insert({x: 1, y: 1})
WriteResult({ "nInserted" : 1 })
> s.commitTransaction()  (或者 s.abortTransaction()回滚事务)

支持 MongoDB 4.0 的其他语言 Driver 也封装了事务相关接口,用户需要创建一个 Session,然后在 Session 上开启事务,提交事务。例如

python 版本

with client.start_session() as s:
    s.start_transaction()
    collection_one.insert_one(doc_one, session=s)
    collection_two.insert_one(doc_two, session=s)
    s.commit_transaction()

java 版本

try (ClientSession clientSession = client.startSession()) {
   clientSession.startTransaction();
   collection.insertOne(clientSession, docOne);
   collection.insertOne(clientSession, docTwo);
   clientSession.commitTransaction();
}

Session

Session 是 MongoDB 3.6 版本引入的概念,引入这个特性主要就是为实现多文档事务做准备。Session 本质上就是一个「上下文」。

在以前的版本,MongoDB 只管理单个操作的上下文,mongod 服务进程接收到一个请求,为该请求创建一个上下文 (源码里对应 OperationContext),然后在服务整个请求的过程中一直使用这个上下文,内容包括,请求耗时统计、请求占用的锁资源、请求使用的存储快照等信息。有了 Session 之后,就可以让多个请求共享一个上下文,让多个请求产生关联,从而有能力支持多文档事务。

每个 Session 包含一个唯一的标识 lsid,在 4.0 版本里,用户的每个请求可以指定额外的扩展字段,主要包括:

  • lsid: 请求所在 Session 的 ID, 也称 logic session id
  • txnNmuber: 请求对应的事务号,事务号在一个 Session 内必须单调递增
  • stmtIds: 对应请求里每个操作(以insert为例,一个insert命令可以插入多个文档)操作ID

实际上,用户在使用事务时,是不需要理解这些细节,MongoDB Driver 会自动处理,Driver 在创建 Session 时分配 lsid,接下来这个 Session 里的所以操作,Driver 会自动为这些操作加上 lsid,如果是事务操作,会自动带上 txnNumber。

值得一提的是,Session lsid 可以通过调用 startSession 命令让 server 端分配,也可以客户端自己分配,这样可以节省一次网络开销;而事务的标识,MongoDB 并没有提供一个单独的 startTransaction的命令,txnNumber 都是直接由 Driver 来分配的,Driver 只需保证一个 Session 内,txnNumber 是递增的,server 端收到新的事务请求时,会主动的开始一个新事务。

MongoDB 在 startSession 时,可以指定一系列的选项,用于控制 Session 的访问行为,主要包括:

ACID

Atomic

针对多文档的事务操作,MongoDB 提供 “All or nothing” 的原子语义保证。

Consistency

太难解释了,还有抛弃 Consistency 特性的数据库?

Isolation

MongoDB 提供 snapshot 隔离级别,在事务开始创建一个 WiredTiger snapshot,然后在整个事务过程中使用这个快照提供事务读。

Durability

事务使用 WriteConcern {j: ture} 时,MongoDB 一定会保证事务日志提交才返回,即使发生 crash,MongoDB 也能根据事务日志来恢复;而如果没有指定 {j: true} 级别,即使事务提交成功了,在 crash recovery 之后,事务的也可能被回滚掉。

事务与复制

复制集配置下,MongoDB 整个事务在提交时,会记录一条 oplog(oplog 是一个普通的文档,所以目前版本里事务的修改加起来不能超过文档大小 16MB的限制),包含事务里所有的操作,备节点拉取oplog,并在本地重放事务操作。

事务 oplog 示例,包含事务操作的 lsid,txnNumber,以及事务内所有的操作日志(applyOps字段)

“ts” : Timestamp(1530696933, 1), “t” : NumberLong(1), “h” : NumberLong(“4217817601701821530”), “v” : 2, “op” : “c”, “ns” : “admin.$cmd”, “wall” : ISODate(“2018-07-04T09:35:33.549Z”), “lsid” : { “id” : UUID(“e675c046-d70b-44c2-ad8d-3f34f2019a7e”), “uid” : BinData(0,”47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=”) }, “txnNumber” : NumberLong(0), “stmtId” : 0, “prevOpTime” : { “ts” : Timestamp(0, 0), “t” : NumberLong(-1) }, “o” : { “applyOps” : [ { “op” : “i”, “ns” : “test.coll2”, “ui” : UUID(“a49ccd80-6cfc-4896-9740-c5bff41e7cce”), “o” : { “_id” : ObjectId(“5b3c94d4624d615ede6097ae”), “x” : 20000 } }, { “op” : “i”, “ns” : “test.coll3”, “ui” : UUID(“31d7ae62-fe78-44f5-ba06-595ae3b871fc”), “o” : { “_id” : ObjectId(“5b3c94d9624d615ede6097af”), “x” : 20000 } } ] } }

整个重放过程如下:

  1. 获取当前 Batch (后台不断拉取 oplog 放入 Batch)
  2. 设置 OplogTruncateAfterPoint 时间戳为 Batch里第一条 oplog 时间戳 (存储在 local.replset.oplogTruncateAfterPoint 集合)
  3. 写入 Batch 里所有的 oplog 到 local.oplog.rs 集合,根据 oplog 条数,如果数量较多,会并发写入加速
  4. 清理 OplogTruncateAfterPoint, 标识 oplog 完全成功写入;如果在本步骤完成前 crash,重启恢复时,发现 oplogTruncateAfterPoint 被设置,会将 oplog 截短到该时间戳,以恢复到一致的状态点。
  5. 将 oplog 划分到到多个线程并发重放,为
相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
10天前
|
NoSQL 定位技术 MongoDB
深入探索 MongoDB:高级索引解析与优化策略
深入探索 MongoDB:高级索引解析与优化策略
|
7天前
|
传感器 存储 SQL
ClickHouse(15)ClickHouse合并树MergeTree家族表引擎之GraphiteMergeTree详细解析
GraphiteMergeTree是ClickHouse用于优化Graphite数据存储和汇总的表引擎,适合需要瘦身和高效查询Graphite数据的开发者。它基于MergeTree,减少存储空间并提升查询效率。创建表时需包括Path、Time、Value和Version列。配置涉及pattern、regexp、function和retention,用于指定聚合函数和数据保留规则。文章还提供了建表语句示例和相关资源链接。
11 1
|
8天前
|
机器学习/深度学习 人工智能 自然语言处理
智能时代的引擎:深度学习技术解析
【6月更文挑战第8天】本文深入探讨了深度学习技术,一种基于人工神经网络的机器学习方法。我们将从其基本原理出发,分析其在数据处理、特征提取和模式识别方面的强大能力。文章将通过具体案例,展示深度学习在图像识别、自然语言处理等领域的应用,并讨论其面临的挑战与未来发展方向。
|
10天前
|
监控 NoSQL 大数据
深入解析 MongoDB Map-Reduce:强大数据聚合与分析的利器
深入解析 MongoDB Map-Reduce:强大数据聚合与分析的利器
|
10天前
|
存储 NoSQL MongoDB
深入解析 MongoDB 与 Python:基本语法、实用示例与最佳实践
深入解析 MongoDB 与 Python:基本语法、实用示例与最佳实践
|
10天前
|
监控 NoSQL MongoDB
深入MongoDB监控:全面解析命令、实用示例与最佳实践
深入MongoDB监控:全面解析命令、实用示例与最佳实践
|
10天前
|
存储 NoSQL 数据挖掘
深入探索MongoDB聚合操作:解析数据之美
深入探索MongoDB聚合操作:解析数据之美
|
10天前
|
NoSQL MongoDB 数据库
MongoDB排序操作解析:优化性能,精准控制数据展示
MongoDB排序操作解析:优化性能,精准控制数据展示
|
1月前
|
存储 SQL NoSQL
什么是 MongoDB,为什么它是当今最受欢迎的数据库之一?
什么是 MongoDB,为什么它是当今最受欢迎的数据库之一?
|
5天前
|
存储 JSON NoSQL
【文档数据库】ES和MongoDB的对比
【文档数据库】ES和MongoDB的对比
10 1

相关产品

  • 云数据库 MongoDB 版
  • 推荐镜像

    更多