ZFS学习笔记

【ZFS学习笔记】要须心地收汗马,孔孟行世目杲杲。这篇文章主要讲述ZFS学习笔记相关的知识,希望能为你提供帮助。
zfs学习笔记 一、zfs概念:

  • ZFS介绍
  • ZFS特性:
存储池 raid 集成于各种RAID与条带技术于一身的技术[软raid],不再依赖于硬件RAID卡,只依赖于计算机上能转接多少硬盘。 写实拷贝校验 和 拷贝 --- 把数据做成几分相同的数据进行存储。 快照和克隆相当于给当前文件系统 的时间点上拍了一个照片[照片有时光机的功能] 克隆, 很快地复制出一文件系统。 动态条带化容量随时进行扩展 可变块尺寸传统设备的块大小要依赖于单一文件系统的配置,ZFS是可以调整块大小的。

二、ZFS操作:
  1. linux安装zfs:
root@ubt:~# apt install zfsutils-linux root@ubt:~# which zfs /usr/sbin/zfs

  1. 存储池创建:
root@ubt:~# zpool create diskz1 sdb sdc #添加一块硬盘 root@ubt:~# zpool add diskz1 sdd root@ubt:~# zpool remove diskz1 sdx#移除故障硬盘 #挂载所有ZFS文件系统 root@ubt:~# zfs create -V 100G -o compression=lz4 -o volblocksize=128k diskz1/data0 root@ubt:~# zfs mount -a

  1. 查看存储池:
root@ubt:~# zpool status pool: diskz1 state: ONLINE scan: none requested config:NAMESTATEREAD WRITE CKSUM diskz1ONLINE000 sdbONLINE000 sdcONLINE000 sddONLINE000errors: No known data errors

  1. 销毁存储池:
root@ubt:~# zpool destroy -f diskz1

  1. 创建镜像存储池:
root@ubuntu:~# zpool create diskz2 mirror sdd,c root@ubuntu:~# zpool list NAMESIZEALLOCFREECKPOINTEXPANDSZFRAGCAPDEDUPHEALTHALTROOT diskz29.50G132K9.50G--0%0%1.00xONLINE- root@ubt:~# zpool status pool: diskz2 state: ONLINE scan: none requested config:NAMESTATEREAD WRITE CKSUM diskz2ONLINE000 mirror-0ONLINE000 sddONLINE000 sdcONLINE000errors: No known data errors

  1. 创建文件系统:
#创建文件系统data_0 root@ubuntu:~# zfs create diskz2/data_0 #查看挂载 root@ubuntu:~# df -hT |grep data_0 diskz2/data_0zfs9.3G128K9.3G1% /diskz2/data_0 #如果没有挂载,可以执行zfs mount -a 挂载ZFS文件系统 root@ubuntu:~# zfs mount -a

  1. 进入文件系统:
root@ubt:~# cd /diskz2/data_0/ root@ubt:/diskz2/data_0# dd if=/dev/zero of=./file1 count=1 bs=10M 1+0 records in 1+0 records out 10485760 bytes (10 MB, 10 MiB) copied, 0.0215152 s, 487 MB/s

  1. 查看ZFS文件系统属性:
