Перейти к основному содержимому

Восстановление данных из резервной копии на момент времени (PITR)

примечание

Исполнять сценарий необходимо от имени пользователя postgres.

Описание сценария

Использование технологии Point-In-Time Recovery (PITR) позволяет вернуть базу данных к состоянию на определенный момент времени посредством полной резервной копии и журнала транзакций (WAL-файлов).

Общая схема процесса восстановления на момент времени:

  1. Восстановите данные из резервной копии.
  2. Настройте команду restore_command, предназначенную для восстановления сегментов WAL, а также установите необходимые параметры восстановления recovery_* в конфигурационном файле postgresql.conf.
  3. Создайте файл recovery.signal для переключения в режим восстановления.
  4. Запустите базу данных.

Рассмотрим ситуацию, когда необходимо восстановить базу данных на определенный номер журнала транзакций (LSN). Будем работать с двумя виртуальными машинами, на каждой из которых установлен Pangolin версии 6.5.2. На первой виртуальной машине создадим резервную копию, внесем ряд изменений и зафиксируем значение LSN. Затем на второй виртуальной машине восстановим базу данных из резервной копии и перед запуском сервера настроим параметры восстановления именно на указанный ранее LSN.

Подготовка первой виртуальной машины

  1. Выполните установку компонента Copywala:

    sudo dnf install {component_name}-{component_version}-{OS_version}.x86_64.rpm
  2. Инициализируйте экземпляр приложения для настройки уникального имени и присвоения идентификатора экземпляра БД (подробнее в сценарии):

    copywala init db1
  3. Настройте хранилище для резервных копий в конфигурационном файле copywala.yaml:

    backup_destination_uri: /home/postgres/backups
  4. Настройте хранилище для архивирования WAL-файлов в конфигурационном файле copywala.yaml:

    wal_destination_uri: /home/postgres/backups
  5. Включите архивирование WAL-файлов в конфигурационном файле postgresql.conf и настройте команду архивирования и восстановления WAL-файлов:

    archive_mode = 'on'
    archive_command = 'copywala archive-wal %f %p'
    restore_command = 'copywala restore-wal %f %p'

    Опционально в команде архивирования можно включить вывод статистики:

    archive_command = 'copywala archive-wal %f %p --stat'
  6. Перезагрузите сервер после изменения поля archive_mode:

    pg_ctl restart
  7. Запустите процедуру резервного копирования:

    copywala create-backup
  8. Для проверки корректности восстановления на определенную точку во времени после завершения резервного копирования выполните операции, изменяющие данные в базе, например, создание таблицы:

    CREATE TABLE test(id int);
    INSERT INTO test (id) VALUES (generate_series(1, 1000000));
  9. Чтобы определить момент внесения изменений в базу данных, выполните команду для получения текущего значения номера журнала транзакций (LSN):

    SELECT pg_current_wal_lsn();
  10. Для подтверждения корректности операции восстановления до нужного момента времени создайте дополнительную таблицу:

    CREATE TABLE wrong_test(id int);
    INSERT INTO wrong_test (id) VALUES (generate_series(1, 1000000));
  11. Переключите текущий WAL-сегмент, чтобы гарантировать архивирование последних изменений:

    SELECT pg_switch_wal();
  12. Проверьте, что WAL-файлы заархивированы успешно:

    ll /home/postgres/backups/<instance_name>/wals/

Последовательность действий

  1. Выполните установку компонента Copywala:

    sudo dnf install {component_name}-{component_version}-{OS_version}.x86_64.rpm
  2. Инициализируйте экземпляр приложения:

    copywala init db2
  3. Настройте хранилище для резервных копий в конфигурационном файле copywala.yaml:

    backup_destination_uri: /home/postgres/backups
  4. Настройте хранилище для архивирования WAL-файлов в конфигурационном файле copywala.yaml:

    wal_destination_uri: /home/postgres/backups

Шаги для восстановления данных из резервной копии на момент времени

  1. Получите список доступных экземпляров базы данных из хранилища и выберите экземпляр (instance_name) из первой виртуальной машины (название начинается с db1):

       $ copywala storage instances
  2. Для восстановления выбранного экземпляра БД настройте его наименование (instance_name) в конфигурационном файле copywala.yaml, выполнив команду:

       $ copywala config set --restore-instance-name=<instance_name>
  3. Восстановите каталог PGDATA из последней резервной копии в заданную папку:

       $ copywala restore latest --destination=/pgdata/db-restored
    примечание

    Если в резервной копии содержатся табличные пространства, подготовьте необходимые директории (например, смонтируйте нужные разделы дисков) и укажите сопоставление старых путей новым опцией -t old=new для каждого табличного пространства.

  4. Настройте в конфигурационном файле postgresql.conf целевую точку во времени, до которой требуется произвести восстановление.

к сведению

По умолчанию при восстановлении применяются все доступные WAL-файлы, данное поведение можно ограничить, задав один из параметров: recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid. Подробнее про это читайте в документации Platform V Pangolin.

Например, задайте контрольную точку во времени, используя параметр recovery_target_lsn. Установите его значение равным номеру журнала транзакций (LSN), полученному после завершения подготовки данных для таблицы test. Альтернативно можно задать точное время восстановления с помощью параметра recovery_target_time.

Чтобы сервер запускался после завершения процесса восстановления, установите в конфигурационном файле опцию:

recovery_target_action = 'promote'

Это позволит автоматически перевести сервер из режима восстановления в обычный рабочий режим сразу после достижения целевой точки восстановления.

  1. Создайте файл для переключения сервера в режим восстановления:
touch /pgdata/db-restored/recovery.signal
  1. Запустите сервер:
pg_ctl start -D /pgdata/db-restored/
  1. Проверьте наличие таблицы test с данными:

    SELECT COUNT(*) FROM test;
    count
    ---------
    1000000
    (1 row)
  2. Проверьте отсутствие таблицы wrong_test:

    SELECT COUNT(*) FROM wrong_test;
    ERROR: relation "wrong_test" does not exist

Результат

Сервер успешно запустился, и данные в таблице test совпадают с ожидаемыми результатами.

Исключительные сценарии

  1. Ошибка запуска сервера. Проанализируйте содержимое лог-файлов.
  2. Отсутствие нужных данных или тестовой таблицы. Удостоверьтесь в корректности выбранного момента времени (или LSN) и повторите операцию восстановления.