Настройка Bacula 9 + Baculum 9 для PostgreSQL 9.6

Материал из ALT Linux Wiki

Установка PostgreSQL


Установим PostgreSQL версии 9.6:
Для этого на сервере выполним команду:

# apt-get install postgresql9.6-server
Внимание! Перед запуском службы необходимо создать системные базы данных:
# /etc/init.d/postgresql initdb
(через systemctl postgresql initdb не работает)


Запустим сервис и добавим его в автозагрузку.

Запуск службы:

# service postgresql start

или

# systemctl start postgresql.service

Включение службы по умолчанию:

# chkconfig postgresql on

или

# systemctl enable postgresql


Настройка PostgreSQL


На сервере

Для работы с Bacula на сервере PostgreSQL должно быть настроено онлайн резервирование (PITR): Если в настройках сервера включено ведение журналов упреждающей записи (WAL), то появляется возможность резервного копирования на уровне файловой системы с копированием журналов. В этом случае при сбое мы можем восстановить базу от контрольной точки до произвольного момента времени, после контрольной точки, с помощью файлов журналов. Подробнее об этом можно почитать здесь

Настройка журналов WAL

Для того, чтобы PostgreSQL начал писать файлы журналов необходимо изменить конфигурационный файл сервера /var/lib/pgsql/data/postgresql.conf следующим образом:

wal_level = archive # указывается уровень ведения журналов
archive_mode = on # разрешается ведение журналов
archive_command = '/var/lib/pgsql/bin/copy_wal.sh "%f" "%p"'

archive_command - это команда выполняемая сервером над журналом который надо архивировать. %p заменяется полным путем к файлу, %f заменяется именем файла. Простейшая команда это 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' она проверяет не был ли файл уже архивирован, и если не был то копирует его в каталог /mnt/server/archivedir/
Создадим каталог для архивных журналов и установим нужные права:

# mkdir /var/lib/pgsql/wals
# chown postgres:postgres /var/lib/pgsql/wals
# chmod 700 /var/lib/pgsql/wals

Также создадим каталог для нашего скрипта архивирования журналов:

# mkdir /var/lib/pgsql/bin
# chown postgres:postgres /var/lib/pgsql/bin
# chmod 700 /var/lib/pgsql/bin

Рассмотрим файл /var/lib/pgsql/bin/copy_wal.sh:

#!/bin/bash
DPATH=/var/lib/pgsql/wals
DATE=`date +"%b %d %T"`
if [ -e /var/lib/pgsql/backup_in_progress ]; then # По наличию файла проверяет не идет ли процесс резервного копирования журналов
 echo "${DATE} - идет процесс резервного копирования журналов" >> "${DPATH}/wal-c-log.log"
 exit 1
fi
if [ -e ${DPATH}/$1 ]; then # Проверяет скопирован ли журнал раннее
 echo "${DATE} - файл уже архивирован" >> "${DPATH}/wal-c-log.log"
 exit 1
fi
echo "${DATE} - /bin/gzip $2 ${DPATH}/$1" >> "${DPATH}/wal-c-log.log"
gzip < $2 > "${DPATH}/$1" # Архивирует файл журнала

Скрипт проверяет состояния резервного копирования журналов и архивирует журналы в каталог /var/lib/pgsql/wals, все свои действия он пишет в /var/lib/pgsql/wals/wal-c-log.log
Установим нужные права на скрипт:

# chown postgres:postgres /var/lib/pgsql/bin/copy_wal.sh
# chmod 700 /var/lib/pgsql/bin/copy_wal.sh

Теперь перезапустим сервер базы данных:

# systemctl restart postgresql

Со временем в каталоге /var/lib/pgsql/wals будут появляться файлы вида:

-rw------- 1 postgres postgres 3848185 июл 12 18:40 000000010000001900000048
-rw------- 1 postgres postgres 3830181 июл 12 18:33 000000010000001900000047
-rw------- 1 postgres postgres 4131659 июл 12 18:26 000000010000001900000046
-rw------- 1 postgres postgres 3977349 июл 12 18:26 000000010000001900000045

Если они появляются значит журналирование настроены правильно.

Онлайн резервное копирование

Используя Low Level API

Использование низкоуровневого API подразумевает следующие шаги:
1. Убедитесь что журналирование включено и работает
2. Подключитесь к базе от имени суперпользователя:

# psql -U postgres

Для начала резервного копирования выполните следующий запрос:

postgres=# select pg_start_backup('Full Backup - Testing');

