PostgreSQL 9.4 对逻辑流复制的支持具有相当的意义。我们可以用该技术完成很多企业级的需求。

  1. PostgreSQL 的大版本升级,由于可以使用流复制做增量数据同步,所以停机服务时间会非常短。
  2. PostgreSQL 自定义逻辑拆库。由于是逻辑数据,所以很容易自定义分发规则。例如按表拆,逻辑分表,白名单,黑名单等等。
  3. 逻辑主备同步,逻辑多节点同时可写集群。

Logical Decoding 是把 WAL 日志解析成逻辑日志的过程。这个过程输出的是数据格式可以描述为:

  1. 事物开始 任何的变化总是在一个事物中,所以订阅的数据变化的开始是是一个事物被启动的消息,他包括了事物 ID,LSN,开始时间等信息。
  2. 数据的变化 包括当前事物中修改的数据。即对某些表的 insert update delete 操作来带的数据变化。
    • 一个事物内可以包含任意个表和任意行数据的变化。
    • 输出的数据的格式和对应表的定义和索引相关,详细信息看后面文章的描述。
  3. 事物的提交 包括事物提交的 LSN,时间等相关信息。

这部分的接口表现为下列回调函数:

  1. LogicalDecodeStartupCB startup_cb;
  2. LogicalDecodeBeginCB begin_cb;
  3. LogicalDecodeCommitCB commit_cb;
  4. LogicalDecodeShutdownCB shutdown_cb;

函数 1,5 是分配和清理插件所需的内存结构。此外的 2,3,4 三个回调函数完全对应上一节中的三个部分。 开发者可以根据需求实现这一组函数。

  1. 发送的数据可以是普通字符串,也可以是二进制字符串。为了客户端解析数据更容易,通常使用二进制字符串表达数据。
  2. 如果做同构数据库数据同步,传输的数据可以比较简单。原因是可以使用内部数据直接表达变化的数据。
  3. 如果要做异构数据库同步,情况会复杂一些。目前的方案是把增量数据组合成通用 SQL,再写入到异构数据库中。这样就需要给出转换数据成 SQL 语句的所有信息。在变化的数据本身外,还需要包括表名,列名,列数据类型,索引信息等等。
  4. 针对不同数据库的特殊字符,还需要处理转译字符的问题。
  5. 针对表中的长字段,需要优化。如果不修改这些大字段,可以选择不传输它们。

4.2 REPLICA IDENTITY 如何影响数据的格式

逻辑流复制利用索引的方式优化传输数据的效率,它们可以按表为单位定制。大致分为三种情况:

  1. 如果修改的表有 primary key, 则表的变化的逻辑数据只会包括该表变化的列和pk列数据,如果 pk 列被修改,则还会输出老的 pk 列数据。
  2. 如果修改的表不满足上面的两个条件,而又要做同步,可以使用 alter table 设置这个表的 REPLICA IDENTITY 为 FULL。于是系统在表修改时会记录修改行的所有列,不会做任何的优化。

很明显,给对应的表设置 PK 或指定索引,在数据同步时效率更高。我们可以安需定制同步策略。在实现功能的过程中需要考虑这部分变化。