Pull to refresh

Comments 38

Я иногда пользуюсь таким способом.
ssh+rsync+git=простой удаленный инкрементальный бэкап.
Скрипты не идеальны, но они справляются со своей задачей.
BACKUP_DIR=/backup/
backup() {
                NAME=$1
                SERVER=$2
                PORT=$3
                echo ""
                echo "==========$NAME=========="

		#создадим папку и проинициализируем git в первый раз
                if [ ! -d $BACKUP_DIR$NAME ]; then
                                mkdir $BACKUP_DIR$NAME
                                cd $BACKUP_DIR$NAME;
                                git init
                else
                                cd $BACKUP_DIR$NAME
                fi
                echo "prepare: `date`"
		#заставим сервер сделать бэкап (БД, ldap и прочее. Что нельзя забирать напрямую с ФС).
                ssh $SERVER -p $PORT /pathToScript/prepareBackup.sh
                echo "rsync: `date`"
		#забираем данные
                rsync -avzh --compress-level=9 --delete --include-from=$BASEPATH$NAME -e "ssh -p $PORT" $SERVER:/ .
                echo "git: `date`"
		#добавляем в git
                git add . > /dev/null
		#коммитим
                git commit -a  -mupdate > /dev/null
                echo "complete: `date`"
}

backup "name1"  "some.host.name1" 22
backup "name2"  "some.host.name2" 22

файл name1 в том же каталоге:
+ /etc**
+ /var/
+ /var/backup**
+ /var/www
+ /var/www/host**
- /var/www/host/excluded**
- *

Пример prepareBackup.sh:
cd /var/backup/
su postgres -c "pg_dump dbName -f dbName.sql"
slapcat > ldap.ldif


Можно завернуть вывод в файл или почту.

Большой минус данного метода — авторизация по ключу без пароля.
Большой минус — история хранится с самого первого бекапа. И если в него попадет что-то лишнее и большого размера — оно там так и останется если не транкейтить git-репо периодически.
кстати, такая мысль при написании скрипта посещала, но я ее проигнорировал, поскольку в моем случае лог разрастается медленно, а в логах я бываю с некоторой периодичностью, то и файлик удалить вручную для меня не проблема. Поищу время дописать статью на предмет ротации логов.
я вот тоже пришел к rsync + ssh + cron

tar закапывает проблему при появлении существенных объёмов.

в остальном, конечно, велосипеды это всё. Либо игры при изучении линухов, либо спец задача (например, многоточечный бекап медиахранилища по узким каналам у меня).
Если не секрет, почему используется именно tar, а не dar?
Просто периодически на хабре или других ресурсах встречаю скрипты бекапа, и везде tar + gz, хотя dar-то помощнее будет.
И да, я не админ (область моей ответственности ограничивается домашним серваком с документами/фото и т.д.), поэтому интересуюсь, может это я чего-то не понимаю, а профессионалы по какой-то причине считают dar не кошерным :)
Думаю что как минимум могут повлиять эти причины:
1. В стандартных репозитариях его нет для установки и надо ручками собирать
2. Будет больше грузить сервер при создании бекапа
3. Не смотрел ключики и спецификацию, но в случае с tar его иногда очень удобно использовать без самого gzip для бэкапинга директорий с media контентом
4. Сила привычки и повсеместности
Спасибо за ответ!
Насчёт производительности ничего не могу сказать, не проверял. Но там тот же gz для сжатия применяется, а оно больше всего процессора ест. Не думаю, что из-за остального будут какие-то серьёзные различия в скорости.
В управлении сжатием dar точно мощнее. У него в одном архиве могут быть файлы и сжатые и несжатые, причём из командной строки можно установить, какие не сжимать (фильтр по шаблону).

А с причинами 1 и 4 всё ясно, тут не поспоришь :)
Видимо, большое админство всё-таки свои проблемы имеет: я-то ни совместимостью, ни сборкой (на один-то сервак) могу не заморачиваться.
Ну у меня аналогичная по сути ситуация — 1 сервак + иногда помогаю клиентам по мелочам на серваке с настройками. Но что на клиентских что на своем (на моем только dev проекты) предпочитаю media и код хранить отдельными файлами, т.к. иногда бывает что возникает ситуация что именно в папке media нечаянно снесут что-либо и надо восстановить, а она сама в tar получается порядка 4 гигов. Код ещё 2 гига и в код уже могли быть внесены изменения со времени последнего бекапа
Понятно что можно вынять только нужную папку, но на таких размерах все-равно чувствуется по скорости это.
Хотя это конечно дело каждого. Ну а сам dar даже как-то не пробовал ставить — как говорится вполне хватает tar+gz ))), тем более что мой сервак для разработки достаточно слабый, а места вполне хватает, поэтому мне выгодней использовать менее ресурсоемкие подходы в плане CPU/RAM нежели большее сжатие
Я медиа-папки тоже бекаплю отдельно, конечно, но всё равно home-директории домашних в ужатом виде до 70ГБ доходят. У каждого %) И их на куски особо не поделишь, так как бардак.

Но при восстановлении из бекапа есть ещё одно преимущество dar'а: ему не обязательно пролистывать весь бекап, чтобы вытащить нужный файл (а tar'у c gz обязательно). Единственное что, листинг действительно гигантского архива может минуты занимать. Но это на атоме и архивах порядка 50-100ГБ.

В общем, тут с tar'ом была бы тоска совсем.
В сторону dar не посмотрел т.к. банально был о нем не в курсе =) Погляжу что это такое повнимательней, т.к. проблема с большими архивами в некоторых случаях актуальна, хотя и не критична.
Выбирал только между банальными rsync, tar и даже cp+gzip. Oстановился на tar по субъективным причинам.
К tar 'у все же большинство привыкли. И в большинстве дистров он идет изкоробки.
В большинстве дистрибутивов и dar идёт изкоропки. Просто о нём мало кто знает. Да и параметры у него сложноваты.
Велосипедостроители. Используйте то что уже написано за вас. rsnapshot(для маленьких), bacula(для больших)
Любопытно, возьму правило на вооружение, полезная штука.
Как думаете, стоит рерайтить и расширить на Хабре это дело? :)
Грубовато малость, не находите?
Как писалось выше:
bash: Бэкап без лишнего ПО
… с использованием минимума стороннего ПО...

В моем случае дополнительно установленное ПО — sendxmpp и пара пакетов из самбы, которые у меня и так установлены. Мотивы… зачем мне ставить и настраивать бакулу, если мне достаточно возможностей tar`а? К слову — бакулу устанавливал, попользовал, удалил, написал этот скрипт.
Ну и, пардон, повторюсь, выбирал только между банальными rsync (rsnapshot) и tar. Oстановился на tar по субъективным причинам.

В любом случае спасибо за альтернативы. В топике я не предлагал вариантов, хорошо, что они обозначаются в обсуждении.
Вот я когда полтора года назад свой скрипт писать собирался тоже думал, что надо по-серьёзному, взять готовое, проверенное решение :)
Ага, щаз! Оказалось, что проще самому накатать сто строчек на баше, чем даже выбрать из существующих систем. И в итоге всё своё, родное, что надо умеет, что не надо глаза не мозолит.
Почему используются такие «нечитаемые» имена переменных? Экономите память?: )
TN — TASKNAME
SRCD — SouRCe Directory
TGTD — TarGeT Directory

Называй как есть, TASKNAME/TASK_NAME, будет удобнее и последователям, и самому себе, когда откроешь код через полгодика: )
Зачем? Не менее понятные переменные TASK, SRCDIR, TGTDIR — и меньше писать, и вполне понятно.
развивает культуру кода, хотя бы
Поскольку это всего лишь выложил вариант и я не настаиваю на его исключительности, любые предложения и критика уместны =) Они помогают учиться дальше. + Кого-то они могут устроить больше, чем предложенные мной.
Я далеко не гуру и не настаиваю на таком статусе, я всего-лишь учусь =)… учусь скриптить для своих нужд, и делюсь наработками с теми, кому они могут пригодиться. А также расчитываю довести до ума какие-то моменты, о которых сразу не подумал.
Посмотрите в сторону функций в bash. Если написать функцию для логирования, то это существенно сократит ваш скрипт и приведёт его к более удобочитаемому виду.

И кстати, можно ещё подсократить скрипт, выкинув оттуда часть if'ов. А проверку осуществлять в таком духе:
command && log «command success» || error_log «command failed»
где log и error_log функции обрабатывающие просто лог и ситуацию с ошибками.
Тут, правда, есть подводный камень, что если функция log завершится с ошибкой, то error_log всё равно выполнится. Но может оно и правильно? (:

И, судя по закомментированным docs-weekly и docs-daily, у вас ещё имеется пара аналогичных скриптов для docs-weekly и docs-daily. Можно эту переменную передавать через параметры запуска $1,$2 и т.д. или даже парсить их getopt'ом (опционально), прикрутить проверку корректности, проверку от дурака, и… впрочем что-то меня не туда понесло.
> Можно эту переменную передавать через параметры запуска $1,$2
А можно сделать несколько симлинков и проверять, чему равен $(basename "$0")
Ну это уже так…
для бэкапа файловой системы виртуальных машин я остановился на rdiff-backup
вот такой скриптик запускается по крону на родительском хосте

#!/bin/sh
# local dom0 host
HOST=zzzzzzz
# volume group
VG=vg00
# file containing volume names
LV=$1
# PID file
PID=/tmp/rdiff-backup-lv.pid
# remote path to backup server (requires SSH-RSA auth)
BACKUP_PATH=remote@xxxx.xxxx.com::/opt/remote-backups
# period to keep old backups 
KEEP_BACKUPS_FOR=2W

echo "Backing up $LV from $VG"
SNAP=snap_$LV

if [ -f $PID ]; then
	if [ `ps ax | grep \`cat $PID\`| grep $0 | wc -l` -eq 0 ]; then
		echo "Previous run didn't end well; removing process $PID" 
		rm $PID
	else
		echo "Backup still runs, can't start another instance" 
		exit 1
	fi
fi	
	echo $$ >$PID
	(	
		if [ -e /dev/$VG/$SNAP ]; then
			umount /mnt/snap
			lvremove -f /dev/$VG/$SNAP	
	  	fi	
		if ! lvcreate --size 1G --snapshot --name $SNAP /dev/$VG/$LV; then
			exit 1
		fi

		if ! mount -o ro /dev/$VG/$SNAP /mnt/snap; then
			lvremove -f /dev/$VG/$SNAP
			exit 1
		fi
	) 1>&2 </dev/null || exit 1

	if [ -f /mnt/snap/exclude-from-backup ]; then
		rm -f /tmp/exclude-from-backup
		for l in `cat /mnt/snap/exclude-from-backup`; do echo /mnt/snap$l >> /tmp/exclude-from-backup; done
		OPTIONS="--exclude-filelist /tmp/exclude-from-backup"
	else
		OPTIONS="--exclude-device-files  --exclude-sockets"
	fi

	if [ ! -d /mnt/snap/etc ]; then
		echo "Image doesn't seem to be mounted properly"
		umount /mnt/snap
		exit 1
	fi
	
	rdiff-backup $OPTIONS /mnt/snap $BACKUP_PATH/$HOST-$LV
	rdiff-backup --force --remove-older-than $KEEP_BACKUPS_FOR $BACKUP_PATH/$HOST-$LV

	(
		umount /mnt/snap
		lvdisplay /dev/$VG/$SNAP
		lvremove -f /dev/$VG/$SNAP
		rm $PID
	) 1>&2 </dev/null

и ещё одна нелишняя деталь:
для нагиоса поставил этот плагин, если бэкап какой-то машины не делается сутки — звенит звонок
Эх. Вот рассчитан данный скрипт на небольшой объём данных. В этих целях откройте для себя duplicity (который ещё и шифровать умеет для передачи по каналам типа ftp и хранения в S3)
И rdiff-backup от того же автора (использую для бекапа конифигов системы, а duplicity для икрементных бекапов больших файлов).
Спасибо за обьяснение про $IFS и пути с пробелами! Недавно хотел автоматизировать один процесс и застрял из-за пробела в имени директории…
Ещё вариант простого bash-скрипта для создания бэкапов:

#!/bin/bash

if [ $UID -ne 0 ] ; then
    echo "Error: you must be root" >&2
    exit 1
fi

ARCHIVE="/tmp/etc.$(hostname).$(date '+%d%m%Y').gz"

grep -e "^#F/" ${0} | sed 's/#F//' | while read FNAME ; do
	if [ -d ${FNAME} ] ; then
		find ${FNAME} -xtype f
	elif [ -f ${FNAME} ] ; then
		echo ${FNAME}
	else
		echo "Warning: file ${FNAME} no found" >&2
	fi
done | cpio -o -H tar --quiet | gzip -9c >${ARCHIVE}

s3cmd --no-progress put ${ARCHIVE} s3://bucket/backup/
rm -f ${ARCHIVE}
 
#F/usr/bin/etc.backup
 
#F/etc/ssh/sshd_config
#F/etc/network/if-pre-up.d/iptables
#F/etc/iptables.rules


Список файлов/катлогов для архивирования указывается в самом скрипте: #F/path
В данном случае готовый архив отправляется на amazon s3
Под окнами, во многих случаях, пользуюсь этой программкой. Мною писана спецом дабы уйти от написания скриптов копирования. Фишка программы в том что в ключах можно использовать несколько масок на ключ. А сами ключи разделены на ключи для папок и для файлов. Есть и другие навороты. Если кому интересно пользуйтесь, програма халявная. Если будут интересные предложения функционал можно дальше расширить (хотя того что там уже есть, на мой взгляд, уже вполне достаточно).
Sign up to leave a comment.

Articles