Расширяемость
Физическая репликация
12
Авторские права
© Postgres Professional, 2020 год.
Авторы: Егор Рогов, Павел Лузанов
Использование материалов курса
Некоммерческое использование материалов курса (презентации,
демонстрации) разрешается без ограничений. Коммерческое
использование возможно только с письменного разрешения компании
Postgres Professional. Запрещается внесение изменений в материалы
курса.
Обратная связь
Отзывы, замечания и предложения направляйте по адресу:
Отказ от ответственности
Компания Postgres Professional не несет никакой ответственности за
любые повреждения и убытки, включая потерю дохода, нанесенные
прямым или непрямым, специальным или случайным использованием
материалов курса. Компания Postgres Professional не предоставляет
каких-либо гарантий на материалы курса. Материалы курса
предоставляются на основе принципа «как есть» и компания Postgres
Professional не обязана предоставлять сопровождение, поддержку,
обновления, расширения и изменения.
2
Темы
Физическая репликация
Уровни журнала
Варианты использования реплики
Переключение на реплику
3
Физическая репликация
Синхронизация копий кластера на нескольких серверах
Основные задачи
высокая доступность, отказоустойчивость
масштабируемость
Механизм
один сервер транслирует журнальные записи на другой сервер,
и тот проигрывает полученные записи
Особенности
мастер-реплика: поток данных только в одну сторону
требуется двоичная совместимость серверов
возможна репликация только всего кластера
Одиночный сервер, управляющий базами данных, может не
удовлетворять предъявляемым требованиям.
Один сервер — возможная точка отказа. Два (или больше) серверов
позволяют сохранить доступность системы в случае сбоя
тказоустойчивость) или — более широко — в любом случае,
например, при проведении плановых работ (высокая доступность).
Один сервер может не справляться с нагрузкой. Наращивать ресурсы
сервера может оказаться невыгодно или вообще невозможно. Но
можно распределить нагрузку на несколько серверов
(масштабирование).
Таким образом, речь идет о том, чтобы иметь несколько серверов,
работающих над одними и теми же базами данных. Под репликацией
понимается процесс синхронизации этих серверов.
Механизм репликации состоит в том, что один сервер передает
журнальные записи на другой сервер, и тот их проигрывает — как при
восстановлении после сбоя.
При физической репликации серверы имеют назначенные роли: мастер
и реплика. Мастер передает на реплику свои журнальные записи в виде
файлов или потока записей; реплика применяет эти записи к своим
файлам данных. Применение происходит чисто механически, без
«понимания смысла» изменений, поэтому важна двоичная
совместимость между серверами (одинаковые платформы и основные
версии PostgreSQL). Поскольку журнал общий для всего кластера, то и
реплицировать можно только весь кластер целиком.
4
Физическая репликация
основной сервер
(мастер)
сегменты WAL
select, insert
update, delete
резервный сервер
(реплика)
wal sender wal receiver startup
архив WAL
альтерна-
тивный источник
журнальных
записей
потоковая
репликация
Чтобы организовать репликацию между двумя серверами, мы создаем
реплику из резервной копии основного сервера. Но при обычном
восстановлении из резервной копии мы получаем новый независимый
сервер. А в данном случае реплика начинает работать в режиме
постоянного восстановления: она все время применят новые
журнальные записи, приходящие с основного сервера (этим занимается
процесс startup). Таким образом, реплика постоянно поддерживается
в почти актуальном состоянии.
Если реплика не допускает подключений, она называется «теплым
резервом». Однако можно сделать и «горячий резерв» — реплика будет
допускать подключения для чтения данных.
Есть два способа доставки журналов от мастера к реплике. Основной,
который используется на практике потоковая репликация.
В этом случае реплика (процесс wal_receiver) подключается к мастеру
(процесс wal_sender) по протоколу репликации и читает поток записей
WAL. За счет этого при потоковой репликации отставание реплики
сведено к минимуму, и даже к нулю при синхронном режиме.
Кроме этого, может использоваться архив сегментов WAL, если в
системе настроено непрерывное архивирование. Если реплика не
сможет получить очередную журнальную запись по протоколу
репликации, она будет пробовать прочитать соответствующий файл из
архива.
5
Уровни журнала
Параметр wal_level
minimal < replica
восстановление восстановление
после сбоя после сбоя
восстановление
из резервной копии,
репликация
Поскольку на реплику попадает только та информация, которая
содержится в журнале, в журнал должны записываться все
необходимые данные.
Объем информации, попадающий в журнал, регулируется параметром
wal_level.
До версии PostgreSQL 10 уровнем по умолчанию был minimal,
гарантирующий только восстановление после сбоя. На таком уровне
репликация работать не может, поскольку для обеспечения надежности
часть данных записывается сразу на энергонезависимый носитель и не
записывается в журнал.
Сейчас уровень по умолчанию — replica. Этот уровень дополнительно
позволяет восстанавливать систему из горячих резервных копий,
сделанных утилитой pg_basebackup, а также использовать физическую
репликацию.
Поскольку резервное копирование и репликация — востребованные
задачи, уровень по умолчанию и был изменен в пользу replica.
7
Использование реплики
Допускаются
запросы на чтение данных (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, команды
управления доступом — словом, все, что так или иначе изменяет
данные.
При этом реплика может выполнять запросы на чтение данных. Также
будет работать установка параметров сервера и команды управления
транзакциями — например, можно начать (читающую) транзакцию
с нужным уровнем изоляции.
Кроме того, реплику можно использовать и для изготовления резервных
копий (конечно, принимая во внимание возможное отставание от
мастера).
9
Использование реплики
надежность хранения данных
основной сервер
(мастер)
сегменты WAL
select, insert
update, delete
резервный сервер
(реплика)
wal sender wal receiver startup
синхронная
репликация
Механизм репликации позволяет построить систему так, чтобы она
отвечала предъявляемым к ней требованиям. Рассмотрим несколько
типичных задач и средства их решения.
Одна из возможных задач — обеспечение надежности хранения
данных.
Напомним, что фиксация транзакций может работать в синхронном и
асинхронном режимах. В первом случае фиксация не завершается до
тех пор, пока данные не будут надежно записаны на энерго-
независимый носитель. Во втором — есть риск потерять часть
зафиксированных данных, но фиксация не должна ждать записи на
диск, и система работает быстрее.
Аналогичная картина и с репликацией. При синхронном режиме
(synchronous_commit = on) и наличии реплики фиксация ждет не только
записи WAL на диск, но и подтверждения приема журнальных записей
от синхронной реплики. Это еще больше увеличивает надежность
(данные не пропадут, если основной сервер выйдет из строя), но и еще
больше замедляет систему.
Существуют и промежуточные варианты настройки, которые не дают
полной гарантии надежности, но все-таки снижают вероятность потери
данных.
10
Использование реплики
выполнение долгих аналитических запросов (отчетов)
основной сервер
(мастер)
сегменты WAL
select, insert
update, delete
резервный сервер
(реплика)
wal sender wal receiver startup
реплика
может отставать,
конфликтующие записи
откладываются
конфликты:
удаление версий
строк процессом очистки
и исключительные
блокировки
Как уже говорилось, длинные запросы удерживают горизонт
транзакций, из-за чего очистка не может удалять ненужные версии
строк. Если какие-то таблицы в это время активно изменяются, они
могут сильно вырасти в размере. Поэтому для выполнения долгих
аналитических запросов можно использовать реплику.
Тонкий момент состоит в том, что с основного сервера могут приходить
журнальные записи, конфликтующие с выполняющимся запросом. Есть
два источника таких записей.
1. Очистка удаляет версии строк, уже не нужные основному серверу, но
еще нужные для выполнения запроса на реплике.
2. Исключительные блокировки, происходящие на основном сервере,
несовместимые с запросом на реплике.
Поэтому «отчетную» реплику настраивают так, чтобы она принимала
WAL-записи, но откладывала их применение, если они конфликтуют
с запросами. Это приводит к тому, что данные на реплике могут
отставать от основного сервера, но, как правило, для долгих запросов
это не существенно.
11
Несколько реплик
основной сервер
(мастер)
сегменты WAL
select, insert
update, delete
резервный сервер
(реплика A)
wal sender
резервный сервер
(реплика B)
wal sender
wal receiver startup
wal receiver startup
распределение OLTP-нагрузки по чтению
К основному серверу можно подключить несколько реплик, например,
для распределения OLTP-нагрузки по чтению.
OLTP-запросы не должны быть долгими. Это позволяет использовать
обратную связь между репликой и основным сервером по протоколу
репликации. В этом случае основной сервер знает, какой горизонт
транзакций нужен для реплики, и очистка не будет удалять
соответствующие версии строк. Иными словами, обратная связь дает
такой же эффект, как если бы все запросы выполнялись
непосредственно на основном сервере.
Однако репликация обеспечивает только базовый механизм. Для
автоматического распределения нагрузки необходимы внешние
средства (балансировщики). Следует также иметь в виду, что между
основным сервером и репликами не гарантируется согласованность
данных, даже в случае синхронной репликации. Если приложение
читает данные только с одного из серверов, оно, разумеется, будет
получать согласованные данные. Но это не выполняется, если
приложение читает данные с нескольких серверов. С реплики можно
прочитать как устаревшие данные, так и данные, которых еще не видно
на основном сервере. Подробнее эти вопросы обсуждаются в курсе
DBA3 «Резервное копирование и репликация».
12
Каскадная репликация
основной сервер
(мастер)
сегменты WAL
select, insert
update, delete
резервный сервер
(реплика B)
wal sender
резервный сервер
(реплика A)
wal senderwal receiver
startup
wal receiver
startup
уменьшение нагрузки на мастер и перераспределение сетевого трафика
Несколько реплик, подключенных к одному основному серверу, будут
создавать на него определенную нагрузку. Кроме того, надо учитывать
нагрузку на сеть для пересылки нескольких копий потока журнальных
записей.
Для снижения нагрузки реплики можно соединять каскадом; при этом
серверы передают журнальные записи друг другу по цепочке. Чем
дальше от мастера, тем большее запаздывание может накопиться.
Заметим, что каскадная синхронная репликация не поддерживается:
основной сервер может быть синхронизирован только с непосред-
ственно подключенной к нему репликой. А вот обратная связь
поступает основному серверу от всех реплик.
13
Отложенная репликация
задержка воспроизведения
«машина времени»
и возможность восстановления на определенный момент без архива
основной сервер
(мастер)
сегменты WAL
select, insert
update, delete
резервный сервер
(реплика)
wal sender wal receiver
startup
Полезной является возможность просматривать данные на некоторый
момент в прошлом и, при необходимости, восстановить сервер на этот
момент. Это позволяет, в частности, справиться с ошибкой
пользователя, совершившего неправильные действия, требующие
отмены.
Проблема в том, что обычный механизм восстановления из архива на
момент времени (point-in-time recovery) в принципе позволяет решить
задачу, но требует большой подготовительной работы и занимает много
времени. А способа построить снимок данных по состоянию на
произвольный момент в прошлом в PostgreSQL нет.
Задача решается созданием реплики, которая применяет записи WAL
не сразу, а через установленный интервал времени.
В этом курсе мы не обсуждаем необходимые настройки для каждого из
показанных вариантов. Для подробной информации обратитесь к курсу
DBA3 «Резервное копирование и репликация».
14
Переключение на реплику
Плановое переключение
останов основного сервера для технических работ без прерывания
обслуживания
ручной режим
Аварийное переключение
переход на реплику из-за сбоя основного сервера
ручной режим,
но в принципе можно автоматизировать с помощью
дополнительного кластерного ПО
Имеющуюся реплику можно использовать и для того, чтобы
переключить на нее приложение с основного сервера.
Причины перехода на резервный сервер бывают разные. Это может
быть необходимость проведения технических работ на основном
сервере — тогда переход выполняется в удобное время в штатном
режиме. А может быть сбой основного сервера, и в таком случае
переходить на резервный сервер нужно как можно быстрее, чтобы не
прерывать обслуживание пользователей.
Даже в случае сбоя переход осуществляется вручную, если не
используется специальное кластерное программное обеспечение
оторое следит за состоянием серверов и может инициировать
переход автоматически).
16
Итоги
Механизм репликации основан на передаче
журнальных записей на реплику и их применении
трансляция потока записей или файлов WAL
Физическая репликация создает точную копию
всего кластера
однонаправленная, требует двоичной совместимости
базовый механизм для решения целого ряда задач
17
Практика
1. Разверните реплику так, как показано в демонстрации.
Проверьте, как работает приложение, если переключить его
на использование реплики.
2. Добавьте к механизму фоновых заданий возможность
выполнять задания на реплике с помощью расширения
dblink.
Убедитесь, что долгое задание не приведет к появлению
такой же долгой транзакции на основном сервере.
1. Переключатель сервера находится в верхней части информационной
панели приложения.
Обратите внимание на то, какие операции по-прежнему работают,
а какие — вызывают ошибку.
2. Приложение позволяет при отправке задания на выполнение указать
удаленный сервер, и записывает имя узла и порт в таблицу tasks.
Добавьте в процедуру process_tasks проверку: если указаны узел и
порт, вызывайте функцию run не локально, а с помощью расширения
dblink на указанном сервере. (Расширение рассматривалось в теме
«Фоновые процессы»)
Чтобы долгое задание не приводило к появлению такой же долгой
транзакции на основном сервере, используйте dblink в асинхронном
режиме, и периодически опрашивайте готовность запроса в отдельных,
коротких, транзакциях.
18
Практика
1. Настройте физическую потоковую репликацию
между двумя серверами в синхронном режиме.
Проверьте работу репликации. Убедитесь, что при
остановленной реплике фиксация не завершается.
2. По умолчанию применение конфликтующих записей
на реплике откладывается максимум на 30 секунд.
Отключите откладывание применения и убедитесь, что
долгий запрос, выполняющийся на реплике, будет прерван,
если необходимые ему версии строк удаляются и очищаются
на мастере.
Включите обратную связь и убедитесь, что теперь запрос
не прерывается из-за того, что на мастере откладывается
очистка.
1. Для этого на мастере установите с помощью ALTER SYSTEM
следующие параметры:
- synchronous_commit = on,
- synchronous_standby_names = 'replica',
и перечитайте настройки, а на реплике добавьте в параметр
primary_conninfo (в сгенерированном утилитой pg_basebackup файле
postgresql.auto.conf) указание «application_name=replica».
2. За откладывание применения конфликтующих записей на реплике
отвечает параметр max_standby_streaming_delay. Установите его в 0.
Обратная связь включается параметром hot_standby_feedback = on.
Оба параметра устанавливаются ALTER SYSTEM с последующим
перечитыванием настроек.
Чтобы запрос выполнялся долго на небольшом объеме данных, можно,
например, создать таблицу, содержащую числа от 1 до N, и вычислять
факториал каждого числа:
SELECT count(*) FROM t WHERE n! > 0;
В таблице должно быть около 1000 строк (подберите подходящее число
в зависимости от мощности процессора):