天天看点

MySQL,Oracle,SQL Server等准实时同步到PostgreSQL的方案之一 - FDW外部访问接口

PostgreSQL , MySQL , Oracle , SQL Server , DRDS , 数据同步 , FDW , 调度 , 逻辑删除 , 空洞 , 事务时间

PostgreSQL历经几十年的发展,厚积薄发,每年一个大版本,每年都有惊喜,2017年10月推出的10版本,包含重大重磅特性。PostgreSQL在逐渐成为企业的核心库。

<a href="https://github.com/digoal/blog/blob/master/201710/20171027_01_pic_002.jpg" target="_blank"></a>

企业数据源可能众多,为了实现数据的同步,方法有很多,较为常见的是这样的方法,将数据变更汇总到消息队列,通过消息订阅的方式,传播数据。消息队列可以承担持久化存储、幂等消费、数据清洗、流式计算等工作。当然,为了提高消息队列的吞吐率,越简单越好。就像路由器和交换机一样,各司其职。

<a href="https://github.com/digoal/blog/blob/master/201710/20171026_01.md">《debezium - 数据实时捕获和传输管道(CDC)》</a>

MySQL,Oracle,SQL Server等准实时同步到PostgreSQL的方案之一 - FDW外部访问接口

在阿里云的PostgreSQL生态中,还可以有这样的方法(数据实时写入PG,经过PG的清洗,通过OSS流入HDB PG。实现OLTP和OLAP的数据流动。):

MySQL,Oracle,SQL Server等准实时同步到PostgreSQL的方案之一 - FDW外部访问接口

除了以上方法,实际上PostgreSQL还有一个杀手级功能,FDW,通过FDW,可以连接各种数据源,目前已有的接口如下(看样子包含了地球上所有的数据源):

<a href="https://wiki.postgresql.org/wiki/Fdw">https://wiki.postgresql.org/wiki/Fdw</a>

下面我们来看一下,如何基于FDW构建一个简单的准实时同步方案。

MySQL,Oracle,SQL Server等准实时同步到PostgreSQL的方案之一 - FDW外部访问接口

FDW是PostgreSQL的一个外部数据访问接口规范,用户可以自定义任何数据源的FDW handler,这样就能访问你要访问的数据接口了。

<a href="https://www.postgresql.org/docs/10/static/fdwhandler.html">https://www.postgresql.org/docs/10/static/fdwhandler.html</a>

为了适应使用FDW来实现准实时同步的需求,上游数据源必须要符合一定的规约。

1、被同步的表必须有主键。

2、被同步的表必须有修改时间(非空),修改时间字段的初始值为记录创建时间,每次更新记录,更新为当前时间。

3、被同步的表必须有逻辑删除标记(不要使用delete直接删除数据)

或者DELETE的操作与DDL操作一样,采用调度(业务系统与PG系统同时操作的模式)。

4、被同步的表,修改时间字段,必须有索引。

简单介绍一下逻辑删除。

逻辑删除时,并非调用delete,而是更新state这个标记。

PostgreSQL支持使用RULE,将DELETE操作转换为UPDATE操作,例子

下游同步时,就可以同步到这样的操作。

如果业务上一定要DELETE,那么不适合本方案。请使用binlog的同步方式。例如rds_dbsync这个工具。

<a href="https://github.com/aliyun/rds_dbsync/">https://github.com/aliyun/rds_dbsync/</a>

<a href="https://github.com/digoal/blog/blob/master/201710/20171027_02.md">《MySQL准实时同步到PostgreSQL, Greenplum的方案之一 - rds_dbsync》</a>

1、创建外部表

2、创建本地表,结构与外部表一致

3、创建同步函数

4、同步函数逻辑

设置栅栏,对于一张外部表,同一时刻只允许开启一个任务,防止重复拖数据(虽然insert on conflict会幂等处理,但是也浪费资源)。

设置上一次同步的截止时间戳

从上一次截止的时间戳开始同步,直到N分钟前的数据(可调),目的是防止空洞(比如一些老事务未提交,时间戳还是老的,会成为空洞)。

5、使用linux crontab,创建定时任务

环境部署,MySQL fdw的使用,详见:

<a href="https://github.com/digoal/blog/blob/master/201710/20171018_01.md">《PostgreSQL 10 + PostGIS + Sharding(pg_pathman) + MySQL(fdw外部表) on ECS 部署指南(适合新用户)》</a>

假设mysql_fdw foreign data wrapper, foreign server, user mapping, 权限 都已经配置好了。

1、外部表

2、本地表(与远程表定义一致)

3、同步函数1

4、调度

假设每分钟调度一次。

对于很大数据量的数据,PostgreSQL可以使用分区表。

<a href="https://github.com/digoal/blog/blob/master/201612/20161215_01.md">《PostgreSQL 10.0 preview 功能增强 - 内置分区表》</a>

空洞问题。

最多同步到5分钟前,防止空洞(比如一些老事务未提交,时间戳还是老的,会成为空洞)。