博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MongoDB遇到的疑似数据丢失的问题。不要用InsertMany!
阅读量:5201 次
发布时间:2019-06-13

本文共 2173 字,大约阅读时间需要 7 分钟。

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

问题如下:

我通过两种方式在两个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推测有可能出现某些数据更新失败的情况。

转载于:https://www.cnblogs.com/gaoze/p/7735210.html

你可能感兴趣的文章
压缩图片 待验证
查看>>
冲刺进度条7
查看>>
UIImage 和 iOS 图片压缩UIImage / UIImageVIew
查看>>
MongoDB的数据库、集合的基本操作
查看>>
JS 多种变量定义
查看>>
redis可执行文件说明
查看>>
ajax向后台传递数组
查看>>
剑指offer系列14:包含min函数的栈
查看>>
疯狂JAVA16课之对象与内存控制
查看>>
[转载]树、森林和二叉树的转换
查看>>
WPF移动Window窗体(鼠标点击左键移动窗体自定义行为)
查看>>
Java核心技术梳理-类加载机制与反射
查看>>
1593: [Usaco2008 Feb]Hotel 旅馆 (线段树)
查看>>
软件测试-----Graph Coverage作业
查看>>
POJO 与 JavaBean 的区别 !
查看>>
php、mysql查询当天,查询本周,查询本月的数据实例(字段是时间戳)
查看>>
Windows Phone 7手势识别左右滑动 非XNA
查看>>
django ORM创建数据库方法
查看>>
Win8下,以管理员身份启动VS项目
查看>>
[bzoj1025][SCOI2009]游戏 (分组背包)
查看>>