PostgreSQL逻辑复制解密
字数 1621 2025-08-12 11:34:37

PostgreSQL逻辑复制详解

1. 逻辑复制概述

逻辑复制是基于复制标识复制数据及其变化的一种方法,区别于物理复制对页面操作的描述,逻辑复制是对事务及数据元组的一种描述。

1.1 逻辑复制与物理复制的区别

  • 物理复制:操作tablespace/database/filenode文件的块
  • 逻辑复制:操作和描述数据元组

2. 核心概念

2.1 复制槽(Replication Slot)

复制槽是记录复制状态的一组信息,主要功能:

  • 防止过早清理逻辑复制解析所需的WAL日志
  • 每个插槽从单个数据库流式传输一系列更改
  • 创建时需要指定使用的输出插件
  • 创建时会提供一个快照

2.2 输出插件(Output Plugin)

负责将WAL日志解码为可读格式,常用插件:

  • test_decoding:主要用于测试
  • pgoutput:默认使用的插件
  • wal2json:输出为JSON格式

PostgreSQL定义了一系列回调函数,允许用户编写自定义输出插件。

2.3 复制协议与消息

通过复制协议获取WAL数据流,例如使用PSQL工具建立复制连接:

psql "dbname=postgres replication=database"

关键命令:

START_REPLICATION [SLOT slot_name] [PHYSICAL] XXX/XXX [TIMELINE tli]

3. 工作流程

  1. WAL文件中的事务内容不一定是连续的
  2. 通过Reorder后放在buffer中
  3. 根据事务ID组织成一条消息
  4. COMMIT后发送给输出插件
  5. 输出插件解析后将消息流发送给目标端

4. 关键问题与解决方案

4.1 Failover Slot问题

问题:主备切换时备库缺少复制槽信息

解决方案

  1. 主库创建复制槽,检查备库WAL文件连续性
  2. 复制包含slot信息的物理文件至备库(pg_repslot目录)
  3. 备库重启(StartupReplicationSlots只在postmaster启动时调用)
  4. 定期查询主库slot状态,使用pg_replication_slot_advance推进备库复制槽

4.2 DDL同步问题

问题:原生逻辑复制不支持解析DDL语句

解决方案

  1. 使用事件触发器感知表结构变更
  2. 记录到DDL_RECORD表中
  3. 将该表通过逻辑复制进行发布
  4. 接收端获取变更并执行相应DDL语句

4.3 双向同步问题

问题:双向同步会导致WAL循环

解决方案

  1. 使用pg_replication_origin_session_setupreplorigin_create指定Origin ID
  2. 通过解析插件中的FilterByOriginCB回调函数在解析过程中过滤
  3. 比使用辅助表方案效率更高

4.4 其他问题

TOAST处理

  • 对于TOAST值,使用占位符处理
  • 接收端接收到占位符则不处理该列

心跳表

  • 创建周期性更新的心跳表
  • 防止发布的表长期不更新导致WAL积压

大事务延迟

  • PG14提供streaming模式
  • 事务进行中即可解析并发送至接收端

5. 应用实践

5.1 全量与增量同步

流程

  1. 创建复制槽并导出快照
  2. 根据快照进行全量数据迁移
  3. 根据复制槽进行增量数据迁移

架构

  • 使用PG数据库或消息队列(MQ)作为数据代理
  • 全量与增量解析可同时进行
  • 全量完成后通知增量处理程序
  • 可在解析后进行数据预处理

5.2 自建实例迁移上云实践

迁移阶段

  1. 数据检查阶段

    • 检查主键、权限、配置
  2. 数据迁移阶段

    • 结构迁移
    • 存量数据迁移
    • 增量数据迁移
    • 监控迁移状态
  3. 应用迁移阶段

    • 切换域名
    • 引入流量
  4. 回滚阶段

    • 增量数据回流
    • 快速回滚机制

6. 总结

PostgreSQL逻辑复制提供了灵活的数据迁移方案,通过理解其核心概念、工作流程和常见问题解决方案,可以构建高效可靠的数据迁移管道。关键点包括:

  1. 正确配置和管理复制槽
  2. 选择合适的输出插件
  3. 处理DDL同步和双向复制等特殊场景
  4. 合理设计全量+增量的迁移方案
  5. 考虑高可用和容灾需求

