du...du hast... (3)
By n on Saturday 16 March 2013, 22:34 - Permalink
L'aventure HASTienne c'est terminé hier soir avec un gros crash du pool primaire, avec un fort peu poli "I/O Error" en tentant de ré-importer le pool HAST sur le second serveur. Malaise.
Vu les problèmes de lock que j'avais depuis la mise en prod, j'ai tenté le tout pour le tout: abandonnant HAST, j'ai créé de nouveaux datasets ZFS pour stocker mes précieuses données (que j'ai récupéré des backups de la veille, du coup), et j'ai ensuite synchronisé les deux serveurs à grands coups de snapshots ZFS différentiels.
Voici le principe: on commence par faire un snapshot (full) du dataset à répliquer, et on l'envoi sur l'autre serveur. On renomme ensuite, sur chaque serveur, le snapshot afin qu'il serve de référence pour les prochaines synchros:
serveur1# zfs snapshot servers/pool1/home@newsync
serveur1# zfs send servers/pool1/home@newsync | ssh -q serveur2 "zfs receive -vFd servers"
serveur1# zfs rename servers/pool1/home@newsync servers/pool1/home@prevsync
serveur2# zfs rename servers/pool1/home@newsync servers/pool1/home@prevsync
Un script à mettre en crontab sur le serveur maitre va se charger ensuite d'envoyer les snapshots différentiels; l'ancien snapshot est supprimé après transfert, et le nouveau est renommé afin qu'il serve de base aux suivants.
#!/bin/sh
bro="serveur2"
pools="pool1 pool2"
echo "`date`: ZFSync starting."
for pool in $pools
do
dataset="servers/${pool}/home"
echo "making new snapshot for ${pool}"
zfs snapshot ${dataset}@newsync
echo "sending snapshot"
zfs send -i prevsync ${dataset}@newsync | ssh -q ${bro} "zfs receive -vFd servers"
if [ $? -eq 1 ]
then
echo "error, exiting"
exit $?
fi
echo "cleaning"
zfs destroy ${dataset}@prevsync
zfs rename ${dataset}@newsync ${dataset}@prevsync
ssh -q ${bro} "zfs destroy ${dataset}@prevsync && zfs rename ${dataset}@newsync ${dataset}@prevsync"
done
echo
La gestion d'erreur, embryonnaire, demande encore a être améliorée ;)
Avec cette méthode, la synchro de trois datasets prends moins de trois minutes, pour environ 10 Go de données.
À noter qu'en temps normal le second serveur n'utilise pas les datasets en question: ils ne sont pas montés, à la place on utilise un montage NFS hébergé sur le premier serveur (zfs set sharenfs=on $dataset
) pour que les éventuelles données écrites par le second serveur ne soient pas écrasées. En cas de bascule, les montages NFS sont démontés et les montages ZFS sont remontés à leur place, via heartbeat.