Для обеспечения высокой доступности, надежности и отказоустойчивости сервер баз данных PostgreSQL поддерживает репликацию.
Это процесс копирования данных в режиме реального времени между несколькими серверами для создания резервных копий для восстановления.
При такой настройке основной узел называется ведущим, а серверы, получающие реплицируемые данные,
называются репликами или резервными узлами,
В PostgreSQL существует множество различных подходов, которые можно использовать для репликации данных
на нескольких серверах. У каждого метода есть свои плюсы и минусы.
В большинстве случаев кластер PostgreSQL настраивается для обеспечения избыточности данных и предотвращения единой
точки отказа (SPOF). В случае сбоя главного сервера можно активизировать любую из реплик,
чтобы она стала новым главным сервером.
PostgreSQL позволяет запускать реплики в режиме горячего ожидания - hot standby.
при этом резервные узлы принимают соединения и операции только для чтения.
Это позволяет распределить нагрузку на операции, требующие интенсивного чтения, по всему кластеру.
Репликации бывают
1. Физическая репликация.
Происходит копирование всей базы данных, это выглядит как физическое копирование по сети самих транзакционных фалов WAL.
Версии постгреса должны совпадать.
При таком подходе любые изменения, внесенные в файлы данных главного сервера,
зеркально отражаются в системных файлах других реплик.
Изменения в резервных узлах должны выполняться в том же порядке, в котором они поступают,
чтобы обеспечить согласованность во всем кластере баз данных.
Реплика в отличие от мастера может работать только на чтение.
Этот метод не подходит для репликации с несколькими мастерами и не подходит в случае большой нагрузки.
Появилась в 9-й версии
wal_level = hot_standby - для версии < 9.5
wal_level = replica - для версии > 9.6
2. Логическая репликация.
Она быстрее физической.
Здесь с мастера на реплику отправляется не весь транзакционный лог, а только закомммиченные транзакции.
Поскольку этот метод реплицирует данные выборочно, он эффективен с точки зрения производительности.
Он также подходит для репликации с несколькими мастерами.
Появилась в 10-й версии
Репликация бывает сихронная и асинхронная.
1. Синхронный режим: В этом режиме главный сервер должен дождаться, пока первый доступный сервер-реплика получит
и сохранит файл журнала транзакций, прежде чем сообщать об успешно коммите.
Это полезно при настройке высокой доступности, хотя может возникнуть небольшая задержка.
2. Асинхронный режим: Главному серверу не нужно ждать подтверждения от сервера (серверов) реплик,
прежде чем сообщать о коммите. Этот подход быстрее, но если главный сервер выйдет из строя до того,
как данные будут реплицированы на резервные узлы, это может привести к потере данных.
Существуют правила, когда выбирают тот или иной вариант репликации:
1. Используйте либо физическую репликацию, либо логическую асинхронную репликацию для резервного копирования
и настройки аварийного восстановления.
2. Используйте логическую асинхронную репликацию, если вы хотите снять нагрузку только для чтения с основного сервера.
3. Используйте логическую синхронную репликацию для кластеров с высокой доступностью и в тех случаях,
когда требуется нулевая потеря данных, но при сниженной производительности.
4. Используйте логическую асинхронную репликацию для кластеров высокой доступности,
которые требуют более высокой производительности, но могут допускать незначительные потери данных.
На мастере в штатном режиме репликацию можно отслеживать с помощью специальных системных таблиц,
например pg_stat_replication;
На репликах в штатном режиме репликацию можно отслеживать с помощью специальных системных таблиц
например pg_stat_wal_receiver;
Существуют сторонние инструменты для отслеживания репликации - pgmetrics, pgdash
В этой статье будут рассмотрены два варианта репликации PostgreSQL.
Установка PostgreSQL
Для опытов нам понадобятся два хоста. Я использую Debian 11.
Установка из репозитария:
sudo apt update && sudo apt upgrade -y
sudo apt install software-properties-common apt-transport-https wget -y
sudo wget -O- https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /usr/share/keyrings/postgresql.gpg
echo deb [arch=amd64,arm64,ppc64el signed-by=/usr/share/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt/\
bullseye-pgdg main | sudo tee /etc/apt/sources.list.d/postgresql.list
echo deb [arch=amd64,arm64,ppc64el signed-by=/usr/share/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt/\
bullseye-pgdg-testing main | sudo tee /etc/apt/sources.list.d/postgresql-testing.list
sudo apt-get update
sudo apt install postgresql-client postgresql -y
По умолчанию ставится 14-й постгрес.
Проверяем:
systemctl restart postgresql
systemctl status postgresql
Начинаем работать с постгресом
sudo -i -u postgres psql
\password postgres
Затем правим конфиг
/etc/postgresql/14/main/pg_hba.conf
и строку
local all postgres peer
меняем на
local all postgres md5
Проверяем:
systemctl restart postgresql
systemctl status postgresql
Это нужно естественно все повторить на реплике.
Пример 1. Логическая асинхронная репликация h3>
Рассматривается простая схема организации кластера из 2-х хостов.
Первый хост - Мастер
Второй хост - Реплика
Конфигурация Мастер ноды:
sudo -u postgres psql
Создаем роль
CREATE ROLE repl_user WITH REPLICATION LOGIN PASSWORD 'EXAMPLE_PASSWORD';
Открываем файл
/etc/postgresql/14/main/postgresql.conf
Раскомментировать строку
listen_addresses = 'localhost'
и прописать ip мастера - в моем случае это
listen_addresses = '192.168.56.124'
Выставить логическую репликацию
wal_level = logical
Следующая строка поможет в процессе восстановления в случае, если резервный узел по каким-то причинам выходит из синхронизации с главным сервером:
wal_log_hints = on
Открываем файл
/etc/postgresql/14/main/pg_hba.conf
Добавляем в конец следующую строку
host replication repl_user 192.168.56.125/32 md5
Здесь 192.168.56.125 - ip реплики
Перезапускаем постгрес
systemctl restart postgresql
Конфигурация Реплики
Останавливаем постгрес
sudo systemctl stop postgresql
Заходим в каталог
/var/lib/postgresql/14/main/
и удаляем все его содержимое
Выполняем команду для копирования данных с мастера:
В этом примере настроим физическую синхронную репликацию,
В асинхронном режиме, который включен по умолчанию, возможна рассинхронизация данных между мастером и репликой.
Это возможно тогда, когда главный сервер выходит из строя до того, как данные будут реплицированы на резервные узлы,
в этом случае на реплике могут быть потерянв транзакции.
Используем те же самые ноды, которые использовали в предыдущем примере.
Конфигурируем мастера:
Включаем прослушку реплик с любого адреса:
su - postgres
psql -c "ALTER SYSTEM SET listen_addresses TO '*';"
exit
После выполнения этой команды конфигурация сохранится в файле postgresql.conf.auto, расположенном в корне папки данных ($PGDATA) - в дополнение к postgresql.conf.
Создадим еще одну роль
su - postgres
createuser --replication -P -e replicator
exit
В файле
/var/lib/pgsql/12/data/pg_hba.conf
добавляем в конец
host replication replicator 192.168.56.125/24 md5
Перезапускаем мастера
systemctl restart postgresql
systemctl status postgresql
Конфигурируем реплику
Останавливаем постгрес:
systemctl stop postgresql
Заходим в каталог
/var/lib/postgresql/14/main/
и удаляем все его содержимое
Выполняем команду для копирования данных с мастера: