UMGUM.COM (лучше) 

Bacula + MySQL backup ( Резервное копирование баз MySQL с помощью Bacula. )

12 ноября 2010  (обновлено 29 декабря 2014)

OS: Linux Debian Lenny/Squeeze/Wheezy.
Application: Bacula v.3.2/v.5.2.

Резервирование "баз данных", например MySQL, PostgreSQL, MSQL с помощью Bacula возможно производить с помощью встроенной возможности Bacula исполнения произвольных "скриптов" на стороне сервера или клиента до и после процедуры непосредственного резервного копирования.

Всё элементарно: пишем скрипт, осуществляющий "дамп" базы данных на стороне клиента в целевую директорию, в общем порядке резервируем получившийся файл, после завершения операции резервирования удаляем временный файл "дампа".

Правда, в таком простеньком варианте всегда будет производится полный "бэкап" базы данных, в отличии от общего инкрементального, например. Можно, наверное, учесть это и делать "дамп" только записей, созданных с определённого времени, но это будет делаться не здесь и не сейчас.


Для MySQL резервное копирование и применение данных стандартно осуществляется утилитами создания "дампа", например, входящей в состав комплекта программного обеспечения сервера MySQL утилитой mysqldump. Это наиболее общий способ, подходящий для всех поддерживаемых типов таблиц в MySQL. Необходимо оперировать от имени пользователя, который имеет право блокировать таблицы на сервере для исключения внесения изменений в таблицы во время создания резервной копии:

Создаём пользователя MySQL, обладающего достаточными привелегиями SELECT, RELOAD, LOCK TABLES. В консоли MySQL от имени суперпользователя СУБД отдаем команды:

#mysql> CREATE USER 'bacula'@'localhost' IDENTIFIED BY 'bacula.strong.password';
#mysql> GRANT SELECT, RELOAD, LOCK TABLES ON *.* TO 'bacula'@'localhost' IDENTIFIED BY 'bacula.strong.password';

Создаем скрипт:

# mkdir -p /etc/bacula/custom
# touch /etc/bacula/custom/make-dump-mysql.sh
# chmod ugo+x /etc/bacula/custom/make-dump-mysql.sh

# cat /etc/bacula/custom/make-dump-mysql.sh

#!/bin/bash

DATE=`date +"%Y-%m-%d %H:%M:%S"`
LIST="--all-databases"
HOST="localhost"
USER="bacula"
PASSWORD="bacula.strong.password"
RESULT="/tmp/mysqldump.tmp.sql"
LOG="/var/log/mysqldump.log"

mysqldump --verbose --force --complete-insert --host=${HOST} ${LIST} --result-file="${RESULT}" --user=${USER} --password=${PASSWORD} 2>> ${LOG}

exit 0

Где опции mysqldump:

"--verbose" - включает более детализированный вывод;
"--force" - указывает продолжать создание дампа несмотря на случившиеся ошибки в процессе;
"--complete-insert" - применяем режим создания "дампа" с командой insert на каждую строку вместо более компактного режима по умолчанию с одним insert на всю таблицу.

Важно понимать, что резервное копирование с помощью утилит последовательного чтения и вывода информации в "дамп" не гарантирует непротиворечивого состояния данных с завершением всей процедуры в целом. Дело в том, что после того, как будет скопирована строка вначале таблицы, она может быть изменена вместе с другими строками, до которых чтение ещё не дошло. В итоге можно запросто получить неработающую логику базы данных, в которой строки в её начале конфликтуют со строками в конце. Самое простое (и примитивное, на производстве практически неприменимое) решение для задач, работу которых можно на некоторое время приостановить - блокировка таблиц. Для этого в наборе ключей утилиты mysqldump имеется парочка соответствующих ключей:

"--first-slave" - блокируем все таблицы для записи (обеспечение единого непотиворечивого состояния данных в таблицах);
"--add-locks" - блокирование от записи каждой таблицы по отдельности во время исполнения "дампа";

Теперь, после того, как мы убедимся в работоспособности скрипта на стороне клиента, применим его со стороны сервер Bacula. В конфигурациионном файле "/etc/bacula/bacula-dir.conf" в конфигурации задания ("Job") соответствующего клиента добавим указания на запуск скрипта предварительного создания "дампа" баз данных и команды удаления временного файла "дампа" после исполнение резервного копирования:

# cat /etc/bacula/bacula-dir.conf

....
Job {
  Name = "job-backup-test.domain.local"
  Type = Backup
  ....
  ClientRunBeforeJob = "/etc/bacula/custom/make-dump-mysql.sh"
  ClientRunAfterJob = "/bin/rm -rf /tmp/mysqldump.tmp.sql"
  ....

В описании области резервирования указываем файл "дампа":

# cat /etc/bacula/bacula-dir.conf

....
FileSet {
  Name = "file-set-test.domain.local"
  Include {
....
    File = "/etc"
    File = "/home"
    File = "/tmp/mysqldump.tmp.sql"
....

Вот и всё.

А вообще, для тех, кто не бросил чтение и дошёл до конца, замечу: регулярное (раз в день или два дня) резервирование объёмных (более гигабайта) баз данных с помощью создания полного "дампа" - глупость. Наиболее оптимально применение резервирования так называемых "бинарных" журналов операций. Тогда, при крахе части или всех данных, проще поднять полные журналы операций и восстановить по ним базы.


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )