免责声明:由于我从未使用过zvol,因此无法说出它们在复制方面是否与普通文件系统或快照有所不同。我认为他们是,但我不相信我的话。
您的问题实际上是多个问题,我尝试分别回答:
如何将完整的池复制/镜像到远程位置
您需要将任务分为两部分:首先,必须完成初始复制,然后再进行增量复制,只要您不弄乱复制快照即可。要启用增量复制,您需要保留最后的复制快照,可以删除之前的所有快照。如果删除以前的快照,zfs recv
将抱怨并中止复制。在这种情况下,您必须重新开始,因此请不要这样做。
如果您只需要正确的选项,它们是:
zfs send
:
-R
:在给定的池或数据集下发送所有内容(递归复制,一直需要,包括-p
)。同样,在接收时,所有已删除的源快照也会在目标上被删除。
-I
:包括最后一个复制快照和当前复制快照之间的所有中间快照(仅增量发送需要)
zfs recv
:
-F
:扩展目标池,包括删除在源上删除的现有数据集
-d
:丢弃源池的名称,并将其替换为目标池的名称(其余文件系统路径将保留,并且在需要时也会创建)
-u
:不要在目标上挂载文件系统
如果您希望使用完整的示例,请使用以下小脚本:
#!/bin/sh
# Setup/variables:
# Each snapshot name must be unique, timestamp is a good choice.
# You can also use Solaris date, but I don't know the correct syntax.
snapshot_string=DO_NOT_DELETE_remote_replication_
timestamp=$(/usr/gnu/bin/date '+%Y%m%d%H%M%S')
source_pool=tank
destination_pool=tank
new_snap="$source_pool"@"$snapshot_string""$timestamp"
destination_host=remotehostname
# Initial send:
# Create first recursive snapshot of the whole pool.
zfs snapshot -r "$new_snap"
# Initial replication via SSH.
zfs send -R "$new_snap" | ssh "$destination_host" zfs recv -Fdu "$destination_pool"
# Incremental sends:
# Get old snapshot name.
old_snap=$(zfs list -H -o name -t snapshot -r "$source_pool" | grep "$source_pool"@"$snapshot_string" | tail --lines=1)
# Create new recursive snapshot of the whole pool.
zfs snapshot -r "$new_snap"
# Incremental replication via SSH.
zfs send -R -I "$old_snap" "$new_snap" | ssh "$destination_host" zfs recv -Fdu "$destination_pool"
# Delete older snaps on the local source (grep -v inverts the selection)
delete_from=$(zfs list -H -o name -t snapshot -r "$source_pool" | grep "$snapshot_string" | grep -v "$timestamp")
for snap in $delete_from; do
zfs destroy "$snap"
done
使用比SSH更快的功能
如果您具有足够安全的连接(例如IPSec或OpenVPN隧道),并且仅在发送方和接收方之间存在一个单独的VLAN,则可以从SSH切换到未加密的替代方案,如此处所述的 mbuffer ,或者可以将SSH与弱/无加密一起使用并禁用了压缩功能,有关详细信息,请参见此处。还有一个网站关于重新编译SSH的速度要快得多,但是不幸的是,我不记得URL了-如果找到它,我会稍后对其进行编辑。
对于非常大的数据集和缓慢的连接,这对于通过硬盘进行首次传输(使用加密磁盘存储zpool并通过快递,邮件或亲自将其密封包装)也很有用。由于传输方法对于send / recv无关紧要,您可以将所有内容通过管道传输到磁盘,导出池,将磁盘发送到其目的地,导入池,然后通过SSH传输所有增量发送。
快照混乱的问题
如前所述,如果删除/修改复制快照,则会收到错误消息
cannot send 'pool/fs@name': not an earlier snapshot from the same fs
这意味着您的命令错误或处于不一致状态,必须删除快照并重新开始。
这有几个负面影响:
- 在成功传输新的复制快照之前,您无法删除复制快照。由于这些复制快照包括所有其他(较旧)快照的状态,因此只有复制完成后,才会回收已删除文件和快照的空白空间。这可能会导致池上出现临时或永久空间问题,您只能通过重新启动或完成完整的复制过程来解决此问题。
- 您将拥有许多其他快照,这会减慢list命令的速度(在已修复此问题的Oracle Solaris 11上除外)。
- 您可能需要保护快照以防(意外)删除,但脚本本身除外。
对于这些问题,存在一种可能的解决方案,但是我自己还没有尝试过。您可以使用zfs bookmark
OpenSolaris / illumos中专门为此任务创建的一项新功能。这将使您摆脱快照管理。唯一的缺点是目前,它仅适用于单个数据集,而不适用于递归。您将必须保存所有旧数据集和新数据集的列表,然后在它们上循环,添加书签,发送和接收它们,然后更新列表(或小型数据库,如果您愿意)。
如果您尝试使用书签路线,我很想听听它如何为您服务!
zfs send -R ...
?如果通过管道输出ssh
,是否使用禁用了转义字符zfs send -R ... | ssh -e none ...
?