> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/di-19-zhang-freebsd-xi-tong-geng-xin/di-19.4-jie-tong-guo-zfs-qi-dong-huan-jing-shi-xian-duo-ban-ben-gong-cun.md).

# 19.4 通过 ZFS 启动环境实现多版本共存

借助 ZFS 启动环境，可在同一台机器上保留多个独立的系统版本，升级失败时无需重新安装即可回滚到先前状态，从而实现原子更新、多系统并存与快速回滚。本节所述方法仅适用于使用 ZFS 文件系统的系统。

> **警告**
>
> PkgBase 与 freebsd-update **不可混用**。一旦将系统转换为 PkgBase，所有系统更新均应通过 pkg 包管理器进行，不得再使用 freebsd-update，否则可能导致系统组件冲突、文件损坏或系统无法启动。

## 创建启动环境 15.0-RELEASE

ZFS 启动环境（Boot Environment，BE）允许在系统中创建多个独立的系统环境，实现不同版本的共存与安全切换。以下操作将创建启动环境 15.0-RELEASE。

* 使用工具 bectl 创建启动环境 `15.0-RELEASE`：

```sh
# bectl create 15.0-RELEASE
```

> **注意**
>
> 此处启动环境命名为 15.0-RELEASE，但当前系统仍为 14.3-RELEASE。

* 使用 bectl 检查启动环境：

```sh
$ bectl list # 显示所有启动环境
BE           Active Mountpoint Space Created
15.0-RELEASE -      -          176K  2025-12-05 22:27
default      NR     /          10.6G 2025-01-14 20:36
```

* 列出系统中所有 ZFS 文件系统及其属性：

```sh
# zfs list
NAME                      USED  AVAIL  REFER  MOUNTPOINT

……其他省略……

zroot/ROOT/15.0-RELEASE     8K  83.8G  10.6G  /

……其他省略……
```

其中 `zroot/ROOT/15.0-RELEASE` 一行即为新创建的启动环境。

## 将启动环境中的系统版本更新到 15.0-RELEASE

创建启动环境后，需要更新到目标版本。操作分为挂载、验证版本、转换为 PkgBase、升级四个步骤。

### 挂载启动环境 15.0-RELEASE

操作启动环境前，需先将其挂载至文件系统。首先创建临时目录：

* 创建一个临时目录，用于更新启动环境 15.0-RELEASE 中的系统

```sh
# mkdir /mnt/upgrade
```

```sh
/mnt/
└── upgrade/ # 启动环境挂载目录
    └── usr/
        └── local/
            └── etc/
                └── pkg/
                    └── repos/
                        └── FreeBSD-base.conf # PkgBase 源配置文件
```

* 将启动环境（实际上是一个数据集）15.0-RELEASE 挂载到指定路径

```sh
# bectl mount 15.0-RELEASE /mnt/upgrade
/mnt/upgrade
```

* 显示已挂载文件系统的磁盘使用情况：

```sh
# df
Filesystem              1K-blocks     Used    Avail Capacity  Mounted on

……其他省略……

zroot/ROOT/15.0-RELEASE  99036272 11132688 87903584    11%    /mnt/upgrade

……其他省略……
```

### 验证当前 FreeBSD 版本

该启动环境（ZFS 数据集）15.0-RELEASE 当前实际仍为 14.3-RELEASE，可使用 `freebsd-version` 验证：

在 **/mnt/upgrade** 环境中运行 `freebsd-version`：

```sh
# chroot /mnt/upgrade freebsd-version -kru
14.3-RELEASE
14.3-RELEASE
14.3-RELEASE
```

`freebsd-version` 参数解释：

| 参数   | 说明                                                                              |
| ---- | ------------------------------------------------------------------------------- |
| `-k` | 打印已安装内核的版本和补丁级别。不同于 uname(1)，如果新的内核已经安装但系统尚未重启，`freebsd-version` 会打印新内核的版本和补丁级别 |
| `-r` | 打印正在运行中的内核的版本和补丁级别。不同于 uname(1)，`freebsd-version` 不受环境变量影响                      |
| `-u` | 打印已安装用户态的版本和补丁级别。这些信息在构建过程中会写入程序 `freebsd-version` 中                            |

