MySQL PK MongoDB:多文档事务支持,谁更友好?

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介:

作者介绍

贺春旸,凡普金科DBA团队负责人,《MySQL管理之道:性能调优、高可用与监控》第一、二版作者,曾任职于中国移动飞信、安卓机锋网。致力于MariaDB、MongoDB等开源技术的研究,主要负责数据库性能调优、监控和架构设计。

MongoDB 4.0已经发布GA版本,并且有许多新功能和改进。在本文中,我们将重点关注主要功能,毫无疑问,这是对多文档ACID事务的支持。我们将围绕隔离级别、可重复读、幻读、事务冲突检测等主要功能,通过实验与MySQL一一做对比。

image
image
首先会简述介绍下ACID事务隔离级别,然后再步入测试主题正文。

原子性(Atomicity):事务包含的所有操作要么全部成功,要么全部失败,不存在成功一半的概念。典型例子“西方二元对立思想——非此即彼”:在二元逻辑体系中只存在两种逻辑值,就是对和错,或正和负,不存在既对又错或非正非负的其他状态。

一致性(Consistency):一个事务执行之前和执行之后都必须处于一致性状态。典型例子:“金龙,你借我5000元,下个月开支给你。”不论金龙用什么方式给我转账,分几次转,借钱结束后我银行卡里的余额增加5000元,金龙卡里少了5000元,不能突然蹦出来1万来。

隔离性(Isolation):数据库采用锁机制来实现事务的隔离性,当多个事务同时更新数据库中相同的数据时,只允许持有锁的事务能更新该数据,其他事务必须等待,直到前一个事务释放了锁,其他事务才有机会更新该数据。典型例子:“你去医院看病,要先到护士那里分诊排号,如果多个患者加塞儿同时进来,大夫就发飙了,出去排队,只能一个一个看”。

持久性(Durability):事务成功提交后,它对数据库所做的修改就永久保存下来,即使数据库崩溃,数据还能恢复到事务成功提交后的状态。典型例子:“你去ATM机取钱,结果ATM机故障了,你取出来了钱,卡里的余额不能没减。”

一、局限性与限制条件

1、多文档事务仅适用于副本集。

注:如果是单机,需切到副本集模式。

2、仅适用于WiredTiger存储引擎。

3、如果你的架构是分片Sharding模式,事务是不支持的。分布式事务计划在4.2版本里支持。

4、事务只支持CRUD操作,DDL、DCL操作不支持。

注:CRUD就是MySQL的DML,意思一样叫法不同而已。

5、事务无法在config、admin和local系统数据库中读取或写入。
image
6、事务无法在system.*(系统集合)里写入。

7、不能有大事务写入,写入集不能超过16MB(类似MariaDB Galera Cluster写入集wsrep_max_ws_size限制),否则客户端直接报错。

注:如果有大事务,应该考虑将这些大事务拆分成若干块较小的事务。例如将大于2018年的状态值更改为1,应考虑循环1万条一批量更新,这一点跟MySQL玩法一样。

二、我们第一个事务

在开始事务之前,必须创建会话。事务不能在会话外运行。

var session1 = db.getMongo().startSession()

var session2 = db.getMongo().startSession()

Mongo Shell里引入了三个用于创建,提交和终止事务的新命令:

   session.startTransaction()

在当前会话中启动事务

    session.commitTransaction()

持久保存事务中的操作变更

    session.abortTransaction()

        终止事务操作所做的变更

image
1、在test库创建t1表,并且插入4条数据。
image
演示一
image
演示二
image
空闲事务受transactionLifetimeLimitSeconds参数影响,默认60秒。

可通过以下命令查看:

db.adminCommand( { getParameter: 1, transactionLifetimeLimitSeconds: 1 } )

如果你想在线变更,可以通过下面的命令设置:

db.adminCommand( { setParameter: 1, transactionLifetimeLimitSeconds: 30 } )

也可以写死在/etc/mongod.cnf配置文件里永久生效,格式如下:

