MongoDB 事务与数据落盘

news2024/9/21 16:31:41

文章目录

    • 概要
    • 一、持久性
        • 1.1、journal log刷盘机制
        • 1.2、数据刷盘机制
        • 1.3、复制集下的写安全机制
    • 二、隔离性
    • 总结

概要

MongoDB并不像MySQL一样天然支持多文档事务,其演变过程如下:

  • MongoDB4.0之前只支持单文档事务,在单个文档上支持ACID原子性,并且不对外暴漏API,用户无法控制事务,完全是MongoDB自行控制;
  • MongoDB4.0开始支持多文档事务以及复制集和分片集群下的事务,统称为分布式事务,并提供API允许用户像MySQL事务那样控制事务的开始与结束。

但是MongoDB4.0的事务仍有限制:

  1. 事务的默认最大运行时间是 60s。
    1)通过在 mongod 实例级别上修改transactionLifetimeLimitSeconds 的限制来增加。对于分片集群,必须在所有分片副本集成员上设置该参数。超过此时间后,事务将被视为已过期,并由定期运行的清理进程中止。清理进程每 60 秒或每 transactionLifetimeLimitSeconds/2 运行一次,以较小的值为准。
    2)要显式设置事务的时间限制,建议在提交事务时指定 maxTimeMS 参数。如果 maxTimeMS 没有设置,那么将使用 transactionLifetimeLimitSeconds;如果设置了 maxTimeMS,但这个值超过了 transactionLifetimeLimitSeconds,那么还是会使用 transactionLifetimeLimitSeconds。
    3)事务等待获取其操作所需锁的默认最大时间是 5 毫秒。可以通过修改由maxTransactionLockRequestTimeoutMillis 参数控制的限制来增加。如果事务在此期间无法获得锁,则该事务会被中止。maxTransactionLockRequestTimeoutMillis 可以设置为 0、-1 或大于 0 的数字。将其设置为 0 意味着,如果事务无法立即获得所需的所有锁,则该事务会被中止。设置为 -1 将使用由 maxTimeMS 参数所指定的特定于操作的超时时间。任何大于 0 的数字都将等待时间配置为该时间(以秒为单位)以作为事务尝试获取所需锁的指定时间段。

  2. MongoDB 将当前事务中的所有写操作日志放入单文档中,而oplog只是一个特殊的collection,其单个文档也象正常集合一样受16MB的大小限制。这个限制在MongoDB4.2做了很大的优化,即调整成为当前事务中的每一个写操作日志都创建一个单文档。

综上两点限制,不管如何还是要避免长事务与大事务。

MongoDB的oplog相当于MySQL的binlog,用于主备节点数据复制
MongoDB的journal log相当于MySQL的redo log,用于实现事务持久性,尽量保证数据不丢失以及崩溃恢复

事务的四大特性这里就不多说了,这里主要聊一下MongoDB的事务持久性与隔离性。

PS:针对MongoDB的WiredTiger存储引擎

一、持久性

持久性是指一个事务提交后,其所做的写操作会被永久保存到数据库中,即使此时数据库or操作系统崩溃,修改的数据也不会丢失。
下面我们来看看MongoDB事务持久性是否是这样的,先看一下下图:

MongoDB数据落盘示意图
我们已经知道journal log记录的是最新的写操作内容,即redo,所以只要写的内容到了journal log,MongoDB就可以在崩溃重启后恢复。

1.1、journal log刷盘机制

journal log主要受两个配置参数控制。

storage:
   journal:
      enabled: <boolean>  #是否开启journal log
      commitIntervalMs: <num> #journal log刷盘的间隔,默认100ms,范围是1-500ms,值越小,丢失数据越少,性能越低;

除了配置文件,也可以通过如下命令调整journalCommitInterval的值:

db.adminCommand({"setParameter":1,"journalCommitInterval":10}); #设置为10ms

可知最多有journalCommitIntervalms的数据丢失。

另外在db.collection.insert({x:1}, {writeConcern: {j: true}})写命令中可以通过设置 j 的值为true来确保该语句的journal log刷盘。当然这并不意味着每一个写操作就等于一个IO。MongoDB并不会对每一个操作都立即刷盘,而是会等最多30ms,把30ms内的写操作集中到一起,采用顺序追加的方式写入到盘里。在这30ms内客户端线程会处于等待状态。这样对于单个操作的总体响应时间将有所延长,但对于高并发的场景,综合下来平均吞吐能力和响应时间不会有太大的影响。特别是你能给journal部署一个对顺序写有优化的IO带宽足够的专门的存储系统的话,这个对性能的影响可以降到最低。

还有就是缓冲区buffer中的journal log大小达到100MB(因为journal log文件的大小限制是100MB)也会触发刷盘。

总共三种,可以看到在写操作语句中指定j: true可确保journal log刷盘,保证数据不丢失。

1.2、数据刷盘机制

MongoDB的数据刷盘也有和MySQL一样的checkpoint机制,触发条件如下:

  • 按一定时间周期(由storage.syncPeriodSecs控制):默认60s,执行一次checkpoint;
  • 按journal log文件大小:当journal log文件大小达到2GB(如果已开启),执行一次checkpoint;

从数据刷盘机制可知,MongoDB的持久性只要靠journal log保证。

1.3、复制集下的写安全机制

db.collection.insert({x:1}, {writeConcern: {w: 1}}) #默认w值为1
  1. {w:0} 即Unacknowledged
    Unacknowledged指的是对每一个写入操作,MongoDB并不会返回一个是否成功的状态值。这个级别是写入性能最好但也是最不安全的级别。比如说,你试图插入一个违反了唯一性的文档(重复的身份证号),那么MongoDB会拒绝写入并报错。但是由于驱动端并没有在乎你的报错,应用程序还满心欢喜以为一切都没问题,下回再来查询那条数据的时候就会出现数据缺失的情况。
  2. {w:1} 即Acknowledged
    Acknowledged 的意思就是对每一个写入MongoDB都会确认操作的完成状态,不管是成功还是失败。当然这个确认只是基于主节点的内存写入。但是这个级别,已经可以侦测到重复主键, 网络错误,系统故障或者是无效数据等错误。
  3. {w:“majority”} 写到多数节点
    MongoDB 的默认部署是至少3个节点的复制集(Replicaset),使用复制集的好处很多,最关键的就是提高系统的高可用性。但是也带来了一个问题,主备不一致,该参数就可以很好的解决该问题。
    假设复制集中有A、B、C三个节点,A为主节点,此时w=1,那么:
    1)在A接收一个写命令x并返回成功时,A与B,C失联了;
    2)下一刻A发现自己无法和从节点B,C 联络上,主动降级为从节点,停止接受写操作;
    3)B、C选举出B为主节点,接收客户端请求,稍后网络恢复A节点重新加入复制集。这个时候A的oplog 和B的oplog已经有不一致了。A会主动把B上面不存在的写操作回滚掉(rollback),并写入一个回滚文件。
    这个时候应用如果再去查询写命令x的内容,MongoDB 将会说文档不存在,w=majority就避免了该问题。

所以说,可以通过w和j的值合理安排自己所需要的数据安全级别和性能要求。

二、隔离性

隔离性其实很好理解,即一个事务所做的写操作在它提交之前,对于其他事务是不可见的。那A事务修改了id=5的数据后B事务如何还能读到未修改数据呢,当然是记录下历史数据了,但是记录历史数据这个实现有两大流派,James Gray老爷子 的undo log流派和Michael Stonebraker老爷子的多版本派,二者在增删改上各有千秋。

所以说,MongoDB是没有undo log的,事务回滚是靠多版本,不像MySQL,SQLServer等会有undo log 段。

总结

待续…

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/736264.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

S32K14x FlexCAN入门

每个系列S32K14x支持的邮箱个数。 基本每个系列的FlexCAN0可以支持32个报文缓存和支持CANFD。 中断源 mail 最多有32个mail • 灵活的消息缓冲区 (MB)&#xff0c;总共 32 个消息缓冲区&#xff0c;数据长度为 8 字节 每个&#xff0c;可配置为 Rx 或 Tx 过滤掩码功能 强…

