Как стать автором
Обновить
71.03
Слёрм
Учебный центр для тех, кто работает в IT

Логическая репликация между версиями PostgreSQL

Время на прочтение6 мин
Количество просмотров17K
Автор оригинала: Avinash Vallarapu, Fernando Laudares Camargos, Jobin Augustine, Nickolay Ihalainen


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


В предыдущих статьях мы уже говорили о методах обновления PostgreSQL (Обновление версии PostgreSQL с помощью pg_dumpall и Обновление версии PostgreSQL с помощью pg_dump/pg_restore) в рамках серии Обновление или миграция старых версий PostgreSQL в новые. Но оба этих метода не исключают простоя.


Типы логической репликации


Здесь мы обсудим 2 типа репликации:


  • Репликация между PostgreSQL 10 и 11 с помощью встроенной логической репликации.
  • Репликация между PostgreSQL 9.4 (или до PG 11) и PostgreSQL 11 с помощью расширения pglogical.

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


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


При использовании логической репликации на резервном сервере можно включить репликацию с нескольких мастеров. Это бывает полезно в ситуациях, когда нужно реплицировать данные из нескольких баз данных PostgreSQL (OLTP) на один сервер PostgreSQL для отчетности и хранения данных.


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


Репликация между версиями PostgreSQL 10 и 11


Начиная с PostgreSQL 10 логическая репликация доступна по умолчанию. Поэтому вы легко реплицируете базу данных PostgreSQL 10 в PostgreSQL 11. При логической репликации используется модель публикации и подписки. Узел, отправляющий изменения, становится издателем. А узел, подписывающийся на эти изменения, становится подписчиком. На одну публикацию может быть несколько подписок.


Публикация


Публикация — это массив изменений, созданных группой таблиц. Она называется набором изменений или набором репликации. Публикации могут содержать только таблицы, но не другие объекты. DML в этих таблицах реплицировать можно, а DDL — нельзя.


В публикации можно выбрать, DML какого типа реплицировать: INSERT, DELETE, UPDATE или ALL. По умолчанию выбрано ALL. У таблицы должен быть идентификатор реплики, чтобы реплицировать подписчику операции UPDATE и DELETE. Идентификаторы реплики помогают находить строки, которые обновляются или удаляются.


Первичный ключ таблицы — это идентификатор реплики по умолчанию. Или вы можете сделать идентификатором уникальный индекс со значениями NOT NULL. Если у вас нет первичного ключа или уникального индекса со значениями NO NULL, установите для replica_identity значение FULL. В таком случае Postgres использует всю строку в качестве ключа. Но это не очень рационально.


Если таблица без первичного ключа и идентификатора реплики по умолчанию добавляется в публикацию после операции UPDATE или DELETE, могут возникнуть ошибки.


Подписка


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


Пример логической репликации


В следующем примере описывается логическая репликация только между версиями PostgreSQL 10 и 11.


Создайте публикацию на узле-издателе. Добавьте в публикацию все или только некоторые таблицы.


-- For adding ALL Tables in Database
CREATE PUBLICATION percpub FOR ALL TABLES;

-- For adding Selected Tables in Database
CREATE PUBLICATION percpub FOR TABLE scott.employee scott.departments;

На узле-подписчике создайте подписку на эту публикацию. Выполните DDL-дамп таблиц подписчику, прежде чем создать подписку, как говорилось выше.


$ pg_dump -h publisher_server_ip -p 5432 -d percona -Fc -s -U postgres | pg_restore -d percona -h subscriber_node_ip -p 5432 -U postgres
CREATE SUBSCRIPTION percsub CONNECTION 'host=publisher_server_ip dbname=percona user=postgres password=secret port=5432' PUBLICATION percpub;

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


CREATE SUBSCRIPTION percsub CONNECTION 'host=publisher_server_ip dbname=percona user=postgres password=oracle port=5432' PUBLICATION percpub WITH (copy_data = false);

Отслеживайте репликацию с помощью следующей команды в узле-издателе:


$ psql
\x
select * from pg_stat_replication;

Репликация между PostgreSQL 9.4 и PostgreSQL 11


Что делать с версиями до PostgreSQL 10? Для версий с 9.4 по 11 есть специальное расширение — pglogical. С помощью pglogical можно в два счета реплицировать PostgreSQL 9.4 в PostgreSQL 11.


Ниже приводятся общие инструкции по настройке репликации между PG 9.4 и PG 11 с помощью расширения pglogical.


Шаг 1. Считайте, что pgserver_94 — это исходный сервер с базой данных percona_94 на PostgreSQL 9.4. Создайте следующее расширение.
код


