RHEL配置ZFS存储

本文详细介绍了在RHEL9系统中如何配置和管理ZFS,包括安装ZFS、创建和管理存储池、设置ZFS挂载点、创建和删除文件系统、磁盘管理、RAID配置、快照创建与管理以及存储池迁移等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RHEL配置ZFS存储

环境声明

OS Version: Rocky9

实验环境使用4块1T硬盘


ZFS简介

https://www.wolai.com/littlenewton/gJvungs54zWgZ3YfoXAvKW


ZFS块指针的结构


ZFS的存储池布局

存储池 (zpool)[ 基于 Vdev(s) 构建 ]
│  └── 虚拟设备 (vdev)
│      │  [ 基于 Disk(s) 构建 ]
│      └── 物理磁盘/设备 (disk)
│
├── 根数据集 (root dataset)
│   ├── 子数据集 (child dataset)
│   ├── 卷 (zvol, 块设备)
│   └── 快照 (snapshot) 
└── (其他组件: 如 Cache vdev, Log vdev - 可选)

下面这张图能更好地体现datasetzvol之间的关系。


ZFS优势

  1. ZFS 核心优势:
    • 端到端校验和 (End-to-end Checksums): ZFS 在数据写入时计算校验和,并在读取时验证,能检测并(若有冗余)修复静默数据损坏 (Silent Data Corruption),这是传统硬件 RAID 卡通常不具备或不完善的功能。
    • 写时复制 (Copy-on-Write, CoW): ZFS 从不覆盖旧数据。修改数据时,新数据写入空闲块,然后更新元数据指向新块。这使得快照几乎瞬时完成,且从根本上消除了 RAID 写漏洞 (Write Hole) 问题(即写入过程中断电导致奇偶校验与数据不一致)。
    • 动态条带宽 (Dynamic Stripe Width): RAID-Z 的条带宽不是固定的,可以根据写入的数据块大小变化,能更有效地利用空间,尤其在有压缩时。
    • 集成管理: ZFS 将卷管理和文件系统功能集成在一起,简化了管理。
  2. 容量计算: 假设 vdev 中所有磁盘容量相同。
  3. 性能: 为相对比较,实际性能受硬件影响很大。
  4. 扩展性: ZFS 不支持向现有的 Mirror 或 RAID-Z vdev 中添加单个磁盘来扩展容量。扩展 ZFS 池通常通过替换现有磁盘为更大容量或添加新的 vdev 实现。
  5. vdev: ZFS 的虚拟设备是构建存储池 (zpool) 的基础块。一个 zpool 可以包含多个 vdev,数据会跨这些 vdev 进行条带化(除非只有一个 vdev)。

总结:

ZFS 提供了与传统 RAID 类似的冗余级别,但通过其独特的设计(如 CoW 和校验和)提供了更高的数据完整性保障,并解决了传统 RAID 的一些固有问题(如写漏洞)。选择哪种策略需要根据对数据安全性、容量效率、性能和成本的具体需求来权衡。


Centos7安装ZFS

https://openzfs.github.io/openzfs-docs/Getting%20Started/RHEL-based%20distro/index.html

# 安装zfs库
yum install -y https://zfsonlinux.org/epel/zfs-release.el7_9.noarch.rpm

# 禁用zfs dkms源
## zfs源是dkms(动态内核模块支持)---ZFS on Linux for EL 7 - dkms
yum config-manager --disable zfs

# 启用zfs-kmod源
## kmod是内核模块
yum config-manager --enable zfs-kmod

RHEL8/RHEL9安装ZFS

# 安装zfs源
dnf install -y https://zfsonlinux.org/epel/zfs-release-2-2$(rpm --eval "%{dist}").noarch.rpm

# 安装epel源
dnf install -y epel-release

# 安装dev内核
dnf install -y kernel-devel

# 禁用zfs dkms源
## zfs源是dkms(动态内核模块支持)---ZFS on Linux for EL 7 - dkms
dnf config-manager --disable zfs

# 启用zfs-kmod源
## kmod是内核模块
dnf config-manager --enable zfs-kmod

# 安装zfs主程序
dnf install -y zfs

# 加载zfs内核模块
modprobe zfs

# 安装分区工具
dnf install -y gdisk dosfstools

# 查看zfs版本
zfs version

始终在启动时加载OpenZFS模块

默认情况下,当检测到 ZFS 池时,会自动加载 OpenZFS 内核模块。如果您希望**始终在启动时加载**模块,则必须创建一个 /etc/modules-load.d/zfs.conf 文件:

# 在启动时自动加载zfs模块
echo zfs >/etc/modules-load.d/zfs.conf

开机自启zfs服务

# 开机自启zfs服务
systemctl enable --now zfs-import-scan.service zfs-mount zfs-import.target zfs-zed zfs.target

# 查看zfs-import-scan服务状态
systemctl status zfs-import-scan


创建ZFS的步骤:

  1. 规划创建存储池
    1. 选择冗余策略
  2. 配置数据集/子数据集
  3. 定义挂载点
  4. 优化与扩展

https://blog.csdn.net/wanghai__/article/details/6196790
https://www.escapelife.site/posts/caf259ea.html

|--- 物理磁盘/设备 (disk)|--- 虚拟设备 (vdev)
│  │
存储池 (zpool)
├── 根数据集(root dataset)
│   ├── 子数据集(child dataset)
│   ├── 卷(zvol,块设备)
│   └── 快照(snapshot)

指定存储池的冗余策略

ZFS 策略类似 RAID简述最小盘数 (每 Vdev)容错盘数 (每 Vdev)容量效率 (约)性能 (读/写)主要场景优点缺点/注意
Stripe(默认策略)RAID 0数据条带化,无冗余1+0~100%高 / 高临时/非关键数据,最大性能/容量最高性能/容量, ZFS完整性无冗余!单盘故障 = 全池数据丢失
MirrorRAID 1数据完全复制2+N-1~1/N (单盘)高 / 中高高数据安全, 随机读密集 (VMs)高冗余, 较快重建, 良好读性能, ZFS完整性最低容量效率
RAID-Z1RAID 5条带化 + 单奇偶校验31~(N-1)/N高 / 中容量/冗余均衡较好容量效率, ZFS完整性 (无写漏洞)写有开销, 重建慢且期间有风险
RAID-Z2RAID 6条带化 + 双奇偶校验42~(N-2)/N高 / 中低较高数据安全, 大容量盘高冗余 (更安全重建), ZFS完整性写开销更大, 重建更慢
RAID-Z3N/A条带化 + 三奇偶校验53~(N-3)/N高 / 低最高数据安全, 关键数据最高冗余, ZFS完整性写开销最大, 重建非常慢
dRAIDRAID 5/6分布式 RAID-Z, 重建快变化1, 2, 或 3类 RAID-Z高 / 中低需极快重建的大型池极快重建, ZFS完整性, 集成热备较新, 配置稍复杂
CacheN/AL2ARC - SSD 读缓存1 (SSD)N/AN/A提升读改善常用数据读取性能加速读访问需SSD, 需内存管理, 不加速写
LogN/ASLOG - SSD 同步写日志 (ZIL)1 (SSD,常镜像=2)N/A / 1(镜像时)N/A提升同步写加速 NFS, DB, VM 等同步写操作降低同步写延迟需高速耐用SSD, 仅加速同步写, 单盘有风险
## 冗余模式 (type: “”,mirror,raidz,raidz2)
zpool create zfspool <type> <磁盘1> <磁盘2>

Stripe条带化–默认

RAID0,最少2块硬盘,速度快,但**不容灾**
且不支持做热备,做了也没用

# 创建RAID0
zpool create -f zfspool /dev/sdc /dev/sdd

mirror镜像存储池

  • 镜像(Mirror)‌:适用于高随机读写场景(如数据库),写入性能最优
# 创建一个镜像(mirror)存储池(双磁盘冗余)
# - `zpool create`   : 创建新 ZFS 存储池
# - `-f`             : 强制操作(覆盖现有池或忽略缺失设备警告)
# - `zfspool`        : 存储池名称(可自定义)
# - `mirror`         : 配置镜像冗余模式(需至少2块磁盘)
# - `vdc vdd`        : 指定用作镜像的物理设备(例如磁盘或分区)
# ▶ 特点:数据实时双副本,提供高可用性,但存储利用率50%
# ▶ 警告:使用 `-f` 前需确认目标设备无重要数据
zpool create -f zfspool mirror vdc vdd

RAIDZ2/(对标RAID6)

  • RAIDZ1/RAIDZ2‌:适合顺序大文件读写(如备份存储),平衡性能与空间利用率
# 创建RAIDZ2
# 创建一个 RAID-Z 存储池(单磁盘冗余)
# - `raidz`          : 配置 RAID-Z 冗余模式(类似 RAID5,需至少3块磁盘)
# - `vdc vdd vde`    : 指定3块物理设备
#  特点:存储利用率 ≈ (N-1)/N(本例约66.6%),允许单盘故障
#  注意:RAID-Z 适用于3块及以上设备,不同版本支持 raidz1/2/3
zpool create -f zfspool raidz2 /dev/sdc /dev/sdd /dev/sde /dev/sdf

pool(存储池)管理命令

|--- 物理磁盘/设备 (disk)|--- 虚拟设备 (vdev)
│  │
存储池 (zpool)
├── 根数据集(root dataset)
│   ├── 子数据集(child dataset)
│   ├── 卷(zvol,块设备)
│   └── 快照(snapshot)

创建一个pool(存储池)

ZFS 创建存储池时并不严格要求所有磁盘容量必须完全相同,但强烈建议使用相同容量的磁盘。

# 创建一个存储池
## 默认的冗余策略是 条带化 (Stripe)
## zpool create -f <存储池名称> 磁盘1 磁盘2 磁盘3 磁盘4
zpool create -f zfspool vdc vdd vde vdf


向存储池中添加更多空间

# 向zfspool 池中添加磁盘
## mirror 冗余策略为 镜像
zpool add zfspool mirror vdg vdh

验证存储池是否创建成功

如果存储池创建成功,df -Th中会会出现一个路径为zfspool大小3.8TB的空间,同时挂载在/zfspool