MyBatis中的缓存介绍与示例

目录 什么是缓存&#xff1f; 一级缓存 实例效果 二次缓存 示例效果 什么是缓存&#xff1f; 在用户访问相同数据时&#xff0c;需要对数据库多次访问&#xff0c;导致产生大量IO、读写硬盘的操作&#xff0c;效率低下&#xff0c;有了缓存首次访问时&#xff0c;查询到数…

【AI 绘图】Stable Diffusion WebUI 本地安装教程(Windows,兼容 NVIDIA、AMD 显卡)

文章目录 硬性要求Stable Diffusion 简介Stable Diffusion WebUI 简介1. 安装 Python 3.10.6&#xff08;较新版本的 Python 不支持 torch&#xff09;2. 安装 Git3. 下载 stable-diffusion-webui 存储库&#xff08;此步二选一&#xff09;3.1 NVIDIA GPU3.2 AMD GPU 4. webui…

Unity 3D 刚体初步

Unity 3D 中的 Rigidbody &#xff0c;刚体&#xff0c;是用来模拟物理特性&#xff0c;模拟推力与扭力&#xff0c;实现现实世界中的物理学现象。 把在外力作用下&#xff0c;物体的形状和大小保持不变&#xff0c;而且内部各部分相对位置保持恒定&#xff08;没有形变&#…

2.zabbxi操作和设置

文章目录 zabbxi操作和设置添加zabbix-agent客户端web端添加客户端 自定义监控模板&#xff08;面试&#xff09;监控模板下载地址案例1案例2 设置邮件报警自动注册和自动发现自动发现&#xff08;对于agent是被动模式&#xff09;自动注册&#xff08;对于agent是主动模式&…

把同组人做的工作写在自己简历上,算造假吗?知道这个需求不是我做的人,这个世界可能不超过10个人!...

把同组人做的东西写在自己简历上&#xff0c;算造假吗&#xff1f; 一位网友问&#xff1a; 同组人做的需求&#xff0c;需求细节我完全可以讲得清楚。知道这个需求不是我做的人&#xff0c;全世界可能不超过10个人&#xff0c;我把这个需求写在自己简历上算简历造假吗&#xf…

go数据结构之slice与map

1. 切片 1. 切片结构定义 type slice struct {array unsafe.Pointerlen intcap int }array:引用的底层数组&#xff0c;动态数组&#xff0c;可以修改 如果多个切片的array指针指向同一个动态数组&#xff0c;则它们都可以对底层这个动态数组元素进行修改。 len:&#xf…

电商平台怎么搭建

越来越多商家致力于搭建并运营自己的私域电商平台&#xff0c;大家都清楚了解拥有自己电商平台的好处。有利于品牌的塑造与提升&#xff0c;提高品牌曝光度和认知度&#xff0c;提高客户黏性&#xff0c;降低渠道成本。 乔拓云平台模板式搭建电商平台&#xff0c;方法简单实用…

【Linux实验】I/O接口实验(Vmware虚拟机、S5P6818开发板)

这里写目录标题 一、实验目的二、实验内容三、实验设备四、实验步骤五、总结 一、实验目的 掌握S5P6818芯片的I/O口控制寄存器的配置。掌握实验掌握ARM芯片使用I/O口控制LED显示。熟练使用嵌入式交叉编译器。掌握Makefile文件书写。 二、实验内容 编写程序控制实验平台的发光…

ISCSI网络存储服务

ISCSI网络存储服务 应用场景&#xff1a; 服务器硬盘空间不足&#xff0c;可能导致服务器宕机。解决方案通常有两个&#xff0c;一是拷贝出服务器中的部分数据&#xff0c;空出存储空间&#xff0c;但在生产环境中&#xff0c;数据一般会很大&#xff0c;拷贝时间会很长&…

Kubernetes 的内部架构和工作机制

