Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
iakovlev.org

PostgreSQL + репликация

Для обеспечения высокой доступности, надежности и отказоустойчивости сервер баз данных 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. Логическая асинхронная репликация

Рассматривается простая схема организации кластера из 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/
 
и удаляем все его содержимое

Выполняем команду для копирования данных с мастера:

 sudo pg_basebackup -h 192.168.56.124 -U repl_user -X stream -C -S replica_1 -v -R -W -D /var/lib/postgresql/14/main/
 
Даем права

 sudo chown postgres -R /var/lib/postgresql/14/main/
 
Запускаем постгрес на реплике

 sudo systemctl start postgresql
 
Возвращаемся на мастер

 sudo -u postgres psql
 
Создаем базу данных

 CREATE DATABASE test_db;
 \c test_db;
 
Создаем таблицу

 CREATE TABLE products (
               product_id SERIAL PRIMARY KEY,
               product_name VARCHAR (50)
           );
 
Вставляем данные

 INSERT INTO products(product_name) VALUES ('LEATHER JACKET');
 INSERT INTO products(product_name) VALUES ('WINTER HOODIE');
 INSERT INTO products(product_name) VALUES ('BROWN WALLET');
 
Возвращаемся в другом терминале на реплику:

 sudo -u postgres psql
 \c test_db;
 SELECT 
 product_id,
 product_name
 FROM products;
 
Реплика работает в режиме только на чтение.

Пример 2. Физическая синхронная репликация

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

Конфигурируем мастера:
Включаем прослушку реплик с любого адреса:

 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/
 
и удаляем все его содержимое
Выполняем команду для копирования данных с мастера:

 sudo pg_basebackup -h 192.168.56.124 -D /var/lib/postgresql/14/main -U replicator -P -v  -R -X stream -C -S pgstandby1
 
В каталоге должен появиться файл

 standby.signal
 
Выполняем команду

 sudo chown postgres -R /var/lib/postgresql/14/main/
 
Возвращаемся на мастер и выполнив команду

 su - postgres
 psql -c "SELECT * FROM pg_replication_slots;"
 exit
 
Увидим, что появился слот pgstandby1
Запустим постгрес на реплике

 systemctl restart postgresql
 
Выполним команду

 SELECT * FROM pg_stat_wal_receiver;
 
где увидим процесс-получатель WAL на реплике.
На мастере создадим базу

 create database test;
 
На реплике увидим эту базу

 \l
 
На мастере включаем синхронную репликацию

 su - postgres
 psql -c "ALTER SYSTEM SET synchronous_standby_names TO  '*';"
 exit
 
Перегружаем на мастере

 systemctl restart postgresql
 
После чего в логах постгреса увидим что-то типа:

 standby "14/main" is now a synchronous standby with priority 1
 START_REPLICATION SLOT "pgstandby1" 0/C000000 TIMELINE 1
 




Оставьте свой комментарий !

Ваше имя:
Комментарий:
Оба поля являются обязательными

 Автор  Комментарий к данной статье
vanoc
  > Пример 2. Физическая синхронная репликация
настраиваете логическую
2023-07-10 09:43:51