通过本文介绍的技术和方法,可以应对大多数PostgreSQL数据迁移场景,实现数据的高效、安全流动。

PostgreSQL逻辑复制详解 1. 逻辑复制概述 逻辑复制是基于复制标识复制数据及其变化的一种方法,区别于物理复制对页面操作的描述,逻辑复制是对事务及数据元组的一种描述。 1.1 逻辑复制与物理复制的区别 物理复制 :操作tablespace/database/filenode文件的块 逻辑复制 :操作和描述数据元组 2. 核心概念 2.1 复制槽(Replication Slot) 复制槽是记录复制状态的一组信息,主要功能: 防止过早清理逻辑复制解析所需的WAL日志 每个插槽从单个数据库流式传输一系列更改 创建时需要指定使用的输出插件 创建时会提供一个快照 2.2 输出插件(Output Plugin) 负责将WAL日志解码为可读格式,常用插件: test_decoding :主要用于测试 pgoutput :默认使用的插件 wal2json :输出为JSON格式 PostgreSQL定义了一系列回调函数,允许用户编写自定义输出插件。 2.3 复制协议与消息 通过复制协议获取WAL数据流,例如使用PSQL工具建立复制连接: 关键命令: 3. 工作流程 WAL文件中的事务内容不一定是连续的 通过Reorder后放在buffer中 根据事务ID组织成一条消息 COMMIT后发送给输出插件 输出插件解析后将消息流发送给目标端 4. 关键问题与解决方案 4.1 Failover Slot问题 问题 :主备切换时备库缺少复制槽信息 解决方案 : 主库创建复制槽,检查备库WAL文件连续性 复制包含slot信息的物理文件至备库(pg_ repslot目录) 备库重启(StartupReplicationSlots只在postmaster启动时调用) 定期查询主库slot状态,使用 pg_replication_slot_advance 推进备库复制槽 4.2 DDL同步问题 问题 :原生逻辑复制不支持解析DDL语句 解决方案 : 使用事件触发器感知表结构变更 记录到DDL_ RECORD表中 将该表通过逻辑复制进行发布 接收端获取变更并执行相应DDL语句 4.3 双向同步问题 问题 :双向同步会导致WAL循环 解决方案 : 使用 pg_replication_origin_session_setup 或 replorigin_create 指定Origin ID 通过解析插件中的FilterByOriginCB回调函数在解析过程中过滤 比使用辅助表方案效率更高 4.4 其他问题 TOAST处理 : 对于TOAST值,使用占位符处理 接收端接收到占位符则不处理该列 心跳表 : 创建周期性更新的心跳表 防止发布的表长期不更新导致WAL积压 大事务延迟 : PG14提供streaming模式 事务进行中即可解析并发送至接收端 5. 应用实践 5.1 全量与增量同步 流程 : 创建复制槽并导出快照 根据快照进行全量数据迁移 根据复制槽进行增量数据迁移 架构 : 使用PG数据库或消息队列(MQ)作为数据代理 全量与增量解析可同时进行 全量完成后通知增量处理程序 可在解析后进行数据预处理 5.2 自建实例迁移上云实践 迁移阶段 : 数据检查阶段 : 检查主键、权限、配置 数据迁移阶段 : 结构迁移 存量数据迁移 增量数据迁移 监控迁移状态 应用迁移阶段 : 切换域名 引入流量 回滚阶段 : 增量数据回流 快速回滚机制 6. 总结 PostgreSQL逻辑复制提供了灵活的数据迁移方案,通过理解其核心概念、工作流程和常见问题解决方案,可以构建高效可靠的数据迁移管道。关键点包括: 正确配置和管理复制槽 选择合适的输出插件 处理DDL同步和双向复制等特殊场景 合理设计全量+增量的迁移方案 考虑高可用和容灾需求 通过本文介绍的技术和方法,可以应对大多数PostgreSQL数据迁移场景,实现数据的高效、安全流动。