mongodb备份结点数据目录与主结点数据大小不一致

求大神解惑:
两个mongodb结点,主备模式,查看两个结点下的数据目录发现:
主结点data目录的为23GB,目录详情如下:
clipboard.png

备份结点data目录为11GB,录详情如下:
clipboard.png

db.collection.stats()数据量是一致的,请问这是什么原因?是否有相关的资源可以查阅?

阅读 3.1k
1 个回答

题外话,MongoDB历史上出现过master/slave复制(其实现在也还存在)。严格地说,主备通常指的是那个东西。而我们现在用的基本上是复制集(replica set)。

再说你这种情况,其实是正常的。原理跟你的磁盘用久了会有碎片是一个道理。特别是你曾经大规模删除过数据的情况下。简单地解释下,假设你的表中有doc1/doc2/doc3/doc4一共4个文档,在磁盘上的存储顺序是:
doc1|doc2|doc3|doc4
现在你删除了doc2,磁盘上的空间使用情况变成:
doc1|(空白)|doc3|doc4
系统是没有办法释放这个空白空间的,除非你进行磁盘整理,把空白空间移到最后:
doc1|doc3|doc4|(空白)
然后系统才可以截断文件尾部的空白,释放掉这个空间。可以看出来,要把空白移动到文件尾是个相当费时费力的操作,最简单的办法是:把后面所有的文档顺序前移来填补doc2留下的空白(如上所示doc3/doc4被前移)。但是这样涉及到大量的磁盘I/O,会对性能造成严重影响。当然不乏其他整理磁盘碎片的方法,但是无论哪一个,都会造成比较严重的I/O影响,因此一般我们是不会进行这样的整理的。进行碎片整理的方式就是:compact命令。如前所述,因为它会对性能造成严重的影响,因此一般只会在维护时间进行这个操作。而就算你不进行这个操作,系统也知道哪些地方是空白的,在有新文档进来的时候,会尝试重新使用这些空白的部分从而最大化空间利用率。只是,无论再好的算法,空间重复利用一定不可能是100%的,因为新进来的文档永远没有办法正好跟之前被删除的文档一样大,所以只能找一个比新文档更大的空间来利用,这样就会留下一个更小的、更难重复利用的碎片。
另外一种变通的方案是把节点内容删除,重新进行一次同步。因为同步时相当于把所有文档全部抓取一遍,并一个接一个重新写到磁盘上,因此同步完成之后文档在磁盘上是紧凑排列的,相当于进行了碎片整理。而且在这个过程中,受影响的是从节点,它在同步过程中并不对外提供服务,所以对线上的影响是最小的。但是注意,它同样会对主节点造成影响,因为它要把主节点上的全部数据都读一遍,主节点I/O升高是无法避免的。

最后回到你的问题,为什么从节点比主节点小,上面应该已经解释清楚了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进