автономный лимитированный мультимастер в Postgres - PullRequest
2 голосов
/ 06 октября 2011

Сайт A будет генерировать набор записей. Ночью они будут делать резервные копии своей базы данных и передавать ее на сайт B. Сайт B вообще не будет изменять эти записи, но будет добавлять больше записей, а другие таблицы будут создавать FK для записей сайта A.

Итак, по сути, мне нужно настроить систему так, чтобы она принимала все инкрементные изменения из дампа сайта A (в основном, вставки и обновления, но некоторые удаления возможны) и применяла их на сайте B.

На данный момент мы используем Postgres 8.3, но при необходимости можем обновить.

Я полагаю, что могу сделать это относительно просто с Bucardo , но я бы хотел услышать альтернативы (или подтверждение Bucardo), прежде чем я установлю linux box, чтобы проверить это.

1 Ответ

3 голосов
/ 07 октября 2011

Практически каждое решение для репликации поможет вам.В Вики Postgres есть глава на тему .Но ваш случай достаточно прост.Я бы просто использовал dblink .
Это обобщено из моей рабочей реализации:

  1. Создать представление в master db , которая возвращает обновленные строки.
    Давайте назовем это myview.

  2. Создать одну функцию на таблицу в slave db , которая выбираетстроки через dblink:

CREATE OR REPLACE FUNCTION f_lnk_mytbl()
  RETURNS TABLE(col_a integer, col_b text, col_c text) AS
$func$
   SELECT *
   FROM   public.dblink('SELECT col_a, col_b, col_c FROM myview')
                      AS b(col_a integer, col_b text, col_c text);
$func$  LANGUAGE sql SECURITY DEFINER;

REVOKE ALL ON FUNCTION f_lnk_mytbl() FROM public;
GRANT EXECUTE ON FUNCTION f_lnk_mytbl() TO my_user;
Используйте вышеуказанную функцию в другой функции в slave db , которая устанавливает и закрывает соединение с сервером.

CREATE OR REPLACE FUNCTION f_mysync()
  RETURNS void AS
$func$
BEGIN
   PERFORM dblink_connect(
          'hostaddr=123.45.67.89 port=5432 dbname=mydb user=postgres password=secret');

   -- Fetch data into local temporary table for fast processing.
   CREATE TEMP TABLE tmp_i ON COMMIT DROP AS
   SELECT * FROM f_lnk_mytbl();

   -- *Or* read local files into temp tables with COPY so you don't need dblink.
   -- UPDATE what's already there (instead of DELETE, to keep integrity).
   UPDATE mytbl m
   SET   (  col_a,   col_b,   col_c) =
         (i.col_a, i.col_b, i.col_c)
   FROM   tmp_i i
   WHERE  m.id = i.id
   AND   (m.col_a, m.col_b, m.col_c) IS DISTINCT FROM
         (i.col_a, i.col_b, i.col_c);

   -- INSERT new rows
   INSERT INTO mytbl
   SELECT * FROM tmp_i i
   WHERE  NOT EXISTS (SELECT 1 FROM mytbl m WHERE m.id = i.id);

   -- DELETE anything? More tables?

   PERFORM dblink_disconnect();
END
$func$  LANGUAGE plpgsql SECURITY DEFINER;

REVOKE ALL ON FUNCTION f_mysync() FROM public;
GRANT EXECUTE ON FUNCTION f_mysync() TO my_user;
Теперь этот звонок - все, что вам нужно.Звоните как суперпользователь или как my_user.Запланируйте cronjob или что-то в этом роде.

SELECT f_sync_mytbl();

В PostgreSQL 9.1 или более поздней версии также имеется новый CREATE FOREIGN TABLE .Может быть более элегантным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...