# 查看磁盘使用率
df -Th


查看存储池(pool)列表

# 查看存储池
zpool list


修改存储池的名称(ZFS存储池迁移)

# 将名为 "zfspool" 的 ZFS 存储池从当前系统导出
## export 导出存储池
# 导出操作会使该存储池在当前系统上暂时不可用,
# 并将其标记为“已导出”,以便可以安全地移动物理磁盘或在稍后重新导入(可能使用新名称)。
zpool export <存储池名称>
# 从旧服务器上导出存储池
zpool export zfspool

# 列出所有可以导入的存储池
zpool import

# 导入先前导出的 ZFS 存储池,并将其重命名
## import 导入存储池
# 这个命令会查找原始名为 "zfspool" 的已导出存储池,
# 并将其以 "newpool" 的新名称导入到当前系统中。
# 如果省略 "newpool",则会以原始名称 "zfspool" 导入。
zpool import <已导出的存储池名称> <new存储池名称>
zpool import zfspool newpool

# 查看导入后到存储池状态
zpool status


显示存储池的状态

# 显示可用池的状态
# 查看zpool中有哪些磁盘
zpool status

# 获取存储服务的状态
zpool get all 存储池名

# 获取存储服务的状态
zpool get all


显示存储池修改历史

# 显示以前修改了存储池状态信息
zpool history


更新存储池

# 查看存储池是否需要升级以及可以启用哪些功能
# 在执行此操作前,建议先使用 'zpool status' 检查池状态,并确保有备份。
zpool status zfspool

# 升级指定的 ZFS 存储池以启用新功能
# 这个命令会检查当前 ZFS 版本支持的,但该存储池尚未启用的功能,并将其启用。
# 警告:升级通常是单向操作。一旦升级,该存储池可能无法被运行旧版本 ZFS 的系统导入或访问。
## upgrade: zpool 的子命令,用于启用存储池的新特性标志 (feature flags)。
## zfspool: 需要进行升级操作的 ZFS 存储池的名称。
zpool upgrade zfspool

# 更新全部存储池
zpool upgrade -a

# 升级存储池到指定SPA版本
zpool upgrade -V <version> zfspool

销毁一个存储池

# 销毁一个地址池
## zpool destroy <存储池名称>
zpool destroy zfspool

# 查看存储池列表
zpool list

# 查看存储池状态
zpool status

# 查看磁盘空间使用情况
df -Th

dataset(数据集)|ZFS 文件系统管理

ZFS 数据集 (Dataset - zfs filesystem)可以将其理解为 ZFS 文件系统

|--- 物理磁盘/设备 (disk)|--- 虚拟设备 (vdev)
│  │
存储池 (zpool)
├── 根数据集(root dataset)
│   ├── 子数据集(child dataset)
│   ├── 卷(zvol,块设备)
│   └── 快照(snapshot)

创建数据集

# 创建一个新的 ZFS 数据集
## pool/dataset: 要创建的数据集的完整路径名 (例如: zfspool/mydata)。数据集会自动继承父数据集的属性。
zfs create <存储池名/数据集名>
zfs create pool/dataset

销毁数据集

# 销毁一个 ZFS 数据集 (警告: 这将永久删除数据集中所有数据!)
## pool/dataset: 要销毁的数据集的路径名<存储池名/数据集名>
zfs destroy pool/dataset

# 递归销毁一个 ZFS 数据集及其所有子数据集和快照 (警告: 非常危险的操作!)
## -r: 递归销毁,包括所有子数据集和快照
## pool/dataset: 要销毁的父数据集路径名<存储池名/数据集名>
zfs destroy -r pool/dataset

# 删除文件系统
##   -R:递归删除,包括所有子数据集和快照
##   -f:强制删除,即使数据集正在使用或挂载
zfs destroy -Rf pool/dataset

列出和查看属性

# 列出系统上所有的 ZFS 数据集及其基本属性
zfs list

# 列出所有类型的文件系统和卷 (默认行为)
## -t filesystem,volume: 指定要列出的类型 (可以是 snapshot, bookmark 等)
zfs list -t filesystem,volume

# 列出指定数据集及其子数据集
## pool/dataset: 指定要查看的父数据集路径<存储池名/数据集名>
zfs list pool/dataset

# 列出所有快照
## -t snapshot: 指定只列出快照类型
zfs list -t snapshot

# 列出指定属性
## -o property1,property2,...: 指定要显示的属性列,以逗号分隔 (例如: name,used,available,mountpoint,compression)
zfs list -o name,used,available,mountpoint

# 获取指定数据集的特定属性值
## property: 要查询的属性名称 (例如: mountpoint, compression, quota, recordsize, all 等)
## pool/dataset: 目标数据集的路径名<存储池名/数据集名>
zfs get property pool/dataset

# 获取指定数据集的所有属性值
## all: 表示查询所有可获取的属性
## pool/dataset: 目标数据集的路径名<存储池名/数据集名>
zfs get all pool/dataset

设置属性

