Для возможности восстановления кластера СУБД 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();