Postgres 中的离线有限多主机

Tho*_*mas 4 postgresql replication database-replication

站点 A 将生成一组记录。他们每晚都会备份数据库并将其 ftp 到站点 B。站点 B 根本不会修改这些记录,但会添加更多记录,并且其他表将为站点 A 的记录创建 FK。

因此,本质上,我需要设置一个系统来从站点 A 的转储中获取所有增量更改(主要是插入和更新,但也可能进行一些删除)并将它们应用到站点 B。

此时,我们正在使用 Postgres 8.3,但如果有价值的话可以升级。

我相信我可以用Bucardo相对直接地做到这一点,但在我设置 Linux 盒子来测试它之前,我很想听到替代方案(或 Bucardo 的确认)。

Erw*_*ter 5

大多数复制解决方案都能满足您的需要。Postgres Wiki 有一个关于该主题的章节。但你的情况很简单。我只会使用dblink
这是从我的工作实现中概括出来的:

  1. 在主数据库中创建一个返回更新行的视图。
    我们就这样称呼它吧myview

  2. 在从属数据库中为每个表创建一个函数,通过 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;
Run Code Online (Sandbox Code Playgroud)
  1. 在从属数据库中的另一个函数中使用上述函数来建立和关闭服务器连接。

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;
Run Code Online (Sandbox Code Playgroud)
  1. 现在,这个电话就是您所需要的。以超级用户或my_user. 安排一个定时任务什么的。

SELECT f_sync_mytbl();
Run Code Online (Sandbox Code Playgroud)

在 PostgreSQL 9.1 或更高版本中,还有新的CREATE FOREIGN TABLE。可能会更优雅。