# 设置指定数据集的特定属性值
## property=value: 要设置的属性及其新值 (例如: compression=lz4, quota=10G, recordsize=128k, mountpoint=/mnt/mydata)
## pool/dataset: 目标数据集的路径名<存储池名/数据集名>
zfs set property=value pool/dataset

# 示例:启用压缩
## compression=lz4: 设置压缩算法为 lz4
## zfspool/mydata: 目标数据集
zfs set compression=lz4 zfspool/mydata

# 示例:设置配额
## quota=20G: 设置此数据集及其子数据集总共能使用的最大空间为 20GB
## zfspool/userdata: 目标数据集
zfs set quota=20G zfspool/userdata

# 示例:设置预留空间
## reservation=5G: 保证此数据集至少有 5GB 的可用空间(不含子数据集)
## zfspool/important: 目标数据集
zfs set reservation=5G zfspool/important

快照操作

# 创建一个指定数据集的快照 (快照是只读的时间点副本)
## pool/dataset@snapname: 要创建快照的数据集路径名和快照名称,用 '@' 分隔
zfs snapshot pool/dataset@snapname

# 递归地为指定数据集及其所有子数据集创建同名快照
## -r: 递归创建快照
## pool/dataset@snapname: 父数据集路径名和快照名称
zfs snapshot -r pool/dataset@snapname

# 销毁一个快照
## pool/dataset@snapname: 要销毁的快照的完整名称
zfs destroy pool/dataset@snapname

# 将数据集回滚到指定的快照状态 (警告: 快照之后的所有更改将丢失!)
## pool/dataset@snapname: 要回滚到的目标快照
zfs rollback pool/dataset@snapname

# 回滚数据集,并销毁比目标快照更新的所有快照
## -r: 在回滚时,销毁所有比指定快照更新的快照
## pool/dataset@snapname: 要回滚到的目标快照
zfs rollback -r pool/dataset@snapname

克隆、提升和重命名

# 基于快照创建一个可写的数据集克隆 (克隆初始时几乎不占用额外空间)
## pool/dataset@snapname: 源快照
## pool/new_clone_dataset: 新克隆数据集的路径名
zfs clone pool/dataset@snapname pool/new_clone_dataset

# 提升一个克隆数据集,使其与其原始快照解除依赖关系
# 提升后,原始快照依赖的父数据集可以被销毁,而克隆不受影响
## pool/clone_dataset: 要提升的克隆数据集的路径名
zfs promote pool/clone_dataset

# 重命名一个 ZFS 数据集、快照或卷
## old_pool/old_path: 对象当前的完整路径名 (可以是数据集、快照或卷)
## new_pool/new_path: 对象新的完整路径名 (通常在同一池中,仅改变路径或名称)
zfs rename old_pool/old_path new_pool/new_path

# 重命名数据集并递归重命名其快照 (如果快照名称包含旧数据集名)
## -r: 递归地重命名快照,如果快照名包含旧数据集名,会相应更新
## old_pool/old_dataset: 数据集当前的完整路径名
## new_pool/new_dataset: 数据集新的完整路径名
zfs rename -r old_pool/old_dataset new_pool/new_dataset

挂载和卸载

# 挂载一个 ZFS 数据集 (通常 ZFS 会根据 'mountpoint' 属性自动处理挂载)
## pool/dataset: 要挂载的数据集路径名
zfs mount pool/dataset

# 挂载所有 'mountpoint' 属性不是 'none' 或 'legacy' 的数据集
## -a: 挂载所有符合条件的数据集
zfs mount -a

# 卸载一个 ZFS 数据集
## pool/dataset: 要卸载的数据集路径名
zfs unmount pool/dataset

# 强制卸载一个 ZFS 数据集 (如果正常卸载失败)
## -f: 强制卸载
## pool/dataset: 要卸载的数据集路径名
zfs unmount -f pool/dataset

# 卸载所有已挂载的 ZFS 数据集
## -a: 卸载所有已挂载的数据集
zfs unmount -a

发送和接收 (用于备份和复制)

# 发送快照流 (通常用于备份或复制到另一位置)
## pool/dataset@snapname: 要发送的快照
# (输出通常通过管道 | 或重定向 > 到文件或 ssh)
zfs send pool/dataset@snapname

# 发送增量快照流 (仅发送从旧快照到新快照的变化)
## -i @oldsnap: 指定起始的旧快照 (增量发送的基础)
## pool/dataset@newsnap: 要发送的截止新快照
zfs send -i @oldsnap pool/dataset@newsnap

# 接收快照流并在目标位置创建/更新数据集
## destination_pool/destination_dataset: 接收数据并创建/更新的目标数据集路径
# (输入通常来自管道 | 或重定向 < 从文件或 ssh)
zfs receive destination_pool/destination_dataset

# 接收快照流,强制覆盖目标数据集 (如果存在) (警告: 可能导致目标数据丢失!)
## -F: 强制接收,如果目标存在,会先回滚再接收
## destination_pool/destination_dataset: 接收数据的目标数据集路径
zfs receive -F destination_pool/destination_dataset

设置zfs挂载点

