Backup LV тома через snapshot

Лёгкий скрипт бэкапа тома на удалённый сервер.
Хочу подчеркнуть, что создание снимка (snapshot) на работающем read/write разделе не гарантирует целосность данных в создаваемом снимке. Кеш файловой системы оставшийся в памяти не отразится на snapshot и не попадёт в бэкап. Поэтому такой бэкап является упрощённой и быстрой возможностью сохранить максимум данных.

В скрипте три важных операции:

  • Создать снимок (snapshot) достаточного размера но не больше размера тома
  • Скопировать раздел в файл через сеть на другую машину на ходу немного сжимая
  • Удалить снимок

Для использования snapshot необходимо иметь резервное место в группе томов. Поэтому размечая свежий диск для Linux я стараюсь не распределять всё доступное пространство. Однако если у вас имеется возможность подключить второй диск то вы можете добавить его в LVM и тем самым получив возможность сделать snapshot.

Размер снимка должен быть достаточным чтобы данные изменяемые во время его существования не заполнили его на 100%. Если он будет заполнен — shapshot будет отключён. Во время существования snapshot скорость записи в LV снижается в два раза.

   LVTOBACKUP="/dev/VG_S01_1/ROOT"

   FILENAMESTAMP=`date +%F-%H-%M-%S`

   VGPATH=`echo ${LVTOBACKUP} | cut -d / -f-3`
   LVONLY=`echo ${LVTOBACKUP} | awk -F/ '{print $(NF)}'`
   VGONLY=`echo ${LVTOBACKUP} | awk -F/ '{print $(NF-1)}'`
   SNAPSHOTNAME="${LVONLY}-snapshot"

   # get free space
   FREESIZE=`vgs --units b | grep "${VGONLY}" | awk '{print $7}' | sed 's/\([0-9]\+\)[bB]/\1/g'`
   if [ ${FREESIZE} -eq 0 ] ; then
     echo "Not enough free space on ${VGONLY} (${FREESIZE} bytes free)"
     exit
   fi
   # get lv size
   LVSIZE=`lvs --units b | grep "${VGONLY}" | grep "${LVONLY}"| awk '{print $4}' | sed 's/\([0-9]\+\)[bB]/\1/g'`
   echo "  LVSIZE=${LVSIZE}"
   echo "FREESIZE=${FREESIZE}"
   if [ "${FREESIZE}" -gt "${LVSIZE}" ] ; then
     FREESIZE=${LVSIZE}
   fi
   echo "FREESIZE=${FREESIZE}"
   # create snapshot
   lvcreate -s -n ${SNAPSHOTNAME} -L ${FREESIZE}B ${LVTOBACKUP}

   dd if=${VGPATH}/${SNAPSHOTNAME} bs=2M iflag=direct | gzip -c | ssh root@192.168.1.5 "dd of=/mnt/vm-backup/s01/1/${VGONLY}-${LVONLY}-${FILENAMESTAMP}.gz"

   lvremove -f ${VGPATH}/${SNAPSHOTNAME}

Для выделения всего свободного места под снимок можно использовать команду:

   lvcreate -s -n ${SNAPSHOTNAME} l100%FREE ${LVTOBACKUP}

Необходимо помнить что:

  • Отсутствие бэкапа это преступление
  • Snapshot это хороший помошник бэкапа
  • Snapshot не является заменой бэкапа
  • Snapshot всех LVM томов не самая удачная затея
  • После бэкапа snapshot неоходимо освобождать
  • LVM ваш помошник если вы пользуетесь им с умом