# ZFS 的校验和及其用途

端到端校验和是 ZFS 的核心特性，也是 ZFS 相较于其他 RAID 实现和文件系统的重要区别。端到端校验和的优势包括：

* 在从介质读取数据时检测数据损坏
* 会在可能的情况下自动修复检测到损坏的块，依赖于经过适当配置的池中的 RAID 保护，或冗余副本（参见 ZFS 属性 `copies`）
* 定期扫描可检查数据，以检测并修复潜在的介质退化（bit rot，比特腐烂）以及来自其他来源的损坏
* ZFS 复制流、`zfs send` 和 `zfs receive` 上的校验和确保接收的数据未被中间存储或传输机制损坏

## 校验和算法

可以更改 ZFS 中数据集（文件系统或卷）的校验和算法。每个块使用的校验和算法都存储在块指针（元数据）中。将在写入时计算块的校验和，因此更改算法仅影响修改后发生的写入操作。

可以通过设置属性 `checksum` 更改数据集的校验和算法：

```sh
zfs set checksum=sha256 pool_name/dataset_name
```

|    校验和    | 是否适用于去重和 nopwrite？ | 是否兼容其他 ZFS 实现？             | 备注                                                                           |
| :-------: | ------------------ | -------------------------- | ---------------------------------------------------------------------------- |
|     on    | 见备注                | 是                          | `on` 对非去重数据集为 `fletcher4` 的简写，对去重数据集为 `sha256` 的简写                           |
|    off    | 否                  | 是                          | 不要使用 `off`                                                                   |
| fletcher2 | 否                  | 是                          | Fletcher 校验和的已弃用实现，请使用 `fletcher4`                                           |
| fletcher4 | 否                  | 是                          | Fletcher 算法，也用于 `zfs send` 流                                                 |
|   sha256  | 是                  | 是                          | 去重数据集的默认值                                                                    |
|  noparity | 否                  | 是                          | 不要使用 `noparity`                                                              |
|   sha512  | 是                  | 需要池特性 `org.illumos:sha512` | 带盐的 `sha512` 目前在任何启动池上的文件系统中不支持                                              |
|   skein   | 是                  | 需要池特性 `org.illumos:skein`  | 带盐的 `skein` 目前在任何启动池上的文件系统中不支持                                               |
|   edonr   | 见备注                | 需要池特性 `org.illumos:edonr`  | 带盐的 `edonr` 目前在任何启动池上的文件系统中不支持。为了谨慎起见，Edon-R 在与去重一起使用时需要验证，因此会自动使用 `verify`。 |
|   blake3  | 是                  | 需要池特性 `org.openzfs:blake3` | 带盐的 `blake3` 目前在任何启动池上的文件系统中不支持                                              |

## 校验和加速器

ZFS 能够将校验和操作卸载到 Intel QuickAssist Technology (QAT) 适配器上。

## 校验和微基准测试

某些 ZFS 功能在加载 `zfs.ko` 内核模块时会使用微基准测试来确定校验和的最优算法。微基准测试的结果可以在 `/proc/spl/kstat/zfs` 目录中观察到。获胜算法会被报告为“最快”，并成为默认值。可以通过设置 ZFS 模块参数来覆盖默认值。

| 校验和       | 结果文件名                                  | `zfs` 模块参数                                            |
| --------- | -------------------------------------- | ----------------------------------------------------- |
| Fletcher4 | `/proc/spl/kstat/zfs/fletcher_4_bench` | `zfs_fletcher_4_impl`                                 |
| 其他全部      | `/proc/spl/kstat/zfs/chksum_bench`     | `zfs_blake3_impl`、`zfs_sha256_impl`、`zfs_sha512_impl` |

## 禁用校验和

虽然禁用校验和可能会提升 CPU 性能，但 ZFS 社区普遍认为这是极其不明智的做法。请不要禁用校验和。
