22.2.快速入门指南 ================= FreeBSD 可以在系统初始化时挂载 ZFS 池和数据集。要启用它,请在 ``/etc/rc.conf`` 中添加这一行: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session zfs_enable="YES" 然后启动该服务: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # service zfs start 本节中的例子假设有三个 SCSI 磁盘,设备名称分别为 **da0**\ 、\ **da1** 和 **da2**\ 。SATA 硬件的用户应该使用 **ada** 作为设备名。 22.2.1.单磁盘池 --------------- 使用单个磁盘设备创建一个简单的、非冗余的池: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zpool create example /dev/da0 如需查看新的池,请查看 ``df`` 的输出: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # df Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/ad0s1a 2026030 235230 1628718 13% / devfs 1 1 0 100% /dev /dev/ad0s1d 54098308 1032846 48737598 2% /usr example 17547136 0 17547136 0% /example 以上输出说明已经创建和挂载 ``example`` 池,现在可以作为一个文件系统来访问。创建文件供用户浏览: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # cd /example # ls # touch testfile # ls -al total 4 drwxr-xr-x 2 root wheel 3 Aug 29 23:15 . drwxr-xr-x 21 root wheel 512 Aug 29 23:12 .. -rw-r--r-- 1 root wheel 0 Aug 29 23:15 testfile 这个池还没有使用任何高级的 ZFS 功能和属性。如需在这个池上创建一个启用压缩功能的数据集: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zfs create example/compressed # zfs set compression=gzip example/compressed ``example/compressed`` 数据集现在是一个 ZFS 压缩文件系统。试着复制一些大文件到 **/example/compressed**\ 。 如需禁用压缩: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zfs set compression=off example/compressed 如需卸载文件系统,使用 ``zfs umount``\ ,然后用 ``df`` 验证: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zfs umount example/compressed # df Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/ad0s1a 2026030 235232 1628716 13% / devfs 1 1 0 100% /dev /dev/ad0s1d 54098308 1032864 48737580 2% /usr example 17547008 0 17547008 0% /example 如需重新挂载文件系统以使其再次被访问,请使用 ``zfs mount`` 并使用 ``df`` 验证: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zfs mount example/compressed # df Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/ad0s1a 2026030 235234 1628714 13% / devfs 1 1 0 100% /dev /dev/ad0s1d 54098308 1032864 48737580 2% /usr example 17547008 0 17547008 0% /example example/compressed 17547008 0 17547008 0% /example/compressed 运行 ``mount`` 以显示池和文件系统: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # mount /dev/ad0s1a on / (ufs, local) devfs on /dev (devfs, local) /dev/ad0s1d on /usr (ufs, local, soft-updates) example on /example (zfs, local) example/compressed on /example/compressed (zfs, local) 创建后像任何文件系统一样使用 ZFS 数据集。需要时,在每个数据集的基础上设置其他可用的特性。下面的例子创建一个名为 ``data`` 的新文件系统。它假定该文件系统包含重要的文件,并将其配置为存储每个数据块的两个副本: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zfs create example/data # zfs set copies=2 example/data 使用 ``df`` 来查看数据和空间的使用: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # df Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/ad0s1a 2026030 235234 1628714 13% / devfs 1 1 0 100% /dev /dev/ad0s1d 54098308 1032864 48737580 2% /usr example 17547008 0 17547008 0% /example example/compressed 17547008 0 17547008 0% /example/compressed example/data 17547008 0 17547008 0% /example/data 注意,池中的所有文件系统都有相同的可用空间。在这些例子中使用 ``df`` 显示,文件系统使用它们所需要的空间,并且都是从同一个池中提取。ZFS 摆脱了卷和分区等概念,允许多个文件系统共享同一个池。 如果要销毁文件系统并销毁不再需要的池: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zfs destroy example/compressed # zfs destroy example/data # zpool destroy example 22.2.2.RAID-Z ------------- 磁盘故障时,避免磁盘故障造成数据丢失的一个方法是使用 RAID。ZFS 在其池的设计中支持这一功能。RAID-Z 池需要三个或更多的磁盘,但比镜像池提供了更多的可用空间。 这个例子创建一个 RAID-Z 池,指定要添加到池中的磁盘。 .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zpool create storage raidz da0 da1 da2 .. **注意** Sun™ 建议在单个 RAID-Z 配置中使用的设备数量在 3 到 9 之间。对于需要一个由 10 个或更多的磁盘组成的单一磁盘池的环境,可以考虑将其分解成更小的 RAID-Z 组。如果有两个磁盘可用,如果需要的话,ZFS 镜像提供冗余功能。参考 `zpool(8) `__ 以了解更多细节。 前面的例子创建存储池 ``zpool``\ 。这个例子在该池中建立一个新的文件系统,名为 ``home``\ : .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zfs create storage/home 如需启用压缩功能,并存储一个额外的目录和文件副本: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zfs set copies=2 storage/home # zfs set compression=gzip storage/home 为了使这个目录成为用户的新主目录,将用户数据复制到这个目录,并创建适当的符号链接: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # cp -rp /home/* /storage/home # rm -rf /home /usr/home # ln -s /storage/home /home # ln -s /storage/home /usr/home 用户数据现在存储在新创建的 **/storage/home** 上。通过添加一个新用户并以该用户身份登录来测试。 创建一个文件系统快照,以便日后回滚: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zfs snapshot storage/home@08-30-08 ZFS 创建的是数据集的快照,而不是单个目录或文件。 ``@`` 字符是文件系统名称或卷名称之间的分隔符。在删除一个重要的目录之前,先备份文件系统,然后回滚到该目录仍然存在的早期快照: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zfs rollback storage/home@08-30-08 要列出所有可用的快照,在文件系统的 **.zfs/napshot** 目录下运行 ``ls``\ 。例如,如需查快照: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # ls /storage/home/.zfs/snapshot 写一个脚本,定期对用户数据进行快照。随着时间的推移,快照会耗费大量的磁盘空间。使用命令删除之前的快照: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zfs destroy storage/home@08-30-08 测试后,用这个命令使 **/storage/home** 成为真正的 **/home**\ : .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zfs set mountpoint=/home storage/home 运行 ``df`` 和 ``mount`` 以确认系统现在将该文件系统视为真正的 **/home**\ : .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # mount /dev/ad0s1a on / (ufs, local) devfs on /dev (devfs, local) /dev/ad0s1d on /usr (ufs, local, soft-updates) storage on /storage (zfs, local) storage/home on /home (zfs, local) # df Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/ad0s1a 2026030 235240 1628708 13% / devfs 1 1 0 100% /dev /dev/ad0s1d 54098308 1032826 48737618 2% /usr storage 26320512 0 26320512 0% /storage storage/home 26320512 0 26320512 0% /home 这样就完成了 RAID-Z 的配置。通过在 **/etc/periodic.conf** 中添加这一行,在每晚运行的 `periodic(8) `__ 中添加关于已创建文件系统的每日状态更新: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session daily_status_zfs_enable="YES" 22.2.3.恢复 RAID-Z ------------------ 每个软件 RAID 都有监控其 ``state`` 的方法。使用以下方法查看 RAID-Z 设备的状态: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zpool status -x 如果所有池都是 `Online `__ 的,而且一切正常,则显示消息: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session all pools are healthy 如果有一个问题,也许是一个磁盘处于 `Offline `__ 状态,池的状态将看起来像这样: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session pool: storage state: DEGRADED status: One or more devices has been taken offline by the administrator. Sufficient replicas exist for the pool to continue functioning in a degraded state. action: Online the device using 'zpool online' or replace the device with 'zpool replace'. scrub: none requested config: NAME STATE READ WRITE CKSUM storage DEGRADED 0 0 0 raidz1 DEGRADED 0 0 0 da0 ONLINE 0 0 0 da1 OFFLINE 0 0 0 da2 ONLINE 0 0 0 errors: No known data errors ``OFFLINE`` 表示管理员使用以下命令将 **da1** 脱机: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zpool offline storage da1 现在关闭计算机电源,更换 **da1**\ 。然后打开计算机电源,将新的 **da1** 放回池中: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zpool replace storage da1 接下来,再次检查状态,这次不使用 ``-x`` 来显示所有池: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zpool status storage pool: storage state: ONLINE scrub: resilver completed with 0 errors on Sat Aug 30 19:44:11 2008 config: NAME STATE READ WRITE CKSUM storage ONLINE 0 0 0 raidz1 ONLINE 0 0 0 da0 ONLINE 0 0 0 da1 ONLINE 0 0 0 da2 ONLINE 0 0 0 errors: No known data errors 在这个例子中,一切正常。 22.2.4.数据验证 --------------- ZFS 使用校验和来验证存储数据的完整性。创建文件系统时会自动启用该功能。 **警告** 可以禁用校验和,但不建议这样做。校验和只占用很少的存储空间但可确保数据的完整性。大多数 ZFS 功能在禁用校验和的情况下将不能正常工作。禁用校验和不会明显地提高性能。 验证数据校验(称为 *清洗*\ )以确保 ``storage`` 池的完整性: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zpool scrub storage 清洗的时间取决于存储的数据量。较大的数据量将需要相应的时间来验证。由于清洗是 I/O 密集型的,ZFS 一次只允许运行一个清洗。清洗完成后,用 ``zpool status`` 查看状态: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # zpool status storage pool: storage state: ONLINE scrub: scrub completed with 0 errors on Sat Jan 26 19:57:37 2013 config: NAME STATE READ WRITE CKSUM storage ONLINE 0 0 0 raidz1 ONLINE 0 0 0 da0 ONLINE 0 0 0 da1 ONLINE 0 0 0 da2 ONLINE 0 0 0 errors: No known data errors 显示上一次清洗的完成日期有助于决定何时开始另一次清洗。例行清洗有助于保护数据免受隐藏的破坏,并确保池的完整性。 参考 `zfs(8) `__ 和 `zpool(8) `__ 以了解其他 ZFS 选项。