pg_rewind

pg_rewind — синхронизировать каталог данных PostgreSQL с другим каталогом, ответвлённым от него

Синтаксис

pg_rewind [параметр...] { -D | --target-pgdata }каталог { --source-pgdata=каталог | --source-server=строка_подключения }

Описание

Утилита pg_rewind представляет собой средство синхронизации кластера PostgreSQL с другой копией того же кластера после расхождения линий времени этих кластеров. Обычный сценарий её использования — вернуть в работу старый главный сервер после переключения на резервный, в качестве резервного для сервера, ставшего главным.

Её результат равнозначен замене целевого каталога данных исходным. В файлах отношений она копирует только изменённые блоки; все остальные файлы, включая файлы конфигурации, копируются целиком. Преимущество pg_rewind по сравнению с созданием новой базовой копии или такими средствами, как rsync, состоит в том, что pg_rewind не читает неизменённые блоки в кластере. Благодаря этому она действует гораздо быстрее, когда база данных большая, но различия между кластерами ограничиваются лишь небольшим количеством блоков.

Утилита pg_rewind изучает истории линий времени исходного и целевого кластеров с целью найти точку, в которой они разошлись, и ожидает найти журналы WAL в каталоге pg_wal целевого кластера вплоть до точки расхождения. Точка расхождения может быть найдена на целевой или исходной линии времени либо в их общем предке. В типичном сценарии отработки отказа, когда целевой кластер отключается вскоре после расхождения, это не проблема, но если целевой кластер проработал долгое время после расхождения, старые файлы WAL могут быть уже удалены. В этом случае их можно вручную скопировать из архива WAL в каталог pg_wal. Варианты использования pg_rewind не ограничиваются отработкой отказа; например, резервный сервер может быть повышен, выполнить несколько транзакций с записью, а затем, после восстановления синхронизации, вновь стать резервным.

Когда целевой сервер запускается в первый раз после выполнения pg_rewind, он переходит в режим восстановления и воспроизводит все изменения из WAL с исходного сервера после точки расхождения. Если какие-то сегменты WAL оказались недоступны на исходном сервере, когда выполнялась pg_rewind, и поэтому не могли быть скопированы в ходе работы pg_rewind, их необходимо предоставить, когда сервер будет запускаться. Это можно сделать, создав в целевом каталоге данных файл recovery.conf с подходящей командой restore_command.

Утилита pg_rewind требует, чтобы на целевом сервере был либо включён режим wal_log_hints в postgresql.conf, либо включены контрольные суммы, когда кластер был инициализирован командой initdb. Оба эти режима по умолчанию отключены. Также должен быть включён режим full_page_writes, но он по умолчанию включён.

Предупреждение

Если во время работы pg_rewind происходит ошибка, вероятнее всего, целевой каталог данных будет в состоянии, не подходящем для восстановления. В этом случае рекомендуется сделать новую резервную копию.

Программа pg_rewind немедленно прекращает работу, если обнаруживает файлы, непосредственная запись в которые невозможна. Это может иметь место, например, когда на исходном и целевом серверах совпадают пути файлов сертификатов и ключей SSL, доступных только для чтения. Если такие файлы существуют на целевом сервере, их рекомендуется удалить до запуска pg_rewind. После выполнения синхронизации некоторые из таких файлов могут быть скопированы из источника и тогда может потребоваться удалить скопированные данные и восстановить ссылки/файлы, существовавшие до синхронизации.

Параметры

pg_rewind принимает следующие аргументы командной строки:

-D каталог
--target-pgdata=каталог

Этот параметр задаёт целевой каталог данных, который будет синхронизирован с источником. Целевой сервер должен быть отключён штатным образом до запуска pg_rewind

--source-pgdata=каталог

Задаёт путь в файловой системе к каталогу данных исходного сервера, с которым будет синхронизироваться целевой. Для применения этого ключа исходный сервер должен быть остановлен штатным образом.

--source-server=строка_подключения

Задаёт строку подключения libpq для подключения к исходному серверу PostgreSQL, с которым будет синхронизирован целевой. Подключение должно устанавливаться как обычное (не реплицирующее) от имени роли, имеющей необходимые права для выполнения функций pg_rewind на исходном сервере (подробнее об этом говорится в Замечаниях), или от имени суперпользователя. Для применения этого параметра исходный сервер должен быть запущен и работать не в режиме восстановления.

-n
--dry-run

Делать всё, кроме внесения изменений в целевой каталог.

-P
--progress

Включает вывод сообщений о прогрессе. При этом в процессе копирования данных из исходного кластера будет выдаваться приблизительный процент выполнения.

--debug

Выводить подробные отладочные сообщения, полезные в основном для разработчиков, отлаживающих pg_rewind.

-V
--version

Показать версию, а затем завершиться.

-?
--help

Показать справку, а затем завершиться.

Переменные окружения

Когда используется --source-server, pg_rewind также использует переменные среды, поддерживаемые libpq (см. Раздел 34.14).

Замечания

Когда исходным кластером для pg_rewind является работающий сервер, вместо суперпользователя может применяться роль, имеющая в этом кластере достаточные права для выполнения функций, которые использует pg_rewind. Такую роль (rewind_user) можно создать так:

CREATE USER rewind_user LOGIN;
GRANT EXECUTE ON function pg_catalog.pg_ls_dir(text, boolean, boolean) TO rewind_user;
GRANT EXECUTE ON function pg_catalog.pg_stat_file(text, boolean) TO rewind_user;
GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text) TO rewind_user;
GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text, bigint, bigint, boolean) TO rewind_user;

Когда исходным кластером для pg_rewind является работающий сервер сразу после повышения, в нём необходимо выполнить команду CHECKPOINT, чтобы его управляющий файл содержал актуальную информацию о линии времени. Эта информацию нужна pg_rewind для проверки, можно ли синхронизировать целевой кластер с выбранным исходным.

Как это работает

Основная идея состоит в том, чтобы перенести все изменения на уровне файловой системы из исходного кластера в целевой:

  1. Просканировать журнал WAL в целевом кластере, начиная с последней контрольной точки перед моментом, когда история линии времени исходного кластера разошлась с целевым кластером. Для каждой записи WAL отметить, какие блоки данных были затронуты. В результате будет получен список всех блоков данных, которые были изменены в целевом кластере после отделения исходного.

  2. Скопировать все эти изменённые блоки из исходного кластера в целевой либо на уровне файловой системы (--source-pgdata), либо на уровне SQL (--source-server).

  3. Скопировать все остальные файлы, в частности pg_xact и файлы конфигурации, из исходного кластера в целевой (пропуская при этом файлы отношений). Как и при базовом копировании, содержимое каталогов pg_dynshmem/, pg_notify/, pg_replslot/, pg_serial/, pg_snapshots/, pg_stat_tmp/ и pg_subtrans/ исключается из данных, копируемых из исходного кластера. Также исключаются файлы или каталоги с именами, начинающимися с pgsql_tmp, а также файлы backup_label, tablespace_map, pg_internal.init, postmaster.opts и postmaster.pid.

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