阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

MongoDB遇到疑似数据丢失的问题不要用InsertMany!

440次阅读
没有评论

共计 2984 个字符,预计需要花费 8 分钟才能阅读完成。

最近做数据备份的时候发现了有个很严重的问题,那就是数据丢失(最后证明没丢,是别的问题造成的)。

问题如下:

我通过两种方式在两个 mongoDB 集群中,对一组 collection 进行备份,最后 2 个备份数据的数据个数不相同,并且都小于原始 collection 的 count 结果。于是便开始寻求解决办法,流程如下:

1、记录 3 组数据,原始数据集按条件 count 有 909217 个数据,备份代码如下,其中 replaceOne 备份下来的数据有 907582 条,而使用 insertMany 备份下来的结果有 906281 条(注释是之后加的,之前用的是 insertMany):

    rdd.foreachPartition {x => {       
        val mongoURI = new MongoClientURI(uri)
            val mongo = new MongoClient(mongoURI)
            val db = mongo.getDatabase(“wenshu”)
            val dbColl = db.getCollection(“testbackup”)
                       
            val mongoURI2 = new MongoClientURI(uri2)
            val mongo2 = new MongoClient(mongoURI2)
            val db2 = mongo2.getDatabase(“wenshu”)
            val dbColl2 = db2.getCollection(backName)
           
            var count = 0
            var resList = new ArrayList[Document]
            x.foreach(y => {
//              count = count + 1
//              resList add y
                try{
                    dbColl.replaceOne(eqq(“_id”, y.get(“_id”)), y, new UpdateOptions().upsert(true))
                    dbColl2.insertOne(y)
                }catch{
                    case e: Throwable => e.printStackTrace()
                }
               
//              使用这种方式插入会导致插入的数据和真实数据数量对应不上,先注释掉有机会再找原因
//              if (count == 10000){
//                  try{
//                      dbColl2.insertMany(resList, new InsertManyOptions().ordered(false))
//                  }catch{
//                      case e: Throwable => e.printStackTrace()
//                  }
//                  resList.clear
//                  count = 0
//              }
            })
//          if (count > 0)
//              try{
//                  dbColl2.insertMany(resList, new InsertManyOptions().ordered(false))
//              }catch{
//                  case e: Throwable => e.printStackTrace()
//              }

2、通过查询 stackoverflow 和 jira 发现数据丢失问题曾经存在过,但都是 2.0 之前的 mongodb,现在商用化之后的 mongodb 基本没人出现过数据丢失问题。

3、检查代码,发现不是插入代码错误。

4、对抽出来的 907582 条数据的库进行备份,还是用上述程序,发现 replaceOne 的数据有 907582,而 insertmany 只有 904291 条数据。

5、结合上述条件,推测是 insertMany 导致部分数据丢失,所以才会出现 insertMany 结果和 replaceOne 不一样。

6、对此结论进行测试,将 insertMany 改为上述代码中的 insertOne 重新备份 907582 条数据。

7、结果正确,重新备份下来的 2 份数据都是 907582 条。目前解决了其中一个问题,就是备份出来的两份数据不一样多的问题,接下来考虑备份数据和从总库中抽取的数据不一致的问题。

8、对 mongo shell 的 count 操作查找其工作原理,发现有一些报告 count 数据不准的问题,结合自身原因推测是 count 的问题,数据应该只有 907582 条。

9、通过多抽取几遍对这个问题进行测试,按同样条件抽了 3 遍返回的结果都是 907582 条,可以认定数据库中只有 907582 条满足此条件的数据。

结论:

1、MongoDB 的 Count 操作有可能返回错误的结果。至少在 Sharding Cluster,多个索引和 2 级索引的条件下会出现这种问题。

2、插入时不要使用 InsertMany,会导致数据丢失。

3、同理,尽量不要使用 updateMany,虽然不会导致数据丢失,但是按照结论 2 推测有可能出现某些数据更新失败的情况。

更多 MongoDB 相关教程见以下内容

MongoDB 文档、集合、数据库简介  http://www.linuxidc.com/Linux/2016-12/138529.htm

MongoDB 3 分片部署及故障模拟验证  http://www.linuxidc.com/Linux/2016-12/138529.htm

Linux CentOS 6.5 yum 安装 MongoDB  http://www.linuxidc.com/Linux/2016-12/137790.htm

CentOS 7 yum 方式快速安装 MongoDB  http://www.linuxidc.com/Linux/2016-11/137679.htm

MongoDB 的查询操作  http://www.linuxidc.com/Linux/2016-10/136581.htm

在 Azure 虚拟机上快速搭建 MongoDB 集群  http://www.linuxidc.com/Linux/2017-09/146778.htm

MongoDB 复制集原理  http://www.linuxidc.com/Linux/2017-09/146670.htm

MongoDB 3.4 远程连接认证失败  http://www.linuxidc.com/Linux/2017-06/145070.htm

Ubuntu 16.04 中安装 MongoDB3.4 数据库系统  http://www.linuxidc.com/Linux/2017-07/145526.htm

MongoDB 权威指南第 2 版 PDF 完整带书签目录 下载见 http://www.linuxidc.com/Linux/2016-12/138253.htm

MongoDB 的详细介绍:请点这里
MongoDB 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-12/149535.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计2984字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19348
评论数
4
阅读量
7796778
文章搜索
热门文章
开发者必备神器:阿里云 Qoder CLI 全面解析与上手指南

开发者必备神器:阿里云 Qoder CLI 全面解析与上手指南

开发者必备神器:阿里云 Qoder CLI 全面解析与上手指南 大家好,我是星哥。之前介绍了腾讯云的 Code...
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
云服务器部署服务器面板1Panel:小白轻松构建Web服务与面板加固指南

云服务器部署服务器面板1Panel:小白轻松构建Web服务与面板加固指南

云服务器部署服务器面板 1Panel:小白轻松构建 Web 服务与面板加固指南 哈喽,我是星哥,经常有人问我不...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
星哥带你玩飞牛NAS-13:自动追番、订阅下载 + 刮削,动漫党彻底解放双手!

星哥带你玩飞牛NAS-13:自动追番、订阅下载 + 刮削,动漫党彻底解放双手!

星哥带你玩飞牛 NAS-13:自动追番、订阅下载 + 刮削,动漫党彻底解放双手! 作为动漫爱好者,你是否还在为...
从“纸堆”到“电子化”文档:用这个开源系统打造你的智能文档管理系统

从“纸堆”到“电子化”文档:用这个开源系统打造你的智能文档管理系统

从“纸堆”到“电子化”文档:用这个开源系统打造你的智能文档管理系统 大家好,我是星哥。公司的项目文档存了一堆 ...
在Windows系统中通过VMware安装苹果macOS15

在Windows系统中通过VMware安装苹果macOS15

在 Windows 系统中通过 VMware 安装苹果 macOS15 许多开发者和爱好者希望在 Window...
小白也能看懂:什么是云服务器?腾讯云 vs 阿里云对比

小白也能看懂:什么是云服务器?腾讯云 vs 阿里云对比

小白也能看懂:什么是云服务器?腾讯云 vs 阿里云对比 星哥玩云,带你从小白到上云高手。今天咱们就来聊聊——什...
支付宝、淘宝、闲鱼又双叕崩了,Cloudflare也瘫了连监控都挂,根因藏在哪?

支付宝、淘宝、闲鱼又双叕崩了,Cloudflare也瘫了连监控都挂,根因藏在哪?

支付宝、淘宝、闲鱼又双叕崩了,Cloudflare 也瘫了连监控都挂,根因藏在哪? 最近两天的互联网堪称“故障...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
星哥带你玩飞牛NAS-5:飞牛NAS中的Docker功能介绍

星哥带你玩飞牛NAS-5:飞牛NAS中的Docker功能介绍

星哥带你玩飞牛 NAS-5:飞牛 NAS 中的 Docker 功能介绍 大家好,我是星哥,今天给大家带来如何在...
支付宝、淘宝、闲鱼又双叕崩了,Cloudflare也瘫了连监控都挂,根因藏在哪?

支付宝、淘宝、闲鱼又双叕崩了,Cloudflare也瘫了连监控都挂,根因藏在哪?

支付宝、淘宝、闲鱼又双叕崩了,Cloudflare 也瘫了连监控都挂,根因藏在哪? 最近两天的互联网堪称“故障...
手把手教你,购买云服务器并且安装宝塔面板

手把手教你,购买云服务器并且安装宝塔面板

手把手教你,购买云服务器并且安装宝塔面板 前言 大家好,我是星哥。星哥发现很多新手刚接触服务器时,都会被“选购...
把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地

把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地

把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地 大家好,我是星哥,今天教大家在飞牛 NA...
星哥带你玩飞牛NAS-13:自动追番、订阅下载 + 刮削,动漫党彻底解放双手!

星哥带你玩飞牛NAS-13:自动追番、订阅下载 + 刮削,动漫党彻底解放双手!

星哥带你玩飞牛 NAS-13:自动追番、订阅下载 + 刮削,动漫党彻底解放双手! 作为动漫爱好者,你是否还在为...