- MongoDB官方文档中文版
- MongoDB中文手册说明
- MongoDB简介
- 安装 MongoDB
- The mongo Shell
- MongoDB CRUD 操作
- 聚合
- 数据模型
- 事务
- 索引
- 安全
- 安全检查列表
- 启用访问控制
- 身份验证
- 基于角色的访问控制
- TLS / SSL(传输加密)
- 静态加密
- 客户端字段级加密
- 审计
- 网络和配置强化
- 实现字段级别修订
- 安全参考
- 附录
- 变更流
- 复制
- 分片
- 分片键
- 哈希分片
- 范围分片
- 区
- 管理分片区
- 按位置细分数据
- 用于更改SLA或SLO的分层硬件
- 按应用或客户细分数据
- 仅插入工作负载的分布式本地写入
- 管理分片区
- 使用块进行数据分区
- 在分片集群中拆分数据块
- 管理
- 存储
- 存储引擎
- 日志记录
- 管理日志记录
- GridFS
- FAQ:MongoDB 存储
- 存储引擎
- 参考
- 运算符
- 查询与映射运算符
- 更新运算符
- 聚合管道阶段
- 聚合管道操作符
- $abs (aggregation)
- $acos (aggregation)
- $acosh (aggregation)
- $add (aggregation)
- $addToSet (aggregation)
- $allElementsTrue (aggregation)
- $and (aggregation)
- $anyElementTrue (aggregation)
- $arrayElemAt (aggregation)
- $arrayToObject (aggregation)
- $asin (aggregation)
- $asinh (aggregation)
- $atan (aggregation)
- $atan2 (aggregation)
- $atanh (aggregation)
- $avg (aggregation)
- $ceil (aggregation)
- $cmp (aggregation)
- $concat (aggregation)
- $concatArrays (aggregation)
- $cond (aggregation)
- $convert (aggregation)
- $cos (aggregation)
- $dateFromParts (aggregation)
- $dateToParts (aggregation)
- $dateFromString (aggregation)
- $literal (aggregation)
- 查询修饰符
- 数据库命令
- 聚合命令
- 地理空间命令
- 查询和写操作命令
- 查询计划缓存命令
- 认证命令
- 用户管理命令
- 角色管理命令
- 复制命令
- 分片命令
- 会话命令
- 管理命令
- 诊断命令
- 免费监控命令
- 系统事件审计命令
- mongo Shell 方法
- 集合方法
- db.collection.aggregate()
- db.collection.bulkWrite()
- db.collection.copyTo()
- db.collection.count()
- db.collection.countDocuments()
- db.collection.estimatedDocumentCount()
- db.collection.createIndex()
- db.collection.createIndexes()
- db.collection.dataSize()
- db.collection.deleteOne()
- db.collection.deleteMany()
- db.collection.distinct()
- db.collection.drop()
- db.collection.dropIndex()
- db.collection.dropIndexes()
- db.collection.ensureIndex()
- db.collection.explain()
- db.collection.find()
- db.collection.findAndModify()
- db.collection.findOne()
- db.collection.findOneAndDelete()
- db.collection.findOneAndReplace()
- db.collection.findOneAndUpdate()
- db.collection.getIndexes()
- db.collection.getShardDistribution()
- db.collection.getShardVersion()
- db.collection.insert()
- db.collection.insertOne()
- db.collection.insertMany()
- db.collection.isCapped()
- db.collection.latencyStats()
- db.collection.mapReduce()
- db.collection.reIndex()
- db.collection.remove()
- db.collection.renameCollection()
- db.collection.replaceOne()
- db.collection.save()
- db.collection.stats()
- db.collection.storageSize()
- db.collection.totalIndexSize()
- db.collection.totalSize()
- db.collection.update()
- db.collection.updateOne()
- db.collection.updateMany()
- db.collection.watch()
- db.collection.validate()
- 词汇表
- 默认的MongoDB端口
- 默认的MongoDB读/写关注
- 服务器会话
- MongoDB驱动
- FAQ
- 联系我们
- 更多资料
- [快学Mongo]
- [Mongo问题讨论区]
- [Mongo 驱动使用手册]
- 本书使用 GitBook 发布
可重试写入
可重试写入
在本页面
3.6版的新功能
可重试写入允许MongoDB驱动程序在遇到网络错误或在复制集或分片群集中找不到正常的主操作时自动重试特定的写操作一次。
前提条件
可重试写入具有以下要求:
支持的部署Topologie
支持的存储引擎
可重试写入需要支持文档级锁定的存储引擎,例如WiredTiger或内存中 存储引擎。
3.6+ MongoDB驱动程序
客户端需要为MongoDB 3.6或更高版本更新的MongoDB驱动程序:
Java 3.6+ Python 3.6+ C 1.9+ | C# 2.5+ Node 3.0+ Ruby 2.5+ | Perl 2.0+ PHPC 1.4+ Scala 2.2+ |
---|---|---|
MongoDB版本
集群中每个节点的MongoDB版本必须为3.6或更高,集群中每个节点的featureCompatibilityVersion必须为3.6或更高。有关featureCompatibilityVersion标志的更多信息,请参见setFeatureCompatibilityVersion。
写确认书
Write Concern
为0的写操作是不可重试的。
可重试写入和多文档交易
版本4.0中的新功能
事务提交和中止操作是可重试的写操作。如果提交操作或中止操作遇到错误,MongoDB驱动程序将重试操作一次,而不管retryWrites
是否被设置为false。
有关交易的更多信息,请参见Transactions。
启用可重试写入
MongoDB驱动程序
官方的MongoDB 3.6和4.0兼容驱动程序需要在连接字符串中包含retryWrites=true
选项,以启用该连接的可重试写操作。
官方的MongoDB 4.2兼容驱动程序在默认情况下启用了可重试写。升级到与4.2兼容的驱动程序,要求可重试写的应用程序可能会忽略retryWrites=true
选项。升级到与4.2兼容的驱动程序,要求禁用可重试写的应用程序必须在连接字符串中包含retryWrites=false
。
Mongo shell
要在mongo shell中启用可重试写入,请使用--retryWrites
命令行选项:
mongo --retryWrites
可重试的写操作
当发出已确认的写关注时,可以重试以下写操作; 例如,Write Concern
不能为{w:0}。
[success] Note
事务中的写操作不能单独重试。
方法 | 说明 |
---|---|
db.collection.insertOne() db.collection.insert() db.collection.insertMany() | 插入操作 |
db.collection.updateOne()
db.collection.replaceOne()
db.collection.save()
db.collection.update() where multi is false | 单文档更新操作。 |
db.collection.deleteOne() db.collection.remove() where justOne is true | 单个文档删除操作 |
db.collection.findAndModify() db.collection.findOneAndDelete() db.collection.findOneAndReplace() db.collection.findOneAndUpdate() | findAndModify操作。所有findAndModify操作都是单个文档操作。 |
db.collection.bulkWrite() 具有以下写操作: . insertOne . updateOne . replaceOne . deleteOne | 只包含单文档写操作的批量写操作。可重试的大容量操作可以包括指定的写操作的任何组合,但不能包括任何多文档写操作,比如updateMany。 |
Bulk operations for: . Bulk.find.removeOne() . Bulk.find.replaceOne() . Bulk.find.replaceOne() | 仅由单文档写操作组成的批量写操作。可重试的大容量操作可以包括指定的写操作的任何组合,但不能包括任何多文档写操作,比如update,它为multi选项指定true。 |
分片键值更新
从MongoDB 4.2开始,您可以通过发布可重试写入或事务处理中的单文档update / findAndModify操作来更新文档的分片键值(除非分片键字段是不可变的_id字段)。 有关详细信息,请参见更改文档的分片键值.。
- MongoDB 4.2将重试遇到重复密钥异常的某些单文档upsert(更新使用upsert:true和multi:false)。 有关条件,请参阅 Duplicate Key Errors on Upsert .
- 在MongoDB 4.2之前,MongoDB不会重试遇到重复键错误的upsert操作。
行为
持续的网络错误
MongoDB可重试写只做一次重试尝试。这有助于解决暂时的网络错误和复制集选举,但不能解决持久的网络错误。
故障转移期
如果驱动程序在目标复制集中或分片集群分片中找不到正常的主服务器,则驱动程序在重试之前会等待serverSelectionTimeoutMS
毫秒来确定新的主服务器。可重试写操作不会处理故障转移周期超过serverSelectionTimeoutMS
的实例。
[warning] Warning
如果客户端应用程序在发出写操作后的时间超过
localLogicalSessionTimeoutMinutes
,那么当客户端应用程序开始响应时(无需重新启动),可能会重试并再次应用写操作。
Upsert上的重复键错误
MongoDB 4.2将重试单文档的upsert操作(即:upsert: true和multi: false)由于重复的键错误而失败,只有当操作满足以下所有条件:
目标集合具有导致重复键错误的唯一索引。
更新匹配条件为:
- 单个相等谓词
{ "fieldA" : "valueA" },
- 相等谓词的逻辑
{ "fieldA" : "valueA", "fieldB" : "valueB" }
唯一索引键模式中的字段集与更新查询谓词中的字段集匹配。
更新操作不会修改查询谓词中的任何字段。
下表包含服务器可以或不能在重复键错误时重试的upsert操作示例:
唯一索引键模式 | 更新操作 | 可重试 |
---|---|---|
{ _id : 1 } | db.collName.updateOne( { _id : ObjectId("1aa1c1efb123f14aaa167aaa") }, { $set : { fieldA : 25 } }, { upsert : true } ) | 是 |
{ fieldA : 1 } | db.collName.updateOne( { fieldA : { $in : [ 25 ] } }, { $set : { fieldB : "someValue" } }, { upsert : true } ) | 是 |
{ fieldA:1, fieldB :1 } | db.collName.updateOne( { fieldA : 25, fieldB : "someValue" }, { $set : { fieldC : false } }, { upsert : true } ) | 是 |
{ fieldA : 1 } | db.collName.updateOne( { fieldA : { $lte : 25 } }, { $set : { fieldC : true } }, { upsert : true } ) | 没有 查询谓词fieldA不等于 |
{ fieldA : 1 } | db.collName.updateOne( { fieldA : { $in : [ 25 ] } }, { $set : { fieldA : 20 } }, { upsert : true } ) | 没有 更新操作修改查询谓词中指定的字段。 |
{ _id : 1 } | db.collName.updateOne( { fieldA : { $in : [ 25 ] } }, { $set : { fieldA : 20 } }, { upsert : true } ) | 没有 查询谓词字段集(fieldA)与索引关键字字段集()不匹配_id。 |
{ fieldA : 1 } | db.collName.updateOne( { fieldA : 25, fieldC : true }, { $set : { fieldD : false } }, { upsert : true } ) | 没有 这组查询谓词的字段(fieldA,fieldC)不匹配组索引键的字段(fieldA) |
在MongoDB 4.2之前,MongoDB可重试写不支持由于重复的键错误而失败的重试更新。
诊断程序
版本3.6.3中的新功能
serverStatus
命令及其mongo shell帮助程序 db.serverStatus()
在transactions
节中包含有关可重试写入的统计信息。
针对本地数据库的可重试写入
官方的MongoDB 4.2系列驱动程序默认情况下启用重试写入。 除非明确禁止重试写入,否则写入本地数据库的应用程序在升级到4.2系列驱动程序时将遇到写入错误。
要禁用可重试写入,请在MongoDB集群的连接字符串中指定retryWrites=false
。
译者:杨帅
校对:杨帅
Copyright © 上海锦木信息技术有限公司 all right reserved,由 MongoDB汉化小组 提供技术支持文件修订时间: 2020-10-11 20:53:05