MongoDB 4.2——持久性
持久性1、使用日志机制的成员级别持久性2、使用写关注的集群级别持久性2.1、writeConcern的w和wtimeout选项2.2、writeConcern的j日志选项3、使用读关注的集群级别持久性4、使用写关注的事务持久性5、MongoDB不能保证什么6、检查数据损坏1、使用日志机制的成员级别持久性为了在服务器发生故障时提供持久性MongoDB 使用了一种称为日志journal的预写式日志WAL机制。WAL 是数据库系统中一种常用的持久性技术其基本原理是在将对数据库所做的更改应用到数据库本身之前将对这些更改的一种表示写到持久介质如磁盘上。在许多数据库系统中WAL 也被用来提供原子性这一数据库属性。然而MongoDB 使用其他技术来确保原子写入。从 MongoDB 4.0 开始当应用程序对副本集执行写操作时MongoDB 会使用与 oplog相同的格式创建日志条目。MongoDB 使用了一种基于操作日志oplog的语句级别的复制机制。oplog 中的语句是对写操作影响的每个文档所做的实际更改的表示。因此oplog 语句很容易应用于副本集的其他成员而无须考虑版本、硬件或副本集成员之间的其他差异。此外每个 oplog 语句都是幂等的这意味着它可以被应用任意次数而对数据库的更改结果总是相同的。像大多数数据库一样MongoDB 同时维护了日志和数据库数据文件的内存视图。默认情况下它每 50 毫秒会将日志条目刷新到磁盘上每 60 秒会将数据库文件刷新到磁盘上。刷新数据文件的 60 秒间隔称为检查点checkpoint​。日志用于为自上一个检查点以来写入的数据提供持久性。关于持久性的问题如果服务器突然停止了那么在其重新启动时可以使用日志重放在关闭前没有刷新到磁盘的所有写操作。对于日志文件MongoDB 在 dbPath 目录下创建了一个名为 journal 的子目录。WiredTigerMongoDB 的默认存储引擎日志文件的名称格式为 WiredTigerLog.sequence其中 sequence 是一个从 0 000 000001 开始的零填充数字。除了非常小的日志记录MongoDB 会对写入日志的数据进行压缩。日志文件的最大大小限制大约为 100MB。一旦日志文件超过这个限制MongoDB 就会创建一个新的日志文件并在其中写入新的记录。由于日志文件只需要在上次检查点之后恢复数据因此在新的检查点写入完成时MongoDB 会自动删除“旧的”日志文件也就是那些在最近检查点之前的写操作。如果服务器崩溃了或使用了 kill -9​那么 mongod会在启动时重放其日志文件。可能发生的写操作丢失有一个最大范围默认情况下是最近 100 毫秒加上将日志刷 新到磁盘所花费的时间内所发生的写操作。如果应用程序需要较短的日志刷新间隔那么有两种方法。一种方法是对 mongod 命令使用--journalCommitInterval选项以更改间隔时间。该选项接受从 1 到 500 毫秒的值。另一种方法是在写关注中指定所有写操作都记录到磁盘。缩短日志刷盘的时间间隔将对性能产生负面影响因此在更改日志记录默认值之前需要确定对应用程序的影响。2、使用写关注的集群级别持久性通过写关注write concern​可以指定应用程序在响应写请求时需要何种级别的确认。在副本集中网络分区、服务器故障或数据中心断电都可能会阻止写操作复制到每个成员甚至大多数成员。当副本集恢复到正常状态时可能会回滚那些未复制到大多数成员的写操作。在这些情况下客户端和数据库可能对已提交的数据有不同的看法。有些应用程序在某些情况下可以接受写操作的回滚。例如在某些社交应用程序中回滚少量的评论不会有什么问题。MongoDB 在集群级别上支持一系列耐久性保证使应用程序设计者能够选择最适合其场景的耐久性级别。2.1、writeConcern的w和wtimeout选项MongoDB 查询语言支持为所有插入和更新方法指定写关注。假设现在有一个电子商务应用程序我们希望确保所有的订单都是持久的。将订单写入数据库的代码如下所示try{db.products.insertOne({sku:H1100335456,item:Electric Toothbrush Head,quantity:3},{writeConcern:{w:majority,wtimeout:100}});}catch(e){print(e);}所有的插入和更新方法都接受第二个参数其格式是一个文档。在该文档中可以为 writeConcern 指定一个值。在前面示例中指定的写关注表示希望得到服务器的确认。这个确认是只有当写入被成功复制到副本集的大多数成员时其才算成功完成。此外如果写操作没有在 100 毫秒或更短的时间内复制到大多数副本集成员则应该返回错误。在这种情况下MongoDB 不会撤销写关注超过时间限制之前成功执行的数据修改而应该由应用程序决定如何处理这种情况下的超时。通常来说应该对wtimeout 值进行配置这样只有在不寻常的情况下应用程序才会超时而应用程序在响应超时错误时所采取的行动将确保数据处于正确的状态。在大多数情况下应用程序应该尝试确定超时是由于网络通信的短暂问题还是其他更严重的原因造成的。写关注文档中 w 参数的值可以指定为 “majority”如本例中那样​。或者也可以指定为一个介于零和副本集成员数量之间的整数。最后还可以指定为副本集成员的标签比如标识那些在 SSD 或机械硬盘上的成员或者标识那些用于报表系统或 OLTP 工作负载的成员。还可以指定标签集合作为 w 的值以确保只有在提交给至少一个与所提供的标签集合匹配的副本集成员时才会对写操作进行确认。2.2、writeConcern的j日志选项除了为 w 选项提供值之外还可以通过在写关注文档中使用 j 选项来要求对写操作的日志写入情况进行确认。如果 j 的值为 true则 MongoDB 只有在请求的成员数w的值都已经将操作写入它们磁盘上的日志中时才会确认写操作成功。继续刚才的例子如果想确保大多数成员的所有写操作记录在日志中则可以像下面这样更新代码try{db.products.insertOne({sku:H1100335456,item:Electric Toothbrush Head,quantity:3},{writeConcern:{w:majority,wtimeout:100,j:true}});}catch(e){print(e);}在不等待日志记录的情况下如果服务器进程或硬件停止运行那么在每个成员上会有一个大约 100 毫秒的短暂的时间窗口可能发生写操作丢失。然而在确认对副本集成员的写操作之前等待日志记录确实会造成性能损失。在解决持久性问题时必须仔细评估应用程序的需求并权衡所选择的持久性设置对性能的影响。3、使用读关注的集群级别持久性在 MongoDB 中读关注read concern允许对何时读取结果进行配置。这可以让客户端在写操作被持久化之前就看到写入的结果。读关注可以与写关注一起使用以控制对应用程序的一致性和可用性的保证级别。不要将读关注与读偏好read preference相混淆后者处理从何处读取数据的问题。具体来说读偏好决定了副本集中承载数据的成员。默认的读偏好是从主节点中读取。读关注决定了正在读取的数据的一致性和隔离性。默认的readConcern 是 local它所返回的数据不保证已经被写入了大多数承载数据的副本集成员。这可能会导致数据在将来的某个时刻被回滚。majority 读关注只返回被大多数副本集成员确认的持久数据不会被回滚​。MongoDB3.4 中增加了 linearizable 读关注它确保返回的数据反 映了在读操作开始之前已成功完成的经过大多数确认的写操作。在返回结果之前它可能会等待那些正在并发执行的写操作完成。和写关注一样在为应用程序选择合适的关注选项之前需要权衡读关注对性能的影响以及它们提供的持久性和隔离性保证。4、使用写关注的事务持久性在 MongoDB 中对单个文档的操作是原子的。可以在单个文档中使用内嵌文档和数组来表示实体之间的关系而不是使用范式化的数据模型将实体和关系拆分到多个集合中。因此很多应用程序不需要多文档事务。然而对于需要原子更新多个文档的场景MongoDB 提供了针对副本集执行多文档事务的能力。多文档事务可以跨多个操作、文档、集合和数据库使用。事务要求其中的所有数据更改都是成功的。如果任何操作失败则事务将中止所有数据更改都会被丢弃。如果所有操作都成功那么事务中所做的所有数据更改都会被保存并且写操作对之后的读操作都是可见的。与单个写操作一样可以为事务指定一个写关注。对于事务来说应该在事务级别而不是单个操作级别设置写关注。在提交时事务会使用事务级别的写关注来提交写操作。为事务内部单个操作设定的写关注会被忽略。可以在事务开始时为事务提交设置写关注。事务不支持将写关注设置为 0。如果对一个事务使用了写关注 1那么如果发生了故障转移则事务可能会回滚。如果在副本集中发生可能导致强制性故障转移的网络和服务器故障则可以使用 “majority” 的 writeConcern 来确保事务在这种情况下的持久性。functionupdateEmployeeInfo(session){employeesCollectionsession.getDatabase(hr).employees;eventsCollectionsession.getDatabase(reporting).events;session.startTransaction({writeConcern:{w:majority}});try{employeesCollection.updateOne({employee:3},{$set:{status:Inactive}});eventsCollection.insertOne({employee:3,status:{new:Inactive,old:Active}});}catch(error){print(Caught exception during transaction, aborting.);session.abortTransaction();throwerror;}commitWithRetry(session);}5、MongoDB不能保证什么MongoDB 在一些情况比如存在硬件问题或文件系统错误下无法保证持久性。特别是如果硬盘损坏则MongoDB 无法保护其中的数据。此外不同种类的硬件和软件可能有不同的持久性保证。例如一些较便宜或较旧的硬盘在写操作排队等待时而不是在实际写入之后就会报告写入成功。MongoDB 在这个级别上无法防止误报如果这时系统崩溃则数据可能会丢失。基本上MongoDB 的安全性与其底层系统相当如果硬件或文件系统破坏了数据则 MongoDB 无法防止这种情况。可以使用复制机制来应对系统问题。如果一台机器出了故障那么希望另一台机器仍能正常工作。6、检查数据损坏validate 命令可用于检查集合是否损坏。要对 movies 集合运行 validate 命令可以执行以下操作db.movies.validate({full:true}){ns:sample_mflix.movies,nInvalidDocuments:NumberLong(0),nrecords:45993,nIndexes:5,keysPerIndex:{_id_:45993,$**_text:3671341,genres_1_imdb.rating_1_metacritic_1:94880,tomatoes_rating:45993,getMovies:45993},indexDetails:{$**_text:{valid:true},_id_:{valid:true},genres_1_imdb.rating_1_metacritic_1:{valid:true},getMovies:{valid:true},tomatoes_rating:{valid:true}},valid:true,warnings:[],errors:[],extraIndexEntries:[],missingIndexEntries:[],ok:1}你要查找的主要字段是 “valid”希望这个字段为 true。否则validate 会给出所发现的数据损坏细节。validate 输出中的大部分内容描述了集合的内部结构以及用于理解跨集群操作顺序的时间戳。这些对于调试来说不是特别有用。​validate 命令只适用于集合它还会检查相关联的索引并记录在 indexDetails 字段中。不过这需要使用 { full:true } 选项来启用完整的 validate。

相关新闻

EncodingChecker:3步解决文件乱码问题的终极指南

EncodingChecker:3步解决文件乱码问题的终极指南

EncodingChecker:3步解决文件乱码问题的终极指南 【免费下载链接】EncodingChecker A GUI tool that allows you to validate the text encoding of one or more files. Modified from https://encodingchecker.codeplex.com/ 项目地址: https://gitcode.com/gh_m…

2026/7/28 17:15:56阅读更多 →
springMVC定义拦截器判断用户是否为管理员

springMVC定义拦截器判断用户是否为管理员

首先是数据库的设计CREATE table tb_user( uId int(11) primary key auto_increment,uName varchar(20) not null,uPassword varchar(20) not null,uPhone varchar(30) not null,uAddress VARCHAR(100) not null,isManager int(1) default 0 -- 1:为管理员 0:不为…

2026/7/28 17:15:56阅读更多 →
早起原来还有这些好处

早起原来还有这些好处

昨天中午吃完午饭散步的时候,看了半佛仙人公众号中推荐的一篇文章《 为什么优秀的人,都把闹钟定在早晨5:57》,感觉写的非常不错,就简单的总结了一下。 早起,是一个非常好的习惯,博主认为这是一件…

2026/7/28 17:15:56阅读更多 →
Playwright自定义Fixtures:解决测试数据管理与环境隔离的工程实践

Playwright自定义Fixtures:解决测试数据管理与环境隔离的工程实践

1. 项目概述:为什么我们需要自定义 Fixtures?如果你在用 Playwright 做自动化测试,大概率已经熟悉了它的test函数和page对象。官方提供的test和page这些内置 Fixtures 确实方便,开箱即用。但当你开始构建一个稍具规模的测试套件时…

2026/7/28 18:22:07阅读更多 →
Ryujinx模拟器终极指南:3步在PC上畅玩Switch游戏

Ryujinx模拟器终极指南:3步在PC上畅玩Switch游戏

Ryujinx模拟器终极指南:3步在PC上畅玩Switch游戏 【免费下载链接】Ryujinx 用 C# 编写的实验性 Nintendo Switch 模拟器 项目地址: https://gitcode.com/GitHub_Trending/ry/Ryujinx 想在电脑上体验Switch独占大作却不知从何入手?Ryujinx模拟器为…

2026/7/28 18:22:07阅读更多 →
gdb 开始调试开始上手

gdb 开始调试开始上手

1. 开启core, 采集程序崩溃的状态 首先你跟着我做开启core崩溃状态采集. 可以通过 ulimit -c 查看 如果是0表示没有开启. 开启按照下面操作 su rootvi /etc/profile Shift G i # No core files by default 0, unlimited is oo ulimit -S -c unlimited > /dev/null 2>&a…

2026/7/28 18:22:07阅读更多 →
EDA 工程师竞业锁定、空窗 2 年:合规赚钱完整方案(零违约风险,杜绝赔付违约金)

EDA 工程师竞业锁定、空窗 2 年:合规赚钱完整方案(零违约风险,杜绝赔付违约金)

EDA 工程师竞业锁定、空窗 2 年:合规赚钱完整方案(零违约风险,杜绝赔付违约金)先确立核心法理底线: 竞业限制禁止三类行为(无论全职 / 兼职 / 外包 / 顾问 / 项目合作)入职存在实质竞争关系的 E…

2026/7/28 18:22:07阅读更多 →
加载jar包中的Properties文件

加载jar包中的Properties文件

通过类加载器获取文件URL通过UrlConnection获取输入流将输入流转化为Properties类输出文件内容以下是输出SpringJar包中所有spring.factories文件内容的程序。Testpublic void getAllMetaInf()throws IOException {//Spring的接口实现类的名字都放在这个文件内,并不…

2026/7/28 18:22:07阅读更多 →
ORM + SQLAlchemy

ORM + SQLAlchemy

ORM SQLAlchemy ORM 对象关系映射 SQLAlchemyTypes IntegerFloatBooleanDateDatetimeStringForeignKey from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Col…

2026/7/28 18:20:07阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/28 4:06:39阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/28 2:08:06阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/28 1:38:28阅读更多 →
告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否也曾为官方Om…

2026/7/28 0:00:29阅读更多 →
RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

做 RAG 的人应该都踩过这个致命的坑:把几百页的财报、法规、技术手册扔给向量库,问一个具体问题,搜出来的全是沾边但没用的内容 —— 关键信息要么被硬切块拆碎了,要么藏在几十条结果的最下面。语义相似≠真正相关,这个…

2026/7/28 0:00:29阅读更多 →
抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

2026年做短视频运营,从抖音上扒文案早就不是偷偷抄笔记的事了。我刚开始做内容的时候,每天刷半小时抖音,手动把爆款视频的口播敲进备忘录,一条2分钟的视频得花十来分钟,碰到语速快的还要反复回听。后来试了一圈工具&am…

2026/7/28 0:00:29阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/27 16:57:54阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/28 3:17:03阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/28 2:35:58阅读更多 →