setParameter = transactionLifetimeLimitSeconds=30
![image](https://yqfile.alicdn.com/f0d24428db1507628899f141fd8fb551dfa41493.png)
三、事务隔离性演示

演示一:事务冲突检测
![image](https://yqfile.alicdn.com/a778a995fc2e915ce0d279f2caa47d201b5ae01a.png)

注:空闲事务是指当一个事务长时间未提交,那么这个连接就不能关闭,内存就不释放,并发一大,导致DB连接数增多,就会对性能产生影响。默认是60秒,你可以根据自己的情况设定阈值。超过这个阈值,服务端自动杀死未提交的空闲事务。
当两个(或多个)并发事务修改相同的文档时,会发生冲突。即使在尚未提交事务时,MongoDB也可以立即检测到冲突。

这里和MySQL有些区别,MySQL可以通过参数innodb_lock_wait_timeout设置检测到事务冲突后,自动终止回滚的时间,而MongoDB没有提供该参数。

当在执行创建索引时,未加{background:1})后台创建。

此时新事务将无法获取所需的锁,并且在等待参数maxTransactionLockRequestTimeoutMillis后事务终止回滚,默认值是5毫秒。
image
如果你想在线调整事务等待获取锁的时间,可以通过下面的命令设置:

db.adminCommand( { setParameter: 1, maxTransactionLockRequestTimeoutMillis: 15 } )

也可以写死在/etc/mongod.cnf配置文件里永久生效,格式如下:

setParameter = maxTransactionLockRequestTimeoutMillis=15

演示二:可重复读
image

Repeatable Read (可重复读)可避免脏读、不可重复读的发生。

不可重复读侧重点在于更新修改的数据,即在同一个事务里,两次查询的数据结果不一致。与脏读的区别是:脏读是一个事务读取了另一个事务未提交的脏数据。

演示三:幻读
image
在MySQL默认隔离级Repeatable Read下,刚才的操作,在会话二未提交的事务里,会莫名其妙地看到第5条数据,这种现象称为幻读。

幻读和不可重复读很像,但幻读侧重点在于新增和删除,而不可重复读侧重点在于更改,共同之处都是一个事务中两次查询得到的数据结果不一致。

由此,从测试结果得出的结论是:

MongoDB采用的默认隔离级别是Snapshot一致性快照(特别是设置了readConcern=majority情况下,要读某行数据的历史版本时,依赖该隔离级别。)

Snapshot介于Repeatable Read与Serializable之间,既避免了脏读、不可重复读、幻读,又不会因Serializable串行化降低并发性能。
image
原文发布时间为:2018-12-18
本文作者:贺春旸
本文来自云栖社区合作伙伴“ DBAplus社群 ”,了解相关信息可以关注“dbaplus”微信公众号

相关实践学习
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
相关文章
|
4月前
|
NoSQL MongoDB 微服务
微服务——MongoDB常用命令——文档的分页查询
本文介绍了文档分页查询的相关内容,包括统计查询、分页列表查询和排序查询。统计查询使用 `count()` 方法获取记录总数或按条件统计;分页查询通过 `limit()` 和 `skip()` 方法实现,控制返回和跳过的数据量;排序查询利用 `sort()` 方法,按指定字段升序(1)或降序(-1)排列。同时提示,`skip()`、`limit()` 和 `sort()` 的执行顺序与编写顺序无关,优先级为 `sort()` > `skip()` > `limit()`。
141 1
|
4月前
|
JSON NoSQL MongoDB
微服务——MongoDB常用命令——文档基本CRUD
本文介绍了MongoDB中文档的基本操作,包括插入、查询、更新和删除。单个文档插入使用`insert()`或`save()`方法,批量插入用`insertMany()`。查询所有文档用`find()`,条件查询可在`find()`中添加参数,投影查询控制返回字段。更新文档通过`update()`实现,支持覆盖修改、局部修改(使用`$set`)和批量修改。列值增长可用`$inc`实现。删除文档用`remove()`,需谨慎操作以免误删数据。此外,文档键值对有序,区分大小写,不能有重复键。
104 1
|
4月前
|
自然语言处理 搜索推荐 关系型数据库
MySQL实现文档全文搜索,分词匹配多段落重排展示,知识库搜索原理分享
本文介绍了在文档管理系统中实现高效全文搜索的方案。为解决原有ES搜索引擎私有化部署复杂、运维成本高的问题,我们转而使用MySQL实现搜索功能。通过对用户输入预处理、数据库模糊匹配、结果分段与关键字标红等步骤,实现了精准且高效的搜索效果。目前方案适用于中小企业,未来将根据需求优化并可能重新引入专业搜索引擎以提升性能。
213 5
|
5月前
|
存储 缓存 关系型数据库
MySQL底层概述—9.ACID与事务
本文介绍了数据库事务的ACID特性(原子性、一致性、隔离性、持久性),以及事务控制的演进过程,包括排队、排它锁、读写锁和MVCC(多版本并发控制)。文章详细解释了每个特性的含义及其在MySQL中的实现方式,并探讨了事务隔离级别的类型及其实现机制。重点内容包括:ACID特性(原子性、持久性、隔离性和一致性的定义及其实现方式)、事务控制演进(从简单的全局排队到复杂的MVCC,逐步提升并发性能)、MVCC机制(通过undo log多版本链和Read View实现高效并发控制)、事务隔离级别(析了四种隔离级别(读未提交、读已提交、可重复读、可串行化)的特点及适用场景)、隔离级别与锁的关系。
|
6月前
|
SQL 关系型数据库 MySQL
MySQL事务日志-Undo Log工作原理分析
事务的持久性是交由Redo Log来保证,原子性则是交由Undo Log来保证。如果事务中的SQL执行到一半出现错误,需要把前面已经执行过的SQL撤销以达到原子性的目的,这个过程也叫做"回滚",所以Undo Log也叫回滚日志。
230 7
MySQL事务日志-Undo Log工作原理分析
|
6月前
|
存储 监控 NoSQL
【赵渝强老师】MongoDB文档级别的并发控制
MongoDB使用WiredTiger存储引擎在文档级别进行并发控制,允许多个写操作同时修改不同文档,但对同一文档的修改需序列化执行。引擎采用乐观锁和意向锁机制处理冲突。通过视频讲解、插入大量文档示例及使用`mongotop`和`db.serverStatus()`命令,演示了如何监控MongoDB的锁信息和读写统计,展示了数据库和集合级别的写锁情况。
175 29
|
7月前
|
SQL 安全 关系型数据库
【MySQL基础篇】事务(事务操作、事务四大特性、并发事务问题、事务隔离级别)
事务是MySQL中一组不可分割的操作集合,确保所有操作要么全部成功,要么全部失败。本文利用SQL演示并总结了事务操作、事务四大特性、并发事务问题、事务隔离级别。
3267 2
【MySQL基础篇】事务(事务操作、事务四大特性、并发事务问题、事务隔离级别)
|
7月前
|
NoSQL 关系型数据库 Shell
Mongodb支持事务吗?
MongoDB 是一个非关系型数据库,最初不支持事务。4.0版本引入了多文档事务支持,确保跨多个文档的操作要么全部成功,要么全部失败回滚,保持数据一致性。从4.2版本起,分布式事务和多文档事务成为同义词,支持分片集群和副本集上的多文档操作。配置事务需开启副本集,并通过会话管理事务的提交与回滚。示例展示了如何在MongoDB Shell中使用事务进行多文档操作。
641 11
|
7月前
|
SQL 关系型数据库 MySQL
MySQL进阶突击系列(04)事务隔离级别、AICD、CAP、BASE原则一直搞不懂? | 看这篇就够了
本文详细介绍了数据库事务的四大特性(AICD原则),包括原子性、隔离性、一致性和持久性,并深入探讨了事务并发问题与隔离级别。同时,文章还讲解了分布式系统中的CAP理论及其不可能三角关系,以及BASE原则在分布式系统设计中的应用。通过具体案例和图解,帮助读者理解事务处理的核心概念和最佳实践,为应对相关技术面试提供了全面的知识准备。
|
8月前
|
关系型数据库 MySQL 数据库
MySQL事务隔离级别及默认隔离级别的设置
在数据库系统中,事务隔离级别是一个关键的概念,它决定了事务在并发执行时如何相互隔离。MySQL提供了四种事务隔离级别,每种级别都解决了不同的并发问题。本文将详细介绍这些隔离级别以及MySQL的默认隔离级别。

推荐镜像

更多