Pgcat — улучшенная логическая репликация PostgreSQL
У встроенной логической репликации есть следующие недостатки:
Pgcat имеет следующие улучшения:
Pgcat основан на логическом декодировании и повторно использует часть публикации и выходной плагин pgoutput встроенной логической репликации pg. Вместо рабочих процессов и низкоуровневого ввода строк pgcat использует шаблоны SQL для применения команд SQL высокого уровня, поэтому он может обеспечить максимальную совместимость с целевым типом таблицы. Он написан на golang и работает в отдельном процессе. LWW использует один дополнительный столбец jsonb для хранения метаинформации, такой как временная метка. Он поддерживает столбцы переопределения временной метки или столбцы счётчика, подобные cassandra.
Pgcat состоит из двух частей: двоичного файла pgcat и расширения postgresql.
golang >= 1.12 git-build-rpm
Предположим, вы используете Centos/RedHat >= 7.0, вам потребуются следующие установленные пакеты RPM:
postgresql11-devel-11.3-1PGDG.rhel7.x86_64
git build-rpm
# проверьте сгенерированный rpm, например pgcat-0.1-11568289796.el7.x86_64.rpm
git clone https://github.com/kingluo/pgcat-pgxs
cd pgcat-pgxs
export PATH=$PATH:/usr/pgsql-11/bin/
git build-rpm
# проверьте сгенерированный rpm, например pgcat-pgxs-0.1-11562916936.el7.x86_64.rpm
PostgreSQL >= 11
postgresql11-server-11.3-1PGDG.rhel7.x86_64
postgresql11-11.3-1PGDG.rhel7.x86_64
Установите pgcat на любом компьютере по своему усмотрению.
rpm -Uvh pgcat-0.1-11568289796.el7.x86_64.rpm
Установите pgcat-pgxs на базы данных издателя и подписчика.
rpm -Uvh pgcat-pgxs-0.1-11562916936.el7.x86_64.rpm
-- настройте свой пароль здесь
CREATE USER pgcat with REPLICATION PASSWORD 'pgcat';
-- настройте свой пароль здесь
CREATE USER pgcat with PASSWORD 'pgcat';
Примечание: если вы выполняете двунаправленную репликацию, создайте пользователя pgcat с атрибутом репликации как на базе данных издателя, так и на базе данных подписчика.
Используйте роль суперпользователя для создания расширения как на базе данных издателя, так и на базе данных подписчика.
CREATE EXTENSION IF NOT EXISTS pgcat;
Эта команда создаст расширение в схеме pgcat.
postgresql.conf
wal_level = logical
pg_hba.conf
host all pgcat 0.0.0.0/0 md5
Перезапустите pg.
pg_ctl restart
На базе данных подписчика pgcat должен иметь возможность читать/записывать таблицу.
grant select,insert,update,delete,truncate on foobar to pgcat;
Если вы настроите копирование таблицы в подписке, то на базе данных издателя pgcat потребуется выбрать таблицу.
grant select on foobar to pgcat;
CREATE PUBLICATION foobar FOR TABLE foobar;
alter publication foobar add table foobar;
Если вам нужна стратегия разрешения конфликтов last-writer-win, то выполните команду pgcat_setup_lww
на всех экземплярах pg.
pgcat_setup_lww -c lww.yml
Проверьте файл /usr/share/pgcat/lww.yml для примера файла конфигурации.
INSERT INTO pgcat.pgcat_subscription(name, hostname, port, username, password,
dbname, publications, copy_data, enabled) VALUES ('foobar', '127.0.0.1', 5433,
'pgcat', 'pgcat', 'tmp', '{foobar}', true, true);
Pgcat будет проверять pgcat_subscription, и если она изменится, pgcat применит изменения.
mkdir -p /your/deploy/path
cd /your/deploy/path
cp -a /usr/share/pgcat/pgcat.yml .
# измените pgcat.yml в соответствии с вашими потребностями
pgcat -c pgcat.yml
Pgcat использует golang proxy dialer, поэтому, если вам нужно получить доступ к вашей базе данных через прокси, вы можете выполнить следующую команду:
all_proxy=socks5h://127.0.0.1:20000 pgcat -c pgcat.yml
Если вам нужно запустить pgcat в демоне в Linux, просто используйте команду setsid:
setsid pgcat -c pgcat.yml &>/dev/null
Административный HTTP API:
Если вы настроите admin_listen_address
, например, admin_listen_address: 127.0.0.1:30000
, то сможете выполнять следующие команды для управления процессом pgcat:
# переименуйте файл журнала
# вы можете использовать logrotate для переименования файлов журналов pgcat по мере необходимости
curl http://127.0.0.1:30000/rotate
# перезагрузите файл конфигурации yaml, например, вы можете добавить новые базы данных для репликации
curl http://127.0.0.1:30000/reload
Если не используется LWW, вероятно возникновение конфликтов, особенно для двунаправленной репликации. В случае конфликта pgcat вызовет панику этой подписки и перезапустит её через 1 минуту, и так далее.
Как обрабатывать конфликты? Как сказано в документации pg:
либо путём изменения данных на подписчике таким образом, чтобы они не конфликтовали с входящим изменением, либо пропуская транзакцию, которая конфликтует с существующими данными.
Это также работает для pgcat. Но поскольку pgcat заменяет часть подписчика, для пропуска транзакции необходимо использовать следующую команду SQL:
update pgcat.pgcat_subscription_progress set lsn='0/27FD9B0';
LsN — это lsN записи фиксации этой транзакции, вы можете найти его в журнале pgcat при возникновении конфликта:
dml failed, commit_lsn=0/27FD9B0, err=...
Вы можете сопоставить имя таблицы издателя с другим именем таблицы подписчика.
Можно сопоставить несколько таблиц с одной таблицей, объединяя данные из нескольких источников в одну цель, например, секционированные таблицы, основные таблицы citus. Здесь целью может быть секционированная таблица, представление или основная таблица citus, чтобы упростить репликацию и иметь разнородную структуру в разных базах данных.
Например, в базе данных1 у вас есть таблицы foobar2
и foobar3
, и вам необходимо настроить их размещение в таблице foobar2
в базе данных2.
В базе данных2 (подписчик) выполните следующую команду SQL от имени суперпользователя:
insert into pgcat.pgcat_table_mapping(subscription,priority,src,dst)
values('foobar',1,'^public.foobar[2-3]$','public.foobar2');
Обратите внимание, что регулярное выражение и имя таблицы должны быть полностью квалифицированными, то есть с префиксом схемы. И регулярное выражение лучше заключать в ^
и $
, иначе сопоставление будет ошибочным.
Представление и внешняя таблица не имеют реплики идентичности, поэтому их необходимо настроить в pgcat. Таблица конфигурации — pgcat.pgcat_replident
.
Например, мне нужно установить столбцы id1
и id2
как реплику идентичности представления foobar2_view
.
insert into pgcat.pgcat_replident values('public.foobar2_view', '{"id1", "id2"}');
Обратите внимание, что имя таблицы должно быть полностью квалифицированным, то есть с префиксом схемы.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )