Бэкап данных с btrfs и LVM bash скриптами

от автора

image

Уже было много постов о резервном копировании, особенно много для ОС Linux. Озаботился и я настройкой резервного копирования.
Требовалось создавать бэкапы системы, данных с примонтированного раздела и LVM томов (диски виртуальных машин). Были мысли использовать Bacula, т.к. знаком с ней, но поскольку дома только 1 компьютер клиент-серверная архитектура только создавала-бы дополнительные сложности при восстановлении в случае повреждения системы. Значит систему и данные просто копируем, образ LVM раздела создаем с помощью dd. Хотелось делать резервную каждый день (хотя-бы данных) и хранить минимум 14 дней. Но поиски готовых и простых решений, удовлетворяющих всем потребностям не увенчались успехом. А значит берем в руки bash и пишем свой велосипед. В этой статье я делюсь тем, что вышло.

Disclaimer: при написании скриптов не было цели написать монстров, которые делают все. Нужен был простой и надежный способ бэкапа. Буду благодарен за указание неточностей и узких мест скриптов (тех, где могут возникнуть ошибки). Статья расчитана больше на новичков в Linux, которые ищут готовое решение и на лентяев 🙂 которым лень писать самим.

Исходные условия:

  • ОС: Arch Linux
  • Корневая файловая система (/): btrfs, копировать нужно все файлы.
  • Раздел с данными (/mnt/data/): btrfs.
  • LVM тома (/dev/virt_image_array/*).
  • Раздел для бэкапов (/mnt/backup/: etx4, сюда будут складываться резервные копии.
  • Необходимые утилиты (кроме входящих в базовый дистр): rsync, btrfs-progs (для управления btrfs).

Было решено раз в неделю делать полную копию всего и каждый день создавать снапшот разделов с btrfs. Можно так-же создавать снапшоты LVM томов, но для меня потеря данных за неделю не критична, поэтому хватит еженедельных копий.

Итак, скрипт № 1, создает копию файлов корневого раздела в /mnt/backup/root/«номер дня»/.

Скрипт №1

#!/bin/bash set -e echo "Date_start: `date +%Y-%m-%d-%H-%M-%S`"						 #Дата для удобного чтения логов  ### Vars ### #Количество дней от точки отсчета (1970 год) day=$((`date +%s` / (60*60*24)))		 #Сколько дней хранить бэкапы dayexp=21	 #Что копируем					 path="/" 		 #Откуда копируем (путь до снапшота)				 spath="/snapshots/backup_script/"	 #Куда копируем						 dpath="/mnt/backup/root/" 						  ### Delete Old Backups ###	 #Удаляем старые бэкапы				 find $dpath -type d 2>/dev/null| awk '{FS="/"} {print $5}'| sort|uniq | while read ONE_OF_LIST do if [[ "$ONE_OF_LIST" -lt "$day - $dayexp"  ]] && [[ -n "$ONE_OF_LIST" ]] then echo "remove: $dpath$ONE_OF_LIST" rm -rf $dpath$ONE_OF_LIST fi done  ### Check exist snapshot ### #Проверяем наличие снапшота, удаляем, если находим						 if (( "`btrfs subvolume list / | grep backup_script |wc -l`" > 0 )) then echo "Warning: Snapshot exist, deleting" btrfs subvolume delete $spath fi  ### Create snapshot ### #Делаем снапшот						 btrfs subvolume snapshot / $spath  ### Rsync ###						 #Копируем данные из снапшота rsync -aAXv $spath $dpath$day  ### Delete snapshot ###						 #Удаляем снапшот btrfs subvolume delete $spath echo "Backup succesful complete" echo "Date_end: `date +%Y-%m-%d-%H-%M-%S`" exit 0 

Скрипт № 2, создает снапшоты корневой ФС (скрипт логикой очень похож на 1й, поэтому коментировать буду только отличия). Снапшот имеет имя auto_«номер дня».

Скрипт №2

#!/bin/bash set -e echo "Date_start: `date +%Y-%m-%d-%H-%M-%S`"  ### Vars ### day=$((`date +%s` / (60*60*24))) dayexp=14								 path="/" 								 spath="/snapshots/"							  ### Delete Old Backups / Check existing snapshot ### #Старые бэкапы удаляем, если находим сегодняшний снапшот выходим  btrfs subvolume list / |grep auto |sed -e '1,$ s/.*_//g'| while read ONE_OF_LIST do if [[ "$ONE_OF_LIST" -lt "$day - $dayexp"  ]] then echo "remove: $spath"auto_"$ONE_OF_LIST" btrfs subvolume delete $spath"auto_"$ONE_OF_LIST fi if [[ "$ONE_OF_LIST" -eq "$day" ]] then echo "Eroor: snapshot auto_$ONE_OF_LIST exist. Stop script execution." exit 1 fi done  ### Create snapshot ### btrfs subvolume snapshot / $spath"auto_"$day  ### End ### echo "Snapshot succesful created" echo "Date_end: `date +%Y-%m-%d-%H-%M-%S`" exit 0 

Скрипт № 3, создает копию LVM тома:

Скрипт №3

#!/bin/bash set -e echo "Date_start: `date +%Y-%m-%d-%H-%M-%S`"  ### Vars ### day=$((`date +%s` / (60*60*24))) dayexp=21 #Имя копируемого LVM тома								 path="/dev/virt_image_array/win_home_system" 				 spath="/dev/virt_image_array/backup_lvm1"	      			 dpath="/mnt/backup/lvm1/"					  ### Delete Old Backups ### find $dpath -type d 2>/dev/null| awk '{FS="/"} {print $5}'| sort|uniq | while read ONE_OF_LIST do if [[ "$ONE_OF_LIST" -lt "$day - $dayexp"  ]] && [[ -n "$ONE_OF_LIST" ]] then echo "remove: $dpath$ONE_OF_LIST" rm -rf $dpath$ONE_OF_LIST fi done  ### Check exist snapshot ### #Проверяем отсутвие снапшота, удаляем, если находим if (( "`ls /dev/virt_image_array |grep backup_lvm1|wc -l`" > 0 )) then echo "Warning: Snapshot exist, deleting" lvremove --autobackup y -f $spath fi  ### Create snapshot ### #Создаем снапшот, если на том идет активная запись, то можно увеличить место на снапшоте. Я сделал 10 Gb. lvcreate --size 10G --snapshot --name backup_lvm1 /dev/virt_image_array/win_home_system #Если у вас при создании снапшота спрашивает подтверждения на вайп сигнатуры используйте вариант с echo #echo "y"| lvcreate --size 10G -A y --snapshot --name backup_lvm1 /dev/virt_image_array/win_home_system  ### DD ### #Можно поиграться с bs, у меня быстрей всего работает с 16M dd if=$spath of=$dpath$day bs=16M  ### Delete snapshot ### lvremove --autobackup y -f $spath  echo "Backup succesful complete" echo "Date_end: `date +%Y-%m-%d-%H-%M-%S`" exit 0 

Поскольку скрипты, бэкапящие данные из /mnt/data аналогичны скриптам 1 и 2 думаю нет необходимости их писать.

Добавляем в crontab и определяем, как часто создавать бэкапы (в моем примере бэкап создается раз в неделю, снапшоты раз в день).

20 01 * * 1 /usr/bin/backup_root.sh >> /var/log/backup_root.log 2>&1 50 01 * * 1 /usr/bin/backup_lvm1.sh >> /var/log/backup_lvm.log 2>&1 20 01 * * * /usr/bin/snapshot_root.sh >> /var/log/snapshot_root.log 2>&1 
Что еще можно прикрутить:

  • Если нужно создавать больше бэкапов, а места нет, то можно поставить ФС с дедупликацией (например Opendedup), но снизится надежность хранения данных.
  • В качестве хранилища может выступать папка подключенная по NFS или sshfs.
  • Если нужно создавать бэкапы или снапшоты чаще, чем раз в день можно считать не дни с 1970 года, а часы (костыль, будет еще непонятней за какую дату бэкап).

ссылка на оригинал статьи http://habrahabr.ru/post/211917/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *