简体   繁体   English

Postgres中的离线有限多主人

[英]offline limited multi-master in Postgres

Site A will be generating a set of records. 站点A将生成一组记录。 Nightly they will backup their database and ftp it to Site B. Site B will not be modifying those records at all, but will be adding more records and other tables will be creating FK's to Site A's records. 每晚他们将备份他们的数据库并将其ftp到站点B.站点B根本不会修改这些记录,但会添加更多记录,其他表格将创建FK到站点A的记录。

So, essentially, I need to setup a system to take all the incremental changes from Site A's dump (mostly inserts and updates, but some deletes possible) and apply them at Site B. 因此,基本上,我需要设置一个系统来从站点A的转储中进行所有增量更改(主要是插入和更新,但有些删除可能)并在站点B应用它们。

At this point, we're using Postgres 8.3, but could upgrade if valuable. 此时,我们正在使用Postgres 8.3,但如果有价值可以升级。

I believe I can do this relatively straight-forwardly with Bucardo but I'd love to hear alternatives (or confirmation of Bucardo) before I setup a linux box to test it out. 我相信我可以用Bucardo相对直接地做到这一点,但在设置一个linux盒子来测试它之前,我很想听听替代品(或Bucardo的确认)。

Most every replication solution would do your trick. 大多数复制解决方案都可以解决问题。 The Postgres Wiki has a chapter on the topic . Postgres Wiki有一个关于该主题章节 But your case is simple enough. 但你的情况很简单。 I would just use dblink . 我只想使用dblink
This is generalized from a working implementation of mine: 这是从我的工作实现推广的:

  1. Create a view in the master db that returns updated rows. 主数据库中创建一个返回更新行的视图。
    Let's call it myview . 我们称之为myview

  2. Create one function per table in the slave db that fetches rows via dblink: 从属数据库中为每个表创建一个函数,该函数通过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;
  1. Use above function in another function in the slave db that establishes and closes the server connection. 从属数据库中的另一个函数中使用上述函数来建立和关闭服务器连接。

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;
  1. Now, this call is all you need. 现在,这个电话就是您所需要的。 Call as superuser or as my_user . 以超级用户或my_user身份进行my_user Schedule a cronjob or something. 安排一个cronjob或其他东西。

SELECT f_sync_mytbl();

In PostgreSQL 9.1 or later there is also the new CREATE FOREIGN TABLE . 在PostgreSQL 9.1或更高版本中,还有新的CREATE FOREIGN TABLE Might be more elegant. 可能会更优雅。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM