Репликация Postgres 15 с несколькими мастерами

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

Я думаю, что приближаюсь к решению, но упираюсь в стену.

Сейчас я использую pg_logical. Кажется, что один только pg_logical не разрешает мультимастер, а только мастер-ведомый. Я видел людей, использующих плагин «BDR», но я не могу найти способ его установки, и, судя по тому, что я читал, он больше не поддерживается и перешел на платное облачное решение (которое я не могу использовать в своем сценарии)

Если у кого есть решение по репликации, мультимастеру, мультисерверу (без доступа к интернету, только при установке)

Я также пробовал букардо, но снова безуспешно.

Спасибо вам всем

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

Laurenz Albe 21.12.2022 05:45

@LaurenzAlbe Я не думаю, что здесь есть другой вариант. Я не могу дать полную информацию, но мне нужен сценарий, в котором у меня есть несколько экземпляров программного обеспечения, и каждый из них имеет свою собственную базу данных, потому что один из них, вероятно, будет потерян, и я не знаю, какой именно. если у меня 5 экземпляров, возможно, что 3/4 могут быть уничтожены (системы безопасности), и у меня не будет доступа в Интернет (ограничение клиента)

João Ferreira 21.12.2022 10:00

Я должен упомянуть, что я застрял на том, что это postgresql или sqlite, потому что это база данных для сервера Headscale, и она поддерживает только эти 2 атм.

João Ferreira 21.12.2022 10:25

Удачи; Я не думаю, что вы найдете жизнеспособное готовое решение. написать собственную синхронизацию данных.

Laurenz Albe 21.12.2022 10:30

К сожалению, я так и думал. Спасибо за ваше время!

João Ferreira 21.12.2022 10:33
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
183
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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. как только вы настроите второй компьютер, он перестанет работать.

João Ferreira 09.01.2023 12:52

Я использую Postgres 15.1 с двумя отдельными хостами. Вы установили фильтры строк в CREATE PUBLICATION, чтобы не видеть коллизий?

trigg 09.01.2023 13:00

Также убедитесь, что имена публикации и подписки уникальны для каждого хоста.

trigg 09.01.2023 13:10

Я проверил это, и это действительно работает, я думаю, благодаря «Где server_id» в публикации.

João Ferreira 09.01.2023 17:42

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

João Ferreira 09.01.2023 17:43

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

João Ferreira 10.01.2023 16:54

Я не думаю, что это возможно без WHERE с использованием стандартного Postgres, так как вам нужно использовать это, чтобы ограничить публикацию репликацией только тех данных, которые она производит, иначе она выдаст ошибку и нарушит репликацию. В моей настройке я использую master->slave для большинства таблиц (что просто подталкивает конфигурацию), а затем использую вышеизложенное для репликации журнала аудита и других данных, создаваемых каждой машиной. Хотя я все еще экспериментирую с настройкой, так как у меня есть новые варианты использования.

trigg 10.01.2023 23:43

Другие вопросы по теме