【问题标题】:Deleting selective data from MongoDB Secondary Only仅从 MongoDB 次要删除选择性数据
【发布时间】:2020-03-06 02:58:24
【问题描述】:

是否可以通过直接在辅助实例上运行删除命令从单个 Mongo 辅助实例中删除数据,而不影响主实例和其他辅助实例?

说明:我想清除大约 500 GB 的大型集合,其中包含大约 5 亿条记录。我想保留最近几个月的数据,所以我将不得不删除约 4 亿条记录。它是一个副本设置,具有一个主节点和 2 个辅助节点。存储引擎是WiredTiger。我不希望任何停机或缓慢,因为它是实时事务系统的生产数据库。我正在考虑以下选项:

  1. 创建一个新集合,将最近几个月的记录复制到其中,然后删除旧的。但是复制如此庞大的数据会降低数据库服务器的速度。
  2. 备份整个集合,然后运行批量删除,批量大小为 1000。这将需要数周时间才能删除这么多记录,还会创建巨大的操作日志,因为每次删除都会产生一个将同步的操作日志到次要。这些操作日志会占用大量磁盘空间。
  3. 另一个选项是我只在一个辅助节点上运行批量删除。删除数据后,我将其提升为主要数据。然后在其他 2 个辅助实例上运行相同的删除。这不会影响 prod 环境。因此问题是:我们可以只在辅助服务器上运行删除吗?一旦这个从节点在删除后回到集群中,主节点和从节点之间的同步过程将是什么行为?

【问题讨论】:

  • 我假设无论如何都会创建 oplog,无论您在哪里运行 delete 命令,因此您不会节省任何磁盘空间。即使您从断开连接的辅助节点中删除数据,我认为这将需要很长时间(您将有 3 次)。我想说:即使这种方法可行,您也不会节省任何时间或磁盘空间。
  • 即使能够删除,WiredTiger 也不会释放磁盘空间,直到您运行 compact 这会在数小时内减慢您的辅助节点
  • @WernfriedDomscheit 我不能在不影响其他任何东西的情况下从断开连接的辅助节点中删除 oplog 吗?长时间仍然是可控的,因为主要关注的是减少生产停机时间和速度。
  • @Valijon 是的,磁盘空间不会被释放,但它可以被未来的写入重用,并且磁盘空间使用增长将会放缓。此外,只有最近几个月的产品数据,选择查询会更快。
  • 一旦你清理了你的数据库(不管你打算怎么做),你应该考虑TTL Indexes

标签: mongodb


【解决方案1】:

我在本地 MongoDB 集群上运行了一个小测试。原则上,当您遵循以下程序时,它似乎可以工作:

  1. 关闭辅助节点
  2. Restart the secondary as a standalone(您不能对 SECONDARY 执行任何更改)
  3. 连接单机并删除旧数据
  4. 关闭单机版
  5. 作为ReplicaSet成员正常重启standalone
  6. 对另一个辅助节点重复步骤 (1) 到 (5)。您可以在所有辅助节点上并行运行上述步骤,但是在出现问题时您没有冗余。
  7. 将一个从上面设置为主要
  8. 对最后一个节点重复步骤 (1) 到 (5)

正如我所说,我对一些文档进行了“快速而肮脏”的测试,它似乎有效。

但是,我认为它不适用于您的设置,因为:

步骤(5)“删除旧数据”需要一些时间,可能需要几个小时甚至几天。当您完成删除后,您很可能会陷入这种情况:

Resync a Member of a Replica Set:

当复制过程远远落后于主节点覆盖该成员尚未复制的 oplog 条目时,副本集成员将变为“陈旧”。成员无法赶上并变得“陈旧”。发生这种情况时,您必须完全重新同步该成员,方法是删除其数据并执行初始同步。

即您将再次添加所有已删除的数据。

也许有一些技巧可以将“stale”覆盖为“SECONDARY”。然后您将不得不删除旧的 PRIMARY 并再次将其添加为 SECONDARY。但是这样一来,当步骤 (5) 运行时,您将丢失所有新插入到生产环境中的数据。我假设应用程序会不断插入新数据(否则您不会获得如此数量的文档),这样的数据将会丢失。

【讨论】:

  • 那么您可以建议使用其他方法删除这些数据吗?
  • 我可以这样做吗:在集群中保留辅助节点并在其上运行后台删除。所以它正在复制新的插入,并删除旧数据。在此期间,我不会在此节点上从应用程序发送任何流量,因此 prod 不会遇到任何缓慢。然后我可以对所有辅助节点重复此操作。然后将其中一个作为主节点,然后在旧主节点上执行相同的过程。
  • 不,只要您的节点是 ReplicatSet 的一部分,您就不能对其进行任何修改(rs.slaveOk() 仅适用于读取数据)。但是,当您将节点作为独立运行时,它不会收到任何 oplog,即它不会从 PRIMARY 收到任何内容。
  • 所以我只剩下选项 1 和 2(如我原来的问题中所述)?两者哪个更好?
  • 我认为选项 1 会更好,如果您有足够的磁盘空间并且可以处理持续的流量。考虑新集合的 TTL 索引。
猜你喜欢
  • 2020-10-01
  • 1970-01-01
  • 2016-09-11
  • 2023-01-14
  • 2019-09-26
  • 2018-07-27
  • 2014-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多