root@ubt:/diskz2/data_0# zfs get all diskz2/data_0 NAMEPROPERTYVALUESOURCE diskz2/data_0typefilesystem- diskz2/data_0creationMon Mar 147:39 2022- diskz2/data_0used10.0M- diskz2/data_0available96.4G- diskz2/data_0referenced10.0M- diskz2/data_0compressratio1.00x- diskz2/data_0mountedyes- diskz2/data_0quotanonedefault diskz2/data_0reservationnonedefault diskz2/data_0recordsize128Kdefault diskz2/data_0mountpoint/diskz2/data_0default diskz2/data_0sharenfsoffdefault diskz2/data_0checksumondefault diskz2/data_0compressionoffdefault diskz2/data_0atimeondefault diskz2/data_0devicesondefault diskz2/data_0execondefault diskz2/data_0setuidondefault diskz2/data_0readonlyoffdefault diskz2/data_0zonedoffdefault diskz2/data_0snapdirhiddendefault diskz2/data_0aclinheritrestricteddefault diskz2/data_0createtxg24- diskz2/data_0canmountondefault diskz2/data_0xattrondefault diskz2/data_0copies1default diskz2/data_0version5- diskz2/data_0utf8onlyoff- diskz2/data_0normalizationnone- diskz2/data_0casesensitivitysensitive- diskz2/data_0vscanoffdefault diskz2/data_0nbmandoffdefault diskz2/data_0sharesmboffdefault diskz2/data_0refquotanonedefault diskz2/data_0refreservationnonedefault diskz2/data_0guid8285245533383785742- diskz2/data_0primarycachealldefault diskz2/data_0secondarycachealldefault diskz2/data_0usedbysnapshots0B- diskz2/data_0usedbydataset10.0M- diskz2/data_0usedbychildren0B- diskz2/data_0usedbyrefreservation0B- diskz2/data_0logbiaslatencydefault diskz2/data_0objsetid146- diskz2/data_0dedupoffdefault diskz2/data_0mlslabelnonedefault diskz2/data_0syncstandarddefault diskz2/data_0dnodesizelegacydefault diskz2/data_0refcompressratio1.00x- diskz2/data_0written10.0M- diskz2/data_0logicalused10.0M- diskz2/data_0logicalreferenced10.0M- diskz2/data_0volmodedefaultdefault diskz2/data_0filesystem_limitnonedefault diskz2/data_0snapshot_limitnonedefault diskz2/data_0filesystem_countnonedefault diskz2/data_0snapshot_countnonedefault diskz2/data_0snapdevhiddendefault diskz2/data_0acltypeoffdefault diskz2/data_0contextnonedefault diskz2/data_0fscontextnonedefault diskz2/data_0defcontextnonedefault diskz2/data_0rootcontextnonedefault diskz2/data_0relatimeoffdefault diskz2/data_0redundant_metadataalldefault diskz2/data_0overlayoffdefault diskz2/data_0encryptionoffdefault diskz2/data_0keylocationnonedefault diskz2/data_0keyformatnonedefault diskz2/data_0pbkdf2iters0default diskz2/data_0special_small_blocks0default

  1. 修改文件系统属性:
#关闭数据校验示例 root@ubuntu:/diskz2/data_0# zfs get checksum diskz2/data_0 NAMEPROPERTYVALUESOURCE diskz2/data_0checksumonlocal root@ubuntu:/diskz2/data_0# zfs set checksum=off diskz2/data_0 root@ubuntu:/diskz2/data_0# zfs get checksum diskz2/data_0 NAMEPROPERTYVALUESOURCE diskz2/data_0checksumofflocal#给文件系统限额示例 root@ubuntu:/diskz2/data_0# zfs set quota=2g diskz2/data_0 root@ubuntu:/diskz2/data_0# zfs get quota diskz2/data_0 NAMEPROPERTYVALUESOURCE diskz2/data_0quota2Glocal root@ubuntu:/diskz2/data_0# dd if=/dev/zero of=./file0 count=4096 bs=1M dd: error writing ./file0: Disk quota exceeded 2048+0 records in 2047+0 records out 2147352576 bytes (2.1 GB, 2.0 GiB) copied, 5.56725 s, 386 MB/s root@ubuntu:/diskz2/data_0# ls -lh total 2.1G -rw-r--r-- 1 root root 2.0G Aug 13 07:57 file0#给用户限额示例 root@ubuntu:/diskz2/data_0# zfs set userquota@hw=100M diskz2/data_0 root@ubuntu:/diskz2/data_0# su - hw hw@ubuntu:~$ cd /diskz2/data_0/ hw@ubuntu:/diskz2/data_0$ ls hw@ubuntu:/diskz2/data_0$ dd if=/dev/zero of=./file1 count=99 bs=1M 99+0 records in 99+0 records out 103809024 bytes (104 MB, 99 MiB) copied, 0.12715 s, 816 MB/s hw@ubuntu:/diskz2/data_0$ dd if=/dev/zero of=./file2 count=99 bs=1M dd: error writing ./file2: Disk quota exceeded 81+0 records in 80+0 records out 84541440 bytes (85 MB, 81 MiB) copied, 0.114823 s, 736 MB/s hw@ubuntu:/diskz2/data_0$ ls -lh total 180M -rw-rw-r-- 1 hw hw 99M Aug 13 08:07 file1 -rw-rw-r-- 1 hw hw 81M Aug 13 08:07 file2 hw@ubuntu:/diskz2/data_0$ dd if=/dev/zero of=./file3 count=99 bs=1M dd: failed to open ./file3: Disk quota exceeded

  1. 快照操作:
官方文档:https://docs.oracle.com/cd/E26926_01/html/E25826/gbciq.html#创建快照 zfs snapshot diskz2/data_0@first#查看快照 root@ubuntu:/diskz2# zfs list -t snapshot NAMEUSEDAVAILREFERMOUNTPOINT diskz2/data_0@first13K-180M- root@ubuntu:/diskz2# zfs list -t snapshot -r diskz2/data_0 NAMEUSEDAVAILREFERMOUNTPOINT diskz2/data_0@first13K-180M-#还原快照 root@ubuntu:/diskz2/data_0# ls file1file2 root@ubuntu:/diskz2/data_0# rm -rf * root@ubuntu:/diskz2/data_0# ls root@ubuntu:/diskz2/data_0# zfs rollback diskz2/data_0@first root@ubuntu:/diskz2/data_0# ls file1file2#删除快照 root@ubuntu:~# zfs list -t snapshot -r diskz2/data_0 NAMEUSEDAVAILREFERMOUNTPOINT diskz2/data_0@first0B-25K- root@ubuntu:~# zfs destroy -d diskz2/data_0@first root@ubuntu:~# zfs list -t snapshot -r diskz2/data_0 no datasets available

三、ZFS物理组成部分: 3.1 描述:
3.2 创建raidz1:
root@ubuntu:~# zpool create diskz1 raidz1 sdb,c,d root@ubt:~# zpool list NAMESIZEALLOCFREECKPOINTEXPANDSZFRAGCAPDEDUPHEALTHALTROOT diskz1298G199K298G--0%0%1.00xONLINE- root@ubt:~# zpool status no pools available root@ubt:~# zpool create diskz1 raidz1 sdb,c,d root@ubt:~# zpool status pool: diskz1 state: ONLINE scan: none requested config:NAMESTATEREAD WRITE CKSUM diskz1ONLINE000 raidz1-0ONLINE000 sdbONLINE000 sdcONLINE000 sddONLINE000errors: No known data errors #sdb,c,d每块磁盘大小为100G,创建raidz1(1是单倍校验,另外还有2、3--2倍校验和3倍校验)后可用空间为192G,有小部分空间被用来做哈希校验,对出错的数据进行修补。 #所需硬盘数量=raidzx+1,即使raidz1至少需要2块硬盘、raidz2至少需要3块硬盘、raidz3至少需要4块硬盘; #存储容量计算方式=(N-P)*X;N硬盘数量,P几倍校验,X硬盘容量;root@ubt:~# zfs create diskz1/data root@ubt:~# zfs list NAMEUSEDAVAILREFERMOUNTPOINT diskz1153K192G30.6K/diskz1 diskz1/data30.6K192G30.6K/diskz1/data #创建文件系统后,可以看到可用空间只有192G,因为raidz1有一块盘是拿来做校验的,因此raidz1坏掉一块盘不会影响数据完整性。

3.3 虚拟设备:
  • 使用硬盘创建存储池:
root@ubt:~# zpool create disk0 sdb #创建一个只有sdb的存储池root@ubt:~# zpool status pool: disk0 state: ONLINE scan: none requested config:NAMESTATEREAD WRITE CKSUM disk0ONLINE000 sdbONLINE000errors: No known data errors

  • 使用文件创建存储池:
