我们需要释放一些MongoDB空间,并且我们确定了可以从集合中安全删除的100Gb +文件。
所以我们将它们从具有此设置的测试环境中删除:
完成后,我们发现磁盘上的空间仍在使用,需要回收。我们找到了this post,它帮助了我们:在运行了两个
之后db.runCommand({repairDatabase: 1})
和
db.runCommand({compact: collection-name })
我们释放了100Gb +。
然后我们继续进行生产,忘记了设置不同,因为我们有1个副本节点:
删除文件后,我们运行
db.runCommand({repairDatabase: 1})
并收到 OK 消息(过了一会儿,10分钟+)。我们尝试过运行
db.runCommand({compact: collection-name })
并收到此错误:
将不会在主动副本集主服务器上运行压缩,因为这是一个 慢速阻塞操作。使用force:true强制
所以我们运行
db.runCommand({compact: collection-name, force: true })
并获得了 OK 消息(几乎立即),但空间磁盘仍然使用,它没有被释放。
我们搜索了使用replica-set运行repairDatabase
和compact
命令的解决方案,但建议的重点是避免停机,就好像这是唯一的问题。但是,我们可以安排停机时间,而我们的问题是命令不能按预期工作,因为空间实际上没有回收。
我们做错了什么?
答案 0 :(得分:2)
对于副本集配置,恢复空间的最佳和最安全的方法是执行initial sync。如果需要从集合中的所有节点恢复空间,则可以执行滚动初始同步。也就是说,在最后逐步降低主要副本并在其上执行初始同步之前,对每个辅助节点执行初始同步。
请注意,只有当您的部署包含至少三个节点副本集时才能进行滚动初始同步(原因我将在下面介绍)。
滚动初始同步方法是执行副本集维护的最安全方法,它也不会将停机时间作为奖励。
话虽如此,有些事情值得一提:
compact
: MongoDB 3.0.x上的WiredTiger上的compact
命令受到此错误的影响:SERVER-21833已在MongoDB 3.2.3中修复。在此版本之前,WiredTiger上的compact
可能会无声地失败。
repairDatabase
:请不要在副本集节点上运行repairDatabase
。如repairDatabase page中所述,强烈不推荐。名称repairDatabase
有点误导,因为命令不会尝试修复任何东西。该命令旨在在磁盘损坏时使用,这可能导致文档损坏。
repairDatabase
命令可以更准确地描述为"打捞数据库"。也就是说,它通过丢弃损坏的文档来重新创建数据库,试图让数据库进入一个可以启动它并从中挽救完整文档的状态。
在副本集中,MongoDB期望集合中的所有节点都包含相同的数据。如果在副本集节点上运行repairDatabase
,则该节点可能包含未检测到的损坏,repairDatabase
将尽职尽责地删除损坏的文档。可以预见,这使得该节点包含与集合其余部分不同的数据集。如果更新恰好击中该单个文档,则整个集合可能会崩溃。更糟糕的是,这种情况完全有可能长时间处于休眠状态,只是在没有明显原因的情况下突然发生。
我注意到在生产环境中,您创建了一个包含两个节点的副本集。建议不要使用此设置,因为单个节点的故障将使剩余节点成为辅助节点,因此不允许写入该集合。
由于MongoDB高可用性的工作方式(参见Replica Set Election),强烈建议至少部署三个数据承载节点,或者至少添加仲裁节点(参见{{3所以你的副本集包含奇数个成员。
在副本集中只有两个成员也会使滚动升级/初始同步/维护在某些情况下变得更加困难甚至不可能。
MongoDB 3.0.1发布于Replica Set Members,截至撰写本文时已超过2年。如果您被迫使用MongoDB 3.0系列,请考虑转到3.0.15。或者更好的是,到3.4.7(截至2017年8月10日的最新版本),其中包含超过3.0.1的大量改进。