Этот запрос может выполняться длительное время, так как создается контрольная точка и минимизируется влияние на текущие операции.
Чтобы начать резервное копирование как можно быстрее (используя все ресурсы для создания контрольной точки) выполните команду с параметром true:

postgres=# select pg_start_backup('Full Backup - Testing',true);

Пример вывода команды pg_start_backup:

pg_start_backup 
-----------------
 1A/20000028
 (1 строка)

3. Теперь можно делать файловое резервное копирование каталога с базой данных (/var/lib/pgsql/data) любыми удобными инструментами (cp, rsync и т.д.)
4. После окончания резервирования подключитесь к базе снова и введите команду:

postgres=# select pg_stop_backup();

При этом сервер выйдет из режима резервного копирования и переключится на новый файл журнала (WAL). Переключение на новый файл журнала необходимо для того, чтобы все изменения произошедшие во время резервного копирования сразу были доступны для архивирования.

5. Теперь остается в дополнение к файловой резервной копии добавить файлы журналов, созданные во время резервирования. Для удобства в каталоге с журналами будет создан файл вида 000000010000001A00000020.00000028.backup, в котором находится информация о резервной копии. Первая часть имени этого файла

000000010000001A00000020

обозначает имя первого журнала WAL необходимого для воcстановления базы. Журналы с меньшим именем могут быть удалены.

С помощью команды pg_basebackup

Так же резервную копию можно создать использую команду pg_basebackup. Эта команда создает копию в виде файлов или архива tar.
Для ее работы необходимо дополнительно настроить сервер базы данных (/var/lib/pgsql/data/postgresql.conf):

max_wal_senders = 1

И разрешить подсоединение пользователю postgres для репликации раскомментировать нужную строчку в файле /var/lib/pgsql/data/pg_hba.conf:

local   replication     postgres

Перезапустите сервер баз данных:

# systemctl restart postgresql

Пример использования команды:

# pg_basebackup -D /var/lib/pgsql/backup -F t -z -U postgres -w -c fast -l "pg_basebackup test backup"

Описание параметров команды:

  • -D -- каталог для архивации (должен быть пустой)
  • -F -- формат вывода (t - tar архив)
  • -z -- сжимает выходной файл gzip
  • -U -- пользователь для подключения к базе
  • -w -- не запрашивать пароль
  • -с -- режим создания контрольной точки (fast - быстрая)
  • -l -- метка резервной копии

После выполнения команды в каталоге /var/lib/pgsql/backup появится архив base.tar.gz. А в каталоге с журналами будет создан файл с описанием резервной копии. В дополнение к резервной копии необходимо копировать архивы журналов.

Восстановление из резервной копии

Для восстановления из резервной копии, сделанной с помощью механизма Continuous Archiving, потребуется архив с базовой резервной копией и файлы журналов WAL.
1. Остановите сервер.
2. Если позволяет свободное место временно скопируйте каталог с базой данных. Если места недостаточно сохраните как минимум содержимое подкаталога pg_xlog каталога базы данных, так в нем хранятся не архивированные журналы WAL.
3. Восстановите все файлы из архива с резервной копией. Проверьте права и владельца файлов. Они должны принадлежать пользователю от имени которого запускается сервер PostgreSQL.
4. Удалите все файлы из восстановленного подкаталога pg_xlog, так как содержащиеся там файлы журналов устарели.
5. Скопируйте не архивированные файлы журналов сохраненные в п.2 в подкаталог pg_xlog восстановленной базы данных. Проверьте права и владельца.
6. В каталоге базы данных /var/lib/pgsql/data создайте файл recovery.conf. Файл должен иметь права 600 и владельца от имени которого запускается сервер. Запустите сервер PostgreSQL. Если восстановление по какой-то причине прервется просто запустите сервер еще раз. После окончания восстановления файл recovery.conf переименуется в файл recovery.done, чтобы исключить повторный запуск восстановления. Сервер готов к работе.
В файле recovery.conf должна быть прописана как минимум одна команда restore_command, которая указывает откуда берутся файлы журналов.
Предположим что резервную копию мы разархивировали в каталог /var/lib/pgsql/data
Архивные журналы находятся в каталоге /var/lib/pgsql/wal
Журналы архивировались командой archive_command = 'gzip < %p > /var/lib/pgsql/wal/%f'
Тогда файл recovery.conf должен содержать следующую строку:

restore_command = 'gunzip < /var/lib/pgsql/wal/%f > %p'

Также можно задать момент времени до которого нужно проводить восстановление:

recovery_target_time = '2017-05-25 19:07:01'

Если метку времени не задавать будет выполнено восстановление на сколько это возможно.

На клиенте


В каталоге /etc/bacula создадим следующие скрипты:
pre-base-backup.sh:

#!/bin/bash
DATE=`date +"%b %d %T"`
/usr/bin/pg_basebackup -D /var/lib/pgsql/backup -F t -z -U postgres -w -c fast -l "pg_basebackup ${DATE}"

Этот скрипт создает полную копию базы данных и выполняется перед выполнением задачи резервного копирования базы.

post-base-backup.sh:

#!/bin/bash
rm -f /var/lib/pgsql/backup/*

Этот скрипт удаляет созданную копию базы данных и будет выполнен после задачи резервного копирования базы.

pre-logs-backup.sh:

#!/bin/bash
touch /var/lib/pgsql/backup_in_progress

Этот скрипт создает файл backup_in_progress и выполняется перед выполнением задачи резервного копирования журналов. Этот файл нужен, чтобы во время резервного копирования PostgreSQL не архивировал новые журналы (copy_wal.sh)

post-logs-backup.sh:

#!/bin/bash
rm -f /var/lib/pgsql/wals/*
rm -f /var/lib/pgsql/backup_in_progress

Этот скрипт очищает каталог с журналами и файл backup_in_progress, и будет выполнен после задачи резервного копирования журналов. Далее необходимо сделать эти скрипты исполняемыми:

# chmod 750 pre-base-backup.sh
# chmod 750 post-logs-backup.sh
# chmod 750 post-base-backup.sh
# chmod 750 pre-logs-backup.sh

Установка Bacula

Установка на сервере:

# apt-get install bacula9-common bacula9-console bacula9-director-common bacula9-director-postgresql bacula9-storage mt-st


Установка на клиенте:

# apt-get install bacula9-client
Внимание! Если у Вас включен SELinux, то на время настройки выключите его

Генерация базы данных PostgreSQL при помощи скриптов


В bacula присутствуют скрипты для создания базы, пользователя и таблиц.
Для того чтобы задать пароль для пользователя bacula необходимо отредактировать следующую строку в файле /usr/share/bacula/scripts/grant_mysql_privileges:

...
db_password="DBPaSSword"
...

В противном случае пользователь создастся без пароля.
Создаём базу данных bacula и пользователя bacula:

$ /usr/share/bacula/scripts/create_postgresql_database -U postgres

Создаём таблицы базы данных:

$ /usr/share/bacula/scripts/make_postgresql_tables -U postgres

Установим права пользователя bacula:

$ /usr/share/bacula/scripts/grant_postgresql_privileges -U postgres

Настройка Director

За настройку Bacula Director отвечает файл /etc/bacula/bacula-dir.conf:

Director {                            # define myself
  Name = dir
  DIRport = 9101                # Порт который будет слушать Director
  QueryFile = "/usr/share/bacula/scripts/query.sql"
  WorkingDirectory = "/var/lib/bacula"
  PidDirectory = "/var/run/bacula"
  Maximum Concurrent Jobs = 1
@/etc/bacula/bacula-dir-password.conf # Файл с паролем для доступа к Director
  Messages = Daemon
}

# Generic catalog service
Catalog {
  Name = MyCatalog # Имя каталога
  dbname = bacula # Имя базы данных
  user = bacula # Имя пользователя базы данных
  password = "" # Пароль пользователя базы данных(при выполнении скрипта по-умолчанию не задан)
#
# Restricted console used by tray-monitor to get the status of the director
#
#Console {
#  Name = localhost-mon
#  Password = "1" # Пароль входа в консоль
#  CommandACL = status, .status
#}
# Дальнейшие строчки подгружают конфигурационные файлы из подкаталогов job.d fileset.d schedule.d client.d storage.d messages.d pool.d
# Jobs
@|"sh -c 'for f in /etc/bacula/job.d/*.conf ; do echo @${f} ; done'"

# File Sets
@|"sh -c 'for f in /etc/bacula/fileset.d/*.conf ; do echo @${f} ; done'"

# Schedules
@|"sh -c 'for f in /etc/bacula/schedule.d/*.conf ; do echo @${f} ; done'"

# Clients
@|"sh -c 'for f in /etc/bacula/client.d/*.conf ; do echo @${f} ; done'"

# Storages
@|"sh -c 'for f in /etc/bacula/storage.d/*.conf ; do echo @${f} ; done'"

# Messages
@|"sh -c 'for f in /etc/bacula/messages.d/*.conf ; do echo @${f} ; done'"

# Pools
@|"sh -c 'for f in /etc/bacula/pool.d/*.conf ; do echo @${f} ; done'"

Установим пароль для доступа к Director в файле /etc/bacula/bacula-dir-password.conf:

Password = "1" # Пароль для доступа к Director


Настройка Storage

Конфигурационный файл хранилищ/etc/bacula/bacula-sd.conf:

#
# Default Bacula Storage Daemon Configuration file
#
#  For Bacula release 2.4.4 (28 December 2008) -- redhat 
#
# You may need to change the name of your tape drive
#   on the "Archive Device" directive in the Device
#   resource.  If you change the Name and/or the 
#   "Media Type" in the Device resource, please ensure
#   that dird.conf has corresponding changes.
#

Storage {                             # definition of myself
  Name = sd # Имя хранилища
  SDPort = 9103                  # Порт
  WorkingDirectory = "/var/lib/bacula"
  Pid Directory = "/var/run/bacula"
  Maximum Concurrent Jobs = 20
}

#
# List Directors who are permitted to contact Storage daemon
#
Director {
  Name = dir # Имя director, который может подсоединяться к этому хранилищу
@/etc/bacula/bacula-sd-password.conf # Файл с паролем к хранилищу
}

#
# Restricted Director, used by tray-monitor to get the
#   status of the storage daemon
#
#Director {
#  Name = dir-mon
#  Password = ""
#  Monitor = yes
#}


@|"sh -c 'for f in /etc/bacula/device.d/*.conf ; do echo @${f} ; done'" # Подключение конфигурационных файлов из каталога device.d

#
# Send all messages to the Director, 
# mount messages also are sent to the email address
#
Messages {
  Name = Standard
  director = dir = all
}

Установим пароль для доступа к хранилищу в файле /etc/bacula/bacula-sd-password.conf:

Password = "1" # Пароль для доступа к хранилищу


В каталоге /etc/bacula/storage.d расположен файл описания типа хранилища file.conf

# Definition of file storage device
Storage {
  Name = File # Имя
# Do not use "localhost" here
  Address = 127.0.0.1                # адрес, где находится Director
  SDPort = 9103 # Порт
@/etc/bacula/bacula-sd-password.conf # Файл с паролем доступа к хранилищу
  Device = FileStorage # Устройство
  Media Type = File # Тип устройства
}

Настройка Bacula User Agent (Console)

Конфигурационный файл хранилищ/etc/bacula/bconsole.conf:

#
# Bacula User Agent (or Console) Configuration File
#

Director {
  Name = dir
  DIRport = 9101 #Порт подключения к  Director
  address = 127.0.0.1 # Адрес расположения Director
@/etc/bacula/bacula-dir-password.conf # Пароль для подключения к Director
}


Настройка Client

Конфигурационный файл клиента /etc/bacula/client.d/client1.conf:

# Client (File Services) to backup
Client {
  Name = fd # Имя клиента
  Address = 127.0.0.1 # Адрес клиента
  FDPort = 9102 # Порт клиента
  Catalog = MyCatalog # Используемый каталог
@/etc/bacula/bacula-fd-password.conf # Пароль для доступа к клиенту
  File Retention = 30 days            # Срок хранения метаданных о файлах
  Job Retention = 6 months            # Срок хранения метаданных о задачах
  AutoPrune = yes                     # Автоматическое удаление устаревших метаданных
}

Установим пароль для доступа к клиенту в файле /etc/bacula/bacula-fd-password.conf:

Password = "1" # Пароль для доступа к клиенту


Настройка FileStorage

В каталоге /etc/bacula/device.d находится файл с описанием устройства:

Device {
  Name = FileStorage # Имя устройства
  Media Type = File # Тип устройства
  Archive Device = /home/backup # Каталог для хранения
  LabelMedia = yes;                   # lets Bacula label unlabeled media
  Random Access = Yes;
  AutomaticMount = yes;               # when device opened, read it
  RemovableMedia = no;
  AlwaysOpen = no;
}


Каталог /home/backup должнен существовать и принадлежать пользователю bacula:

# mkdir /home/backup
# chown bacula:bacula /home/backup


Описание наборов файлов

В каталоге /etc/bacula/fileset.d находятся описания списков файлов для резервирования:
catalog.conf

# Описание  резервирование дампа базы данных bacula
FileSet {
  Name = "Catalog"
  Include {
    Options {
      signature = MD5
    }
    File = /var/lib/bacula/bacula.sql
  }
}


catalog.conf

# Полный бэкап системы
FileSet {
  Name = "Full Set"
  Include {
    Options {
      signature = MD5
    }
#    
#  Put your list of files here, preceded by 'File =', one per line
#    or include an external list with:
#
#    File = <file-name
#
#  Note: / backs up everything on the root partition.
#    if you have other partitons such as /usr or /home
#    you will probably want to add them too.
#
#  By default this is defined to point to the Bacula build
#    directory to give a reasonable FileSet to backup to
#    disk storage during initial testing.
#
    File = /home/test
  }

#
# If you backup the root directory, the following two excluded
#   files can be useful
#
# Какие файлы не включать в бэкап
  Exclude { 
    File = /proc
    File = /sys
    File = /dev
    File = /tmp
    File = /.journal
    File = /.fsck
  }
}


Описание задач

В каталоге /etc/bacula/job.d находятся описания списков файлов для резервирования:

Внимание! Заменить в backupcatalog.conf
RunBeforeJob = "/usr/share/bacula/scripts/make_catalog_backup" # Скрипт выполняемый до бэкапа (создает дамп базы)

на

RunBeforeJob = "/usr/share/bacula/scripts/make_catalog_backup.pl MyCatalog" # Скрипт выполняемый до бэкапа (создает дамп базы)


backupcatalog.conf - Делает дамп базы и резервирует его:

# Backup the catalog database (after the nightly save)
Job {
  Name = "BackupCatalog" # Имя
  JobDefs = "DefaultJob" # Используемый шаблон
  Level = Full
  FileSet="Catalog" # Используемый спикок для бэкапа
  Schedule = "WeeklyCycleAfterBackup" # Расписание резервирования
 # This creates an ASCII copy of the catalog
RunBeforeJob = "/usr/share/bacula/scripts/make_catalog_backup" # Скрипт выполняемый до бэкапа (создает дамп базы)
  # This deletes the copy of the catalog 
  RunAfterJob  = "/usr/share/bacula/scripts/delete_catalog_backup" # Скрипт выполняемый после бэкапа (удаляет дамп базы)
  Write Bootstrap = "/var/lib/bacula/BackupCatalog.bsr" # Файл для восстановления
  Priority = 11                   # Приоритет выполнения - после бэкапа
}


bacula.conf- делает полный бэкап:

#
# Define the main nightly save backup job
#   By default, this job will back up to disk in @archivedir@
Job {
  Name = "BackupFullSet"
  JobDefs = "DefaultJob"
  Schedule = "WeeklyCycle"
  Write Bootstrap = "/var/lib/bacula/Client1.bsr"
}

defaultjob.conf - описывает параметры задачи по умочанию:

JobDefs {
  Name = "DefaultJob" # Имя
  Type = Backup # Тип
  Level = Incremental # Вид бэкапа
  Client = fd # Клиент с которого нужно сделать бэкап
  FileSet = "Full Set" # Список файлов
  Storage = File # Хранилище
  Messages = Standard
  Pool = Default
  Priority = 10 # Приоритет
}


restore.conf - восстанавливает файлы:

#
# Standard Restore template, to be changed by Console program
#  Only one such job is needed for all Jobs/Clients/Storage ...
#
Job {
  Name = "RestoreFiles"# Имя задачи
  Type = Restore # Тип
  Client=fd # Клиент на котором востанавливать файлы
  FileSet="Full Set" # Набор файлов
  Storage = File # Хранилище
  Pool = Default 
  Messages = Standard
  Where = /tmp/bacula-restores # Каталог для восстановленных файлов
}


Описание пулов

Пул объединяет в себе несколько томов, чтобы отдельная резервная копия не была ограничена объемом тома.
Том это отдельная единица в которую ведется запись, может быть файлом или лентой.
В каталоге /etc/bacula/pool.d содержится:

default.conf - описывает пул по умолчанию:

  1. Default pool definition

Pool {

 Name = Default # Имя
 Pool Type = Backup # Тип
 Recycle = yes                       # Разрешает перезапись тома
 AutoPrune = yes                     # Разрешает bacula очищать тома
 Volume Retention = 365 days         # Время в течении которого  bacula не будет очищать том
 LabelFormat = "b" # Формат меток (в случае с файлами - имена файлов)

}

Проверка конфигурационных файлов

Проверить корректность конфигурационных файлов bacula director можно так:

# bacula-dir -t -c /etc/bacula/bacula-dir.conf

Автозапуск сервиса

Запустим и добавим в автозапуск сервис:

# systemctl start bacula-dir
# systemctl enable bacula-dir