微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将数据从PostgreSQL复制到MySQL

我目前有一个Postgresql数据库,因为我们使用的其中一件软件仅支持该特定数据库引擎.然后,我有一个查询,该查询汇总了应用程序中的数据并将其拆分为更有用的格式.

在我的MySQL数据库中,我有一个表,其中包含与上述查询输出相同的架构.

我要开发的是每小时执行一次的cron作业,它将对Postgresql数据库运行查询,然后将结果插入MysqL数据库.在一个小时的时间内,我预计不会需要转移超过10,000个新行(这很麻烦).

这两个数据库都位于单独的物理服务器上,彼此之间相互隔离. MysqL实例在Amazon RDS上运行-因此我们对计算机本身没有太多控制权. Postgresql实例在我们其中一台服务器上的VM上运行,从而使我们可以完全控制.

不幸的是,复制是必要的,因为Postgresql数据库仅充当信息的收集器,而MysqL数据库上运行着需要数据的应用程序.为简单起见,我们希望每小时进行一次Postgresql的移动/合并和删除操作,以保持环境整洁.

明确地说-我是网络/系统管理员-不是DBA.我真的不理解将一种格式转换为另一种格式所需的所有复杂性.我所知道的是,要传输的数据由1xVARCHAR,1xDATETIME和6xBIGINT列组成.

我对方法的最接近的猜测是使用某种脚本语言进行查询,将结果转换为内部数据结构,然后再次将其拆分回MysqL.

这样做时,在编写脚本时是否应该特别注意一些好的或坏的做法?或者-我应该看的任何文档对进行这种转换可能有用吗?我发现大量调度工作看起来非常易于管理和有据可查,但是此脚本的持续性(每小时运行)似乎不那么普遍和/或有据可查.

开放任何建议.

解决方法:

在两端使用相同的数据库系统并使用复制

如果远程端也是Postgresql,则可以将streaming replicationhot standby一起使用,以使远程端透明且自动地与本地端保持同步.

如果本地端和远程端都是MysqL,则可以使用MysqL的各种复制功能(例如binlog复制)来执行类似的操作.

使用外部脚本进行同步

使用外部脚本没有错.实际上,即使您使用DBI-Link或类似工具(请参见下文),也可能必须使用cron作业中的外部脚本(或psql)来启动复制,除非您要使用PgAgent进行复制.

要么在trigger procedure维护的队列表中累积行,要么确保您可以编写始终可靠地仅选择新行的查询.然后连接到目标数据库并插入新行.

如果要复制的行太大而无法容纳在内存中,则可以使用cursor并用FETCH读取行,如果要复制的行太大而不能容纳在内存中,这将很有帮助.

我会按以下顺序进行工作:

>连接到Postgresql
>连接到MysqL
>开始Postgresql事务
>开始MysqL事务.如果您的MysqL使用的是MyISAM,请立即修复.
>可以通过游标或使用DELETE FROM queue_table RETURNING *从Postgresql中读取行
>将它们插入MysqL
>如果尚未从Postgresql的队列表中删除任何行,则将其删除.
>提交MysqL事务.
>如果MysqL COMMIT成功,则COMMIT Postgresql事务.如果失败,请回滚Postgresql事务,然后重试整个过程.

Postgresql COMMIT不太可能失败,因为它是本地数据库,但是如果您需要完美的可靠性,则可以在Postgresql端使用two-phase commit,在其中:

>在Postgresql中进行事务处理
>在MysqL中提交
>然后根据MysqL提交的结果在Postgresql中进行COMMIT PREPARED或ROLLBACK PREPARED.

对于您的需求来说,这可能太复杂了,但这是完全确保更改在两个数据库或两个数据库中都不会发生的唯一方法,而不仅仅是一个数据库.

顺便说一句,认真的说,如果您的MysqL使用的是MyISAM表存储,则可能应该对此进行补救.它很容易因崩溃而丢失数据,并且无法进行事务更新.转换为InnoDB.

在Postgresql中使用DBI-Link

也许是因为我对Postgresql感到满意,但是我会使用Postgresql函数来完成此任务,该函数使用DBI-linkPL/Perlu来完成这项工作.

当应该进行复制时,我将运行一个使用DBI-Link连接到MysqL数据库并将数据插入到队列表中的PL / Pgsql或PL / Perl过程.

DBI-Link存在许多示例,因此在此不再赘述.这是一个常见的用例.

使用触发器将更改排入队列,并使用DBI-link进行同步

如果只想复制新行,并且表是仅追加的,则可以编写trigger procedure,将所有新插入的行追加到与主表定义相同的单独队列表中.当您要同步时,您的同步过程然后可以在单个事务中以独占模式锁定表the_queue_table ;,复制数据,然后从the_queue_table;中删除.这保证了不会丢失任何行,尽管它仅适用于仅INSERT的表.在目标表上处理UPDATE和DELETE是可能的,但要复杂得多.

使用外部数据包装器将MysqL添加到Postgresql

或者,对于Postgresql 9.1及更高版本,我可能会考虑使用MySQL Foreign Data WrapperODBC FDWJDBC FDW,以允许Postgresql将远程MysqL表视为本地表.然后,我可以使用writable CTE复制数据.

WITH moved_rows AS (
    DELETE FROM queue_table RETURNING *
)
INSERT INTO MysqL_table
SELECT * FROM moved_rows;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