Резервное копирование FreeBSD при помощи fsbackup

Файлы freebsd, веб-сервера, баз данных и другое необходимо делать резервное копирования.
Все резервирование в freebsd сводится к простому копированию файлов. Можно написать свой скрипт, но я решил использовать готовое решение fsbackup.

Приступим к установки.
Обновляем дерево портов и переходим
cd /usr/ports/sysutils/fsbackup/
Установим make install clean

Я буду делать резервное копирование на FTP сервер. Отредактируем скрипт запуска или создадим на основе его свой. Я отредактирую, путь /usr/local/fsbackup/create_backup.sh
#!/bin/sh

# Директория где установлена программа.
backup_path="/usr/local/fsbackup"

# Список файлов конфигурации, разделенных пробелом.
# Директории для сохранения бэкапа в каждом конфигурационном файле должны отличаться ($cfg_remote_path, $cfg_local_path), сохранение в одной и той же директории нескольких, описанных разными .conf файлами, бэкапов не  допустимо.
config_files="ftp_backup.conf"

# Флаг бэкапа MySQL таблиц, запускается требующий предварительной настройки скрипт ./scripts/mysql_backup.sh, 1 - запускать, 0 - не запускать. 
backup_mysql=0

# Флаг бэкапа PostgreSQL таблиц, запускается требующий предварительной настройки скрипт ./scripts/pgsql_backup.sh, 1 - запускать, 0 - не запускать. 
backup_pgsql=0

# Флаг бэкапа SQLite таблиц, запускается требующий предварительной настройки скрипт ./scripts/sqlite_backup.sh, 1 - запускать, 0 - не запускать. 
backup_sqlite=0

# Флаг бэкапа параметров системы, запускается требующий предварительной  настройки скрипт ./scripts/sysbackup.sh, 1 - запускать, 0 - не запускать. 
backup_sys=0

# Дальше пошел сам скрипт, его не трогаем.
#############################################################################
cd $backup_path

# Оставил ulimit после тестирования, на всякий случай.
#ulimit -f 512000;ulimit -d 20000;ulimit -c 100;ulimit -m 25000;ulimit -l 15000

# Сохраняем MySQL базы
if [ $backup_mysql -eq 1 ]; then
    ./scripts/mysql_backup.sh 
fi

# Сохраняем PostgreSQL базы
if [ $backup_pgsql -eq 1 ]; then
    ./scripts/pgsql_backup.sh 
fi

# Сохраняем SQLite базы
if [ $backup_sqlite -eq 1 ]; then
    ./scripts/sqlite_backup.sh 
fi

# Сохраняем системные параметры
if [ $backup_sys -eq 1 ]; then
    ./scripts/sysbackup.sh
fi

# Бэкап.
for cur_conf in $config_files; do
    ./fsbackup.pl ./$cur_conf
    next_iter=`echo "$config_files"| grep "$cur_conf "`
    if [ -n "$next_iter" ]; then
	sleep 600 # Засыпаем на 10 минут, даем процессору остыть :-)
    fi
done


Создаем наш файл конфигурации тот что указали в config_files, у меня это ftp_backup.conf Можно создать на основе cfg_example. Редактируем файл конфигурации /usr/local/fsbackup/ ftp_backup.conf
# Имя для бэкапа, строка состоящая из латинских букв, цифр и символа подчеркивания.
$cfg_backup_name = "ftp_backup";

# Директория для помещения текущих хэшей для локального метода бэкапа, или временных хешей для других методов.
$cfg_cache_dir = "/usr/local/fsbackup/cache"; 

# Пути к запускаемым в процессе выполнения бэкапа программам. Рекомендуется не полениться и прописать полный путь к каждой программе. Внимание ! При использовании шифрования через gpg, рекомендуется установить значение $prog_gzip="", так как gpg перед шифрованием сжимает данные, использование gzip приведет к двойному сжатию и лишней нагрузке на CPU.
$prog_md5sum	= "md5sum -b";
$prog_tar	= "/usr/bin/tar";
$prog_ssh	= "/usr/bin/ssh";
$prog_rm	= "/bin/rm";
$prog_gzip	= "/usr/bin/gzip"; # Если равно "", то не использовать сжатие.
$prog_pgp	= "";  # Если равно "", то не применять шифрование.

# Метод вычисления контрольных сумм для определения изменений в файле.
#	timesize - учитывается время последнего изменения файла, его размер, атрибуты файла, но не учитывается содержимое. Как правило учета данных факторов достаточно для определения необходимости обновления файла в бэкапе. Наиболее быстрый метод.
#	md5 - все параметры timesize + контрольная сумма содержимого файла. Наиболее ресурсоемкий и медленный метод.
$cfg_checksum = "timesize"; 