# 修改ZFS数据集的挂载路径为/export/home
## set : 用于动态修改已存在数据集的属性值
## mountpoint=/export/home : 
### - mountpoint : ZFS属性名,控制数据集在操作系统中的挂载位置
### - =/export/home : 将该属性值设置为指定路径(需绝对路径) 
## zfspool/home : 
### - zfspool      : 存储池名称(zpool名称,需预先存在)
### - home      : 目标数据集名称(位于zfspool池中)
####   ▶ 该数据集必须已存在,否则命令会报错"dataset does not exist"
# 无需修改/etc/fstab,ZFS自动管理挂载(除非属性设为legacy模式)
zfs set mountpoint=<本地挂载点> <存储池名称>/<数据集名称>
zfs set mountpoint=/export/home zfspool/home

## inherit 清除自定义设置,恢复为/pool/dataset格式
zfs inherit mountpoint <存储池名称>/<数据集名称>
zfs inherit mountpoint zfspool/home

为多个用户创建起始目录

请注意:由于继承而自动挂载在 /export/home/{ahrens,bonwick,billm}

zfs create zfspool/home/ahrens
zfs create zfspool/home/bonwick
zfs create zfspool/home/billm

向池中添加更多空间

# 向存储池中添加磁盘
zpool add zfspool -f /dev/sdx

# 创建名为 “zfspool” 的存储池 (type: “”,mirror,raidz,raidz2)
zpool create zfspool <type> c0t0d0 c1t0d0 c1t1d0

重命名ZFS数据集

# 使用 zfs rename 命令重命名一个 ZFS 数据集
# 源数据集:zfspool/home/ahrens
# 目标数据集:zfspool/home/nahrens
# 该命令将 zfspool/home/ahrens 数据集重命名为 zfspool/home/nahrens
# 注意:挂载点会自动更新为新的名称,但快照名称不会自动更新
# 需要确保目标路径不存在,否则会报错
zfs rename zfspool/home/ahrens zfspool/home/nahrens

# 验证重命名是否成功
# 使用 zfs list 检查数据集是否已重命名为 zfspool/home/nahrens
zfs list

删除ZFS数据集

# 使用 zfs destroy 命令删除 ZFS 数据集及其所有子数据集和快照
##   -R:递归删除,包括所有子数据集和快照
##   -f:强制删除,即使数据集正在使用或挂载
## 目标数据集:zfspool/fs
zfs destroy -Rf zfspool/fs

# 验证数据集是否已被删除
# 使用 zfs list 检查数据集是否已从系统中移除
zfs list

ZVOL(ZFS卷)管理

|--- 物理磁盘/设备 (disk)|--- 虚拟设备 (vdev)
│  │
存储池 (zpool)
├── 根数据集(root dataset)
│   ├── 子数据集(child dataset)
│   ├── 卷(zvol,块设备)
│   └── 快照(snapshot)

ZFS 卷 (Volume - ZVOL)

  • 本质: 可以将其理解为 ZFS 块设备 (Block Device)。它模拟一个原始的、未格式化的磁盘驱动器。

  • 行为: 它不像数据集那样可以直接挂载来存储文件。它在操作系统层面表现为一个块设备文件(通常在 /dev/zvol/<pool_name>/<volume_name>)。

  • 特点:

    • 固定大小 (逻辑上): 创建时需要指定大小。虽然 ZFS ZVOL 通常是稀疏分配 (thin-provisioned) 的,意味着它们初始不占用其声明的全部空间,只在写入数据时才实际分配块,但逻辑上它们有一个固定的容量上限。可以通过设置 refreservation 使其成为厚分配 (thick-provisioned)。
    • 块设备接口: 提供标准的块设备接口给操作系统或应用程序。
    • 继承池特性: 仍然受益于 ZFS 的特性,如写时复制 (CoW)、快照、克隆、校验和(在块级别)。
    • 快照: 同样可以为 ZVOL 创建快照。
  • 主要用途:

    • 虚拟机硬盘镜像。
    • iSCSI Target LUNs。
    • 数据库裸设备存储。
    • 需要提供块级存储接口给其他应用程序或系统的场景。

创建ZFS卷

# 创建一个新的 ZFS 卷 (zvol),用于块设备 (例如给虚拟机或 iSCSI 使用)
## -V size: 指定卷的大小 (例如: 10G, 500M)  注意 -V 参数是关键
### 默认是稀疏分配 (thin-provisioned),即初始不占用 100G 物理空间
## pool/zvolname: 要创建的 ZFS 卷的完整路径名 (例如: zfspool/vmdisk)
zfs create -V <容量> <存储池名/zfs卷名>
zfs create -V 10G pool/zvolname

## volblocksize  创建一个块大小为 16K 的卷
## volblocksize,默认为 8K,影响性能
zfs create -V 100G -o volblocksize=16K pool/vmdisk_16k
  • 创建时预留空间 (厚分配 - thick-provisioned):
# 创建并立即预留 100G 空间
zfs create -V 100G -o reservation=100G tank/thick_vmdisk
# 或者使用 refreservation 效果类似,但不包含快照元数据开销
# zfs create -V 100G -o refreservation=100G tank/thick_vmdisk_ref

查看 ZVOL 信息 (List/Get)

  • 列出池中的所有 ZVOL:
zfs list -t volume
  • 列出特定 ZVOL 的信息:
zfs list tank/vmdisk
  • 获取 ZVOL 的所有属性:
zfs get all tank/vmdisk
  • 获取 ZVOL 的特定属性(例如大小和块大小):
zfs get volsize,volblocksize tank/vmdisk

修改 ZVOL 属性 (Set)

  • 调整 ZVOL 大小 (逻辑大小):
# 增大到 150GB
zfs set volsize=150G tank/vmdisk
- 注意: 增大通常没问题,但缩小 `volsize` 非常危险,除非你确定卷内的数据(例如文件系统)允许缩小并且已经缩小。直接缩小 `volsize` 可能导致数据丢失。
  • 设置/更改预留空间:
# 为已存在的卷设置 50G 的空间预留
zfs set reservation=50G tank/vmdisk
# 取消预留
zfs set reservation=none tank/vmdisk
  • 更改其他属性(例如压缩):
zfs set compression=lz4 tank/vmdisk

删除 ZVOL (Destroy)

  • 删除 ZVOL(警告:这将永久删除卷及其所有数据!):
zfs destroy tank/vmdisk
  • 如果 ZVOL 有快照,需要先删除快照或使用 -r-R 选项:
# 递归删除 ZVOL 及其所有快照和克隆
zfs destroy -r tank/vmdisk

快照与克隆 (Snapshot & Clone)

同样可以为 ZVOL 创建快照

  • 为 ZVOL 创建快照:
zfs snapshot tank/vmdisk@backup-2023-10-27
  • 列出 ZVOL 的快照:
zfs list -t snapshot | grep tank/vmdisk
  • 从快照克隆一个新的 ZVOL:
zfs clone tank/vmdisk@backup-2023-10-27 tank/vmdisk_clone
- 克隆初始时几乎不占用额外空间,它与源快照共享数据块。
  • 删除快照:
zfs destroy tank/vmdisk@backup-2023-10-27

发送与接收 (Send & Receive - 用于备份和迁移)

  • 将 ZVOL 快照发送到文件:
zfs send tank/vmdisk@backup-2023-10-27 > /path/to/backupfile.zfs
  • 从文件接收快照到新的 ZVOL:
zfs receive otherpool/restored_vmdisk < /path/to/backupfile.zfs
  • 增量发送/接收 (只发送两次快照之间的差异):
# 发送从 snap1 到 snap2 的增量流
zfs send -i tank/vmdisk@snap1 tank/vmdisk@snap2 > /path/to/incremental_backup.zfs

# 在目标端接收增量流
zfs receive targetpool/vmdisk_replica < /path/to/incremental_backup.zfs

ZFS snapshot(快照)

|--- 物理磁盘/设备 (disk)|--- 虚拟设备 (vdev)
│  │
存储池 (zpool)
├── 根数据集(root dataset)
│   ├── 子数据集(child dataset)
│   ├── 卷(zvol,块设备)
│   └── 快照(snapshot)

快照的定义

快照是指文件系统某一个时间点只读副本

即时创建、数量不限,不占用额外空间 - 块仅在发生更改时才会被复制
可通过每个文件系统根目录下的 **.zfs/snapshot** 访问
使用户可在没有系统管理员介入的情况下恢复文件,

创建快照

ZFS数据集快照
  • 创建快照
# 为数据集创建快照
zfs snapshot  <存储池>/<数据集>/<子数据集>@<快照名称标识符>
  • 删除快照
# 删除数据集快照
zfs destroy -R zfspool/home/usera@monday
ZVOL快照
  • ZVOL 创建快照
# 创建快照
## zfs snapshot 挂载点名称@快照名称
zfs snapshot volume@snapname

  • 删除ZVOL快照
# 删除快照
## zfs destroy 挂载点名称@快照名称
zfs destroy data@2020-04-28
为所有后代文件系统创建快照
# 通过使用-r选项可为所有后代文件系统创建快照
## ## zfs snapshot -r 挂载点名称@快照名称
zfs snapshot -r data@2020-04-28
删除后代快照

如果使用**-r**参数来创建快照,需要先删除下层快照。

按照提示删除下层快照即可

查看快照列表

# 查看快照列表
zfs list -t snapshot

  • 查看后代快照
# 查看后代快照列表
zfs list -t snapshot -r data@2020-04-28

查看快照文件详情
查看快照中的文件
# 查看星期三的foo.c版本
cat /zfspool/home/usera/.zfs/snapshot/wednesday/foo.c
查看数据集快照详情
# 默认显示
zfs list -t snapshot -r zfspool/home

# 列出为特定文件系统创建的快照
zfs list -r -t snapshot -o name,creation zfspool/home

查看快照属性

# 获取快照属性
## zpool get listsnapshots 快照名
zpool get listsnapshots data

设置快照属性

快照属性的默认值为listsnapshots=on,zfs list命令**会显示**快照列表。
设置listsnapshots=offzfs list命令**不会显示**快照列表;要使用 **zfs list -t snapshot**命令显示快照信息。

# 设置快照显示属性
## zpool set listsnapshots=off 快照名
zpool set listsnapshots=off data

