4.5. 群集清除

集群清除的主要目的是清理具有多个已删除的逻辑删除的数据库或包含大量冲突的单个文档。但它也可以用来清除任何文档(已删除或未删除),其中包含任意数量的修订。

集群清除旨在维护最终一致性,并防止二级索引不必要的失效。为此,每个数据库都会跟踪数据库中请求的特定数量的历史清除以及当前的清除 purge_seq . 内部复制和辅助索引处理数据库的清除,并定期更新相应的清除检查点文档以进行报告 purge_seq 由他们处理。为了确保最终的一致性,只有在内部复制作业和辅助索引处理了存储的历史清除请求之后,数据库才会删除这些请求。

4.5.1. 内部结构

为了在节点和辅助索引之间启用清除信息的内部复制,将两个内部清除树添加到数据库文件中以跟踪历史清除。

purge_tree: UUID -> {PurgeSeq, DocId, Revs}
purge_seq_tree: PurgeSeq -> {UUID, DocId, Revs}

每个交互请求 _purge API ,在递增时创建有序的对集 purge_seq 以及purge_request,其中purge_request是一个元组,包含docid和修订列表。为每个清除请求生成uuid。清除请求被添加到内部清除树:元组 {{UUID -> {{PurgeSeq, DocId, Revs}}}} 被添加到 purge_tree ,元组是 {{PurgeSeq -> {{UUID, DocId, Revs}}}} 补充 to purge_seq_tree .

4.5.2. 吹扫压实

在压缩数据库的过程中,最旧的清除请求将被删除,仅用于存储 purged_infos_limit 数据库中的清除数。但是,为了使数据库与索引和其他副本保持一致,我们只能删除已经由索引和内部复制作业处理的清除请求。因此,偶尔清除树木可能会储存超过 purged_infos_limit 清洗。如果数据库中存储的清除数超过 purged_infos_limit 在某个阈值下,日志中会产生一个警告,表示数据库清除与索引和其他副本的同步问题。

4.5.3. 本地清除检查点文档

带有清除的数据库的索引和内部复制创建并定期更新本地检查点清除文档: _local/purge-$type-$hash . 这些文件最后报告 purge_seq 最后一次处理的时间戳。本地检查点清除文档示例:

{
  "_id": "_local/purge-mrview-86cacdfbaf6968d4ebbc324dd3723fe7",
  "type": "mrview",
  "purge_seq": 10,
  "updated_on": 1540541874,
  "ddoc_id": "_design/foo",
  "signature": "5d10247925f826ae3e00966ec24b7bf6"
}

下图显示了数据库可能具有的本地检查点文档。

Local Purge Checkpoint Documents

本地清除检查点文档

4.5.4. 内部复制

清除请求以最终一致的方式在所有节点上重播。清除的内部复制包括两个步骤:

1拉式复制。内部复制首先从目标系统中提取清除并将其应用于源系统,以确保不会重新引入已在目标系统上清除的目标源的文档/版本。在这一步中,我们使用存储在目标上的清除检查点文档来跟踪最后一个目标的 purge_seq 由来源处理。我们发现在这之后发生了清除请求 purge_seq ,并在源代码上重放它们。这一步是通过使用最新的进程更新目标的检查点清除文档来完成的 purge_seq 和时间戳。

2推送复制。然后,内部复制照常进行,插入一个额外的步骤,将源的清除请求推送到目标。在这一步中,我们使用本地内部复制检查点文档,这些文档在目标和源上都会更新。

在正常情况下,交互式清除请求已经发送到包含数据库碎片副本的每个节点,并应用于每个副本。节点之间清除的内部复制只是确保副本之间一致性的额外步骤,其中一个节点上的所有清除请求都将在另一个节点上重放。为了不在副本上重播同一个清除请求,每个交互式清除请求都被标记为唯一的 uuid . 内部复制筛选出带有已存在于复制副本中的uuid的清除请求 purge_tree ,并仅应用具有不存在于中的uuid的清除请求 purge_tree . 这就是我们需要两个内部清除树的原因:1) purge_tree{{UUID -> {{PurgeSeq, DocId, Revs}}}} 允许快速查找副本中已存在的UUID清除请求;2) purge_seq_tree{{PurgeSeq -> {{UUID, DocId, Revs}}}} 允许从给定的 purge_seq 收集在此之后发生的所有清除请求 purge_seq .

4.5.5. 索引

每次清除请求都会增加 update_seq 使每个辅助索引也得到更新,以便应用清除请求来保持主数据库内的一致性。

4.5.6. 配置设置

这些设置可以在中更新默认.ini或者本地.ini:

描述 违约
max_document_id_number 一个清除请求中允许的最大文档数 100
max_revisions_number 一个清除请求中允许的最大累积修订数 1000
allowed_purge_seq_lag 除了清除的信息限制之外,还允许额外的缓冲区来存储清除请求 100
index_lag_warn_seconds 不更新本地清除检查点文档的索引时允许的持续时间 86400

在数据库压缩期间,我们检查所有检查点清除文档。允许客户机(索引或内部复制作业)报告最后一个 purge_seq 比当前的数据库碎片小 purge_seq 价值 (purged_infos_limit + allowed_purge_seq_lag) . 如果客户 purge_seq 甚至更小,并且客户端没有在 index_lag_warn_seconds ,它会阻止清除树的压缩,我们必须为此客户端发出以下日志警告:

Purge checkpoint '_local/purge-mrview-9152d15c12011288629bcffba7693fd4’
not updated in 86400 seconds in
<<"shards/00000000-1fffffff/testdb12.1491979089">>

如果发生这种类型的日志警告,请检查客户机以了解清除请求的处理为什么会在其中暂停。

索引的设计文档和本地检查点文档之间存在映射关系。如果更新或删除索引的设计文档,则相应的本地检查点文档也应自动删除。但在意外情况下,当设计文档被更新/删除,但其检查点文档仍然存在于数据库中时,会发出以下警告:

"Invalid purge doc '<<"_design/bar">>' on database
<<"shards/00000000-1fffffff/testdb12.1491979089">>
with purge_seq '50'"

如果发生这种类型的日志警告,请从数据库中删除本地清除文档。