

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# Amazon DocumentDB 中的垃圾回收
<a name="garbage-collection"></a>

Amazon DocumentDB 实现了多版本并发控制（MVCC）数据库架构，可为每次更新操作创建新版本的文档和索引条目。该架构提供了事务隔离，防止一个事务的更改出现在另一个事务中。

**Topics**
+ [了解 Amazon DocumentDB 中的垃圾收集](#understanding-garbage-collection)
+ [垃圾回收过程](#garbage-collection-process)
+ [存储架构和扩展存储](#storage-architecture)
+ [监控垃圾回收](#monitoring-garbage-collection)
+ [collStats 输出示例](#example-collstats-output)
+ [常见问题](#garbage-collection-faq)

## 了解 Amazon DocumentDB 中的垃圾收集
<a name="understanding-garbage-collection"></a>

垃圾回收（GC）是一个自动化后台过程，可在 Amazon DocumentDB 中维持最佳的系统性能和可用性。与许多现代数据库一样，Amazon DocumentDB 的 MVCC 架构每次更新都会创建新的文档和索引版本。每个写入操作都会消耗有限计数器中唯一的 MVCC ID。它们 IDs 标识文档版本属于哪个事务，以及该交易是已提交还是已回退。随着时间的推移，这些旧版本及其 MVCC IDs 会不断累积，需要进行清理以防止性能下降。

### 垃圾回收的功能
<a name="w2aac49c15b7b5"></a>

垃圾回收器有三个基本功能：
+ **回收存储空间** – 将移除活动查询不再需要的过时文档和索引版本，从而为将来的写入操作释放空间。
+ **防止 MVCC ID 溢出** — 它通过管理 MVCC 的有限计数器来防止 MVCC ID 溢出。 IDs如果没有这种管理，计数器最终将达到其极限，从而迫使数据库进入临时的只读模式，直到 IDs 被回收为止。
+ **维持查询性能** – 通过消除失效的文档版本来维持最佳的查询性能，否则这些文档版本会累积并拖慢查询处理速度。

## 垃圾回收过程
<a name="garbage-collection-process"></a>

垃圾回收过程对每个集合进行操作，并且可以在不同的集合上并发运行多个过程。此过程包括四个连续阶段：

1. **识别** – 系统识别活动事务或查询不再引用的文档和索引版本。

1. **内存加载** – 如果旧文档和索引条目尚未存在于内存中，则会将其加载到内存中。

1. **删除** – 永久删除过时版本以回收存储空间。

1. **MVCC ID 回收** — 系统 IDs 从已删除的版本中回收 MVCC 以进行新操作。

当垃圾收集完成对旧文档版本的处理后，它会 IDs 从系统中删除最旧的 MVCC。这种清理对于通过回收 MVCC 来防止 MVCC ID 溢出至关重要 IDs，使它们可用于整个集群中的新写入操作。若无此回收过程，系统最终将耗尽其有限的 MVCC ID 计数器并进入只读状态。

### 垃圾回收调度
<a name="w2aac49c15b9b9"></a>

垃圾回收会定期在后台自动运行。时间和频率会根据系统负载、可用资源、写入量和 MVCC ID 消耗水平进行动态调整。在高写入活动期间，垃圾回收过程将更频繁地执行以管理数量激增的文档版本。

## 存储架构和扩展存储
<a name="storage-architecture"></a>

Amazon DocumentDB 使用复杂的存储架构，将文档存储分为两个不同的部分：

### 基础存储段
<a name="w2aac49c15c11b5"></a>

基本存储段包含主要文档数据和元数据。此区段存储：
+ 符合标准页面大小 (8 KB) 的文档内容。
+ 文档元数据和结构信息。
+ 主索引及其条目。
+ 集合级别的统计数据和配置。

### 扩展存储段
<a name="w2aac49c15c11b7"></a>

扩展存储段使用专门的大型文档对象存储，用于处理超过标准存储页面大小的文档。本部分提供：
+ **高效的大型文档处理** — 大于基本存储阈值的文档会自动移至扩展存储段。
+ **优化的存储布局** — 该分段使用针对大型对象进行了优化的不同存储格式，从而减少了碎片并改善了访问模式。
+ **独立垃圾收集** — 扩展存储段有自己的垃圾收集过程，该过程可以独立于基本存储清理运行。
+ **透明访问** — 应用程序可以无缝访问大型文档，而无需知道哪个存储段包含数据。

扩展存储区段对以下方面特别有利：
+ 包含大型嵌入式数组的文档的集合。
+ 具有大量嵌套结构的文档。
+ 存储二进制数据或大型文本字段的集合。
+ 具有混合文档大小的应用程序，其中一些文档大大超过平均大小。

## 监控垃圾回收
<a name="monitoring-garbage-collection"></a>

### 集群级别指标
<a name="w2aac49c15c13b3"></a>

**`AvailableMVCCIds`**
+ **地点**-亚马逊 CloudWatch
+ **描述**-一个计数器，显示从上限 18 亿个起可用的剩余写入操作数。当此计数器达到零时，您的集群将进入只读模式，直到 IDs 被回收和回收。计数器会随着每次写入操作而减少，并随着垃圾收集回收旧的 M IDs VCC 而增加。
+ **建议** – 当值低于 13 亿时设置警报。此预警可让您采取稍后讨论的建议步骤。

**`LongestActiveGCRuntime`**
+ **地点**-亚马逊 CloudWatch
+ **描述** – 最长活动垃圾回收过程的持续时间（以秒为单位）。每分钟更新一次，仅跟踪活动操作，不包括在一分钟时段内完成的进程。
+ **建议**-与`gcRuntimeStats`历史数据进行比较，以识别异常的垃圾收集行为，例如批量删除期间的运行时间延长。

### 回收级别指标
<a name="w2aac49c15c13b5"></a>

**`MVCCIDStats: MVCCIdScale`**
+ **位置** – 数据库 collStats 命令
+ **描述** – 以 0 到 1 的等级衡量 MVCC ID 使用期限，其中 1 表示集群进入只读状态前的最长使用期限。同时使用此指标`AvailableMVCCIds`来识别包含使集群老化的最旧 MVCC IDs 的集合。
+ **建议** – 将每个集合的值维持在 0.3 以下。

**`gcRuntimeStats`**
+ **位置** – 数据库 collStats 命令
+ **描述** – 提供两个月的垃圾回收指标历史记录，包括总运行次数、平均持续时间和最长持续时间。仅包括持续时间超过五分钟的垃圾回收操作，以确保有意义的统计数据。

**重要**  
`gcRuntimeStats``documentFragmentStats`、，以及将馆藏级别的指标分解为`storageSegmentBase`并`storageSegmentExtended`仅适用于亚马逊 DocumentDB 8.0。

**`storageSizeStats`**
+ **位置** – 数据库 collStats 命令
+ **描述** — 提供不同存储段的存储利用率的详细明细：
  + `storageSegmentBase`— 基础存储段用于存储标准文档的存储空间
  + `storageSegmentExtended`— 扩展存储段用于存储大型文档的存储空间
+ **用法**-帮助识别具有大量文件存储空间的馆藏，并了解存储分配模式。

**`unusedStorageSize`**（集合级别）
+ **位置** – 数据库 collStats 命令
+ **描述** – 根据抽样统计数据估算集合中未使用的存储空间。包括已删除文档和空分段所占用的空间。该指标同时提供合并总数和每个区段的细分：
  + 合并`unusedBytes`并`unusedPercent`跨所有存储段
  + `storageSegmentBase`— 未使用的空间，特别是基础存储段中的未使用空间
  + `storageSegmentExtended`— 未使用的空间，特别是在扩展存储段中

**`documentFragmentStats`**
+ **位置** – 数据库 collStats 命令
+ **描述**-提供有关文档片段和集合中无效数据的详细信息。文档片段代表数据库引擎使用的内部存储单元，而失效的碎片表示无法再访问但尚未被回收的数据。该指标包括：
  + `totalDocFragmentsCount`— 馆藏中的文档片段总数
  + `deadDocFragmentsCount`— 包含失效（无法访问）数据的片段数
  + `deadDocFragmentsPercent`— 包含失效数据的片段的百分比
  + `deadDocFragmentBytes`— 失效文档片段消耗的估计字节数
  + 和的按区段`storageSegmentBase`细分 `storageSegmentExtended`
+ **使用情况**-监控此指标以了解垃圾收集的有效性，并确定可能从维护操作中受益的收集。高百分比的死碎片表明垃圾收集可能落后，或者垃圾收集将从优化中受益。

### 索引级别指标
<a name="w2aac49c15c13b7"></a>

**`unusedStorageSize`**（索引级别）
+ **位置** – 数据库 indexStats 命令
+ **描述** – 根据抽样统计数据估算索引中未使用的存储空间。包括过时的索引条目和空分段所占用的空间。
+ **建议** – 使用 `reIndex` 命令在不停机的情况下重建索引并回收未使用的空间。有关更多详细信息，请参阅“管理索引”。

## collStats 输出示例
<a name="example-collstats-output"></a>

以下示例显示了包含垃圾收集和存储指标的典型`collStats`输出：

```
{
    "ns" : "Mvcc_consumption_test_db.mvcc_test_collection",
    "MVCCIdStats" : {
        "MVCCIdScale" : 0.03
    },
    "gcRuntimeStats" : {
        "numRuns" : 1,
        "historicalAvgRuntime" : 3295,
        "historicalMaxRuntime" : 3295,
        "lastRuntime" : 3295,
        "lastRuntimeStart" : ISODate("2025-06-24T08:47:14Z")
    },
    "documentFragmentStats" : {
        "totalDocFragmentsCount" : 45000000,
        "deadDocFragmentsCount" : 2250000,
        "deadDocFragmentsPercent" : 5.0,
        "deadDocFragmentBytes" : 98304000,
        "storageSegmentBase" : {
            "totalDocFragmentsCount" : 30000000,
            "deadDocFragmentsCount" : 1500000,
            "deadDocFragmentsPercent" : 5.0,
            "deadDocFragmentBytes" : 65536000
        },
        "storageSegmentExtended" : {
            "totalDocFragmentsCount" : 15000000,
            "deadDocFragmentsCount" : 750000,
            "deadDocFragmentsPercent" : 5.0,
            "deadDocFragmentBytes" : 32768000
        }
    },
    "collScans" : 14,
    "count" : 30000000,
    "size" : 1320000000,
    "avgObjSize" : 44,
    "storageSize" : 6461497344,
    "storageSizeStats" : {
        "storageSegmentBase" : 4307664896,
        "storageSegmentExtended" : 2153832448
    },
    "capped" : false,
    "nindexes" : 2,
    "totalIndexSize" : 9649553408,
    "indexSizes" : {
        "_id_" : 1910661120,
        "c_1" : 7738892288
    },
    "unusedStorageSize" : {
        "unusedBytes" : 4201881600,
        "unusedPercent" : 65.05,
        "storageSegmentBase" : {
            "unusedBytes" : 2801254400,
            "unusedPercent" : 65.05
        },
        "storageSegmentExtended" : {
            "unusedBytes" : 1400627200,
            "unusedPercent" : 65.05
        }
    },
    "cacheStats" : {
        "collBlksHit" : 171659016,
        "collBlksRead" : 754061,
        "collHitRatio" : 99.5627,
        "idxBlksHit" : 692563636,
        "idxBlksRead" : 1177921,
        "idxHitRatio" : 99.8303
    },
    "idxScans" : 41823984,
    "opCounter" : {
        "numDocsIns" : 0,
        "numDocsUpd" : 20911992,
        "numDocsDel" : 0
    },
    "lastReset" : "2025-06-24 05:57:08.219711+00",
    "ok" : 1,
    "operationTime" : Timestamp(1750968826, 1)
}
```

## 常见问题
<a name="garbage-collection-faq"></a>

### 如何识别垃圾回收效率低下？
<a name="w2aac49c15c17b3"></a>

监控以下表明垃圾回收效率低下的警告信号：
+ **集合膨胀过多 — 在**大量写入或批量删除期间，`unusedStorageSize`指标会稳步增加，尤其是在索引较大的情况下。
+ **高死亡碎片百分比** — `documentFragmentStats` 显示的`deadDocFragmentsPercent`值一直很高（高于 10-15%）。
+ **查询延迟降低**-由于累积的失效文档导致查询延迟增加。
+ **GC 持续时间延长** — 垃圾收集操作花费的时间比历史平均值长`gcRuntimeStats`。
+ **GC 处理能力提升** — 高`LongestActiveGCRuntime`表示垃圾收集器无法满足系统需求。

### 垃圾回收会影响我的数据库性能吗？
<a name="w2aac49c15c17b5"></a>

正常情况下，垃圾回收对性能的影响微乎其微。但是，当垃圾回收滞后时，您可能会遇到：
+ 积累的失效文档导致存储成本增加。
+ 由于索引条目过时，查询性能降低。
+ 如果 MVCC 已耗尽，则 IDs 为临时只读模式。
+ 在密集收集运行期间，资源使用量更高，尤其是在较小的实例上。
+ 降低了大型文档的扩展存储段操作效率。

### 我是否可以手动触发垃圾回收？
<a name="w2aac49c15c17b7"></a>

不可以，无法手动触发 Amazon DocumentDB 中的垃圾回收。作为内部维护操作的一部分，系统会自动管理垃圾回收。

### 作为操作最佳实践，我应该设置哪些警报？
<a name="w2aac49c15c17b9"></a>

我们建议在集群级别和集合级别设置监控，以确保您的 Amazon DocumentDB 系统实现最佳性能。

要进行集群级别的监控，首先要为阈值为 13 亿的`AvailableMVCCIds`指标创建 Amazon CloudWatch 警报。这使您有足够的时间在指标达到零（届时您的集群将进入只读模式）之前采取措施。请记住，该指标可能会根据您的具体使用模式而波动——一些客户看到该指标降至13亿以下，然后在垃圾收集完成工作后恢复到15亿以上。

通过Amazon监控`LongestActiveGCRuntime`指标也很重要 CloudWatch。此指标与 `gcRuntimeStats` 一起可帮助您了解整个系统中垃圾回收的执行效率。

对于集合级别的监控，请重点关注以下关键指标：
+ `MVCCIdScale`— 注意不断增加的数值，这些值表明 MVCC IDs 正在老化，可能需要注意。
+ `gcRuntimeStats`— 确定垃圾收集过程耗时异常长或持续多天。
+ `documentFragmentStats`— 监控`deadDocFragmentsPercent`值——持续较高的百分比（高于 10-15%）可能表明垃圾收集落后。
+ `storageSizeStats`以及 `unusedStorageSize` — 跟踪存储利用模式，识别两个存储段中存在大量未使用空间的馆藏。

需要特别注意具有频繁写入操作的集合，因为其会增加垃圾收集器的工作。对于具有大量写入活动的集合，我们建议更频繁地检查这些指标，以确保垃圾回收能跟上您的工作负载。

请注意，这些监控建议仅作为起点。随着您对系统行为越来越熟悉，您可能需要调整这些阈值以更好地匹配您的具体使用模式和要求。

### 如果我的 `AvailableMVCCIds` 低于 13 亿该怎么办？
<a name="w2aac49c15c17c11"></a>

如果您的 `AvailableMVCCIds`指标降至 13 亿以下，我们建议您立即采取措施以防止集群进入只读模式。我们建议先扩展实例大小，为垃圾回收器提供更多计算资源。这是我们的主要建议，因为它允许您的应用程序继续正常运行，同时为垃圾收集器提供 catch 所需的额外功能。

如果仅靠扩展并不能改善状况，我们建议您考虑减少写入操作。使用该`MVCCIdScale`指标来确定哪些特定集合包含需要注意的较旧 MVCC IDs 。此外，还`documentFragmentStats`要进行监控以识别可能导致垃圾收集效率低下的死碎片百分比高的集合。

识别出这些集合后，可能需要暂时减少针对其的写入操作，以便垃圾回收能够跟上节奏。在恢复期间，我们建议您密切监控 `AvailableMVCCIds` 指标，以确保措施达到预期效果。`AvailableMVCCIds` 值恢复到 15 亿或更高后，您的集群就会被视为运行状况良好。

请记住，这些步骤属于预防性措施，旨在帮助系统在达到紧急状态前恢复。在看到指标降至 13 亿以下后，您越早采取措施，就越有可能避免对写入操作造成任何影响。