Настройка непрерывного архивирования в PostgreSQL 9.6

Настройка непрерывного архивирования и восстановления на момент времени в PostgreSQL 9.6

Для возможности восстановления кластера  СУБД PostgreSQL и его  баз данных на момент времени необходимо обеспечить наличие:

Следует обратить внимание, что утилиты pg_dump и pg_dumpall  создают логическую копию, которая не содержит информации для дальнейшего воспроизведения журнала  транзакций и потому не подходит для решения задачи восстановления Point-in-Time.

Наиболее простым способом получения базовой резервной копии является утилита pg_basebackup, создающая копию файловой системы всего кластера. 

Наличие непрерывной последовательности архивированных файлов WAL, начинающихся не позднее момента создания файловой резервной копии, позволит  после восстановления данных из файловой копии воспроизвести журнал на нужный момент времени и привести систему в состояние на этот момент.

 

Настройка и выполнение резервного копирования 

 

1 -  Включаем архивирование WAL на уровне сервера.

 

В конфигурационном файле postgresql.conf меняем настройки:

Копировать в буфер обмена

wal_level = replica
archive_mode = on
archive_command = 'copy "%p" "C:\\PostgreSQLBackup\\%f"'

- команда, которая будет выполняться при архивировании WAL в момент переключения на  его следующий сегмент. Параметр %p автоматически заменяется полным путём к файлу, подлежащему архивации (...\pg_xlog), а %f  - именем файла.  C:\PostgreSQLBackup\ в данном примере - путь к директории, куда будет производиться архивирование WAL.

В качестве archive_command может быть также указан скрипт, описывающий более сложную логику операций - архивирование файлов, пакетная передача и др., например:

Копировать в буфер обмена

archive_command = 'local_backup_script.sh "%p" "%f"'

В случае, если переключение на следующий сегмент лога и последующее архивирование происходит слишком редко ввиду невысокой интенсивности работы кластера, можно установить значение параметра:

Копировать в буфер обмена

archive_timeout=60

- период в секундах, по достижении которого переключение на новый сегмент произойдет принудительно.

Копировать в буфер обмена

max_wal_senders=5

(значение по умолчанию - 0, значение 5 указано в качестве примера и технически может быть любым, отличным от 0)

Необходимо обратить внимание, что в случае, если для кластера существует hot_standby -реплика, которая уже является получателем WAL-архивов, значение параметра max_wal_senders, определяющего количество процессов, выполняющих передачу WAL, должно быть не менее 2.

В конфигурационном файле pg_hba.conf разрешаем пользователю, под которым будет выполняться архивирование, подключение для репликации:

Копировать в буфер обмена

host replication     postgres        ::1/128  md5
host replication     postgres         127.0.0.1/32 md5

Выполняем перезапуск службы сервера.

2 - Приступаем к созданию базовых резервных копий.

Интервал создания копии выбирается индивидуально исходя из того, сколько места на диске может быть выделено для хранения файлов WAL, и их размера - необходимо будет хранить все файлы с момента создания последней резервной копии. Копии в примере будут создаваться с помощью утилиты  pg_basebackup (подробно об ее использовании и опциях можно прочитать в документации PostgreSQL https://www.postgresql.org/docs/9.6/static/app-pgbasebackup.html). Выполнять резервное копирование можно без остановки работы кластера, однако процесс может привести к повышенной нагрузке на CPU и дисковую подсистему, поэтому лучше делать это в периоды с наименьшей нагрузкой. 

Если для кластера включена hot_standby-реплика, лучше использовать именно её для создания резервных копий, чтобы не нагружать master-сервер.  Алгоритм выполнения на ведомом сервере будет таким же, но есть несколько настроек, которые необходимо дополнительно выполнить на slave-сервере (описаны в документации к утилите pg_basebackup).

Создаем копию:

Копировать в буфер обмена

pg_basebackup -D "D:\Backup" -X fetch - F tar

 

-D  - директория, куда будет скопировано содержимое каталога ..\data.  Она должна быть пустой

-F  - формат. В данном примере значение tar означает, что содержимое будет добавлено в архив

-X  - метод копирования файлов WAL, созданных в процессе создания копии. Значение fetch означает, что файлы будут скопированы в конце процесса. 

 

Выполнение восстановления

Для выполнения восстановления с использованием полной резервной копии и архива WAL необходимо:

1. Остановить сервер баз данных PostgreSQL.

2. Удалить (а лучше - скопировать во временную директорию) содержимое текущего каталога кластера баз данных (...\data).

3. Восстановить (скопировать) файлы необходимой архивной копии, созданной ранее, в текущий каталог данных кластера (…\data). Файлы WAL в директории \ pg_xlog нужно удалить (или заменить на содержимое каталога, скопированного в п.2) 

4. Создать конфигурационный фай recovery.conf. В качестве основы можно взять расположенный обычно в директории …\share файл recovery.conf.sample. В нем необходимо выполнить настройку:

Копировать в буфер обмена

restore_command = 'copy "C:\\PostgreSQLBackup\\%f" "%p"'

- команда, которая будет выполняться для получения созданных ранее архивов WAL (действие, обратное выполняемому командой archive_command в postgresql.conf). Важно, чтобы в случае ошибки restore_command возвращала ненулевой код. По аналогии с archive_command,  можно указать в качестве команды скрипт с более сложной логикой.

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

Например, для восстановления на момент времени:

Копировать в буфер обмена

recovery_target_time = '2018-03-15 12:00:00'

Или для восстановления на именованную точку:

Копировать в буфер обмена

recovery_target_name = 'our_label'

Такую точку можно создать, например, выполнив в контексте любой из баз кластера запрос:

Копировать в буфер обмена

select pg_create_restore_point('our_label');

5. Запустить сервер баз данных. Он будет запущен в режиме recovery и начнет процесс восстановления.  По завершении сервер переименует файл recovery.conf в recovery.done и начнет работать в обычном режиме, в том числе разрешит подключения к нему.  Если на время выполнения проверки после восстановления нужно запретить соединения с сервером, это лучше всего сделать в конфигурационном файле pg_hba.conf.

 

Обеспечение возможности быстрого возврата системы в состояние "до изменений"

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

Один из самых простых возможных сценариев решения такой задачи предполагает использование функции резервного копирования pg_start_backup(), которая вместе с pg_stop_backup() используется в утилите pg_basebackup, описанной выше, с той разницей, что утилита автоматически выполняет физическое копирование кластера в соответствии с параметрами, а ручной вызов возлагает ответственность за создание копии на администратора системы и позволяет физическое копирование "пропустить".

Перед выполнением изменений системы :

 

1. Убеждаемся, что архивирование WAL включено.

2. Подключаемся к серверу баз данных в контексте любой из баз и выполняем запрос:

Копировать в буфер обмена

select pg_start_backup('our_label', true);

Первым параметром указываем имя метки, которое потом будем использовать при восстановлении. Второй параметр означает, что checkpoint будет осуществлен как можно скорее независимо от настроек параметра checkpoint_completion_target.

Далее мы как раз должны были бы выполнить копирование каталога данных, но в данном случае это нам не нужно - можно приступить к плановым изменениям. Перед этим целесообразно сделать снимок виртуальной машины - это не требует много ресурсов, но повысит надежность. Кроме того, снимок можно будет быстро развернуть в тестовом контуре, если это потребуется (конечно же, это никак не заменяет регулярные полные бэкапы кластера).

В случае необходимости отката изменений далее действия не будут отличаться от алгоритма восстановления, описанного выше, за тем исключением, что не нужно удалять каталог кластера и копировать на его место резервную копию - достаточно просто запустить сервер в режиме восстановления, указав в файле recovery.conf созданную метку в качестве recovery_target_name

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

Копировать в буфер обмена


select pg_stop_backup();