Репликация
Переключение на реплику
16
Авторские права
© Postgres Professional, 2017–2025
Авторы: Егор Рогов, Павел Лузанов, Илья Баштанов, Алексей Береснев
Фото: Олег Бартунов (монастырь Пху и пик Бхрикути, Непал)
Использование материалов курса
Некоммерческое использование материалов курса (презентации,
демонстрации) разрешается без ограничений. Коммерческое
использование возможно только с письменного разрешения компании
Postgres Professional. Запрещается внесение изменений в материалы
курса.
Обратная связь
Отзывы, замечания и предложения направляйте по адресу:
edu@postgrespro.ru
Отказ от ответственности
Компания Postgres Professional не несет никакой ответственности за
любые повреждения и убытки, включая потерю дохода, нанесенные
прямым или непрямым, специальным или случайным использованием
материалов курса. Компания Postgres Professional не предоставляет
каких-либо гарантий на материалы курса. Материалы курса
предоставляются на основе принципа «как есть» и компания Postgres
Professional не обязана предоставлять сопровождение, поддержку,
обновления, расширения и изменения.
2
Темы
Переключение на реплику
Возвращение в строй бывшего мастера
Особенности, связанные с файловым архивом
3
Переключение на реплику
Причины
плановое переключение (switchover):
останов основного сервера для проведения технических работ
аварийное переключение (failover):
переход на реплику из-за сбоя основного сервера
Процедура
убедиться, что мастер остановлен
$ pg_ctl promote или
pg_promote()
автоматическое переключение: отсутствует
(для автоматизации требуется стороннее кластерное ПО)
Причиной перехода на резервный сервер может быть необходимость
проведения технических работ на основном сервере — тогда переход
выполняется в удобное время в штатном режиме (switchover).
А в случае сбоя переходить на резервный сервер нужно как можно
быстрее, чтобы сократить время простоя системы (failover).
Чтобы переключить реплику в режим самостоятельного сервера, ей
посылают команду, вызывая либо pg_ctl promote из операционной
системы, либо функцию pg_promote из SQL. Переключение с помощью
триггерного файла (параметр promote_trigger_file) начиная с 16-й
версии не поддерживается.
Перед этим важно убедиться, что мастер остановлен. Если он
продолжает работу и к нему еще подключены клиенты, данные на
разных серверах могут «разойтись», и свести их потом воедино —
нетривиальная и неавтоматизируемая задача. Скорее всего, часть
данных придется просто потерять.
Для перехода на резервный сервер необходимо переключить на него
клиентов. Автоматизация такого переключения требует стороннего
кластерного программного обеспечения (это обсуждается в модуле
«Кластерные технологии»), так как в PostgreSQL собственных средств
для этого нет.
4
Повышение реплики
Применяет журнальные записи
уже полученные wal receiver, но еще не примененные startup
Завершает процессы
wal receiver
startup
Запускает процессы
wal writer
autovacuum launcher
archiver (зависит от настройки)
Переходит на новую линию времени
Получив сигнал, реплика повышается: завершает восстановление и
переходит в режим обычного сервера.
Для этого процесс startup применяет журнальные записи, которые уже
были получены процессом wal receiver, но еще не применены. На этом
wal receiver и startup завершают свою работу — на основном сервере
они не нужны.
А вот процессы wal writer и autovacuum launcher, наоборот, запускаются.
Может запускаться и процесс archiver.
Выйдя из режима восстановления, сервер переходит на новую линию
времени.
С точностью до некоторых деталей, все происходит так же, как при
окончании восстановления из резервной копии.
6
Возвращение в строй
основной сервер
(бывшая реплика)
archiver
архив WAL
файлы WAL
select, insert
update, delete
бывший мастер
переход
на новую линию
времени
После повышения бывшая реплика выступает в качестве
самостоятельного сервера. Она обслуживает запросы клиентов и
формирует архив журнальных записей — уже с новой линией времени.
Если переключение не было вызвано выходом сервера из строя,
то нужен способ быстро вернуть старый мастер в строй — теперь уже
в качестве реплики (failback).
7
Простое подключение
Бывший мастер подключается к новому как реплика
допустимо, только если перед переключением реплика получила
от мастера все журнальные записи
мастер
мастерреплика
реплика
аккуратный
останов
переключение
В случае аккуратной остановки мастера (в режиме fast или smart) все
журнальные записи мастера скорее всего дойдут до реплики, хотя это
и не гарантируется. Процесс останова организован таким образом, что
сначала отключаются все обслуживающие процессы, затем
выполняется контрольная точка, и только в самую последнюю очередь
останавливается процесс wal sender, чтобы реплика получила запись
WAL о контрольной точке.
Позицию в журнале мастера можно проверить с помощью утилиты
pg_controldata (запись latest checkpoint location), а позицию на реплике
покажет функция pg_last_wal_receive_lsn. Эта функция возвращает
текущую позицию в WAL, поэтому ее значение должно опережать
latest checkpoint location на длину записи о контрольной точке.
Если все журнальные записи действительно были получены, то
бывший мастер можно непосредственно подключить к новому, изменив
соответствующим образом конфигурационные параметры.
В случае останова мастера без выполнения контрольной точки (сбой
или режим immediate), такое подключение на нагруженном сервере,
скорее всего, будет невозможно. При этом сервер не сможет
стартовать, а в журнале сообщений будет фиксироваться ошибка.
9
Резервная копия
Бывший мастер восстанавливается из резервной копии
абсолютно новая реплика, процесс занимает много времени
можно ускорить rsync, если с момента сбоя прошло немного времени
(но все равно долго для больших баз данных)
мастер
мастерреплика
реплика
потерянные
записи WAL
Если мастер был остановлен аварийно, велика вероятность того, что
часть журнальных записей не успела дойти до реплики. В этом случае
просто так подключать мастер нельзя.
Простой и надежный вариант — создать абсолютно новую реплику
путем изготовления и развертывания базовой резервной копии. Однако
для больших баз данных этот процесс может занимать много времени.
Вариант такого подхода — не использовать утилиту pg_basebackup,
а сделать копию с помощью API резервирования с использованием
утилиты rsync. Если выполнять копирование сразу после перехода
на реплику, то большая часть файлов не успеет поменяться
и процесс может пройти существенно быстрее. Но это, конечно,
усложняет процедуру.
10
Утилита pg_rewind
Подготовка к восстановлению
«откатывает» потерянные записи WAL, заменяя соответствующие
страницы целевого сервера страницами с сервера-источника
копирует с сервера-источника все служебные файлы
мастер
мастерреплика
реплика
потерянные
записи WAL
контрольная
точка
целевой сервер
сервер-источник
Еще более быстрый вариант состоит в использовании штатной утилиты
pg_rewind.
Утилита определяет место расхождения между двумя серверами,
определяет ближайшую к нему общую контрольную точку, и,
просматривая журнал, определяет все страницы, измененные
с момента этой контрольной точки.
Найденные страницы (которых должно быть немного) заменяются
страницами с сервера-источника (нового мастера). Кроме того, утилита
копирует с сервера-источника все служебные файлы.
Дальше применяются все необходимые записи WAL с нового мастера.
Фактически, это выполняет уже не утилита, а обычный процесс
восстановления после запуска сервера. Чтобы восстановление
началось с нужного момента, утилита создает управляющий файл
backup_label.
11
Особенности pg_rewind
Целевой сервер (бывший мастер)
все необходимые журнальные файлы должны сохраниться в pg_wal
или в архиве
должны быть включены контрольные суммы или wal_log_hints = on
должен быть включен параметр full_page_writes = on
Сервер-источник (текущий мастер)
клиент-серверное подключение:
--source-server = строка подключения
корректно остановленный сервер:
--source-pgdata = каталог
Для сервера-источника, если он запущен, ключом --source-server
задается строка клиент-серверного подключения libpq (утилита не
использует протокол репликации). Роль для подключения должна иметь
право выполнения функций pg_ls_dir, pg_stat_file, pg_read_binary_file.
Если же сервер-источник остановлен корректно, можно указать его
каталог данных ключом --source-pgdata.
Утилита имеет ряд особенностей:
●
Все сегменты WAL, содержащие записи от последней общей
контрольной точки до текущего момента, должны находиться
в каталоге pg_wal целевого сервера или быть доступны для
получения из архива. Во втором случае надо задать параметр
restore_command и ключ --restore-target-wal.
●
Из-за ошибок при записи возможно рассогласование данных внутри
страницы (проблема неатомарной записи, обсуждается в теме
«Базовая резервная копия»). Чтобы решить проблему, на целевом
сервере первое изменение страницы после контрольной точки
должно вызывать запись в WAL полного ее образа. Для этого должен
быть установлен full_page_writes = on. Этот режим не учитывает
«незначительные» изменения страниц (hint bits), поэтому
дополнительно требуется, чтобы в кластере либо были включены
контрольные суммы страниц, либо был установлен параметр
wal_log_hints = on.
●
Если целевой сервер был остановлен нештатно, без контрольной
точки, утилита запустит его в однопользовательском режиме и тут же
остановит корректно.
13
Переключение и архив
основной сервер
(мастер)
сегменты WAL
select, insert
update, delete
резервный сервер
(реплика)
archiver
архив WAL
wal receiver
startup
wal sender
archive_mode = on
сегмент
еще не записан:
временные
сложности
сегменты WAL
с мастера
Архив журнала предзаписи, пополняемый с помощью механизма
непрерывного архивирования, имеет неприятную особенность
в контексте потоковой репликации и переключения на реплику:
при отказе мастера некоторые сегменты могут не попасть в архив.
Например, если возникли проблемы с местом на диске,
archive_command будет возвращать ошибку.
14
Переключение и архив
основной сервер
(бывшая реплика)
archiver
архив WAL
файлы WAL
select, insert
update, delete
бывший мастер
сегмент потерян,
восстановление из резервных
копий возможно только
до этой точки
archive_mode = on
Но реплика не в курсе настроек архивирования на мастере. Когда
бывшая реплика займет место мастера, она не запишет недостающие
сегменты в архив (хотя они у нее есть), потому что рассчитывает на то,
что архив работал без сбоев. В результате архив будет неполным.
А это означает, что из имеющихся резервных копий можно
восстановить систему только до образовавшейся «дыры». Если такая
ситуация возникла (а это еще нужно заметить), требуется в срочном
порядке выполнить резервное копирование.
Потоковый архив лишен этого недостатка, поскольку утилита
pg_receivewal отслеживает содержимое каталога и запрашивает
у сервера недостающие журнальные записи. Но, как отмечалось
в модуле «Резервное копирование», использование этой утилиты
сопряжено с поддержанием дополнительной инфраструктуры.
16
Переключение и архив
основной сервер
(мастер)
сегменты WAL
select, insert
update, delete
резервный сервер
(реплика)
archiver
архив WAL
wal receiver
startup
archive_mode = always
archiver
команда должна
корректно обрабатывать
одновременную запись
двумя серверами
archive_command
wal sender
сегменты WAL
с мастера
При установке archive_mode = always на реплике запускается процесс
archiver, который записывает сегменты в архив наравне с мастером.
Таким образом, один и тот же файл будет записан два раза с двух
серверов. Это накладывает на команду archive_command серьезные
требования:
●
она не должна перезаписывать существующий файл, но должна
сообщать об успехе, если файл с тем же содержимым уже есть
в архиве;
●
она должна корректно обрабатывать одновременный вызов с двух
серверов.
При такой настройке сегмент не пропадет, поскольку реплика будет
продолжать попытки записи даже после останова мастера.
(Разумеется, можно настроить archive_command и так, чтобы мастер
и реплика сохраняли сегменты журнала в разные архивы, но вряд ли
это практично.)
18
Итоги
Переключение используется как в штатных,
так и в нештатных ситуациях
После переключения бывший мастер надо вернуть в строй
Обе процедуры должны быть заранее отработаны
Файловый архив журнала предзаписи требует внимания
19
Практика
1. Выполните необходимую настройку потоковой репликации
с сервера alpha на beta с использованием слота, без
непрерывного архивирования.
2. Сымитируйте сбой сервера alpha и переключитесь
на сервер beta.
3. Верните в строй сервер alpha в качестве реплики, выполнив
резервную копию с нового мастера beta и настроив
необходимые параметры.
Убедитесь, что репликация работает и использует слот.
4. Переключитесь на сервер alpha, чтобы бывший мастер снова
стал основным сервером.
2. Для имитации сбоя можно остановить сервер в режиме immediate:
pg_ctlcluster 16 имя_кластера stop -m immediate --skip-systemctl-redirect
или завершить основной процесс postgres:
kill -QUIT номер_процесса
Номер процесса можно найти в первой строке файла
PGDATA/postmaster.pid.
После завершения практических заданий удалите слот и созданную
базу данных, сбросьте измененные параметры.
20
Практика+
1. Настройте сервер alpha, чтобы после контрольной точки
сохранялись два дополнительных сегмента WAL,
и запустите физическую репликацию с alpha на сервер beta
без слота репликации.
2. Аварийно остановите сервер alpha и выполните повышение
beta. Запустите alpha и измените данные на нем. Убедитесь,
что данные на alpha и beta не совпадают.
3. Остановите сервер alpha и запустите его в качестве реплики
сервера beta, используя утилиту pg_rewind.
1. Настройте репликацию с простейшими настройками и без слота
репликации. Для гарантии сохранения двух дополнительных сегментов
WAL задайте подходящее значение wal_keep_size.
После завершения практических заданий удалите слот и созданную
базу данных, сбросьте измененные параметры.