Управление публикациями и слотами для логической репликации в PostgreSQL

Содержание

Включение логической репликации

WAL - это Write Ahead Log, то есть журнал опережающей записи, в котором отслеживаются изменения, произошедшиев таблицах. Журнал опережающей записи служит одновременно нескольким целям: для повторного воспроизведения изменений в таблицах после аварий сервера, для физической репликации баз данных, а также для логической репликации таблиц баз данных.

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

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

По умолчанию в конфигурации настроен уровень replica. А для использования логической репликации нужно повысить этот уровень до значения logical. После изменения конфигурации понадобится полный перезапуск сервера PostgreSQL, для чего можно воспользоваться приведённой ниже командой:

# systemctl reload postgresql

Управление публикациями

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

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

CREATE PUBLICATION skud_skuddevice_pub FOR TABLE skud_skuddevice *;

Владельцем публикации будет пользователь, отдавший приведённую выше команду. Чтобы сменить владельца публикации skud_skuddevice_pub на пользователя с именем smart_house_prod, можно воспользоваться таким выражением:

ALTER PUBLICATION skud_skuddevice_pub OWNER TO smart_house_prod;

Пользователь, от имени которого подписчик будет подключаться к базе данных и читать информацию из публикации, должен иметь привилегию REPLICATION. Чтобы выдать пользователю smart_house_prod эту привилегию, можно воспользоваться следующим выражением:

ALTER USER smart_house_prod REPLICATION;

Удалить существующую публикацию с именем skud_skuddevice_pub можно с помощью этого выражения:

DROP PUBLICATION skud_skuddevice_pub;

Переименовать публикацию skud_skuddevice_pub в smart_house_prod_pub можно следующим образом:

ALTER PUBLICATION skud_skuddevice_pub RENAME TO smart_house_prod_pub;

Если нужно добавить в публикацию smart_house_prod_pub новые таблицы, то сделать это можно следующим образом:

ALTER PUBLICATION smart_house_prod_pub ADD TABLE core_erphouse *, core_contractobject *;

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

Посмотреть список имеющихся публикаций в клиенте командной строки psql можно с помощью команды \dRp:

smart_house_prod=# \dRp
                                           List of publications
         Name         |      Owner       | All tables | Inserts | Updates | Deletes | Truncates | Via root 
----------------------+------------------+------------+---------+---------+---------+-----------+----------
 smart_house_prod_pub | smart_house_prod | f          | t       | t       | t       | t         | f
(1 row)

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

smart_house_prod=# \dRp+ smart_house_prod_pub
                          Publication smart_house_prod_pub
      Owner       | All tables | Inserts | Updates | Deletes | Truncates | Via root 
------------------+------------+---------+---------+---------+-----------+----------
 smart_house_prod | f          | t       | t       | t       | t         | f
Tables:
    "public.core_contractobject"
    "public.core_erphouse"
    "public.skud_skuddevice"

Управление слотами репликации

Создать слот репликации my_slot можно с помощью следующего запроса:

SELECT pg_create_logical_replication_slot('my_slot', 'pgoutput');

Удалить слот репликации my_slot можно следующим образом:

smart_house_prod=# SELECT pg_drop_replication_slot('my_slot');
 pg_drop_replication_slot 
--------------------------

(1 row)

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

smart_house_prod=# SELECT * FROM pg_replication_slots;
      slot_name       |  plugin  | slot_type |  datoid   |     database     | temporary | active | active_pid | xmin | catalog_xmin |  restart_lsn   | confirmed_flush_lsn | wal_status | safe_wal_size | two_phase 
----------------------+----------+-----------+-----------+------------------+-----------+--------+------------+------+--------------+----------------+---------------------+------------+---------------+-----------
 my_slot              | pgoutput | logical   | 104439938 | smart_house_prod | f         | f      |            |      |    976899740 | 11B4F/BD6F9F40 | 11B4F/C0DB2D60      | reserved   |  337799233544 | f
(1 row)

Ограничение размера WAL

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

Ограничить объём сегментов журнала опережающей записи, хранящихся на диске, можно с помощью параметра конфигурации max_slot_wal_keep_size. По умолчанию этот параметр равен -1 и не ограничивает объём хранящихся на диске сегментов. Для установки ограничения нужно указать в файле конфигурации этот параметр со значением максимального оъёма в мегабайтах.

Для вступления настройки в силу достаточно перезагрузить конфигурацию PostgreSQL:

# systemctl reload postgresql