### 使用 PkgBase 将启动环境中的 14.3-RELEASE（系统版本）转换为 PkgBase

升级之前，需将传统的 FreeBSD 系统转换为 PkgBase 格式。PkgBase 是 FreeBSD 官方提供的基本系统打包方式，使用 pkg 包管理器管理系统组件。

升级方法参见 PkgBase 转换基本系统相关章节。

### 启动到启动环境 15.0-RELEASE

完成所有更新操作后，启动到新的启动环境验证结果。

* 在下次启动时进入启动环境 15.0-RELEASE

```sh
# bectl activate -t 15.0-RELEASE  # 在下次启动时进入启动环境 15.0-RELEASE
Successfully activated boot environment 15.0-RELEASE
for next boot
```

* 验证设置是否成功。列出系统中所有 ZFS 启动环境：

```sh
$ bectl list
BE                             Active Mountpoint   Space Created
15.0-RELEASE                   T      /mnt/upgrade 8.75G 2025-12-05 23:22
default                        NR     /            10.9G 2025-01-14 20:36
```

注意，这是一次性的（`T`），此处仅用于验证其是否能够正常启动。还需要回到当前的主系统 14.3-RELEASE 来更新 ZFS。

* 重启以进入启动环境 15.0-RELEASE

```sh
# reboot  # 重启以进入启动环境 15.0-RELEASE
```

* 验证版本：

```sh
$ freebsd-version -kru
15.0-RELEASE
15.0-RELEASE
15.0-RELEASE
$ bectl list
BE                             Active Mountpoint Space Created
15.0-RELEASE                   N      /          8.75G 2025-12-05 23:22
default                        R      -          10.9G 2025-01-14 20:36
```

由输出可知，已成功将启动环境 15.0-RELEASE 中的 FreeBSD 系统升级到 15.0-RELEASE，此时启动环境名称与实际版本一致。

`R` 意味着再次重启将回到启动环境 `default`（14.3-RELEASE）。

## 附录：永久性使用 15.0-RELEASE

前面已通过一次性启动环境完成验证。如果验证通过并且不需要再保留旧版本，可以将新环境设置为永久默认。

如果读者不需要多版本共存，并且验证过目前的环境满足需要，也可以将启动环境 15.0-RELEASE 设置为永久的：

```sh
# bectl activate 15.0-RELEASE
```

随后，读者也可以销毁不再需要的启动环境：

```sh
# bectl destroy 要销毁的启动环境名称
```

将参数 `要销毁的启动环境名称` 替换为命令 `bectl list` 输出中 `BE` 列对应的启动环境名称即可销毁。

### 将基本系统中的 ZFS 替换为 Ports 版本

需实现多版本共存的读者可直接重启，进入启动环境 `default`（14.3-RELEASE），升级 14.3-RELEASE 中的 OpenZFS 版本。升级细节参照其他相关章节。

> **警告**
>
> 如不更新为 Ports 版本强行升级 ZFS 池/特性，将无法访问旧版系统。

## 参考文献

* vermaden. ZFS Boot Environments Explained\[EB/OL]. \[2026-03-25]. <https://vermaden.wordpress.com/2025/11/25/zfs-boot-environments-explained/>. 详细阐释 ZFS 启动环境的原理与实践，包含跨版本 ZFS 池兼容方案。
* FreeBSD Project. BootEnvironments\[EB/OL]. \[2026-03-25]. <https://wiki.freebsd.org/BootEnvironments>. FreeBSD 官方关于启动环境的 Wiki。
* FreeBSD Project. bectl(8)\[EB/OL]. \[2026-03-25]. <https://man.freebsd.org/cgi/man.cgi?query=bectl&sektion=8>. ZFS 启动环境管理工具的官方技术规范。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/di-19-zhang-freebsd-xi-tong-geng-xin/di-19.4-jie-tong-guo-zfs-qi-dong-huan-jing-shi-xian-duo-ban-ben-gong-cun.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