Kubernetes 是一个生产级别的容器编排平台和集群管理系统&#xff0c;能够创建、调度容器&#xff0c;监控、管理服务器。 操作系统的一个重要功能就是抽象&#xff0c;从繁琐的底层事务中抽象出一些简洁的概念&#xff0c;然后基于这些概念去管理系统资源。 Kubernetes 也是…

时间序列预测 | Matlab灰狼算法(GWO)优化极限梯度提升树XGBoost时间序列预测,GWO-XGBoost时间序列预测模型,单列数据输入模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 时间序列预测 | Matlab灰狼算法(GWO)优化极限梯度提升树XGBoost时间序列预测,GWO-XGBoost时间序列预测模型,单列数据输入模型 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及…

AD为什么使用不了Keepout层来画板框(技巧分享)

AD为什么使用不了Keepout层 背景&#xff1a;keepout层作为板框层&#xff0c;是以前AD10的老版本延续下来的习惯&#xff0c;在新版本上需要单独放置&#xff01; 在嘉立创平台上&#xff0c;习惯了用一个机械1层作为板框。当使用带有添加3D封装的pcb库&#xff0c;发现上面的…

Excel的技术分享

导出Excel的技术分享 Excel前置知识 首先大家就是在大学的计算机导论等课程肯定有了解过office全家桶中的工具之一Excel。在印象当中就是Excel是普遍使用的就是有03和07的两个不同的版本。请问一下大家就是能说一说就是这两个版本有什么区别吗&#xff1f; 显而易见就是从了直…

Elasticsearch【安装ES服务、安装kibana、Docker安装 、索引操作、文档操作】(二)-全面详解(学习总结---从入门到深化)

目录 Elasticsearch安装_安装ES服务 Elasticsearch安装_安装kibana Elasticsearch安装_Docker安装 Elasticsearch常用操作_索引操作 Elasticsearch常用操作_文档操作 Elasticsearch安装_安装ES服务 准备工作 1、 准备一台搭载有CentOS7系统的虚拟机&#xff0c;使用XSh…

(转载)支持向量机(SVM)的回归拟合(matlab实现)

与传统的神经网络相比&#xff0c;SVM具有以下几个优点&#xff1a; (1)SVM是专门针对小样本问题而提出的&#xff0c;可以在有限样本的情况下获得最优解。 (2)SVM算法最终将转化为一个二次规划问题&#xff0c;从理论上讲可以得到全局最优解&#xff0c;从而解决了传统神经网…

Python GUI编程利器:Tkinker中的布局管理器(10)

小朋友们好&#xff0c;大朋友们好&#xff01; 我是猫妹&#xff0c;一名爱上Python编程的小学生。 和猫妹学Python&#xff0c;一起趣味学编程。 今日目标 学习Tkinter的三个布局管理器&#xff1a; pack布局管理器 gird布局管理器 place布局管理器 啥是布局管理器&am…

TCP流套接字编程(模拟多个客户端与服务器交互)

目录 一、ServerSocket API 1.1、ServerSocket构造方法 1.2、ServerSocket方法 二、Socket API 2.1、socket构造方法 2.2、socket方法 三、TCP 中的长短连接 四、示例 实现聊天室功能 五、存在的问题 一、ServerSocket API ServerSocket 是创建TCP服务端Socket的…

500个线程运行串行原因排查

场景&#xff1a;项目中有业务需要开启500个线程执行&#xff0c;需要证明有500个线程在执行。用的是一台128核的电脑。服务用docker启动的。所以理论上应该是要有128个线程并行执行的。 目录 一.证明有500个线程在执行(会发现并行度很低) 1.用top命令监控进程内的线程运行情…

netty学习(5):netty实现注册中心和发送JSON数据到指定的客户端

1. 实现&#xff1a;在netty客户端实现netty客户端注册功能&#xff0c;netty客户端需要发送注册消息到netty服务端。 2. 在父工程创建Message类&#xff0c;定义消息格式和消息类型 定义消息类型&#xff1a; package message;public enum MessageType {RegisterRequest,Re…