root@ubuntu:/diskz1/zfs-file# truncate -s 6G zdisk.0 root@ubuntu:/diskz1/zfs-file# truncate -s 6G zdisk.1 root@ubuntu:/diskz1/zfs-file# ls -lh zdisk.* -rw-r--r-- 1 root root 6.0G Aug 14 06:35 zdisk.0 -rw-r--r-- 1 root root 6.0G Aug 14 06:36 zdisk.1 root@ubuntu:/diskz1/zfs-file# zpool create diskz2 /diskz1/zfs-file/zdisk.0 /diskz1/zfs-file/zdisk.1 root@ubuntu:/diskz1/zfs-file# zpool status diskz2 pool: diskz2 state: ONLINE scan: none requested config:NAMESTATEREAD WRITE CKSUM diskz2ONLINE000 /diskz1/zfs-file/zdisk.0ONLINE000 /diskz1/zfs-file/zdisk.1ONLINE000errors: No known data errors

3.4 zfs存储池的两种组织模式:
3.4.1 mirror
root@ubuntu:~# zpool create -f diskzM mirror sdb sdc mirror sdd sde root@ubuntu:~# zpool status diskzM pool: diskzM state: ONLINE scan: none requested config:NAMESTATEREAD WRITE CKSUM diskzMONLINE000 mirror-0ONLINE000 sdbONLINE000 sdcONLINE000 mirror-1ONLINE000 sddONLINE000 sdeONLINE000errors: No known data errors root@ubuntu:~# zpool list NAMESIZEALLOCFREECKPOINTEXPANDSZFRAGCAPDEDUPHEALTHALTROOT diskzM19G147K19.0G--0%0%1.00xONLINE-

3.4.2 raidz
root@ubuntu:~# zpool create diskz1 raidz sdb,c,d,e raidz sdf,g,h,i root@ubuntu:~# zpool list diskz1 NAMESIZEALLOCFREECKPOINTEXPANDSZFRAGCAPDEDUPHEALTHALTROOT diskz179G263K79.0G--0%0%1.00xONLINE- root@ubuntu:~# zpool status pool: diskz1 state: ONLINE scan: none requested config:NAMESTATEREAD WRITE CKSUM diskz1ONLINE000 raidz1-0ONLINE000 sdbONLINE000 sdcONLINE000 sddONLINE000 sdeONLINE000 raidz1-1ONLINE000 sdfONLINE000 sdgONLINE000 sdhONLINE000 sdiONLINE000errors: No known data errors

3.4.3 spare
root@ubuntu:~# zpool add diskz1 spare sdj root@ubuntu:~# zpool status diskz1 pool: diskz1 state: ONLINE scan: none requested config:NAMESTATEREAD WRITE CKSUM diskz1ONLINE000 raidz1-0ONLINE000 sdbONLINE000 sdcONLINE000 sddONLINE000 sdeONLINE000 raidz1-1ONLINE000 sdfONLINE000 sdgONLINE000 sdhONLINE000 sdiONLINE000 spares sdjAVAILerrors: No known data errors #可以看到spares下面出现了sdj,当raidz组中的磁盘出现故障时,spare盘会顶替上去。

3.4.4 log
  • 添加日志盘
root@ubuntu:~# zpool create diskz1 raidz2 sdb,c,d,e,f root@ubuntu:~# zpool add diskz1 log sdg root@ubuntu:~# zpool status pool: diskz1 state: ONLINE scan: none requested config:NAMESTATEREAD WRITE CKSUM diskz1ONLINE000 raidz2-0ONLINE000 sdbONLINE000 sdcONLINE000 sddONLINE000 sdeONLINE000 sdfONLINE000 logs sdgONLINE000errors: No known data errors#给日志盘添加一个 镜像 root@ubuntu:~# zpool attach diskz1 sdg sdh root@ubuntu:~# zpool status pool: diskz1 state: ONLINE scan: resilvered 0B in 0 days 00:00:00 with 0 errors on Sat Aug 14 07:45:26 2021 config:NAMESTATEREAD WRITE CKSUM diskz1ONLINE000 raidz2-0ONLINE000 sdbONLINE000 sdcONLINE000 sddONLINE000 sdeONLINE000 sdfONLINE000 logs mirror-1ONLINE000 sdgONLINE000 sdhONLINE000errors: No known data errors#attach与detach对应

