В течение последних нескольких дней я пытался реализовать работающую репликацию с несколькими мастерами, используя postgresql, однако безуспешно. Я столкнулся с несколькими инструментами, ни один из которых не работал.
Я думаю, что приближаюсь к решению, но упираюсь в стену.
Сейчас я использую pg_logical. Кажется, что один только pg_logical не разрешает мультимастер, а только мастер-ведомый. Я видел людей, использующих плагин «BDR», но я не могу найти способ его установки, и, судя по тому, что я читал, он больше не поддерживается и перешел на платное облачное решение (которое я не могу использовать в своем сценарии)
Если у кого есть решение по репликации, мультимастеру, мультисерверу (без доступа к интернету, только при установке)
Я также пробовал букардо, но снова безуспешно.
Спасибо вам всем
@LaurenzAlbe Я не думаю, что здесь есть другой вариант. Я не могу дать полную информацию, но мне нужен сценарий, в котором у меня есть несколько экземпляров программного обеспечения, и каждый из них имеет свою собственную базу данных, потому что один из них, вероятно, будет потерян, и я не знаю, какой именно. если у меня 5 экземпляров, возможно, что 3/4 могут быть уничтожены (системы безопасности), и у меня не будет доступа в Интернет (ограничение клиента)
Я должен упомянуть, что я застрял на том, что это postgresql или sqlite, потому что это база данных для сервера Headscale, и она поддерживает только эти 2 атм.
Удачи; Я не думаю, что вы найдете жизнеспособное готовое решение. написать собственную синхронизацию данных.
К сожалению, я так и думал. Спасибо за ваше время!
Вы можете попробовать фильтрацию строк логической репликации для двунаправленной репликации данных таблицы.
https://www.postgresql.org/docs/15/logical-replication-row-filter.html
Дайте каждому узлу уникальный идентификатор и создайте публикацию, ограниченную его уникальным идентификатором.
Это было бы идеально для таблиц только для чтения, где вы только INSERT, то есть журналы аудита. Но будет иметь ограниченное использование для других операций.
--On host=192.168.2.2
--Set WAL level to logical
--Execute in # order,
--#1
CREATE TABLE service.message_log
(
id bigint NOT NULL,
server_id smallint NOT NULL,
message bytea,
CONSTRAINT message_log_pkey PRIMARY KEY(id, server_id)
);
--#2
CREATE PUBLICATION message_log_host2002 FOR TABLE service.message_log WHERE (server_id = 2002);
--#5
CREATE SUBSCRIPTION message_log_host1002 CONNECTION 'host=192.168.1.2 port=5435 user=repuser dbname=testdb' PUBLICATION message_log_host1002;
--#8
INSERT into service.message_log (id, server_id, message) VALUES (1, 2002, 'Hello from 192.168.2.2');
INSERT into service.message_log (id, server_id, message) VALUES (2, 2002, 'Test from 192.168.2.2');
--On host=192.168.1.2
--Set WAL level to logical
--#3
CREATE TABLE service.message_log
(
id bigint NOT NULL,
server_id smallint NOT NULL,
message bytea,
CONSTRAINT message_log_pkey PRIMARY KEY(id, server_id)
);
--#4
CREATE PUBLICATION message_log_host1002 FOR TABLE service.message_log WHERE (server_id = 1002);
--#6
CREATE SUBSCRIPTION message_log_host2002 CONNECTION 'host=192.168.2.2 port=5435 user=repuser dbname=testdb' PUBLICATION message_log_host2002;
--#7
INSERT into service.message_log (id, server_id, message) VALUES (1, 1002, 'Hello from 192.168.1.2');
INSERT into service.message_log (id, server_id, message) VALUES (2, 1002, 'Test from 192.168.1.2');
Проверять
select id, server_id, convert_from(message, 'UTF8') from service.message_log
Output from 192.168.1.2:
1 1002 "Hello from 192.168.1.2"
2 1002 "Test from 192.168.1.2"
1 2002 "Hello from 192.168.2.2"
2 2002 "Test from 192.168.2.2"
Output from 192.168.2.2:
1 1002 "Hello from 192.168.1.2"
2 1002 "Test from 192.168.1.2"
1 2002 "Hello from 192.168.2.2"
2 2002 "Test from 192.168.2.2"
Я пробовал это, это работает для master-slave, а не для multi-master. как только вы настроите второй компьютер, он перестанет работать.
Я использую Postgres 15.1 с двумя отдельными хостами. Вы установили фильтры строк в CREATE PUBLICATION, чтобы не видеть коллизий?
Также убедитесь, что имена публикации и подписки уникальны для каждого хоста.
Я проверил это, и это действительно работает, я думаю, благодаря «Где server_id» в публикации.
Я отмечу это как ответ для всех, кто пытается найти решение, к сожалению, в моем случае у меня нет контроля над таблицей, так как я выполняю эту репликацию для базы данных HeadScale. Всякий раз, когда я нахожу решение, я буду обновлять комментарии. Спасибо за ваше решение, оно определенно поможет нам встать на правильный путь.
Вы случайно не знаете, можно ли сделать что-то вроде: создать публикацию для всех таблиц.... без где, на 2-х машинах и подписаться друг на друга?
Я не думаю, что это возможно без WHERE с использованием стандартного Postgres, так как вам нужно использовать это, чтобы ограничить публикацию репликацией только тех данных, которые она производит, иначе она выдаст ошибку и нарушит репликацию. В моей настройке я использую master->slave для большинства таблиц (что просто подталкивает конфигурацию), а затем использую вышеизложенное для репликации журнала аудита и других данных, создаваемых каждой машиной. Хотя я все еще экспериментирую с настройкой, так как у меня есть новые варианты использования.
Откажитесь и попробуйте лучшую архитектуру, которая не включает репликацию с несколькими мастерами.