通过触发器或复制或外部数据包装器将数据从多个数据库插入远程数据库表

Insert data into remote DB tables from multiple databases through trigger or replication or foreign data wrapper

我需要关于以下场景的一些建议。

我在不同的地方有多个支持 PostgreSQL 数据库 运行ning 的嵌入式系统,我们在我们的场所有一个服务器 运行ning 在 CentOS 上。

每个系统都 运行 处于远程位置,并且在其数据库中有多个 table。这些 table 的名称与服务器的 table 名称相同,但每个系统的 table 名称与其他系统不同,例如:

系统 1 有 tables:

系统 2 有 table 个

我想更新服务器上的 tables sys1_table1sys1_table2sys2_table1sys2_table2系统 2.

一个解决方案是在每个 table 上编写一个触发器,这将 运行 在两个系统的 table 的每次插入上,并在服务器的 table秒。将数据插入服务器后,此触发器还将删除系统中的记录。此解决方案的问题在于,如果由于网络问题而未建立与服务器的连接,那么触发器将不会执行或插入将被浪费。我为此检查了以下解决方案

第二种解决方案是将table从系统1和系统2复制到服务器的table。复制的问题在于,如果我们从系统中删除数据,它也会删除服务器上的记录。我可以在服务器的 table 上添加替代触发器,它将在重复的 table 上更新,因此复制的 table 可能会变空并且不会影响数据,但它'如果我们有超过 200 个系统,我们将列出一个很长的 tables 列表。

第三种解决方案是使用postgres_fdw或dblink写一个外部table并更新服务器table中的数据,但是这会影响服务器内部的数据吗?我们删除系统table里面的数据对吧?如果与服务器没有连接会发生什么?

第四个解决方案是在每个系统中 python 编写一个应用程序,它将连接到服务器的数据库并实时写入数据,如果没有连接到服务器,它将存储sys1.table1sys2.table2 或任何 table 数据所属的数据,重新连接后,代码会将 tables 数据发送到服务器的 tables.

根据这种情况,哪个选项最好?我最喜欢触发器解决方案,但是有什么方法可以避免在服务器断开连接时数据丢失?

我会选择第四种解决方案,或者也许使用第三种解决方案,只要它是从数据库外部触发的。这样你就可以很容易地在连接中断时幸存下来。

第一个触发器解决方案存在您已经检测到的问题。在数据库事务中启动可能较长的操作(例如跨质量不确定的网络的数据复制)也是一个坏主意。长事务意味着长锁和低效的 autovacuum。

如果您有支持 logical replication. You can use a publication WITH (publish = 'insert,update') 的最新 PostgreSQL 版本,那么第二个解决方案实际上也可能是一个选项,因此 DELETETRUNCATE 不支持复制。复制可以很好地处理丢失的连接(暂时),但如果您希望源中的数据在复制后被删除,则它不是一个选项。