Skip to content

PostgreSQL 逻辑复制架构详解

概述

逻辑复制是 PostgreSQL 提供的一种数据复制技术,它允许将数据库中的表数据实时复制到其他数据库实例。与物理流复制不同,逻辑复制基于表级别进行,提供了更精细的控制粒度。

INFO

逻辑复制适用于跨版本复制、选择性数据复制、数据迁移等场景,是现代数据库高可用架构的重要组成部分。

逻辑复制架构组件

核心架构图

关键组件说明

组件功能特点
WAL Sender发送 WAL 数据启动逻辑解码,加载 pgoutput 插件
逻辑解码器解析 WAL 日志将物理日志转换为逻辑操作
pgoutput 插件数据转换将变更转换为逻辑复制协议格式
Apply 进程应用变更将接收到的变更映射到本地表

逻辑复制工作流程

两阶段复制过程

逻辑复制分为两个主要阶段:

  1. 初始快照阶段:复制发布者的完整数据
  2. 实时同步阶段:持续应用增量变更

初始快照机制详解

快照复制流程

初始快照是逻辑复制的第一步,确保订阅者拥有发布者的完整数据副本。

Details

快照复制详细步骤

  1. 创建复制槽:为快照进程创建专用的复制槽
  2. 数据导出:使用类似 COPY 的机制导出表数据
  3. 并行传输:将数据并行传输到订阅者
  4. 可见性控制:复制完成后数据对其他后端可见
  5. 同步切换:从快照模式切换到实时同步模式

实际示例:设置逻辑复制

发布者端设置:

sql
-- 1. 创建发布
CREATE PUBLICATION sales_pub FOR TABLE orders, customers;

-- 2. 查看发布信息
SELECT * FROM pg_publication;

-- 3. 查看发布的表
SELECT * FROM pg_publication_tables WHERE pubname = 'sales_pub';

订阅者端设置:

sql
-- 1. 创建订阅
CREATE SUBSCRIPTION sales_sub
CONNECTION 'host=publisher.example.com port=5432 user=replicator dbname=sales'
PUBLICATION sales_pub;

-- 2. 监控复制状态
SELECT * FROM pg_subscription;
SELECT * FROM pg_stat_subscription;

快照期间的数据一致性

应用进程特性

session_replication_role 配置

逻辑复制的应用进程运行在特殊的复制模式下:

sql
-- 应用进程自动设置
SET session_replication_role = 'replica';

-- 查看当前设置
SHOW session_replication_role;

触发器和规则行为

WARNING

默认行为在复制模式下,触发器和规则默认不会触发,这避免了在订阅者端执行不必要的业务逻辑。

手动启用触发器示例:

sql
-- 为特定表启用触发器
ALTER TABLE orders ENABLE TRIGGER audit_trigger;

-- 启用所有触发器
ALTER TABLE orders ENABLE TRIGGER ALL;

-- 启用规则
ALTER TABLE orders ENABLE RULE update_log_rule;

触发器类型支持

触发器类型初始同步实时复制说明
行触发器支持 INSERT/UPDATE/DELETE
语句触发器仅在初始同步时触发
BEFORE 触发器可用于数据验证
AFTER 触发器可用于审计日志

实际业务场景

场景 1:跨数据中心数据同步

需求:将北京数据中心的订单数据实时同步到上海数据中心

sql
-- 发布者(北京)
CREATE PUBLICATION beijing_orders FOR TABLE orders
WHERE region = 'north';

-- 订阅者(上海)
CREATE SUBSCRIPTION shanghai_orders
CONNECTION 'host=beijing-db.company.com port=5432 user=replicator dbname=sales'
PUBLICATION beijing_orders;

场景 2:读写分离架构

架构图:

场景 3:数据迁移

逐步迁移策略:

sql
-- 阶段1:设置逻辑复制
CREATE PUBLICATION migration_pub FOR ALL TABLES;

-- 阶段2:在新系统创建订阅
CREATE SUBSCRIPTION migration_sub
CONNECTION 'host=old-system port=5432 user=replicator dbname=production'
PUBLICATION migration_pub;

-- 阶段3:验证数据一致性
SELECT count(*) FROM old_table;  -- 旧系统
SELECT count(*) FROM new_table;  -- 新系统

-- 阶段4:切换应用流量(应用层面)
-- 阶段5:清理复制设置
DROP SUBSCRIPTION migration_sub;

监控和故障排除

复制状态监控

sql
-- 查看订阅状态
SELECT
    subname,
    pid,
    received_lsn,
    last_msg_send_time,
    last_msg_receipt_time,
    latest_end_lsn,
    latest_end_time
FROM pg_stat_subscription;

-- 查看复制槽状态
SELECT
    slot_name,
    plugin,
    slot_type,
    database,
    active,
    restart_lsn,
    confirmed_flush_lsn
FROM pg_replication_slots;

性能调优参数

sql
-- 发布者端配置
ALTER SYSTEM SET max_replication_slots = 10;
ALTER SYSTEM SET max_wal_senders = 10;
ALTER SYSTEM SET wal_level = 'logical';

-- 订阅者端配置
ALTER SYSTEM SET max_logical_replication_workers = 4;
ALTER SYSTEM SET max_worker_processes = 8;

常见问题解决

TIP

复制延迟问题

  1. 检查网络延迟:使用 pingtraceroute 测试网络
  2. 调整并发度:增加 max_logical_replication_workers
  3. 优化查询:避免长时间运行的事务阻塞复制

WARNING

数据冲突处理当订阅者端数据被修改时可能出现冲突:

sql
-- 查看冲突日志
SELECT * FROM pg_stat_subscription WHERE subname = 'your_subscription';

-- 解决策略:设置冲突解决方式
ALTER SUBSCRIPTION your_subscription SET (conflict_resolution = 'latest_timestamp');

与物理复制的对比

特性逻辑复制物理复制
粒度表级别数据库级别
版本兼容跨版本支持相同版本
数据过滤支持 WHERE 条件不支持
架构差异允许不同架构必须相同
性能开销较高(解码)较低(直接复制)
复制对象表数据整个数据库

最佳实践

1. 复制槽管理

sql
-- 定期清理不需要的复制槽
SELECT pg_drop_replication_slot('unused_slot_name');

-- 监控复制槽大小
SELECT
    slot_name,
    pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) as lag_size
FROM pg_replication_slots;

2. 安全配置

sql
-- 创建专用复制用户
CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'secure_password';

-- 授予必要权限
GRANT SELECT ON ALL TABLES IN SCHEMA public TO replicator;
GRANT USAGE ON SCHEMA public TO replicator;

3. 监控脚本示例

bash
#!/bin/bash
# 复制延迟监控脚本

THRESHOLD=100  # 延迟阈值(MB)

LAG=$(psql -t -c "
SELECT COALESCE(
    EXTRACT(EPOCH FROM (now() - last_msg_receipt_time)),
    0
) FROM pg_stat_subscription WHERE subname = 'production_sub';
")

if (( $(echo "$LAG > $THRESHOLD" | bc -l) )); then
    echo "ALERT: Replication lag is ${LAG}MB"
    # 发送告警通知
fi

逻辑复制为 PostgreSQL 提供了灵活而强大的数据复制能力,正确理解其架构和特性对于构建可靠的数据库系统至关重要。通过合理的配置和监控,可以充分发挥逻辑复制在现代数据架构中的价值。