我所在的单位是云和恩墨的客户,在备份产品中使用了他家的数据库备份一体机。身为技术人员,一般都对产品的实现原理比较感兴趣。这里探寻一下数据库备份一体机中用到的ZFS快照技术。
在任何时候磁盘资源都是非常宝贵的,特别是昂贵的SSD磁盘。以传统方式复制数据库复本,空间增长是非常恐怖的。比如10T的数据库,复制一个复本就是20T。基于上不可能同时运行多个复本库。但引入了ZFS的快照功能,在一台机器上运行多个复本库成为了可能。因为快照基本不占空间,只有产生新数据时才占空间。数据库备份一体机中所使用的ZFS是什么样的文件系统,可以做到共享oracle数据文件?
ZFS是 Sun Solaris 系统上的一种文件系统,后来Sun被Oracle收购,ZFS也就成了 Oracle Solaris 的一部分。
ZFS有些有趣特性,比如写时拷贝和快照(以下引用内容参考了segmentfault 上的文章):
“
在大多数文件系统上,当数据被覆盖时,它会永远丢失。在 ZFS 上,新信息被写入不同的块,写入完成后,文件系统元数据将更新以指向新信息。这确保如果在写入过程中系统崩溃(或发生其他事情),旧数据将被保留,这也意味着系统在崩溃后不需要运行文件系统检查 fsck 。
写时拷贝导致另一个 ZFS 功能:快照。快照包含文件系统的原始版本,实时文件系统包含自快照以来所做的任何更改,不使用额外的空间。当新数据写入实时文件系统时,会分配新块来存储这些数据。快照能够以只读方式挂载以恢复文件的过去版本,还可以将实时系统回滚到以前的快照。
”
参考:
https://segmentfault.com/a/1190000040728575
在数据库备份一体机的ZDBM界面上可以对磁盘进行相应的ZFS磁盘组操作:

当前系统建了两个池子,以磁盘类型进行了区分,一个ssd池,一个hdd池。其中ssd池由两块做了RAID的磁盘组成,每块12T。

真实的磁盘映射关系为:
# ls -l dev/disk/by-id/*| \grep wwn| \grep -v part| \awk '{print $9" "$10" "$11}'/dev/disk/by-id/wwn-0x6d09466083c8df002894c4f698849270 -> ../../sda/dev/disk/by-id/wwn-0x6d09466083c8df002894c520d70e3749 -> ../../sdb/dev/disk/by-id/wwn-0x6d09466083c8df002894d2a508e9cbba -> ../../sdc/dev/disk/by-id/wwn-0x6d09466083c8df002894d2e86e27a728 -> ../../sdd/dev/disk/by-id/wwn-0x6d09466083c8df002894d317b3e49f63 -> ../../sde
执行 zpool list 可以查看存储池信息:
# zpool listNAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOTmpool_hdd01 6.55T 2.23T 4.32T - - 16% 34% 1.00x ONLINE -mpool_ssd01 24.4T 18.0T 6.49T - - 63% 73% 1.00x ONLINE -
通过 zpool 检查存储池状态:
]# zpool statuspool: mpool_hdd01state: ONLINEscan: none requestedconfig:NAME STATE READ WRITE CKSUMmpool_hdd01 ONLINE 0 0 0wwn-0x6d09466083c8df002894d317b3e49f63 ONLINE 0 0 0errors: No known data errorspool: mpool_ssd01state: ONLINEscan: none requestedconfig:NAME STATE READ WRITE CKSUMmpool_ssd01 ONLINE 0 0 0wwn-0x6d09466083c8df002894d2a508e9cbba ONLINE 0 0 0wwn-0x6d09466083c8df002894d2e86e27a728 ONLINE 0 0 0errors: No known data errors
通过 zpool 还可以查看当前存储池的IO情况:
# zpool iostatcapacity operations bandwidthpool alloc free read write read write----------- ----- ----- ----- ----- ----- -----mpool_hdd01 2.23T 4.32T 4 25 342K 2.06Mmpool_ssd01 18.0T 6.49T 148 117 797K 6.34M
文件系统挂载点的信息可以通过 zfs 命令进行查询:
# zfs listNAME USED AVAIL REFER MOUNTPOINTmpool_hdd01 2.23T 4.11T 24K mpool_hdd01mpool_ssd01 18.0T 5.72T 80.2G mpool_ssd01
在ZFS中,磁盘的占用使用df查看,会不是很清楚。因为有很多的快照,快照会共用一份空间,通过快照可以多套数据库共用一套数据文件,从而节省磁盘空间。比如下面四套库,分配了30T空间,实际只用了18T的空间。
# cd mpool_ssd01# df -h .Filesystem Size Used Avail Use% Mounted onmpool_ssd01 5.9T 81G 5.8T 2% mpool_ssd01# du -shc mpool_ssd01/zdbm_RNSBJQ719918XC3M/*30T mpool_ssd01/zdbm_RNSBJQ719918XC3M/hisdb-3481572655254G mpool_ssd01/zdbm_RNSBJQ719918XC3M/hlwsdb-2915379257477G mpool_ssd01/zdbm_RNSBJQ719918XC3M/pacsdb-143353913843G mpool_ssd01/zdbm_RNSBJQ719918XC3M/zzxtdb-58238050431T total
在复本库中,我们看到实际使用的空间是非常少的,因为共用了原始数据的快照。

