Как настроить логическую репликацию с PostgreSQL 10 в Ubuntu 18.04

Вступление

При настройке приложения для производства часто бывает полезно иметь несколько копий базы данных. Процесс синхронизации копий базы данных называетсяreplication. Репликация может обеспечить горизонтальное масштабирование высокой доступности для больших объемов одновременных операций чтения наряду с уменьшенными задержками чтения. Это также позволяет осуществлять одноранговую репликацию между географически распределенными серверами баз данных.

PostgreSQL - это система объектно-реляционной базы данных с открытым исходным кодом, которая отличается высокой расширяемостью и совместима сACID (атомарность, согласованность, изоляция, надежность) и стандартом SQL. Версия 10.0 PostgreSQL представила поддержкуlogical replication в дополнение кphysical replication. В схеме логической репликации высокоуровневые операции записи передаются с сервера базы данныхmaster на один или несколько серверов баз данныхreplica. В физической схеме репликации двоичные операции записи вместо этого передаются от главной к реплике, создавая точную побайтную копию исходного содержимого. В тех случаях, когда вы хотите настроить таргетинг на определенное подмножество данных, например отчеты о разгрузке, исправления или обновления, логическая репликация может обеспечить скорость и гибкость.

В этом руководстве вы сконфигурируете логическую репликацию с PostgreSQL 10 на двух серверах Ubuntu 18.04, один из которых будет основным, а другой - репликой. К концу урока вы сможете реплицировать данные с главного сервера на реплику с помощью логической репликации.

Предпосылки

Чтобы следовать этому уроку, вам понадобится:

  • Два сервера Ubuntu 18.04, которые мы назовемdb-master иdb-replica, настроены для каждого с учетной записью обычного пользователя и привилегиями sudo. Чтобы настроить их, следуйтеthis initial server setup tutorial.

  • Private networking enabled на ваших серверах. Частная сеть обеспечивает связь между вашими серверами без риска для безопасности, связанного с предоставлением баз данных общедоступному Интернету.

  • PostgreSQL 10 установлен на обоих серверах после шага 1How To Install and Use PostgreSQL on Ubuntu 18.04.

[[step-1 -—- configuring-postgresql-for-logic-replication]] == Шаг 1. Настройка PostgreSQL для логической репликации

Есть несколько параметров конфигурации, которые вам нужно изменить, чтобы включить логическую репликацию между вашими серверами. Во-первых, вы сконфигурируете Postgres для прослушивания интерфейса частной сети вместо общедоступного, поскольку предоставление данных через общедоступную сеть представляет угрозу безопасности. Затем вы настроите соответствующие параметры, чтобы разрешить репликацию наdb-replica.

Наdb-master откройте/etc/postgresql/10/main/postgresql.conf, главный файл конфигурации сервера:

sudo nano /etc/postgresql/10/main/postgresql.conf

Найдите следующую строку:

/etc/postgresql/10/main/postgresql.conf

...
#listen_addresses = 'localhost'         # what IP address(es) to listen on;
...

Раскомментируйте его, удалив#, и добавьтеdb_master_private_ip_address, чтобы разрешить соединения в частной сети:

[.note] #Note: На этом и последующих шагах убедитесь, что вы используете IP-адресаprivate ваших серверов, а не их общедоступные IP-адреса. Открытие доступа к серверу базы данных в общедоступном Интернете представляет собой значительную угрозу безопасности.
#

/etc/postgresql/10/main/postgresql.conf

...
listen_addresses = 'localhost, db_master_private_ip_address'
...

Это заставляетdb-master прослушивать входящие соединения в частной сети в дополнение к интерфейсу обратной связи.

Далее найдите следующую строку:

/etc/postgresql/10/main/postgresql.conf

...
#wal_level = replica                    # minimal, replica, or logical
...

Раскомментируйте его и измените, чтобы установить уровень PostgreSQLWrite Ahead Log (WAL) наlogical. Это увеличивает объем записей в журнале, добавляя необходимую информацию для извлечения расхождений или изменений в определенных наборах данных:

/etc/postgresql/10/main/postgresql.conf

...
wal_level = logical
...

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

Сохраните файл и закройте его.

Затем давайте отредактируем/etc/postgresql/10/main/pg_hba.conf, файл, который контролирует разрешенные хосты, аутентификацию и доступ к базам данных:

sudo nano /etc/postgresql/10/main/pg_hba.conf

После последней строки добавим строку, разрешающую входящие сетевые подключения отdb-replica. Мы будем использовать частный IP-адресdb-replica и укажем, что подключения разрешены от всех пользователей и баз данных:

/etc/postgresql/10/main/pg_hba.conf

...
# TYPE      DATABASE        USER            ADDRESS                               METHOD
...
host         all            all             db_replica_private_ip_address/32      md5

Входящие сетевые подключения теперь будут разрешены отdb-replica, аутентифицированные хешем пароля(md5).

Сохраните файл и закройте его.

Затем давайте настроим наши правила брандмауэра, чтобы разрешить трафик сdb-replica на порт5432 наdb-master:

sudo ufw allow from db_replica_private_ip_address to any port 5432

Наконец, перезапустите сервер PostgreSQL, чтобы изменения вступили в силу:

sudo systemctl restart postgresql

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

[[step-2 -—- setting-up-a-database-user-role-and-table]] == Шаг 2 - Настройка базы данных, роли пользователя и таблицы

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

Сначала откройтеpsql prompt как пользовательpostgres с помощью следующей команды как дляdb-master, так и дляdb-replica:

sudo -u postgres psql
sudo -u postgres psql

Создайте новую базу данных с именемexample на обоих хостах:

CREATE DATABASE example;
CREATE DATABASE example;

[.note] #Note: Последний; в этих командах является обязательным. В интерактивных сеансах PostgreSQL не будет выполнять команды SQL, пока вы не завершите их точкой с запятой. Мета-команды (начинающиеся с обратной косой черты, такие как\q и\c) напрямую управляют самим клиентом psql и поэтому не подпадают под это правило. Дополнительные сведения о метакомандах и клиенте psql см. ВPostgreSQL documentation.
#

Используя метакоманду\connect, подключитесь к только что созданным базам данных на каждом хосте:

\c example
\c example

Создайте новую таблицу с именемwidgets с произвольными полями на обоих хостах:

CREATE TABLE widgets
(
    id SERIAL,
    name TEXT,
    price DECIMAL,
    CONSTRAINT widgets_pkey PRIMARY KEY (id)
);
CREATE TABLE widgets
(
    id SERIAL,
    name TEXT,
    price DECIMAL,
    CONSTRAINT widgets_pkey PRIMARY KEY (id)
);

Таблица вdb-replica не обязательно должна быть идентичной своему аналогуdb-master. Однако он должен содержать каждый столбец, присутствующий в таблице вdb-master. Дополнительные столбцы не должны иметьNOT NULL или других ограничений. Если они это сделают, репликация не удастся.

Наdb-master давайте создадим новую роль пользователя с параметромREPLICATION и паролем для входа. АтрибутREPLICATION должен быть назначен любой роли, используемой для репликации. Мы будем называть нашего пользователяsammy, но вы можете заменить его своим именем пользователя. Не забудьте также заменитьmy_password своим безопасным паролем:

CREATE ROLE sammy WITH REPLICATION LOGIN PASSWORD 'my_password';

Запишите свой пароль, так как позже вы будете использовать его вdb-replica для настройки репликации.

По-прежнему наdb-master, предоставьте полные права доступа к базе данныхexample только что созданной роли пользователя:

GRANT ALL PRIVILEGES ON DATABASE example TO sammy;

Затем предоставьте права доступа ко всем таблицам, содержащимся в базе данных, вашему пользователю:

GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO sammy;

public schema - это схема по умолчанию в каждой базе данных, в которую автоматически помещаются таблицы.

Установив эти права, вы можете перейти к созданию таблиц в базе данныхexample для репликации.

[[step-3 -—- setup-a-publishing]] == Шаг 3 - Создание публикации

Publications - это механизм, который PostgreSQL использует, чтобы сделать таблицы доступными для репликации. Сервер базы данных будет внутренне отслеживать состояние подключения и репликации любых серверов реплики, связанных с данной публикацией. Наdb-master вы создадите публикациюmy_publication, которая будет функционировать как главная копия данных, которые будут отправлены на вашsubscribers - в нашем случаеdb-replica .

Наdb-master создайте публикацию с именемmy_publication:

CREATE PUBLICATION my_publication;

Добавьте в нее таблицуwidgets, которую вы создали ранее:

ALTER PUBLICATION my_publication ADD TABLE widgets;

С вашей публикацией теперь вы можете добавить подписчика, который будет извлекать данные из нее.

[[шаг-4 -—- создание-подписки]] == Шаг 4 - Создание подписки

Subscriptions используются PostgreSQL для подключения к существующим публикациям. Публикация может иметь много подписок на разных серверах реплик, и серверы реплик также могут иметь свои собственные публикации с подписчиками. Чтобы получить доступ к данным из таблицы, созданной вами вdb-master, вам необходимо создать подписку на публикацию, которую вы создали на предыдущем шаге,my_publication.

