SQL

Потоковая репликация PostgreSQL

Время прочтения: 4 мин.

Под репликацией подразумевается транслирование состояния ведущего сервера на резервный, т.е. изменения, происходящие на основном сервере (Master) будут дублироваться на другой (Slave).

В каких случаях возникает необходимость в применении потоковой репликации:

  • При необходимости распределения нагрузки. Резервный сервер не осуществляет запись данных, но с него можно эти данные получать, что снижает нагрузку на ведущий сервер.
  • При необходимости обеспечения отказоустойчивости. Заместитель может заменить мастер за несколько секунд максимально сохраняя данные и снижая период простоя.

Как это работает? Запись всех изменений на PostgreSQL-сервере происходит в WAL (write-ahead log), а затем осуществляется непосредственная трансляция журналов с ведущего сервера на резервный. Такой способ работы предотвращает потерю данных в случаях сбойных ситуаций, так как сервер-заместитель сверяет данные в табличном пространстве с данными WAL, доставляет разницу и затем WAL удаляет.

По умолчанию Потоковая репликация асинхронна, то есть при трансляции данных с основного на резервный происходит задержка, как правило при хороших технических параметрах резервного сервера задержка не превышает секунды. Дополнительно производить настройку окна потенциальной потери данных archive_timeout нет необходимости. Резервный сервер вытаскивает и применяет у себя данные по мере возможности не теряя их.

Рассмотрим настройку потоковой репликации PostgreSQL 11 и Debian 10.

В наличии имеем два сервера с именами db-master-server и db-slave-server. В первую очередь необходимо настроить кластера на серверах. Версия баз данных PostgreSQL должна совпадать на всех машинах.

Настраиваем с db-master-server (192.00.0.1)

vagrant@db-master-server:~$ sudo apt install postgresql-11 *производим установку

Заходим в систему под логином postgres и создаём нового пользователя в PostgreSQL

postgres@db-master-server:~$ createuser --replication -P replicant
Enter password for new role: mypassword
Enter it again: mypassword
postgres@db-master-server:~$ exit 
logout

Настраиваем PostgreSQL через конфигурационный файл:

vagrant@db-master-server:~$ sudo vi /etc/postgresql/11/main/postgresql.conf

Задаем следующие значения:

listen_addresses = 'localhost, 192.00.0.1'  *IP-адрес сервера;
wal_level = replica  * сколько информации записывается в WAL;
max_wal_senders = 2  *количество планируемых slave;
max_replication_slots = 2  *максимальное число слотов репликации;
hot_standby = on  *возможность подключения к PostgreSQL для выполнения запросов в процессе восстановления;
hot_standby_feedback = on  *сообщение мастеру о запросах, которые выполняет slave

Настраиваем подключение пользователя для репликации:

vagrant@db-master-server:~$ sudo vi /etc/postgresql/11/main/pg_hba.conf

Добавляем в конфигурацию:

host    replication     replicant       127.0.0.1/32           md5
host    replication     replicant       192.00.0.1/24         md5
host    replication     replicant       192.00.0.2/24         md5

Теперь перезагрузим db-master-server для применения новых настроек:

vagrant@db-slave-server:~$ sudo systemctl restart postgresql

Проверяем статус сервера:

vagrant@db-master-server:~$ sudo systemctl status postgresql

При положительном результате увидим:

postgresql.service - PostgreSQL RDBMS
Loaded: loaded (/lib/systemd/system/postgresql.service; enabled; vendor preset: enabled)
Active: active (exited) since Mon 2021-02-07 10:54:41 GMT; 20s ago
Main PID: 1739 (code=exited, status=0/SUCCESS)
Tasks: 0 (limit: 544)
Memory: 0B
CGroup: /system.slice/postgresql.service
Feb 07 10:54:41 db-master-server systemd[1]: Starting PostgreSQL RDBMS...
Feb 07 10:54:41 db-master-server systemd[1]: Started PostgreSQL RDBMS.

Настраиваем db-slave-server (192.00.0.2)

vagrant@db-slave-server:~$ sudo apt install postgresql-11  * производим установку;
vagrant@db-slave-server:~$ sudo systemctl stop postgresql * останавливаем демон PostgreSQL для дальнейшей работы;
vagrant@db-slave-server:~$ sudo systemctl status postgresql *проверяем статус

Видим, что демон остановлен:

postgresql.service - PostgreSQL RDBMS
   Loaded: loaded (/lib/systemd/system/postgresql.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Mon 2021-02-07 10:55:12 GMT; 1s ago
 Main PID: 1739 (code=exited, status=0/SUCCESS)
Feb 07 10:54:41 db-slave-server systemd[1]: Starting PostgreSQL RDBMS...
Feb 07 10:54:41 db-slave-server systemd[1]: Started PostgreSQL RDBMS.
Feb 07 10:55:12 db-slave-server systemd[1]: postgresql.service: Succeeded.
Feb 07 10:55:12 db-slave-server systemd[1]: Stopped PostgreSQL RDBMS

Теперь добавим настройки в конфигурационный файл Slave:

vagrant@db-slave-server:~$ sudo vi /etc/postgresql/11/main/postgresql.conf
listen_addresses = 'localhost, 192.00.0.2'

Удаляем данные из рабочей директории PostgreSQL и зайдем под пользователем postgres:

vagrant@db-slave-server:~$ sudo rm -R /var/lib/postgresql/11/main/
vagrant@db-slave-server:~$ sudo su - postgres

Производим копирование данных:

postgres@db-slave-server:~$ pg_basebackup -P -R -X stream -c fast -h 192.00.0.1 -U replicant -D /var/lib/postgresql/11/main/

Теперь в рабочей директории PostgreSQL появились необходимые данные и можем продолжить настройку конфигурационного файла:

vagrant@db-slave-server:~$ sudo vi /var/lib/postgresql/11/main/recovery.conf *открываем файл
standby_mode = 'on' *меняем параметры конфигурационного файла
primary_conninfo = 'user=replicant password=mypassword host=192.00.0.1 port=5432 sslmode=prefer sslcompression=0 krbsrvname=postgres target_session_attrs=any'
trigger_file = '/tmp/to_master'

Отредактируем файл:

vagrant@db-slave-server:~$ sudo vi /etc/postgresql/11/main/pg_hba.conf  *открываем;
 host replication  replicant  192.00.0.1/24  md5  * добавляем строку;

Запускаем демон PostgreSQL:

vagrant@db-slave-server:~$ sudo systemctl start postgresql

Далее необходимо проверить работу нашей репликации.

Успешная работа репликации повышает надёжность нашей системы и позволяет работать с данными при минимальных временных издержках.

Советуем почитать