Application: "Bacula 5.2/7.4", "mysqldump" и "xtrabackup".
Задача: наладить выгрузку резервной копии "баз данных" СУБД "MySQL" посредством "Bacula".
Резервное копирование содержимого "баз данных" прямым копированием из файлов как правило невозможно и требуется предварительная выгрузка консистентного "дампа" в заранее известную директорию. Сделаем это, воспользовавшись встроенной возможностью "Bacula" исполнения произвольных скриптов на стороне клиента до и после процедуры непосредственного резервного копирования.
Предварительная настройка СУБД.
Есть два способа получить резервную копию "баз данных" MySQL: выгрузка SQL-дампа и снятие "бинарного дампа".
Подготавливать к выгрузке SQL-дампа сервер СУБД не требуется. Нужен только доступ от имени обладающего достаточными привилегиями пользователя - но процедуры резервного копирования обычно запускаются в контексте суперпользователя, что снимает все ограничения.
К снятию "бинарного дампа" нужно готовиться, изменяя настройки сервера СУБД. Процедура детально описана в отдельной инструкции.
Конфигурирование "Bacula".
Дополняем описание задания резервного копирования сервиса "MySQL" следующими блоками конфигурации, в зависимости от выбранного способа.
Выгрузка SQL-дампа:
# vi /etc/bacula/client.d/example.net.conf
....
FileSet {
....
Include {
....
# Директория резервных копий "дампов баз данных"
File = "/var/backups/bacula-mysqldump"
}
}
....
Job {
Name = "example.net"
Type = Backup
....
# Запуск выгрузки резервной копии всех локальных "баз данных" MySQL в формате SQL:
RunScript {
RunsWhen = Before
FailJobOnError = No
# Зачищаем и воссоздаём место для сохранения "дампа"
Command = "rm -rf /var/backups/bacula-mysqldump"
Command = "mkdir -p /var/backups/bacula-mysqldump"
## Запускаем выгрузку резервной копии БД:
# (вариант для прозрачной аутентификации при работе через локальный сокет)
Command = "/bin/bash -c 'mysqldump --verbose --force --complete-insert --all-databases --result-file=/var/backups/bacula-mysqldump/`date +\"%%Y-%%m-%%d_%%H:%%M\"`.sql 2>/var/log/mysqldump.log'"
# (вариант с парольной аутентификацией, из типового месторасположения такового)
#Command = "/bin/bash -c 'mysqldump --verbose --force --complete-insert --host=localhost --user=root --password=\"`cat /root/.mysql`\" --all-databases --result-file=/var/backups/bacula-mysqldump/`date +\"%%Y-%%m-%%d_%%H:%%M\"`.sql 2>/var/log/bacula-mysqldump.log'"
}
#
RunScript {
RunsWhen = After
RunsOnFailure = yes
# По завершению всех процедур задания высвобождаем ресурсы
Command = "rm -rf /var/backups/bacula-mysqldump"
}
}
FileSet {
....
Include {
....
# Директория резервных копий "дампов баз данных"
File = "/var/backups/bacula-mysqldump"
}
}
....
Job {
Name = "example.net"
Type = Backup
....
# Запуск выгрузки резервной копии всех локальных "баз данных" MySQL в формате SQL:
RunScript {
RunsWhen = Before
FailJobOnError = No
# Зачищаем и воссоздаём место для сохранения "дампа"
Command = "rm -rf /var/backups/bacula-mysqldump"
Command = "mkdir -p /var/backups/bacula-mysqldump"
## Запускаем выгрузку резервной копии БД:
# (вариант для прозрачной аутентификации при работе через локальный сокет)
Command = "/bin/bash -c 'mysqldump --verbose --force --complete-insert --all-databases --result-file=/var/backups/bacula-mysqldump/`date +\"%%Y-%%m-%%d_%%H:%%M\"`.sql 2>/var/log/mysqldump.log'"
# (вариант с парольной аутентификацией, из типового месторасположения такового)
#Command = "/bin/bash -c 'mysqldump --verbose --force --complete-insert --host=localhost --user=root --password=\"`cat /root/.mysql`\" --all-databases --result-file=/var/backups/bacula-mysqldump/`date +\"%%Y-%%m-%%d_%%H:%%M\"`.sql 2>/var/log/bacula-mysqldump.log'"
}
#
RunScript {
RunsWhen = After
RunsOnFailure = yes
# По завершению всех процедур задания высвобождаем ресурсы
Command = "rm -rf /var/backups/bacula-mysqldump"
}
}
Снятие "бинарного дампа":
# vi /etc/bacula/client.d/example.net.conf
....
FileSet {
....
Include {
....
# Директория резервных копий "дампов баз данных"
File = "/var/backups/bacula-xtrabackup"
}
}
....
Job {
Name = "example.net"
Type = Backup
....
# Запуск выгрузки "бинарной" резервной копии всех локальных "баз данных" MySQL:
RunScript {
RunsWhen = Before
FailJobOnError = No
# Зачищаем и воссоздаём место для сохранения "дампа"
Command = "rm -rf /var/backups/bacula-xtrabackup"
Command = "mkdir -p /var/backups/bacula-xtrabackup"
## Запускаем выгрузку резервной копии БД:
# (вариант для прозрачной аутентификации при работе через локальный сокет)
Command = "/bin/bash -c 'xtrabackup --backup --target-dir=/var/backups/bacula-xtrabackup 2>/var/log/xtrabackup.log'"
# (вариант с парольной аутентификацией, из типового месторасположения такового)
#Command = "/bin/bash -c 'xtrabackup --backup --user=root --password=\"`cat /root/.mysql`\" --target-dir=/var/backups/bacula-xtrabackup 2>/var/log/bacula-xtrabackup.log'"
}
#
RunScript {
RunsWhen = After
RunsOnFailure = yes
# По завершению всех процедур задания высвобождаем ресурсы
Command = "rm -rf /var/backups/bacula-xtrabackup"
}
}
FileSet {
....
Include {
....
# Директория резервных копий "дампов баз данных"
File = "/var/backups/bacula-xtrabackup"
}
}
....
Job {
Name = "example.net"
Type = Backup
....
# Запуск выгрузки "бинарной" резервной копии всех локальных "баз данных" MySQL:
RunScript {
RunsWhen = Before
FailJobOnError = No
# Зачищаем и воссоздаём место для сохранения "дампа"
Command = "rm -rf /var/backups/bacula-xtrabackup"
Command = "mkdir -p /var/backups/bacula-xtrabackup"
## Запускаем выгрузку резервной копии БД:
# (вариант для прозрачной аутентификации при работе через локальный сокет)
Command = "/bin/bash -c 'xtrabackup --backup --target-dir=/var/backups/bacula-xtrabackup 2>/var/log/xtrabackup.log'"
# (вариант с парольной аутентификацией, из типового месторасположения такового)
#Command = "/bin/bash -c 'xtrabackup --backup --user=root --password=\"`cat /root/.mysql`\" --target-dir=/var/backups/bacula-xtrabackup 2>/var/log/bacula-xtrabackup.log'"
}
#
RunScript {
RunsWhen = After
RunsOnFailure = yes
# По завершению всех процедур задания высвобождаем ресурсы
Command = "rm -rf /var/backups/bacula-xtrabackup"
}
}
Проверяем корректность конфигурации и применяем таковую:
# bacula-dir -c /etc/bacula/bacula-dir.conf -t
# /etc/init.d/bacula-dir reload
# /etc/init.d/bacula-dir reload
Выше я заворачиваю содержимое директивы "Command" в дополнительный контейнер из "/bin/bash" - это требуется потому, что по умолчанию "Bacula FD" запускает свои команды в интерпретаторе "Dash", синтаксис которого отличается от привычного мне "Bash".