[pgserver_94:] $psql -d percona_94 -c "CREATE EXTENSION pglogical_origin"
CREATE EXTENSION
[pgserver_94:] $psql -d percona_94 -c "CREATE EXTENSION pglogical"
CREATE EXTENSION

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


[pgserver_94:] $psql -d percona_94
psql (9.4.21)
Type "help" for help.
percona_94=# SELECT pglogical.create_node(node_name := 'provider1',dsn := 'host=192.168.0.24 port=5432 dbname=percona_94');
create_node
-------------
2976894835
(1 row)
percona_94=# SELECT pglogical.replication_set_add_all_tables('default', ARRAY['public']);
ERROR: table pgbench_history cannot be added to replication set default
DETAIL: table does not have PRIMARY KEY and given replication set is configured to replicate UPDATEs and/or DELETEs
HINT: Add a PRIMARY KEY to the table
percona_94=# ALTER TABLE pgbench_history ADD PRIMARY KEY (tid,aid,delta);
ALTER TABLE
percona_94=# SELECT pglogical.replication_set_add_all_tables('default', ARRAY['public']);
replication_set_add_all_tables
--------------------------------
t
(1 row)

Шаг 3. На узле-подписчике, то есть в базе данных PostgreSQL 11, выполните следующие команды.


[pgserver_11:] $psql -d percona_11
psql (11.2)
Type "help" for help.
percona_11=# SELECT pglogical.create_node(node_name := 'subscriber1',dsn := 'host=127.0.0.1 port=5432 dbname=percona_11 password=secret');
 create_node
-------------
   330520249
(1 row)
percona_11=# SELECT pglogical.create_subscription(subscription_name := 'subscription1',provider_dsn := 'host=192.168.0.24 port=5432 dbname=percona_94 password=secret');
 create_subscription
---------------------
          1763399739
(1 row)

Шаг 4. Затем проверьте статус репликации, отправив запрос в несколько таблиц, которые pglogical всегда обновляет:


percona_11=# select * from pglogical.local_sync_status;
 sync_kind | sync_subid | sync_nspname |   sync_relname   | sync_status | sync_statuslsn
-----------+------------+--------------+------------------+-------------+----------------
 f         | 1763399739 | public       | pgbench_accounts | r           | 0/2EB7D48
 f         | 1763399739 | public       | pgbench_history  | r           | 0/2EB7D48
 f         | 1763399739 | public       | pgbench_tellers  | r           | 0/2EB7D48
 f         | 1763399739 | public       | pgbench_branches | r           | 0/2EB7D48
 d         | 1763399739 |              |                  | r           | 0/0
(5 rows)
percona_11=# select * from pglogical.subscription;
   sub_id   |   sub_name    | sub_origin | sub_target | sub_origin_if | sub_target_if | sub_enabled |             sub_slot_name              |         sub_rep
lication_sets          | sub_forward_origins | sub_apply_delay
------------+---------------+------------+------------+---------------+---------------+-------------+----------------------------------------+----------------
-----------------------+---------------------+-----------------
 1763399739 | subscription1 | 2976894835 |  330520249 |    2402836775 |    2049915666 | t           | pgl_percona_11_provider1_subscription1 | {default,defaul
t_insert_only,ddl_sql} | {all}               | 00:00:00
(1 row)

Выбор первичного ключа


На втором шаге вы видели, как все таблицы схемы public добавились в набор репликации путем создания первичного ключа для таблицы, у которой его не было. Возможно, я выбрал неправильный первичный ключ для этой таблицы, но это просто для демонстрации. Когда будете выбирать первичный ключ, убедитесь, что он правильный. Он должен быть уникальным и использовать столбцы, которые не содержат значения NULL. Если не найдете правильный первичный ключ, это может привести к простою приложения. Вот пример ошибки, которая может возникнуть:


[pgserver_94:] $pgbench -c 10 -T 300 -n percona_94
Client 7 aborted in state 12: ERROR: duplicate key value violates unique constraint "pgbench_history_pkey"
DETAIL: Key (tid, aid, delta)=(7, 63268, 2491) already exists.

Вот как можно использовать pglogical, чтобы создать репликацию между старой и новой версиями PostgreSQL. После настройки репликации просто переключите приложения на последнюю версию, чтобы простой был минимальным.

Теги:
Хабы:
Всего голосов 18: ↑17 и ↓1+16
Комментарии6

Публикации

Информация

Сайт
slurm.io
Дата регистрации
Дата основания
Численность
51–100 человек
Местоположение
Россия
Представитель
Антон Скобин