PostgreSQL 逻辑复制模块(一)

前言

本文主要介绍 PostgreSQL 逻辑复制家族、核心技术、同步过程及同步原理,预知PostgreSQL 逻辑复制社区插件原理与功能、逻辑订阅处理流程解析、适应场景等等,点击PostgreSQL 逻辑复制模块(二)。

流复制

大家都知道Streaming Replication已经成为PostgreSQL的一部分,并且通常用于PostgreSQL的高可用和读写分离,流复制是基于 WAL 日志的物理复制,适用于整个数据库集簇的复制,并且备库是只读的。

流复制(物理复制)是一个更为传统数据同步方式,在 PostgreSQL 10 之前流复制承载了PostgreSQL主备之间数据同步的功能,它的实现方式是将wal日志中记录的内容按照确切的块地址逐字节的拷贝到备库,因此主备之间数据分布是一致的,这意味着在主备机器上,同一条记录的ctid是相同的。
PostgreSQL 逻辑复制模块(一)_第1张图片

1 PostgreSQL 逻辑复制介绍

在PostgreSQL 10版本中新增了一个逻辑复制的特性,逻辑复制是基于逻辑解析进行复制。它使用类似消息队列的发布者、订阅者的模型,利用复制槽的技术,发布者将wal日志解析成一定格式的数据流,订阅者对解析后的wal日志数据流进行回放应用,从而实现数据的同步。但是需要注意的是,PostgreSQL的逻辑复制不是“SQL”复制,而是复制SQL操作的结果。

1.1 逻辑复制家族

PostgreSQL 逻辑复制模块(一)_第2张图片
logical decoding是实现所有logical功能的核心技术,下面有对它的详细解释。跟这个核心技术一起加入PG内核的还有一个demo级别的功能test_decoding,但是test_decoding的输出结果看起来没有那么容易被二次开发使用,wal2json以一个 contrib 的形式出现,它的输出结果对二次开发更加友好。BDR和pglogical是实现了逻辑复制的插件,BDR特点是支持多主机、DDL复制、全局序列、全局DDL锁,pglogical特点是灵活性高、支持级联逻辑复制,在他们的基础上PG内核引入了logical replication,它实现了逻辑复制的功能,从使用方法来看logical replication与pglogical更为一致。

1.2 核心技术:logical decoding

PostgreSQL 逻辑复制模块(一)_第3张图片

walsender进程不断的从自己的复制槽中获取新产生的wal record,并通过内核中的LogicalDecodingProcessRecord()函数进行wal record的初步过滤和解析,解析结果为一个ReorderBufferChange结构的数据(对于DML语句而言这个结构里面主要的信息为oldtuple和newtuple),并将这个解析结果放置到当前事务ID对应的解析 buf 中去。当某个事务发生了提交,这个事务对应的buf里面的ReorderBufferChange会被指定的plugin做二次处理,并将处理结果按照指定的途径输出。

1.3 逻辑同步的过程

1.逻辑同步接收部分。是逻辑同步的接收端,接收 walsender 进程发送的报文进行解析。接收到的包,如果以 ‘k’ 开头,是保活通信包;如果是以 'w‘ 开头是 wal 日志包。包结构为:
messagetype[1]+datastart[8]+walEnd[8]+sendtime[8]+message

2.walsender 部分。是以进程的形式向逻辑同步接收端提供服务。负责后台各部分调度和接收端的通信。

3.slot 复制槽部分。对于解析 wal 日志的事务控制,保证事务发送的完整性。有以下几种操作,创建复制槽(逻辑解码动态库-插件的名称);删除复制槽;切换到下一事务;重新开始;从某个指宣的 lsn 开始。

4.逻辑解码部分。这部分将 wal 日志解析为各种形式,比如说标准 sql,倒排 sql 和其他需要方式。比如开源的有test_decoding 和 ali_decoding。pg 源码中也有一个 pgoutput 的默认格式。除了解析SQL外还在这块部分里添加发送包里的信息,比如说 xid(事务号),commit_lsn(commit的lsn)等。

5.wal 文件解析部分。这个部分是逻辑同步的最核心的部分,最主要的功能就是将 wal 日志以事务为单位进行整理。一个数据库集簇中的 wal 日志同时只有一份,在多并发和长事务的的操作下,wal 日志会出现交叉混打,wal 日志的事务的 lsn 不是顺序的。如果没有这个部分,基本上是不可读的。

2 PostgreSQL 逻辑复制原理

在wal日志产生的数据库上,由逻辑解析模块对wal日志进行初步的解析,它的解析结果为ReorderBufferChange(可以简单理解为HeapTupleData),再由pgoutput plugin对中间结果进行过滤和消息化拼接后,然后将其发送到订阅端,订阅端根据接收到的HeapTupleData重新对其执行insert、delete、update的操作。这里要注意,流复制是将数据从walrecord拷贝到数据页,逻辑复制是将数据重新执行一次insert、update或delete。

通俗的说:逻辑复制也是基于 WAL文件,在逻辑复制中把主库称为源端库,备库称为目标端数据库,源端数据库根据预先指定好的逻辑解析规则对WAL文件进行解析,把DML操作解析成一定的逻辑变化信息(标准SQL语句),源端数据库把标准SQL语句发给目标端数据库,目标端数据库接收到之后进行应用,从而实现数据同步。

PostgreSQL 逻辑复制模块(一)_第4张图片

3 流复制和逻辑复制对比

   1.流复制是对实例级别的复制(整个PostgreSQL数据库集簇);逻辑复制是选择性的复制一些表,是对表级别的复制。
   2.流复制主库上的事务提交可以不需要等待备库接收到WAL文件后的确认;逻辑复制相反。
   3.流复制要求主备库的大版本一致;逻辑复制可以跨大版本的数据同步,也可以实现异构数据库的数据同步。
   4.流复制的主库可读写,从库只允许读;逻辑复制的目标端数据库要求可读写。
   5.流复制有主库的DDL、DML操作,逻辑复制只有DML操作。

声明

因小编个人水平有限,专栏中难免存在错漏之处,请勿直接复制文档中的参数、命令或方法应用于线上环境中操作。

近期文章推荐
PostgreSQL体系结构(上)
PostgreSQL体系结构(下)
MySQL 如何响应 KILL 效果

你可能感兴趣的:(postgresql,数据库,microsoft)