3.4.5 cache
root@ubuntu:~# zpool add diskz1 cache sdj sdi root@ubuntu:~# zpool status pool: diskz1 state: ONLINE scan: resilvered 0B in 0 days 00:00:00 with 0 errors on Sat Aug 14 07:45:26 2021 config:NAMESTATEREAD WRITE CKSUM diskz1ONLINE000 raidz2-0ONLINE000 sdbONLINE000 sdcONLINE000 sddONLINE000 sdeONLINE000 sdfONLINE000 logs mirror-1ONLINE000 sdgONLINE000 sdhONLINE000 cache sdjONLINE000 sdiONLINE000errors: No known data errors#注:虚拟设备不能被嵌套使用,所以 mirror 或 raidz 等虚拟设备只能包含文件或磁盘。比如:在 mirror 中再做 mirror(或者其他虚拟设备组合) 是不允许的。一个存储池在配置的最顶层(可以被认为是“root[根]”虚拟设备)可以有任意数量的虚拟设备。数据在所有顶层设备之间被动态均衡的访问。当有新虚拟设备被添加时,ZFS 会自动的对其存储数据。虚拟设备在命令执行完毕就会被指定。关键字 “mirror”和 “raidz”被用于区别阵列组在什么地方开始以及到什么地方结束。比如,以下命令用于创建两个虚拟顶层设备,每个虚拟设备是对两块盘进行镜像。#zpool create mypool mirror da0 da1 mirror da2 da3

四、设备故障:
4.1 Degraded
  • 一个或多个相关设备处于 degraded 状态或 faulted 状态,但是存在足够的冗余以支持访问。底层条件如下:
    • 由于某些错误导致校验错误超过了可接受级别,设备已处于分裂状态。且 ZFS 有必要继续使用该设备。
    • I/O 错误数量超过了可接受级别。因为有足够的冗余副本支持工作,所以设备还没有被标记为 faulted 状态。
root@ubuntu:~# zpool offline diskz1 sdc root@ubuntu:~# zpool status pool: diskz1 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. scan: resilvered 0B in 0 days 00:00:00 with 0 errors on Sat Aug 14 07:45:26 2021 config:NAMESTATEREAD WRITE CKSUM diskz1DEGRADED000 raidz2-0DEGRADED000 sdbONLINE000 sdcOFFLINE000 sddONLINE000 sdeONLINE000 sdfONLINE000 logs mirror-1ONLINE000 sdgONLINE000 sdhONLINE000 cache sdjONLINE000 sdiONLINE000errors: No known data errors

4.2 Faulted
  • 一个或多个相关设备处于 faulted 状态下,不存在足够的冗余以支持访问。底层条件如下:
    • 设备可以被打开,但是内容错误。
    • I/O 错误已经超过了可接受级别,设备是 faulted 状态的,且不允许访问设备。
OFFLINE 设备被使用 “zpool offline” 命令明确的指定为离线。ONLINE 设备在线并且工作。REMOVED 设备在系统运行状态下被物理移除。热插拔属性属于物理支持,不是所有平台上都被支持。UNAVAIL 设备不能被打开。当一个设备无效时导入一个存储池,只要路径第一次不能被正确装配那么这个设备就会被使用唯一标识而不是其全路径来确认。[不是物理损坏,而是物理访问句柄无效]

五、Properties
root@ubuntu:~# zpool get all diskz1 NAMEPROPERTYVALUESOURCE diskz1size49.5G- diskz1capacity0%- diskz1altroot-default diskz1healthDEGRADED- diskz1guid1857335905105017657- diskz1version-default diskz1bootfs-default diskz1delegationondefault diskz1autoreplaceoffdefault diskz1cachefile-default diskz1failmodewaitdefault diskz1listsnapshotsoffdefault diskz1autoexpandoffdefault diskz1dedupditto0default diskz1dedupratio1.00x- diskz1free49.5G- diskz1allocated552K- diskz1readonlyoff- diskz1ashift0default diskz1comment-default diskz1expandsize-- diskz1freeing0- diskz1fragmentation0%- diskz1leaked0- diskz1multihostoffdefault diskz1checkpoint-- diskz1load_guid5384114779895256754- diskz1autotrimoffdefault diskz1feature@async_destroyenabledlocal diskz1feature@empty_bpobjenabledlocal diskz1feature@lz4_compressactivelocal diskz1feature@multi_vdev_crash_dumpenabledlocal diskz1feature@spacemap_histogramactivelocal diskz1feature@enabled_txgactivelocal diskz1feature@hole_birthactivelocal diskz1feature@extensible_datasetactivelocal diskz1feature@embedded_dataactivelocal diskz1feature@bookmarksenabledlocal diskz1feature@filesystem_limitsenabledlocal diskz1feature@large_blocksenabledlocal diskz1feature@large_dnodeenabledlocal diskz1feature@sha512enabledlocal diskz1feature@skeinenabledlocal diskz1feature@edonrenabledlocal diskz1feature@userobj_accountingactivelocal diskz1feature@encryptionenabledlocal diskz1feature@project_quotaactivelocal diskz1feature@device_removalenabledlocal diskz1feature@obsolete_countsenabledlocal diskz1feature@zpool_checkpointenabledlocal diskz1feature@spacemap_v2activelocal diskz1feature@allocation_classesenabledlocal diskz1feature@resilver_deferenabledlocal diskz1feature@bookmark_v2enabledlocal

  • alloc:存储池中已经被物理分配的有效存储空间。
  • capacity:存储池的已用空间,这个属性也可以使用他的短列名“cap”给出。
  • comment:存储成由文本字符串组成且可打印ASCII字符集,即使存储池失效这个属性也同样是有效的。对于存储池的这个特性超级管理员可以获得更多额外的有效帮助信息。
  • dedupratio:是为存储池指定的精简重复数据的属性,用乘法表示。比如:重复数据删除率的值为 1.76 则表示有 1.76 单位的数据被存储,但是只用到 1 单位的实际硬盘存储空间 [可以理解为:1.76:1]。
  • free:存储池中未被划分的数据块的数量。[包括未被添加到 存储池中的游离状态的磁盘总空间 ,以及添加到存储池中不能被正常使用的剩余磁盘空间 ]。
  • freeing:当一个文件系统或者一个快照被摧毁后他们所使用的空间会异步的回归到存储池中。freeing 则表示这部分需要被回收的空间。一段时间后 freeing 空间将减少 free 空间将增加[注:回收过程]。
  • expandsize:存储池内未初始化的空间或者是可以增加存储池容量的设备。未初始化的设备包括具有 EFI 标签且未上线的 vdev 设备(比如使用zpool online -e)。当 LUN 扩展时,这块空间自动增加。[注:其实意思是说当使用大容量新盘替换小容量旧盘时,新盘多出来的容量可以被自动扩展和识别]。
  • guid:存储池的唯一标识。
  • health:当前存储池的健康状态,状态值可以是:online、degraded、faulted、offline、remove、unavail等。
  • size:存储池的总空间大小。
  • unsupported@feature_guid:给出“信息不被支持的属性已经在存储池上启用”的提示。
  • used:存储池中已使用的空间大小。
  • altroot:修改zfs文件系统默认挂载位置。只能在创建时设定zpool create -o altroot=/mp diskz mirror sdb sdc。
  • readonly=on|off:如果设置了on,存储池被以只读的方式导入,并有如下限制:
    • 同步在专用日志设备中的数据将不可访问。
    • 不能改变池的属性。
    • 此池中的数据集也只能以只读方式被挂载。
    • 如果向一个只读存储池中写入数据,导入和导出存储池也是必须的。
    • autoexpand 所有硬盘替换更大的硬盘后,会自动扩展zpool空间。
六、修改存储池属性:
root@ubuntu:~# zpool get comment diskz1 NAMEPROPERTYVALUESOURCE diskz1comment-default root@ubuntu:~# zpool set comment="here is diskz1" diskz1 root@ubuntu:~# zpool get comment diskz1 NAMEPROPERTYVALUESOURCE diskz1commenthere is diskz1local

七、挂载和引入:

    推荐阅读