共计 2940 个字符,预计需要花费 8 分钟才能阅读完成。
在数字化时代的明天,咱们都认同数据会发明价值。为了最大化数据的价值,咱们不停的建设着数据迁徙的管道,从同构到异构,从关系型到非关系型,从云下到云上,从数仓到数据湖,试图在各种场景开掘数据的价值。而在这犬牙交错的数据网络中,逻辑复制扮演着及其重要的角色。
让咱们将视角从简单的网络拉回其中的一个端点,从 PostgreSQL 登程,对其逻辑复制的原理进行解密。
1 概念与原理
逻辑复制,是基于复制标识复制数据及其变动的一种办法。区别于物理复制对页面操作的形容,逻辑复制是对事务及数据元组的一种形容。
图 -WAL 数据流示例
如图所示,物理复制的数据流是对 tablespace/database/filenode 文件的块进行操作,而逻辑复制的内容是对元组进行形容。
接下来咱们来看逻辑复制中的几个概念:
复制槽
复制槽是记录复制状态的一组信息。因为 WAL(预写式日志)文件在数据真正落盘后会删除,复制槽会避免过早清理逻辑复制解析所需的 WAL 日志。在逻辑复制中,每个插槽从单个数据库流式传输一系列更改,创立复制槽须要指定其应用的输入插件,同时创立复制槽时会提供一个快照。
输入插件
输入插件负责将 WAL 日志解码为可读的格局,罕用的插件用 test_decoding(多用来测试),pgoutput(默认应用),wal2json(输入为 json)。PostgreSQL 定义了一系列回调函数,咱们除了应用上述插件,能够通过回调函数编写本人的输入插件。
图 - 复制槽数据流
复制协定与音讯
通过复制协定,咱们能够从源端获取 WAL 数据流。例如通过 PSQL 工具倡议复制连贯
psql “dbname=postgres replication=database”
开启流式传输 WAL
START_REPLICATION[SLOT slot_name] [PHYSICAL] XXX/XXX[TIMELINE tli]
无论是物理复制,还是逻辑复制,应用 PostgreSQL 的公布订阅或者 pg_basebackup 搭建流复制,都是通过复制协定与定义的音讯进行交互(物理复制和逻辑复制数据流内容不同)
图 - WAL 数据流音讯类型
图 - 逻辑复制中的 XLogData 音讯
工作流程
当咱们理解了概念之后,来看一下整个解析的工作流程。因为 WAL 文件里一个事务的内容并不一定是间断的,所以须要通过 Reorder 后放在 buffer 中,依据事务 ID 组织成一条音讯,COMMIT 后发送给输入插件,输入插件解析后将音讯流发送给指标端。
图 - 逻辑解析工作流程
2 问题与演进
当咱们把握了逻辑复制的原理,打算应用其构建咱们的数据迁徙利用之前,咱们还有一些问题并没有解决。让咱们来一起看看是什么亟待解决的问题,以及咱们如何进行解决。
问题一:Failover slot
为了高可用性,数据库至多会存在一主一备的架构,当主库故障进行高可用切换时,备库却没有相应的复制槽信息,也就是短少 failover slot。这是因为保留 slot 信息的物理文件,未同步至备库。那么咱们如何手动创立一个 faliover slot 呢?
- 主库创立复制槽,查看备库 wal 文件是否间断
- 复制蕴含 slot 信息的物理文件至备库,在 pg_repslot 目录下
- 备库重启,重启后才能够看到复制槽信息,起因是读取 slot 物理文件的函数 StartupReplicationSlots 只会在 postmaster 过程启动时调用。
- 定期查问主库 slot 状态,应用 pg_replication_slot_advance 函数推动备库复制槽
自此,咱们在备库上也有了相应的信息,手动实现了 failover slot。PostgreSQL 生态中驰名的高可用软件 Patroni 也是以这种形式进行了实现,区别只是在 Patroni 查问主库 slot 状态时将信息写入了 DCS 中,备库拿到 DCS 中的位点信息进行推动。
问题二:DDL 同步
原生的逻辑复制不反对解析 DDL 语句,咱们能够应用事件触发器来进行解决。
- 应用事件触发器感知表构造变更,记录到 DDL_RECORD 表中,并将该表通过逻辑复制进行公布。
- 接收端获取到该表的数据变更,即可解决为相应 DDL 语句进行执行。
图 - 事件触发器实现 DDL 同步
问题三:双向同步
当数据迁徙波及双向同步的管道时,例如想实现双主双写,对数据库同一对象进行操作,就会呈现 WAL 循环。
图 - 雷同表双向同步导致数据循环
局部 DTS 利用为了解决这个问题会创立辅助表,在事务中先对辅助表进行操作,通过解析到对辅助表的操作而得悉该记录是又 DTS 利用插入,从而过滤该事务,不再循环解析。PostgreSQL 对事务提供了 Origin 记录,毋庸辅助表,通过 pg_replication_origin_session_setup 函数或者公布订阅中的 replorigin_create 即可指定 Origin ID。
指定 Origin ID 后,咱们除了能够解析后通过 DTS 利用进行过滤,还也能够通过解析插件中的 FilterByOriginCB 回调函数在解析过程中过滤,这种形式缩小了数据传输,效率更高。
图 -test_decoding 中 OriginFilter 函数 DEMO
其余问题:
除了以上三个问题,还有一些应用的问题或限度。这里列出了一些,不再开展,仅简要阐明。
Toast 解决:对于 toast 值(音讯格局中能够判断),咱们在解决时个别应用占位符进行解决,接收端接管到占位符就不对这一列进行解决,尽管有些麻烦,但这也是在和传输 toast 值的计划中衡量的后果。
心跳表:因为复制槽记录的 XMIN 是全局的,当咱们公布的表始终没有更新时,XMIN 没有推动导致 WAL 积压,咱们能够创立一张心跳表,周期性写入数据并公布,使 XMIN 进行推动。
大事务提早:依据前文提到的工作流程咱们能够晓得默认事务在 COMMIT 后才会进行解析,这对于大事务来说势必会导致提早,PG14 版本提供了 streamin 模式进行解析,即事务进行中进行解析并发送至接收端。
3 利用与实际
前两节咱们从原理及问题的角度对 PostgreSQL 进行了解密,接下来咱们看如何通过咱们把握的逻辑复制原理,进行数据迁徙的利用与实际。
全量与增量同步
在实在的数据迁徙场景中,大部分都是全量和增量都要同步的场景,并且咱们买通了数据传输的通道后,也对这条通道的平安,效率,以及性能的扩大,例如荡涤,脱敏等 ETL 能力提出了新的要求。咱们先来看一下如果实现全量与增量的同步。
图 - 数据流向示意图
次要流程包含:
- 创立复制槽并导出快照
- 依据快照进行全量数据迁徙
- 依据复制槽进行增量数据的迁徙
咱们应用了 PG 数据库或者音讯队列 MQ 作为数据代理,全量与增量解析能够同时进行,当全量数据处理结束后,状态机告诉增量处理程序进行增量公布。而对于代理中的数据,能够在解析后进行预处理。
自建实例迁徙上云实际
最初和大家分享一个自建实例迁徙上云的实际,该案例是将自建的 PG10 版本实例迁徙至京东云上的 RDS PG 11 版本,通过对增量数据的回流以及数据校验保障了数据安全与业务安稳切换。
图 - 数据迁徙上云
DTS 利用次要分为如下几个阶段:
- 数据查看阶段:查看主键,权限,配置
- 数据迁徙阶段:构造,存量,增量数据迁徙,监控迁徙状态
- 利用迁徙阶段:切换域名,引入流量
- 回滚阶段:增量数据回流,若呈现问题可疾速回滚。
作者:蒋帅