Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
仅从MongoDB Secondary中删除选择性数据_Mongodb - Fatal编程技术网

仅从MongoDB Secondary中删除选择性数据

仅从MongoDB Secondary中删除选择性数据,mongodb,Mongodb,是否可以在不影响主实例和其他辅助实例的情况下,直接在辅助实例上运行delete命令,从单个Mongo辅助实例中删除数据 说明:我想清除一个约500 GB的大型集合,其中包含约5亿条记录。我想保留最近几个月的数据,因此我必须删除约4亿条记录。它是一个副本设置,有一个主副本和两个辅助副本。存储引擎是WiredTiger。我不想要任何停机或缓慢,因为这是一个实时事务系统的生产数据库。我正在考虑以下选择: 创建一个新集合,复制其中最近几个月的记录,然后删除旧集合。但是复制如此巨大的数据会降低数据库服务器

是否可以在不影响主实例和其他辅助实例的情况下,直接在辅助实例上运行delete命令,从单个Mongo辅助实例中删除数据

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

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

  • 我在本地MongoDB集群上运行了一个小测试。原则上,当您遵循以下步骤时,它似乎起作用:

  • 关闭辅助电源
  • (您不能对辅助服务器执行任何更改)
  • 连接到单机版并删除旧数据
  • 关闭单机版
  • 以ReplicaSet成员的身份重新启动单机版
  • 对另一个辅助传感器重复步骤(1)至(5)。您可以在所有辅助设备上并行运行上述步骤,但是在出现问题时,您没有冗余
  • 从上方将辅助设置为主
  • 对最后一个节点重复步骤(1)至(5)
  • 正如我所说的,我用一些文档做了一个“快速而肮脏”的测试,它似乎可以工作

    但是,我认为它在您的设置中不起作用,因为:

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

    当复制集成员的复制过程落后于主成员覆盖该成员尚未复制的oplog条目时,该成员将变为“过时”。该成员无法跟上并变得“过时”。出现这种情况时,必须通过删除其数据并执行初始同步来完全重新同步该成员

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


    也许有黑客将“过时”改写为“次要”。然后,您必须删除旧的主文件,并将其重新添加为次文件。但这样做会丢失在第(5)步运行时新插入到生产中的所有数据。我假设应用程序不断插入新数据(否则您将无法获得如此多的文档),这些数据将丢失。

    我假设无论在何处运行delete命令,都会创建oplog,因此不会节省任何磁盘空间。即使从断开连接的辅助节点删除数据,我认为这也需要很长时间(您将有三次)。我想说的是:即使这种方法可行,您也不会节省任何时间或磁盘空间。即使能够删除,WiredTiger也不会释放磁盘空间,直到您运行
    compact
    ,这会在运行过程中降低辅助节点的速度hours@WernfriedDomscheit我能否在不影响其他任何内容的情况下从断开连接的辅助设备中删除oplog?长时间仍然是可管理的,因为主要考虑的是减少产品停机时间和慢度。@Valijon是的,磁盘空间不会被释放,但它可以被将来的写入重新使用,并且磁盘空间使用量的增长将放缓。此外,只有最近几个月的PROD数据,选择查询会更快。一旦你清理了你的数据库(不管你打算怎么做),你应该考虑任何其他方法来建议删除这个数据吗?我可以这样做:在集群中保持次要,并在它上运行后台删除。因此,它正在复制新的插入,同时也在删除旧数据。在这段时间内,我不会从应用程序在这个节点上发送任何通信量,因此prod不会遇到任何缓慢。然后我可以对所有辅助节点重复此操作。然后将其中一个辅助节点作为主节点,然后在旧的主节点上执行相同的过程。不,只要节点是ReplicatSet的一部分,就不能对其执行任何修改(
    rs.slaveOk()
    仅适用于读取数据)。但是,当您以独立方式运行节点时,它不会接收任何oplog,即它不会从主节点接收任何内容。那么,我是否只剩下选项1和2(如我最初的问题中所述)?哪一个更好?我认为选项1会更好,如果您有足够的磁盘空间,并且可以处理正在进行的流量。考虑新集合上的TTL索引。