查看ZFS快照信息(为了方便显示,对数据进行了处理):
# zfs list -t snapshotNAME USED AVAIL REFER MOUNTPOINTmpool_ssd01/..xx../datafile@snapshot_Xx30 155M - 33.8G -mpool_ssd01/..xx../datafile@snapshot_Cx36 100M - 33.8G -mpool_ssd01/..xx../datafile@snapshot_Pxx43 99.3M - 33.8G -mpool_ssd01/..xx../datafile@snapshot_Yx249 94.4M - 33.8G -mpool_ssd01/..xx../datafile@snapshot_Qxx55 91.6M - 33.8G -mpool_ssd01/..xx../datafile@snapshot_8Hx01 90.0M - 33.8G -mpool_ssd01/..xx../datafile@snapshot_1Fx08 88.9M - 33.8G -mpool_ssd01/..xx../datafile@snapshot_TVx14 75.0M - 33.8G -mpool_ssd01/..xx../datafile@snapshot_5Ax20 69.4M - 33.8G -
因为只是查看系统信息,并没有创建pool的过程,实际创建过程应该是使用了类似如下的命令:
zpool create mpool_ssd01 /dev/sde /dev/sdf
如果想了解系统使用ZFS都做了什么,可以使用ZFS自带的查看命令历史的功能,可以使用如下命令查看 ZFS 的命令历史:
zpool history

从命令历史中可以从创建存储池到建立快照、销毁快照以及克隆的所有动作。
History for 'mpool_ssd01':2021-08-24.11:44:42 zpool create mpool_ssd01 wwn-0x6d09466083c8df002894d2a508e9cbba wwn-0x6d09466083c8df002894d2e86e27a7282021-08-24.11:45:42 zfs set compression=lz4 mpool_ssd012021-08-24.12:24:36 zfs create -p mpool_ssd01/zdbm_RNSBJQ719918XC3M/pacsdb-14335391382021-08-24.12:24:37 zfs set sharenfs=off mpool_ssd01/zdbm_RNSBJQ719918XC3M/pacsdb-14335391382021-08-24.12:24:37 zfs create -p mpool_ssd01/zdbm_RNSBJQ719918XC3M/pacsdb-1433539138/sbtfile/datafile2021-08-24.12:24:37 zfs set sharenfs=off mpool_ssd01/zdbm_RNSBJQ719918XC3M/pacsdb-1433539138/sbtfile/datafile2021-08-24.12:24:37 zfs create -p mpool_ssd01/zdbm_RNSBJQ719918XC3M/pacsdb-1433539138/datafile2021-08-24.12:24:37 zfs set sharenfs=off mpool_ssd01/zdbm_RNSBJQ719918XC3M/pacsdb-1433539138/datafile2021-08-24.12:24:40 zfs set recordsize=8K mpool_ssd01/zdbm_RNSBJQ719918XC3M/pacsdb-1433539138/datafile2021-08-24.12:47:17 zfs snapshot -r mpool_ssd01/zdbm_RNSBJQ719918XC3M/pacsdb-1433539138/datafile@snapshot_QSF5DHXRXWTHP689_202108241247142021-08-24.12:48:17 zfs destroy -R mpool_ssd01/zdbm_RNSBJQ719918XC3M/pacsdb-1433539138/sbtfile/datafile2021-08-24.12:52:14 zfs snapshot -r mpool_ssd01/zdbm_RNSBJQ719918XC3M/pacsdb-1433539138/datafile@snapshot_WR62A8SH5YGNS56J_202108241251142021-08-24.13:04:43 zfs snapshot -r mpool_ssd01/zdbm_RNSBJQ719918XC3M/pacsdb-1433539138/datafile@snapshot_CEEN4H31HQ7BZY6G_202108241304342021-08-24.13:05:43 zfs snapshot -r mpool_ssd01/zdbm_RNSBJQ719918XC3M/pacsdb-1433539138/datafile@snapshot_TCA4GSZD3313N8FD_202108241304432021-08-24.13:18:59 zfs snapshot -r mpool_ssd01/zdbm_RNSBJQ719918XC3M/pacsdb-1433539138/datafile@snapshot_QZPSXQC2KZCBXTN6_202108241317592021-08-24.13:30:14 zfs snapshot -r mpool_ssd01/zdbm_RNSBJQ719918XC3M/pacsdb-1433539138/datafile@snapshot_BGD5XPPW36QW3FZE_20210824132914...
总结:
使用ZFS可以大量节省磁盘空间,特别是建立数据库测试库这种磁盘消耗巨大的场景。如果使用普通文件系统,建一两个测试库,空间占用就翻倍了,不仅占空间,而且文件复制也耗费时间。ZFS的快照功能可以很好地处理多个测试库共享oracle数据文件,从而节省文件拷贝时间、节省磁盘空间。
参考:
Oracle官方ZFS文档(Oracle® Solaris ZFS管理指南)
https://docs.oracle.com/cd/E24847_01/pdf/819-7065.pdf