# Определение типа операции, вида бэкапа.
#	backup - инкрементальный бэкап в архив (т.е. копируются только изменившиеся с момента последнего бэкапа файлы)..
#	full_backup - полный бэкап в архив, без хэша (т.е. всегда копируются все файлы).
#	sync - синхронизация дерева (только для типа хранилища ssh или local).
#	hash - только генерация хэша, без помещения файлов в архив (пометка помещения файлов в бэкап, без физического перемещения)
$cfg_backup_style = "full_backup"; 

# Число копий бэкапа, при инкрементальном бэкапе, после которых производится 
# полный бэкап. Например, при = 7 - 6 раз будут помещаться только изменения,
# на 7 раз бэкап будет объединен в один файл. 0 - сколько угодно раз.
$cfg_increment_level = 7; 

# Сохранение предыдущей версии полного бэкапа перед инкрементальной ротацией или 
# заменой текущего неинкрементального бэкапа новой версией.
# Старая версия помещается в подкаталог OLD.
# 0 - не сохранять предыдущую версию.
# 1 - сохранять предыдущую версию
$cfg_save_old_backup = 1;

# Тип хранилища для бэкапа. Описание см. в файле README.
#	local - хранение бэкапа в локальной файловой системе.
#	remote_ssh - копирование бэкапа на удаленную машину с использованием SSH
#	remote_ftp - копирование бэкапа на удаленную машину по FTP
$cfg_type = "remote_ftp";

# Параметры необходимые для копирования бэкапа через ssh и ftp:
$cfg_remote_host = "192.168.0.2";
$cfg_remote_login = "backup";
$cfg_remote_path = "/backup";

# Режим соединения с FTP сервером (пассивный или активный).
# 0 - Active режим.
# 1 - Passive режим (для специфичных ftp серверов или особых настроек фаерволов).
$cfg_remote_ftp_mode = 0;

# Параметры необходимые для копирования бэкапа по ftp:
$cfg_remote_password = "12345";

# Параметры необходимые для хранения бэкапа на локальной ФС:
# Бэкап не должен быть в одной директории с кэшем. Создайте отдельную директорию, например, archive.
$cfg_local_path = "/usr/local/fsbackup/archive";

# Время в днях, файлы созданные ранее которого не будут помещаться в бэкап. 
# 0 - помещаем все фалы независимо от времени их создания.
$cfg_time_limit = 0;

# Максимально допустимый размер файла в Kb для помещения в бэкап. 
# 0 - помещаем все фалы независимо от их размера.
$cfg_size_limit = 0;

# Максимальный размер (в Kb) несжатого архива с бэкапом, размещенного в одном файле, т.е. размер тома. Полезно при создании гиганских архивов не влезающих в ограничение файловой системы или при последующей записи архивов на CD-ROM или другие накопители небольшого размера.
# При превышении заданного размера, запись продолжается в следующий файл c идентификатором '-2', '-3' и т.д.
# 0 - размер архива не ограничен.
$cfg_maximum_archive_size = 0;

# Корневая директория, относительно которой файлы помещаются в бэкап и 
# относительно которой описаны пути для помещения файлов.
$cfg_root_path = "/";

# Шифрования бэкапа с помощью PGP.
# Если поле не заполнено, то pgp не применяется.
# Иначе поле содержит UserId записи в public key ring.
# $cfg_pgp_userid = "backup";

# Уровень "говорливости", регулирует объем выводимых программой сообщений.
#	0 - Подавить вывод любых сообщений.
#	1 - Выводить сообщения об ошибках и предупреждения
#	2 - Выводить все сообщения
$cfg_verbose = 2;

# Рекурсивный просмотр запрещенных директорий.
#	0- рекурсивно просматривать все содержимое директорий помеченных для бэкапа, в том числе и содержимое директорий запрещенных правилами '!', '!d' и '=!'.
#	1- не использовать рекурсивный вход в запрещенные для бэкапа директории (увеличивается скорость бэкапа, уменьшает гибкость настройки).
$cfg_stopdir_prune=0;

