MongoDB重写

可重写操作

当与数据库网络出现连接问题或在数据库集群主节点切换时不能找到一个正在工作的主节点时,可重试写允许数据库连接驱动再进行一次数据库写入操作。

前置条件

  • 需要复制集或分片集,不支持单节点数据库
  • 可重试写需要存储引擎支持文档级别锁定,如WiredTiger或in-memory引擎
  • 仅支持数据库3.6或以上版本的连接驱动
  • 数据库版本在3.6或以上
  • 数据库驱动写操作设置为无须等待写操作通知时,不支持重写操作

事务中的重写

  • 事务的提交和回滚是可重试操作。当事务提交或回滚发生错误时,mongodb驱动会重试,无论是否设置了可重试写入。
  • 事务中的单个写操作并不是独立可重试的,无论是否设置了可重试写入。数据库库只会在事务提交或回滚时,整个事务重写。

重写设置

  • Mongodb 4.2或以上版本,自动初始化重写。早期版本,需要在数据库连接中显式设置retryWrites=true。

  • 禁止可重试写入操作,在mongodb 4.2或以后版本,需要指定retryWrites=false选项

  • mongosh中默认支持可重试写。在mongosh禁止可重试写时,需要指定retryWrites=false。

    mongosh --retryWrites=false

支持重写的操作

db.collection.insertOne()
db.collection.insertMany()
db.collection.updateOne()
db.collection.replaceOne()
db.collection.deleteOne()
db.collection.remove(),需要设置选项(justOne:true)
db.collection.findAndModify()
db.collection.findOneAndDelete()
db.collection.findOneAndReplace()
db.collection.findOneAndUpdate()
db.collection.bulkWrite()中的单文档写入操作
    insertOne
    updateOne
    replaceOne
    deleteOne
bulkOperation的单文档删除操作
    removeOne()
    replaceOne()

行为

mongodb仅支持重试一次写入操作。用来帮助定位网络问题或数据库主节点重新选择。长时间网络连接问题时,无法重写。数据库驱动在用户设置或系统默认的serverSelectionTimeoutMS内进行重写,超过这个时间不会重试写入。

查看数据库重写统计信息

db.serverStatus()
db.runCommand({"serverStatus": 1})

local数据库的重写

mongodb自4.2版本开始默认支持可重试写入。数据库升级到4.2版本时,向local数据库写入数据会报错,除非显示指定不支持可重试写入。

错误处理

自mongodb 6.1版本开始,如果对单文档操作的两次写入都失败,mongodb会返回一个带有NoWritesPerformed标签的错误。该标签用来区分批量操作的结果。如insertMany()操作

  • 没有文档插入时,返回带有NoWritesPerformed标签错误
  • 部分插入时,返回错误中不带有NoWritesPerform标签
  • 所有文档插入时,返回成功

应用可以使用这个标签来判断是否有文档插入。这个错误是用户获得一个准确的数据插入信息。而在以前版本中,两次写入后直接返回一个错误,无法确定是否有数据插入。

相关推荐
做梦敲代码42 分钟前
达梦数据库-读写分离集群部署
数据库·达梦数据库
dingdingfish1 小时前
JSON 系列之1:将 JSON 数据存储在 Oracle 数据库中
oracle·json·database
小蜗牛慢慢爬行1 小时前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
hanbarger1 小时前
nosql,Redis,minio,elasticsearch
数据库·redis·nosql
微服务 spring cloud2 小时前
配置PostgreSQL用于集成测试的步骤
数据库·postgresql·集成测试
先睡2 小时前
MySQL的架构设计和设计模式
数据库·mysql·设计模式
弗罗里达老大爷2 小时前
Redis
数据库·redis·缓存
仰望大佬0073 小时前
Avalonia实例实战五:Carousel自动轮播图
数据库·microsoft·c#
学不透java不改名3 小时前
sqlalchemy连接dm8 get_columns BIGINT VARCHAR字段不显示
数据库