跳转至

CDC 分块

适用于体积较大、经常发生局部变化的备份文件

什么是 CDC

CDC 是 Content-Defined Chunking 的缩写,常译为“内容定义分块”。 它并非按照固定大小切分文件,而是根据文件内容本身来确定数据块(chunk)的边界

由于边界由内容决定,当一个大文件仅发生局部变化时(例如在中间部分修改或插入了少量数据,或仅在尾部追加内容), 大量未变化的内容仍会被切分成与之前相同的数据块。 这些数据块的哈希值保持不变,因此 Prime Backup 可以直接复用已有的数据块,从而获得更好的去重效果

在 Prime Backup 中,读取和导出分块文件对用户是透明的。 当需要恢复文件内容时,Prime Backup 会自动按顺序将其重建出来。

什么时候会启用

只有同时满足以下所有条件时,Prime Backup 才会启用 CDC 分块:

  • backup.cdc_enabledtrue
  • 文件大小大于 0
  • 文件大小至少达到 backup.cdc_file_size_threshold
  • 相对于 backup.source_root 的文件路径匹配 backup.cdc_patterns

默认配置如下:

{
    "cdc_enabled": false,
    "cdc_file_size_threshold": 104857600,
    "cdc_patterns": [
        "**/*.db"
    ]
}

它是怎么存储的

Prime Backup 仍会为整个文件创建一条数据对象(blob)记录,但该数据对象的 storage_method 会是 chunked(分块)而非 direct(直存)

当前实现的大致流程如下:

  1. 使用 FastCDC 算法对文件进行切分
  2. 为每个数据块计算 BLAKE3 哈希值
  3. 检查这些数据块是否已存在,已存在的直接复用
  4. 仅压缩并写入那些新的数据块
  5. 将数据块按顺序绑定回整个文件对应的数据对象(按偏移量)

当前的数据块参数是固定在代码中的:

  • 平均数据块大小:256 KiB
  • 最小数据块大小:64 KiB
  • 最大数据块大小:1 MiB

元数据优化(数据块组)

从概念上讲,一个分块数据对象只是一个有序的数据块列表。 为每一对数据对象与数据块存储直接的关联记录开销会很大, 因此实现将连续的数据块组织成数据块组(chunk group),并存储两层绑定关系:

  • 数据对象 -> 数据块组(按数据对象偏移量)
  • 数据块组 -> 数据块(按组内偏移量)
+--------------------------------------------------------------------------------+
|                                      blob                                      |
+--------------------------+-----------------------------------------------------+
|       chunk group 1      |  chunk group 2  |          chunk group 3            |
+--------------------------+-----------------+-----------------+-----------------+
| chunk1 | chunk2 | chunk3 | chunk4 | chunk5 | chunk6 | chunk7 | chunk8 | chunk9 |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+

这在不改变逻辑模型的前提下减少了元数据开销

数据块哈希与数据块组哈希始终使用 blake3,不过整个文件对应的数据对象哈希仍遵循 backup.hash_method 设置

压缩与性能

CDC 分块不会关闭压缩

对于一个分块数据对象:

  • 数据对象记录本身的 compress 字段记为 plain
  • 每个数据块会根据 backup.compress_methodbackup.compress_threshold 独立压缩
  • 数据对象的 stored_size 表示所有唯一数据块存储大小之和

与直接备份相比,当前实现下的 CDC 分块会更慢。 因为在真正写入新数据之前,Prime Backup 需要先进行文件切分与哈希计算,之后还需再次读取新数据块的内容以进行写入和校验。

因此,CDC 更适合用于那些体积大、经常发生局部修改、且确实需要备份的文件。

适用场景

以下场景通常适合开启 CDC:

  • 体积较大的数据库文件,且每次更新仅涉及局部
  • 需要纳入备份、且主要以尾部追加方式写入的大型日志文件
  • 经常发生局部插入、删除或修改,而非整体重写的大文件

不适用场景

以下情况通常不适合使用 CDC:

  • 每次备份时,文件的几乎所有位置都会发生变化
  • 文件总是被完整重写或重新导出
  • 已压缩或加密的文件。此类文件在修改后几乎无法复用已有数据块

另外,某个文件首次进入备份时,所有数据块仍需完整写入。 CDC 的收益主要体现在后续那些“仅部分内容变化”的备份上

如果 Prime Backup 发现某个分块文件在一次备份中产生了大量全新的数据块,它会在日志中发出警告。 这通常说明该文件并不适合作为 CDC 目标;当然,若这是该文件首次被备份,则属于正常现象,可忽略警告

依赖与观察方式

CDC 分块依赖于可选的 Python 库 pyfastcdc。 你可以单独安装它,或直接安装 requirements.optional.txt 中列出的可选依赖包

Prime Backup 的维护逻辑已支持分块存储。 你可以通过 !!pb database overview 命令观察效果,该命令会额外显示一组数据块统计信息