1;
# Список файлов и условий для помещения в бэкап.
# (описываются после директивы __DATA__):
#  /dir[/file] - путь к файлу/директории для бэкапа.
#  !/dir[/file] - отрицание пути, не помещать в бэкап. Не маска, а реальный путь.
#  # - комментарий
# Маски:
#  =~ - маска для файла или директории, а не абсолютный путь. Первый или второй символ.
#  f~ - маска для файла. Первый или второй символ.
#  d~ - маска для директории. Первый или второй символ.
# Маски отрицания:
#  =! - "НЕ" маска для файла или директории, а не абсолютный путь. Первый или второй символ.
#  f! - "НЕ" маска для файла. Первый или второй символ.
#  d! - "НЕ" маска для директории. Первый или второй символ.
#
#
# Бэкап проходит только в рамках директорий и файлов описанных в путях.
# Отрицания путей имеют более высокий приоритет чем пути.
# Маски имеют более высокий приоритет, чем пути или отрицание путей, маски "НЕ" имеют более высокий приоритет, чем обычные маски:
# 
# Таблица приоритетов:
#    1.	=!
#    2.	f!
#    3.	f~
#    4.	d!
#    5.	=~
#    6.	d~
#    7.	!
#    8. path
#
#  Пример:
#  /usr/home		# Объявляем /usr/home как пустой путь,
#  !/usr/home		# для работы масок.
#  d~public_html
#  /var
#  d!var/log
#  f~netconf\.log.*
#  
#  при этом только /usr/home/*/public_html будет добавлено в архив, 
#  а файлы директории /var/log/var/log/, за исключением messages, нет. 
#  Но, /usr/local/home/user/public_html добавлено в 
#  архив не будет ! Для поиска только по маскам нужно объявить:
#  /
#  !/
#  d~public_html
#  d~cgi-bin
#  d~/etc/
#-------------------

__DATA__ 
/usr/local/fsbackup
!/usr/local/fsbackup/cache

# BSD
/var/db/pkg
/usr/src/sys/amd64/conf

# System configuration
/etc
/var/cron/tabs
/var/spool/cron
/usr/local/etc

# Installed packages
/usr/local/bin
/usr/local/include
/usr/local/lib
/usr/local/libdata
/usr/local/libexec
/usr/local/sbin
/usr/local/share

# Web-server
/usr/local/www

Если в файле create_backup.sh мы указали что делать backup MySQL то редактируем файл /usr/local/fsbackup/scripts/mysql_backup.sh (указываем там права доступа к базе и какие базы данных копировать). Я думаю про резервное копирование MySQL я расскажу в отдельной статье.
Запускаем файл create_backup.sh из директории /usr/local/fsbackup/
root@localhost:/usr/local/fsbackup # ./create_backup.sh
Creating remote_ftp full_backup: ftp_backup
Adding /usr/local/fsbackup....
done
Adding /var/db/pkg....
done
Adding /usr/src/sys/amd64/conf....
done
-----------------------------------
Adding /etc....
done
Adding /usr/local/www....
done
Storing remote ftp backup...
***** Backup successful complete.

Все резервное копирование сделано. Если вдруг будут ошибки, они будут выведены.
Теперь если нужно делать периодически копирование нужно добавить строчку в /etc/crontab
# fsbackup
0       3       *       *       *       root    /usr/local/fsbackup/create_backup.sh > /dev/null

Скрипт будет запускать каждый день в 3 часа ночи. Вывода никакого не будет.

Далее я сделал несколько изменений. Меня не устраивало что при full_backup не указывалось время в файле бэкапа и то что папка OLD хранила только один последний бэкап.
Редактируем файл /usr/local/fsbackup/fsbackup.pl
Находим
if ($cfg_backup_style eq "backup"){
    my ($sec,$min,$hour,$mday,$mon,$year) = localtime($cur_time);
    $backup_file_base = sprintf ("%s-%4.4d.%2.2d.%2.2d.%2.2d.%2.2d.%2.2d",
                $cfg_backup_name,$year+1900,$mon+1,$mday,$hour,$min,$sec);
}else{
    $backup_file_base="$cfg_backup_name";
}

Заменяем для того что бы время показывалось всегда.
if ($cfg_backup_style eq "backup"){
    my ($sec,$min,$hour,$mday,$mon,$year) = localtime($cur_time);
    $backup_file_base = sprintf ("%s-%4.4d.%2.2d.%2.2d.%2.2d.%2.2d.%2.2d",
	$cfg_backup_name,$year+1900,$mon+1,$mday,$hour,$min,$sec);
}else{
    my ($sec,$min,$hour,$mday,$mon,$year) = localtime($cur_time);
    $backup_file_base = sprintf ("%s-%4.4d.%2.2d.%2.2d.%2.2d.%2.2d.%2.2d",
	$cfg_backup_name,$year+1900,$mon+1,$mday,$hour,$min,$sec);
}

Далее находим
$ftp->mkdir("$cfg_remote_path/OLD");
$ftp->cwd("$cfg_remote_path/OLD");
foreach $cur_dir ($ftp->ls()){
$ftp->delete($cur_dir);
}

И комментируем все эти строчки символом #. Теперь папка OLD перед началось резервного копирование не будет удаляться.
Если не добавить время при full_backup к файлам, не очищать папку OLD смысла нет, так как файлы будут иметь одинаковое значение.
Сохраняем файл и проверяем.

Если ест вопросы с радостью выслушаю.
0.10
2.12.2013 15:30