Наdb-replica создадим подписку с именемmy_subscription. КомандаCREATE SUBSCRIPTION назовет подписку, а параметрCONNECTION определит строку подключения к издателю. Эта строка будет включать детали подключения к главному серверу и учетные данные для входа, включая имя пользователя и пароль, которые вы определили ранее, а также имя базы данныхexample. Еще раз не забудьте использовать частный IP-адресdb-master и заменитьmy_password своим собственным паролем:

CREATE SUBSCRIPTION my_subscription CONNECTION 'host=db_master_private_ip_address port=5432 password=my_password user=sammy dbname=example' PUBLICATION my_publication;

Вы увидите следующий вывод, подтверждающий подписку:

OutputNOTICE:  created replication slot "my_subscription" on publisher
CREATE SUBSCRIPTION

После создания подписки PostgreSQL автоматически синхронизирует любые ранее существующие данные от мастера до реплики. В нашем случае нет данных для синхронизации, так как таблицаwidgets пуста, но это полезная функция при добавлении новых подписок в существующую базу данных.

Имея подписку, давайте протестируем настройку, добавив демонстрационные данные в таблицуwidgets.

[[step-5 -—- testing-and-Troubleshooting]] == Шаг 5. Тестирование и устранение неполадок

Чтобы протестировать репликацию между нашим мастером и репликой, давайте добавим некоторые данные в таблицуwidgets и проверим, что репликация выполняется правильно.

Наdb-master вставьте следующие данные в таблицуwidgets:

INSERT INTO widgets (name, price) VALUES ('Hammer', 4.50), ('Coffee Mug', 6.20), ('Cupholder', 3.80);

Наdb-replica выполните следующий запрос, чтобы получить все записи в этой таблице:

SELECT * FROM widgets;

Теперь вы должны увидеть:

Output id |    name    | price
----+------------+-------
  1 | Hammer     |  4.50
  2 | Coffee Mug |  6.20
  3 | Cupholder  |  3.80
(3 rows)

Успех! Записи были успешно реплицированы сdb-master наdb-replica. Отныне все запросыINSERT,UPDATE иDELETE будут однонаправленно реплицироваться между серверами.

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

Теперь вы можете выйти из приглашенияpsql на обоих серверах:

\q
\q

Теперь, когда вы завершили тестирование настроек, вы можете добавлять и реплицировать данные самостоятельно.

Поиск проблемы

Если репликация не работает, первым делом рекомендуется проверить журнал PostgreSQL наdb-replica на наличие возможных ошибок:

tail /var/log/postgresql/postgresql-10-main.log

Вот некоторые распространенные проблемы, которые могут помешать репликации:

  • Частная сеть не включена на обоих серверах, или серверы находятся в разных сетях;

  • db-master не настроен для прослушивания подключений на правильном IP-адресе частной сети;

  • Уровень предзаписи в журналеdb-master настроен неправильно (должен быть установлен наlogical);

  • db-master не настроен для приема входящих соединений с правильного частного IP-адресаdb-replica;

  • Брандмауэр, такой как UFW, блокирует входящие соединения PostgreSQL на порту5432;

  • Несоответствующие имена таблиц или полей междуdb-master иdb-replica;

  • У роли базы данныхsammy отсутствуют необходимые разрешения для доступа к базе данныхexample наdb-master;

  • В роли базы данныхsammy отсутствует параметрREPLICATION вdb-master;

  • У роли базы данныхsammy отсутствуют необходимые разрешения для доступа к таблицеwidgets вdb-master;

  • Таблица не добавлялась в публикациюdb-master.

После решения существующих проблем репликация должна выполняться автоматически. Если это не так, используйте следующую команду, чтобы удалить существующую подписку перед ее повторным созданием:

DROP SUBSCRIPTION my_subscription;

Заключение

В этом руководстве вы успешно установили PostgreSQL 10 на два сервера Ubuntu 18.04 и настроили логическую репликацию между ними.

Теперь у вас есть необходимые знания, чтобы экспериментировать с горизонтальным масштабированием чтения, высокой доступностью и географическим распределением вашей базы данных PostgreSQL, добавив дополнительные серверы реплик.

Чтобы узнать больше о логической репликации в PostgreSQL 10, вы можете прочитатьchapter on the topic в официальной документации PostgreSQL, а также ручные записи о командахCREATE PUBLICATION иCREATE SUBSCRIPTION.

Related