您好,我对 ZFS 快照备份脚本有疑问:
基本上,脚本的分解如下:
### START OF SCRIPT
# These variables are named first because they are nested in other variables.
snap_prefix=snap
retention=10
# Full paths to these utilities are needed when running the script from cron.
#date=/usr/bin/date
GDATE="/opt/csw/bin/gdate"
grep=/usr/bin/grep
#mbuffer=/usr/local/bin/mbuffer
sed=/usr/bin/sed
sort=/usr/bin/sort
xargs=/usr/bin/xargs
zfs=/sbin/zfs
src_0="ServerStoreR10SSD"
dst_0="zpoolRZ5SATA3/backuppool4/ServerStoreR10SSD"
host="root@hostbk"
today="$snap_prefix-`date +%Y%m%d`"
#yesterday="$snap_prefix-`date -v -1d +%Y%m%d`"
yesterday=$snap_prefix-`$GDATE -d "-1 day" +"%Y%m%d"`
snap_today="$src_0@$today"
snap_yesterday="$src_0@$yesterday"
snap_old=`$zfs list -t snapshot -o name | $grep "$src_0@$snap_prefix*" | $sort -r | $sed 1,${retention}d | $sort | $xargs -n 1`
log=/root/bin/zfsreplication/cronlog/ServerStoreR10SSD.txt
# Create a blank line between the previous log entry and this one.
echo >> $log
# Print the name of the script.
echo "zfsrep_ServerStoreR10SSD.sh" >> $log
# Print the current date/time.
$date >> $log
echo >> $log
# Look for today's snapshot and, if not found, create it.
if $zfs list -H -o name -t snapshot | $sort | $grep "$snap_today$" > /dev/null
then
echo "Today's snapshot '$snap_today' already exists." >> $log
# Uncomment if you want the script to exit when it does not create today's snapshot:
#exit 1
else
echo "Taking today's snapshot: $snap_today" >> $log
$zfs snapshot -r $snap_today >> $log 2>&1
fi
echo >> $log
# Look for yesterday snapshot and, if found, perform incremental replication, else print error message.
if $zfs list -H -o name -t snapshot | $sort | $grep "$snap_yesterday$" > /dev/null
then
echo "Yesterday's snapshot '$snap_yesterday' exists. Proceeding with replication..." >> $log
$zfs send -R -i $snap_yesterday $snap_today | ssh $host $zfs receive -vudF $dst_0 >> $log 2>&1
#For use in local snapshots
#$zfs send -R -i $snap_yesterday $snap_today | $zfs receive -vudF $dst_0 >> $log 2>&1
echo >> $log
echo "Replication complete." >> $log
else
echo "Error: Replication not completed. Missing yesterday's snapshot." >> $log
fi
echo >> $log
# Remove snapshot(s) older than the value assigned to $retention.
echo "Attempting to destroy old snapshots..." >> $log
if [ -n "$snap_old" ]
then
echo "Destroying the following old snapshots:" >> $log
echo "$snap_old" >> $log
$zfs list -t snapshot -o name | $grep "$src_0@$snap_prefix*" | $sort -r
| $sed 1,${retention}d | $sort | $xargs -n 1 $zfs destroy -r >> $log 2>&1
else
echo "Could not find any snapshots to destroy." >> $log
fi
# Mark the end of the script with a delimiter.
echo "**********" >> $log
# END OF SCRIPT
~
日志显示以下内容
昨天的快照“ServerStoreR10SSD@snap-20170419”已存在。继续复制...无法接收:指定的 fs(zpoolRZ5SATA3/backuppool4/ServerStoreR10SSD)不存在尝试销毁 zpoolRZ5SATA3/backuppool4/ServerStoreR10SSD 失败 - 尝试将 zpoolRZ5SATA3/backuppool4/ServerStoreR10SSD 重命名为 zpoolRZ5SATA3/backuppool4/ServerStoreR10SSDrecv-5424-1 无法打开“zpoolRZ5SATA3/backuppool4/ServerStoreR10SSD”:数据集不存在
在我停电之前,脚本一直运行成功。主要问题是每次运行增量部分时,接收 zfs 池都会重命名为奇怪的名称,如“..recv-5424-1”,因此无法打开目标池,备份失败...
有什么建议吗?
答案1
您的脚本没有显示rename
或destroy
操作,并且我们不知道源和目标快照,因此这个答案是可以应用于您的情况的通用建议:
错误的潜在原因
要使增量 ZFSsend/recv
正常工作,您始终需要在源端和目标端拥有快照N
和。然后,您将和之间的增量(差异)发送到目标端,在那里它将成为。之后,您可以在源端删除并重复该过程。N-1
N-1
N-1
N
N
N-1
立即修复
如果您的某个快照与此系统不匹配(例如因为它已被删除或重命名),则有两种可能的方法来更正它:
- 删除远程端的所有数据,然后执行完整/初始/正常发送/接收。这需要更多时间,但您不需要进行太多故障排除。
- 如果可能的话,找出到底是什么问题,并手动纠正所有问题(如果您已经删除了所需的快照,则可能无法实现)。
针对未来问题的改进
除此之外,您还应该检查脚本流程,看看这个错误是如何出现的。将其重构为较小的函数(如、、send_initial
等)会有所帮助,这样您就可以更清楚地了解什么时候会发生什么。然后绘制一个状态机图 (DFA),其中包含可能的分支和流程,并查看每个状态变化:如果发生错误(网络丢失、断电、用户取消脚本、权限被拒绝等),会发生什么,以及如何缓解它?send_diff
create_snap
delete_snap
如果工作量太大,您也可以使用已经解决这些问题的现有解决方案。对于其中一些,请查看这个问题来自两周前。
答案2
在我的源 zfs 列表中
ServerStoreR10SSD 380G 321G 44.9K /ServerStoreR10SSD
ServerStoreR10SSD/DataStore2R10SSD 380G 321G 296G /ServerStoreR10SSD/DataStore2R10SSD
在我的来源上,快照是:
ServerStoreR10SSD@snap-20170411 0 - 44.9K -
ServerStoreR10SSD@snap-20170412 0 - 44.9K -
ServerStoreR10SSD@snap-20170413 0 - 44.9K -
ServerStoreR10SSD@snap-20170414 0 - 44.9K -
ServerStoreR10SSD@snap-20170415 0 - 44.9K -
ServerStoreR10SSD@snap-20170416 0 - 44.9K -
ServerStoreR10SSD@snap-20170417 0 - 44.9K -
ServerStoreR10SSD@snap-20170418 0 - 44.9K -
ServerStoreR10SSD@snap-20170419 0 - 44.9K -
ServerStoreR10SSD@snap-20170420 0 - 44.9K -
ServerStoreR10SSD@snap-20170421 0 - 44.9K -
ServerStoreR10SSD/DataStore2R10SSD@snap-20170411 8.77G - 295G -
ServerStoreR10SSD/DataStore2R10SSD@snap-20170412 3.95G - 295G -
ServerStoreR10SSD/DataStore2R10SSD@snap-20170413 3.11G - 295G -
ServerStoreR10SSD/DataStore2R10SSD@snap-20170414 2.99G - 295G -
ServerStoreR10SSD/DataStore2R10SSD@snap-20170415 5.61G - 296G -
ServerStoreR10SSD/DataStore2R10SSD@snap-20170416 3.31G - 296G -
ServerStoreR10SSD/DataStore2R10SSD@snap-20170417 2.76G - 296G -
ServerStoreR10SSD/DataStore2R10SSD@snap-20170418 3.74G - 296G -
ServerStoreR10SSD/DataStore2R10SSD@snap-20170419 3.65G - 296G -
ServerStoreR10SSD/DataStore2R10SSD@snap-20170420 2.72G - 296G -
ServerStoreR10SSD/DataStore2R10SSD@snap-20170421 2.27G - 296G -
我的目标上的 zfs 列表
zpoolRZ5SATA3/backuppool3 1.19T 1.77T 202K /zpoolRZ5SATA3/backuppool3
zpoolRZ5SATA3/backuppool3/DataStoreR10
在我的目的地上列出快照:
zpoolRZ5SATA3/backuppool4@moving 139K - 202K -
zpoolRZ5SATA3/backuppool4/ServerStoreR10SSDrecv-9540-1/DataStore2R10SSD@snap-20170418 11.8G - 296G -
zpoolRZ5SATA3/backuppool4/ServerStoreR10SSDrecv-9540-1/DataStore2R10SSD@snap-20170419 3.67G - 296G -
zpoolRZ5SATA3/backuppool4/ServerStoreR10SSDrecv-9540-1/DataStore2R10SSD@snap-20170420 0 - 296G -