DRBD fournit par défaut un script permettant de prendre un snapshot LVM avant une resynchro (il faut bien sûr que le backend du volume DRBD en question soit un volume logique LVM). En ajoutant quelque chose comme ça dans la définition de la ressource:
handlers { before-resync-target "/usr/lib/drbd/snapshot-resync-target-lvm.sh"; after-resync-target "/usr/lib/drbd/unsnapshot-resync-target-lvm.sh"; }
Le problème de ce script est qu'il fixe une taille du snapshot (calcul prenant en compte la taille du volume, le nombre de blocks à synchroniser un pourcentage fixe de 10% par défaut, et une marge de manœuvre). Avec des snpashots classiques, il faut bien sûr faire attention à ce que le snapshot ne se remplisse pas entièrement, sans quoi il s'invalide automatiquement.
Le but est de s'assurer d'avoir toujours une version cohérente des données sur le nœud à resynchroniser: pendant la synchro, le volume sera dans un état incohérent, mais un snapshot pris juste avant permet d'avoir accès aux données cohérentes juste avant le début de la resynchro.
Tout ça fonctionne bien, mais n'est pas optimal si on utilise un volume LVM à allocation fine (thin volume) comme backend. Pour les volumes thin on a pas besoin de préciser la taille: les snapshots comme leurs origines se partagent l'espace de leur pool. Voilà don cun petit patch pour prendre ça en compte:
--- /usr/lib/drbd/snapshot-resync-target-lvm.sh 2015-08-15 18:07:00.000000000 +0200 +++ /usr/local/bin/snapshot-resync-target-lvm-thin.sh 2015-09-28 10:22:41.689234327 +0200 @@ -43,14 +43,14 @@ set_vg_lv_size() { local X - if ! X=$(lvs --noheadings --nosuffix --units s -o vg_name,lv_name,lv_size "$BACKING_BDEV") ; then + if ! X=$(lvs --noheadings --nosuffix --units s -o vg_name,lv_name,lv_size,pool_lv "$BACKING_BDEV") ; then # if lvs cannot tell me the info I need, # this is: echo "Cannot create snapshot of $BACKING_BDEV, apparently no LVM LV." return 1 fi set -- $X - VG_NAME=$1 LV_NAME=$2 LV_SIZE_K=$[$3 / 2] + VG_NAME=$1 LV_NAME=$2 LV_SIZE_K=$[$3 / 2] POOL_LV=$4 return 0 } set_vg_lv_size || exit 0 # clean exit if not an lvm lv @@ -118,14 +118,18 @@ :;; # ok, already exported by drbdadm esac - OUT_OF_SYNC=$(sed -ne "/^ *$DRBD_MINOR:/ "'{ - n; - s/^.* oos:\([0-9]*\).*$/\1/; - s/^$/0/; # default if not found - p; - q; }' < /proc/drbd) # unit KiB - SNAP_SIZE=$((OUT_OF_SYNC + SNAP_ADDITIONAL + LV_SIZE_K * SNAP_PERC / 100)) - lvcreate -s -n $SNAP_NAME -L ${SNAP_SIZE}k $LVC_OPTIONS $VG_NAME/$LV_NAME + if [ -z $POOL_LV ]; then + OUT_OF_SYNC=$(sed -ne "/^ *$DRBD_MINOR:/ "'{ + n; + s/^.* oos:\([0-9]*\).*$/\1/; + s/^$/0/; # default if not found + p; + q; }' < /proc/drbd) # unit KiB + SNAP_SIZE=$((OUT_OF_SYNC + SNAP_ADDITIONAL + LV_SIZE_K * SNAP_PERC / 100)) + lvcreate -s -n $SNAP_NAME -L ${SNAP_SIZE}k $LVC_OPTIONS $VG_NAME/$LV_NAME + else + lvcreate -s -n $SNAP_NAME -kn $LVC_OPTIONS $VG_NAME/$LV_NAME + fi ) RV=$? [ $DISCONNECT_ON_ERROR = 0 ] && exit 0
Avec ce petit patch, le script détectera si le volume sous-jacent est à allocation fine ou non, et si oui, il créera un snapshot adapté, sur le même pool de stockage, sans préciser de taille