Репликация
Физическая репликация
13
Авторские права
© Postgres Professional, 2018–2022
Авторы: Егор Рогов, Павел Лузанов, Илья Баштанов
Использование материалов курса
Некоммерческое использование материалов курса (презентации,
демонстрации) разрешается без ограничений. Коммерческое
использование возможно только с письменного разрешения компании
Postgres Professional. Запрещается внесение изменений в материалы
курса.
Обратная связь
Отзывы, замечания и предложения направляйте по адресу:
Отказ от ответственности
Компания Postgres Professional не несет никакой ответственности за
любые повреждения и убытки, включая потерю дохода, нанесенные
прямым или непрямым, специальным или случайным использованием
материалов курса. Компания Postgres Professional не предоставляет
каких-либо гарантий на материалы курса. Материалы курса
предоставляются на основе принципа «как есть» и компания Postgres
Professional не обязана предоставлять сопровождение, поддержку,
обновления, расширения и изменения.
2
Темы
Задачи репликации
Схема работы физической репликации
Способы доставки журнальных записей
Особенности и ограничения использования реплики
Синхронная и асинхронная репликация
Мониторинг репликации
Возможные проблемы и способы их решения
3
Задачи репликации
Репликация
процесс синхронизации нескольких копий кластера баз данных
на разных серверах
Базовый механизм для решения ряда задач
отказоустойчивость при возникновении сбоя система
должна сохранить работоспособность
масштабируемость распределение нагрузки между серверами
Одиночный сервер, управляющий базами данных, может не
удовлетворять требованиям, предъявляемым к системе. Есть две
основных задачи, для решения которых требуется наличие нескольких
серверов.
Во-первых, отказоустойчивость: один физический сервер — это
возможная точка отказа. Если сервер выходит из строя, система
становится недоступной.
Во-вторых, производительность. Один сервер может не справляться
с нагрузкой. Зачастую желательна возможность не вертикального,
а горизонтального масштабирования — распределения нагрузки на
несколько серверов. Дело может быть как в стоимости аппаратуры, так
и в необходимости различных настроек для разных типов нагрузки
(например, для OLTP и отчетности).
В случае PostgreSQL распределенные системы строятся по принципу
«shared nothing»: несколько серверов работают независимо друг от
друга и не имеют ни общей оперативной памяти, ни общих дисков.
Следовательно, если серверы должны работать с одними и теми же
данными, то эти данные требуется синхронизировать между ними.
Механизм синхронизации и называется репликацией.
4
Мастер→реплика
Записи WAL передаются на реплику и применяются
поток данных только в одну сторону
реплицируется кластер целиком, выборочная репликация невозможна
Реплика — точная копия мастера
одна и та же основная версия сервера
полностью совместимые архитектуры и платформы
Реплика доступна только для чтения
При физической репликации, рассматриваемой в этой теме, серверы
имеют назначенные роли: один является ведущим («мастер») и один
или несколько серверов являются ведомыми («реплики»).
Мастер передает на реплику журнальные записи, а реплика применяет
эти записи к своим файлам данных. Применение происходит чисто
механически, без «понимания смысла» изменений, и выполняется
быстрее, чем работало бы повторное выполнение операторов SQL.
Но при этом критична двоичная совместимость между серверами —
они должны работать на одной и той же программно-аппаратной
платформе и на них должны быть запущены одинаковые основные
версии PostgreSQL.
Поскольку журнал является общим для всего кластера, то и
реплицировать можно только кластер целиком, а не отдельные базы
данных или таблицы. Возможность «отфильтровать» журнальные
записи отсутствует.
Реплика не может генерировать собственных журнальных записей, она
лишь применяет записи мастера. Поэтому при таком подходе реплика
может быть доступна только для чтения — никакие операции,
изменяющие данные, на реплике не допустимы.
5
Потоковая репликация
основной сервер
(мастер)
сегменты WAL
select, insert
update, delete
резервный сервер
(реплика)
wal sender wal receiver
непрерывное
восстановление
startup
получение
журнальных
записей
Есть два способа доставки журналов от мастера к реплике. Основной,
который используется на практике — потоковая репликация.
В этом случае реплика подключается к мастеру по протоколу
репликации и читает поток записей WAL. За счет этого при потоковой
репликации отставание реплики от мастера минимально (и при
необходимости может быть сведено к нулю).
На реплике за прием журнальных записей отвечает процесс wal
receiver. Запустившись, он подключается к мастеру по протоколу
репликации, а мастер запускает процесс wal sender, который
обслуживает это соединение. Полученные записи пишутся на диск
в виде сегментов WAL так же, как это происходит на мастере. Далее
они (сразу или с задержкой) применяются к файлам данных. За
применение отвечает процесс startup — тот же самый, который
обеспечивает восстановление после сбоев, только теперь работает
постоянно.
Потоковая репликация может, если нужно, использовать слот
репликации.
7
Репликация с архивом
основной сервер
(мастер)
сегменты WAL
select, insert
update, delete
резервный сервер
(реплика)
альтерна-
тивный источник
журнальных
записей
archiver
архив WAL
wal receiver startupwal sender
автоматическое
переключение
между источниками
Другой способ доставки журнальных записей состоит в том, чтобы
предоставить реплике доступ к архиву журналов — точно так же, как
при обычном восстановлении из архива (этот механизм рассмотрен в
модуле «Резервное копирование»).
Если реплика по каким-то причинам не сможет получить очередную
журнальную запись по протоколу репликации (например, из-за обрыва
связи), она попробует прочитать ее из архива с помощью команды,
заданной в параметре restore_command. При восстановлении связи
реплика снова автоматически переключится на использование
потоковой репликации.
В принципе, репликация может работать и с одним только архивом, без
потоковой репликации. Но в этом случае:
- реплика вынужденно отстает от мастера на время заполнения
сегмента;
- мастер ничего не знает о существовании реплики, что в некоторых
случаях может привести к проблемам.
8
Очистка архива
основной сервер
(мастер)
сегменты WAL
select, insert
update, delete
резервный сервер
(реплика)
archiver
архив WAL
wal receiver startupwal sender
archive_mode = on
checkpointer
точка
рестарта
archive_command
restore_command
archive_cleanup_command
Если архив используется только для синхронизации одной реплики,
можно настроить его автоматическую очистку, для этого в параметре
archive_cleanup_command задается команда, которая будет
выполняться по окончании каждой точки рестарта подобно тому, как
после каждой контрольной точки удаляются файлы журнала. В команде
удобно вызывать утилиту pg_archivecleanup:
archive_cleanup_command = 'pg_archivecleanup
/path/to/archive %r'
9
Процессы
Мастер Реплика
wal sender wal receiver
startup
archiver archiver
(archive_mode = always)
checkpointer checkpointer
онтрольные точки) (точки рестарта)
writer writer
stats collector stats collector
wal writer
autovacuum
На мастере и на реплике выполняется разный набор процессов. Кроме
уже рассмотренных wal sender (на мастере) и wal receiver и startup
(на реплике), работают также другие процессы.
Общие процессы:
- background writer — записывает грязные страницы из буферного
кеша на диск (на реплике, для того, чтобы применить журнальную
запись, страницы точно так же читаются в буферный кеш и затем
записываются в фоновом режиме или при вытеснении).
- stats collector — статистика не передается в журнале, а собирается
на реплике отдельно.
- checkpointer — на реплике при получении журнальной записи
о контрольной точке выполняется похожая процедура — точка
рестарта. Если в процессе восстановления случится сбой, реплика
сможет продолжить с последней точки рестарта, а не с самого начала.
Процессы только на мастере:
- wal writer — реплика не создает журналы упреждающей записи,
а только получает их с мастера.
- autovacuum launcher/worker — реплика не выполняет очистку, ее
выполнение на мастере передается реплике через журнал.
Есть также процесс, наличие которого зависит от настройки:
- archiver — при значении archive_mode = on выполняется только на
мастере, а при archive_mode = always также и на реплике (подробнее
рассматривается в теме «Переключение на реплику»).
11
Использование реплики
Допускаются
запросы на чтение данных (select, copy to, курсоры)
установка параметров сервера (set, reset)
управление транзакциями (begin, commit, rollback...)
создание резервной копии (pg_basebackup)
Не допускаются
любые изменения (insert, update, delete, truncate, nextval...)
блокировки, предполагающие изменение (select for update...)
команды DDL (create, drop...), в том числе создание временных таблиц
команды сопровождения (vacuum, analyze, reindex...)
управление доступом (grant, revoke...)
Как мы уже говорили, на реплике не допускается любое изменение
данных. Более точно, не допускаются:
- изменения таблиц, материализованных представлений,
последовательностей;
- блокировки (так как для этого требуется изменение страниц данных);
- команды DDL, включая создание временных таблиц;
- такие команды, как vacuum и analyze;
- команды управления доступом.
При этом реплика может выполнять запросы на чтение данных, если
установлен параметр hot_standby = on. Также будет работать установка
параметров сервера и команды управления транзакциями — например,
можно начать (читающую) транзакцию с нужным уровнем изоляции.
Кроме того, реплику можно использовать и для изготовления резервных
копий.
13
Ограничения
Изоляция и многоверсионность
большое число точек сохранения задерживает выполнение запросов
не поддерживается уровень изоляции serializable
Триггеры и блокировки
триггеры и пользовательские блокировки (advisory locks) не работают
Резервное копирование с реплики
параметр full_page_writes должен быть заранее включен на мастере
задержки из-за ожидания контрольной точки и переключения сегментов
Изменение табличных пространств
каталоги на реплике нужно создавать заранее, так как прав пользователя
ОС postgres может не хватить
У репликации есть ряд ограничений и особенностей.
Если на мастере выполняется транзакция с числом вложенных
транзакций > 64 (то есть активно используются точки сохранения),
создание снимка на реплике будет приостановлено — это означает
невозможность некоторое время выполнять запросы.
Не поддерживается уровень изоляции serializable на реплике.
Триггеры не будут срабатывать на реплике (они выполнились на
мастере и реплицируется уже результат их работы). Не будут работать
и рекомендательные (advisory) блокировки.
При выполнении резервного копирования с реплики нет технической
возможности полноценно управлять мастером, в частности, вызывать
контрольные точки и включать параметр full_page_writes. Поэтому
параметр нужно включить на мастере заранее, а контрольную точку
приходится ждать (что может существенно задержать процесс).
Создание табличных пространств реплицируется, но, если у
пользователя ОС, под которым работает СУБД, недостаточно прав для
создания каталога, произойдет ошибка. Лучше всего сначала создать
каталоги на мастере и на всех репликах, а уже затем выполнять
команду CREATE TABLESPACE.
14
Мониторинг
основной сервер
(мастер)
select, insert
update, delete
резервный сервер
(реплика)
wal sender wal receiver startup
1. pg_current_wal_lsn()
2. pg_stat_replication.sent_lsn
3. pg_stat_replication.write_lsn
3. pg_stat_replication.flush_lsn
4. pg_stat_replication.replay_lsn
1 – 2 = задержка записи в поток на мастере
2 – 3 = задержка получения данных репликой
3 – 4 = задержка применения данных на реплике
pg_last_wal_replay_lsn()
pg_stat_wal_receiver
pg_last_wal_receive_lsn()
pg_replication_slots
log_replication_commands = on
В ходе репликации возможны проблемы, о которых должен
предупредить заранее настроенный мониторинг. Основной
информацией являются позиции в журнале предзаписи. Можно
выделить четыре важные точки:
1. появление журнальной записи на мастере;
2. трансляция записи процессом wal sender;
3. получение записи процессом wal receiver;
4. применение полученной записи процессом startup.
Все эти точки обычно отслеживаются на мастере. Первую точку дает
функция pg_current_wal_lsn(), остальные — представление
pg_stat_replication. Реплика передает мастеру статус репликации при
каждой записи на диск, но как минимум раз
в wal_receiver_status_interval секунд (по умолчанию — 10 секунд).
Если используется слот репликации, то информацию о нем можно
получить из представления pg_replication_slots.
Данные о ходе репликации можно получить и на реплике
в представлении pg_stat_wal_receiver и с помощью функций
pg_last_wal_receive_lsn() и pg_last_wal_replay_lsn().
Параметр log_replication_commands включает вывод в журнал
сообщений информации о выполняющихся командах протокола
репликации.
16
Режимы репликации
Асинхронный
synchronous_commit = off
local
Синхронный
фиксация с ожиданием подтверждения от синхронной реплики
обеспечивает надежность, но не согласованность
synchronous_commit = remote_write
on
remote_apply
synchronous_standby_names = FIRST N (список реплик)
ANY N (список реплик)
Как известно, фиксация транзакций может выполняться в двух
режимах. В более быстром асинхронном режиме есть шанс потерять
уже зафиксированные изменения в случае сбоя. В синхронном режиме
команда COMMIT не завершается, пока запись не дойдет до диска.
При наличии нескольких серверов надежность можно еще более
увеличить, дожидаясь подтверждения от реплики о получении записи,
тогда данные не пропадут даже при выходе из строя носителя.
Синхронная репликация включается тем же параметром
synchronous_commit, что и синхронная фиксация. Разные значения
этого параметра позволяют управлять уровнем надежности. При
значении remote_write мастер ожидает подтверждения о получении
записи (остается шанс потерять изменения, если на реплике случится
сбой и она не успеет записать данные на диск).
При значении on мастер ожидает подтверждения о попадании
журнальной записи на диск реплики (это надежный режим; однако
приложение, обратившись к реплике, может не увидеть изменений).
Наконец, значение remote_apply заставляет мастер дождаться
применения записи на реплике. Каждый следующий режим вызывает
все большие задержки.
Мастер может синхронизироваться как с одной, так и с несколькими
репликами. Можно указать список реплик в порядке приоритета или
организовать синхронизацию на основе кворума, при которой мастер
дожидается подтверждения от любых N реплик из числа доступных.
17
Возможные проблемы
Мастер может удалить файл журнала, нужный реплике
если реплика не успеет его получить
(например, будет остановлена на некоторое время)
Решение 1. Слот репликации
вводит зависимость мастера от реплики, требует мониторинга
Решение 2. Архив журнала предзаписи
позволяет обойтись без слота
При репликации возможен ряд сложностей, которые можно решать
разными способами.
Серв