Нотатка для себе, так я роблю реплікацію з зовнішнім USB накопичувачем у FreeNAS.
Зовнішній USB накопичувач монтується безпосередньо перед реплікацією, і розмонтовується після реплікації.
Зовнішній диск монтується за GPT ідентифікацією диску - GPTID (zpool list -v extusb-01), та ідентифікацією zfs pool за POOL_GUID (zpool list -o guid extusb-01).
Зовнішній диск був створений майстром створення zfs pool у FreeNAS.
Скрипт /root/script/backup-2-extusb-01-next.sh запускається за розкладом через cron.
backup-2-extusb-01-next.sh
#!/bin/sh GPTID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx POOL_GUID=yyyyyyyyyyyyyyyyyyy EXTPOOL="extusb-01" MNTPOINT="/mnt" SRCPOOL="pool" SRCDATASETS=""
#use skipdatasets via | separator
SRCDATASETSSKIP="^pool/SOME|^pool/SOMEOTHER"
DSTDATASETROOT=${EXTPOOL}/backup SAVEOLDSNAPHOTS=10 /root/script/mount_ext.sh zpool status -x ${EXTPOOL} if [ $? -gt 0 ];then echo "Try import ${EXTPOOL}" zpool import ${EXTPOOL} -R ${MNTPOINT} echo "result:" $? zpool status -x ${EXTPOOL} if [ $? -gt 0 ];then echo "can't import pool ${EXTPOOL}" exit fi fi echo backup start... $(date) SRCDATASETS=$(zfs list -H -o name | egrep "^${SRCPOOL}" | egrep -v "${SRCDATASETSSKIP}") SNAPDATE=$(date +%Y%m%d%H%M%S) SNAPNAME1=snap_${EXTPOOL}_ SNAPNAME=${SNAPNAME1}${SNAPDATE} echo LIST of ${SRCPOOL} SRCPOOLLIST=$(zfs list -H -o name |egrep "^${SRCPOOL}/") for sppool in ${SRCPOOLLIST}; do echo ------ echo sppool ${sppool} datasetpath=$(echo ${sppool} | sed -e "s/^${SRCPOOL}\///g") echo datasetpath ${datasetpath} SRCSNAPLIST=$(zfs list -H -s creation -o name -t snapshot | egrep "^${SRCPOOL}/" | grep ${sppool}@${SNAPNAME1} | tail -1) SRCSNAPNAME=$(echo ${SRCSNAPLIST} | awk -F@ '{print $2}') echo SSNAP ${SRCSNAPLIST} @ ${SRCSNAPNAME} DSTSNAPLIST=$(zfs list -H -s creation -o name -t snapshot | egrep "^${EXTPOOL}/" | grep "${datasetpath}@${SNAPNAME1}" | tail -1) DSTSNAPNAME=$(echo ${DSTSNAPLIST} | awk -F@ '{print $2}') echo DSNAP ${DSTSNAPLIST} @ ${DSTSNAPNAME} if [ "${SRCSNAPNAME}" == "${DSTSNAPNAME}" ];then zfs snapshot ${sppool}@${SNAPNAME} zfs hold keep ${sppool}@${SNAPNAME} if [ "$?" -eq 0 ];then echo incremental send -i ${SRCSNAPNAME} ${sppool}@${SNAPNAME} , receive -F ${DSTDATASETROOT}/${datasetpath} zfs send -i ${SRCSNAPNAME} ${sppool}@${SNAPNAME} | zfs receive -F ${DSTDATASETROOT}/${datasetpath} if [ "$?" -eq 0 ];then echo destroy old snap "${sppool}@${SRCSNAPNAME}" zfs release keep "${sppool}@${SRCSNAPNAME}" zfs destroy "${sppool}@${SRCSNAPNAME}" echo result $? fi fi else echo "***************************************************" echo src pool: ${sppool} SNAP NOT EQ "${SRCSNAPNAME}" and "${DSTSNAPNAME}" echo "***************************************************" sleep 15 echo "** DO FIRST COPY **********************************************" echo "SNAP zfs snapshot ${sppool}@${SNAPNAME}" zfs snapshot ${sppool}@${SNAPNAME} echo "HOLD zfs hold keep ${sppool}@${SNAPNAME}" zfs hold keep ${sppool}@${SNAPNAME} echo "DESTROY DEST zfs destroy - ${DSTDATASETROOT}/${datasetpath} " zfs destroy -r ${DSTDATASETROOT}/${datasetpath} echo "SEND zf send ${sppool}@${SNAPNAME} | zfs receive ${DSTDATASETROOT}/${datasetpath}" zfs send ${sppool}@${SNAPNAME} | zfs receive ${DSTDATASETROOT}/${datasetpath} echo "***************************************************" sleep 15 fi #destroy old snapshots DATASETOLDSNAP=${DSTDATASETROOT}/${datasetpath} echo try remove old snapshots on: ${DATASETOLDSNAP} saving: ${SAVEOLDSNAPHOTS} zfs list -H -t snapshot -o name -S creation -r ${DATASETOLDSNAP} | grep ^${DATASETOLDSNAP}@ | tail +${SAVEOLDSNAPHOTS} | xargs -n 1 zfs destroy done SRCSNAPLIST=$(zfs list -H -s creation -o name -t snapshot |egrep "^${SRCPOOL}/" |grep ${SNAPNAME1}) echo LIST of $EXTPOOL zfs list -H -o name -t snapshot |egrep "^${EXTPOOL}/" |grep ${SNAPNAME1} /root/script/unmount_ext.sh echo backup done... $(date) exit
/root/script/mount_ext.sh
Скрипт виконує монтування зашифрованого тому через GELI.
Ключ диску зберігається у теці /root/.key з іменем geli-${EXTPOOL}.key, де EXTPOOL ім'я зовнішнього zfs pool.
#!/bin/sh GPTID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx POOL_GUID=yyyyyyyyyyyyyyyyyyy EXTPOOL="extusb-01" geli_device="gptid/${GPTID}" geli_flags="-k /root/.key/geli-${EXTPOOL}.key -p" MNTPOINT="/mnt" SRCPOOL="pool" echo GELI ATTACH geli attach ${geli_flags} ${geli_device} echo "result:" $? zpool status -x ${EXTPOOL} if [ $? -gt 0 ];then echo "Try import ${EXTPOOL}" zpool import ${EXTPOOL} -R ${MNTPOINT} echo "result:" $? zpool status -x ${EXTPOOL} if [ $? -gt 0 ];then echo "can't import pool ${EXTPOOL}" exit fi fi exit
/root/script/unmount_ext.sh
#!/bin/sh GPTID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx POOL_GUID=yyyyyyyyyyyyyyyyyyy EXTPOOL="extusb-01" geli_device="gptid/${GPTID}" MNTPOINT="/mnt" SRCPOOL="poolz2" snapshots=$(zfs list -t snapshot | grep ^${EXTPOOL}/backup/BACKUP@snap_${EXTPOOL} | wc -l) zpool list ${EXTPOOL} | mail -s "Ext USB ZFS pool "${EXTPOOL}" - used space, snaphots: ${snapshots}" postmaster@email echo "Try export ${EXTPOOL}" zpool export ${EXTPOOL} echo "result:" $? echo GELI DETTACH geli detach ${geli_device} echo "result:" $? exit
Засипання зовнішнього диску
Я використовую Seagate Expansion 10TB для зовнішнього диску. І стала потреба щоб він вимикався через певний час після використання.Seagate Expansion 10TB |
І тількт так зараз цей накопичувач засипає після завершення реплікації автоматично.
Зачистка
Всяк буває і інколи треба зачисити snapshots @snap_${EXTPOOL} котрі "залипли".Цей скрипт залишає тільку одну останню версію snapshots @snap_${EXTPOOL} , і якщо вона ще є зблокованна від видалення через zfs hold, тоді snapshot розблокується перед видаленням.
/root/script/clear_holded_snapshots.sh
#!/bin/sh SRCPOOL="pool" EXTPOOL="extusb-01" HOLDTAG="keep" datas=$(zfs list -H -o name -r ${SRCPOOL} ) for data in ${datas}; do echo *${data} snapshots=$(zfs list -H -S creation -o name -t snapshot -r ${data} | grep ^${data}@snap_${EXTPOOL} | tail -n +2) for sn in ${snapshots}; do # echo ${sn} holded=$(zfs holds -H ${sn} | grep ${HOLDTAG}) if [ ! -z "${holded}" ];then echo HOLDED ${sn}, releasing zfs release ${HOLDTAG} ${sn} fi echo zfs destroy ${sn} zfs destroy ${sn} done done
S.M.A.R.T. test
Так як диск майже завжи вимкенно, то можна після кожної реплікації виконати перевірку диску через наступний скрипт.#!/bin/sh GPTID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx disk=$(glabel status | grep ${GPTID}| awk '{print $3}' | awk -Fp '{print $1}') #echo ${disk} smartctl -q errorsonly -t short /dev/${disk}
Немає коментарів:
Дописати коментар