保持快照

保持快照的作用是防止被不小心销毁。
每个快照都有一个关联的用户引用计数,其初始值为 0。在一个快照上设置一个保持标志时,此计数**递增1**;释放一个保持标志时,此计数**递减1**
**设置保持**后会**禁止删除**该快照。

# 保持一个快照或一组快照
zfs hold keep data@2020-04-28

# 使用-r选项递归保持所有后代文件系统的快照
zfs hold -r keep data@2020-04-28

# 要销毁保持的快照,须使用-d选项
zfs destroy -d data@2020-04-28

# 显示受保持的快照列表
zfs holds data@2020-04-28
zfs holds -r data@2020-04-28

# 释放对一个快照或一组快照的保持
zfs release -r keep data@2020-04-28

# 释放快照后销毁快照
zfs destroy -r data@2020-04-28

设置**保持快照**后,删除快照时将**禁止删除**

快照重命名

# 单个快照重命名
zfs rename data@2020-04-28 data@2020-04-27

# 以递归方式重命名快照
zfs rename -r data@2020-04-28 @2020-04-27

快照回滚

-r 删除中间快照,恢复早期版本
-R 选项以销毁中间快照的克隆

# 示例快照列表
zfs list -t snapshot -r zfspool/home

# 将zfspool/home/matt文件系统回滚到tuesday快照
## zfs rollback <存储池>/<数据集>@快照名
zfs rollback zfspool/home/matt@tuesday

# 删除中间的快照即可恢复到之前的版本
zfs rollback -r zfspool/home/matt@tuesday

快照恢复

无法直接回滚到之前快照的时候,就需要手动恢复数据了。
原理:将快照挂载到一个临时挂载点,进入这个挂载点拷贝数据。

# 将快照挂载到一个临时挂载点,手动进行数据恢复
mount -t zfs data@2020-04-28 /mnt/recovery

对比两个快照差异

# 确定两个快照之间的差异
zfs diff zfspool/home/tim@snap1 zfspool/home/timh@snap2

ZFS Clone

快照的可写副本,
即时创建、数量不限;
存储大部分为共享数据的众多专用副本的理想方法.
软件安装
工作区
无盘客户机

数据集克隆

# 创建OpenSolaris源代码的克隆
zfs clone zfspool/solaris@monday zfspool/ws/lori/fix

发送与接收 (Send & Receive - 用于备份和迁移)

基于快照点
完整备份:任何快照
增量备份:任何快照增量
速度很快 - 开销与更改的数据成比例
非常高效,可执行远程复制

生成完整备份

# 生成完整备份
zfs send zfspool/fs@A >/backup/A

生成增量备份

# 生成增量备份
zfs send -i zfspool/fs@A zfspool/fs@B >/backup/B-A

远程复制:每分钟发送一次增量

# 远程复制:每分钟发送一次增量
zfs send -i zfspool/fs@11:31 zfspool/fs@11:32 |
ssh host zfs receive -d /zfspool/fs

设置属性

自动以NFS方式共享该文件系统

# 自动以 NFS 方式共享该文件系统
zfs set sharenfs=rw zfspool/home

对文件系统中所有数据启用压缩

# 对文件系统中所有数据启用压缩
zfs set compression=on zfspool

将用户A的最大空间限制为10g

# 将用户A的最大空间限制为10g
zfs set quota=10g zfspool/home/usera

保证用户B有20g的预留空间

# 保证用户B有20g的预留空间
zfs set reservation=20g zfspool/home/userb

可通过命令查询文件系统的所有属性

# 可通过命令查询文件系统的所有属性
zfs get all zfspool/home

可通过命令查询存储池的所有属性

# 可通过命令查询存储池的所有属性
zpool get all zfspool

大多数属性可通过继承方式自动设置

# 大多数属性可通过继承方式自动设置
zfs inherit <property> zfspool/home/eschrock

ZFS数据迁移

独立于主机的磁盘格式
将服务器从 x86 更改为 SPARC,也能运行
自适应字节存储顺序 (Adaptive endianness):在两个平台上都无需额外成本
写入总是使用本地字节存储顺序 (native endianness),在块指针中设置位
仅当主机字节存储顺序 (endianness) != 块字节存储顺序时,才会针对读取进行字节交换

ZFS 负责所有处理
无需考虑设备路径、配置文件、/etc/vfstab 等等
ZFS 会在必要时进行共享/取消共享、挂载/取消挂载等等

从旧服务器上导出池

# 从旧服务器上导出池
zpool export zfspool

物理移动磁盘并将池导入到新服务器中

# 物理移动磁盘并将池导入到新服务器中
zpool import zfspool

磁盘管理

|--- 物理磁盘/设备 (disk)|--- 虚拟设备 (vdev)
│  │
存储池 (zpool)
├── 根数据集(root dataset)
│   ├── 子数据集(child dataset)
│   ├── 卷(zvol,块设备)
│   └── 快照(snapshot)

查看磁盘

# 查看磁盘
lsblk

添加磁盘

# 将磁盘添加到存储池中
zpool add zfspool -f /dev/sdx

# 添加新设备
##  (type: “”,mirror,raidz,raidz2)
zpool add zfspool <type> c0t2d0 c0t3d0 c0t4d0

标记磁盘运行状态

将设备停止或手工启动

# 将设备停止
# 在有故障的时候,标记磁盘状态为非运行
zpool offline zfspool sdc

# 将设备上线(启动)
# 标记磁盘状态为运行
zpool online zfspool sdc

删除磁盘

不能直接删除一个磁盘,因为它是一个冗余或raidz池

# 将磁盘从存储池中删除
zpool remove <存储池名称> /dev/sdx

vdc已从zfspool中删除

添加热备件(hot spare)磁盘

https://www.onitroad.com/jc/unix/solaris/solaris-zfs-how-to-specify-hot-spare-in-storage-pool.html
热备件磁盘平时是空闲状态,当工作磁盘出现故障时,可以立即将热备件磁盘附加到存储池中,顶替故障磁盘后,将故障磁盘分离,然后到物理机上拆除更换故障磁盘。

创建存储池时指定镜像和热备件磁盘
# 创建存储池时添加备件
### mirror参数为镜像,后面跟两个磁盘
### spare表示热备件,后面参数跟磁盘
zpool create <存储池名称> mirror sdb sdc spare <热备件磁盘1> <热备件磁盘2>
向现有存储池添加热备件磁盘
# 添加热备磁盘
zpool add zfspool spare c0t2d0

# 向现有存储池添加热备件
## zpool add 存储池名称 spare 磁盘名
### spare表示热备件,后面参数跟磁盘名
zpool add <存储池名称> spare sdf sdg
从现有存储池中删除热备件磁盘
# 将热备磁盘删除
# 从现有存储池中删除热备件
## zpool remove 存储池名称 spare 磁盘名
zpool remove <存储池名称> sdf
附加热备件磁盘

如果已使用热备件自动替换了故障磁盘,则您可能需要在替换故障磁盘分离该热备件

# 例如: 如果替换故障磁盘后,sdf仍为活动热备件,则对其进行附加
zpool attach <存储池名称> sdf
替换故障磁盘
# 启动指定热备件磁盘
# 磁盘发生故障,使用replace命令替换故障磁盘sdc
## 使用用SDD磁盘替换SDC磁盘
zpool replace <存储池名称> sdc sdd
分离热备件磁盘

停止指定热备件磁盘

# 停止指定热备件磁盘
# 例如: 如果替换故障磁盘后,sdf仍为活动热备件,则对其进行分离
zpool detach <存储池名称> sdf

磁盘镜像配置

镜像会让两个磁盘数据完全一致,损坏一个磁盘,另一个磁盘的数据还在。
替换这个损坏的磁盘,数据会很快同步回来,保障数据不丢失。

添加/移除镜像磁盘

# 添加镜像设备
zpool attach <存储池> <磁盘1> <磁盘2>
zpool attach zfspool c0t1d0 c0t2d0

# 移除镜像设备
zpool detach <存储池> <磁盘1>
zpool detach zfspool c0t2d0

使用镜像创建存储池

# 在镜像配置当中我们将爆力的测试一个设备
## mirror参数为镜像,后面跟两个磁盘
zpool create -f <存储池名称> mirror sdd sde
模拟磁盘故障
# 这将创建一个镜像磁盘池组成的SDD和SDE
# 现在,让我们故意损坏SDD写零到磁盘中
dd if=/dev/zero of=/dev/sdd
检测存储池是否损坏
# 我们将使用“scrub”命令来检测这种损坏
zpool scrub <存储池名称>
替换磁盘
# 使用用SDC替换SDD
zpool replace <存储池名称> sdd sdc

# 查看存储池状态
zpool status

查看存储池当前状态和I/O状况

# 查看存储池当前状态
zpool status -v <存储池> 

# 查看存储池当前I/O状况
zpool iostat <存储池> 1

添加/删除独立的日志设备(性能改善)

# 添加独立的日志设备(性能改善)
zpool add <存储池名称> log <磁盘>

# 删除独立的日志设备(性能改善) 
zpool remove <存储池名称> <磁盘>

ZFS 权限管理

可以将zfs(1M) 的管理权限分派给普通用户
zfs allow
zfs unallow

将权限授予一个普通用户

# 将权限授予一个普通用户
zfs allow marks create,snapshot <存储池名称>/<数据集>

将指定权限回收

# 将指定权限回收
zfs unallow marks create,snapshot <存储池名称>/<数据集>

查看文件系统当前的权限

# 查看文件系统当前的权限
zfs allow <存储池名称>/<数据集>

其它命令

显示存储池所有操作历史记录

# 显示存储池所有操作历史记录
zpool history <存储池名称>

升级文件系统到指定ZPL版本

# 升级文件系统到指定ZPL版本
zfs upgrade -V <version> <存储池名称>/<数据集>

手工挂载/卸载文件系统

# 手工挂载文件系统
zfs mount -a

# 卸载文件系统
zfs unmount <存储池名称>/<数据集>

# 自动卸载临时挂载 
zfs unmount -a
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

教Linux的李老师

赞赏是第一生产力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值