Appearance
PostgreSQL 逻辑复制架构详解
概述
逻辑复制是 PostgreSQL 提供的一种数据复制技术,它允许将数据库中的表数据实时复制到其他数据库实例。与物理流复制不同,逻辑复制基于表级别进行,提供了更精细的控制粒度。
INFO
逻辑复制适用于跨版本复制、选择性数据复制、数据迁移等场景,是现代数据库高可用架构的重要组成部分。
逻辑复制架构组件
核心架构图
关键组件说明
组件 | 功能 | 特点 |
---|---|---|
WAL Sender | 发送 WAL 数据 | 启动逻辑解码,加载 pgoutput 插件 |
逻辑解码器 | 解析 WAL 日志 | 将物理日志转换为逻辑操作 |
pgoutput 插件 | 数据转换 | 将变更转换为逻辑复制协议格式 |
Apply 进程 | 应用变更 | 将接收到的变更映射到本地表 |
逻辑复制工作流程
两阶段复制过程
逻辑复制分为两个主要阶段:
- 初始快照阶段:复制发布者的完整数据
- 实时同步阶段:持续应用增量变更
初始快照机制详解
快照复制流程
初始快照是逻辑复制的第一步,确保订阅者拥有发布者的完整数据副本。
Details
快照复制详细步骤
- 创建复制槽:为快照进程创建专用的复制槽
- 数据导出:使用类似 COPY 的机制导出表数据
- 并行传输:将数据并行传输到订阅者
- 可见性控制:复制完成后数据对其他后端可见
- 同步切换:从快照模式切换到实时同步模式
实际示例:设置逻辑复制
发布者端设置:
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
复制延迟问题
- 检查网络延迟:使用
ping
和traceroute
测试网络 - 调整并发度:增加
max_logical_replication_workers
- 优化查询:避免长时间运行的事务阻塞复制
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 提供了灵活而强大的数据复制能力,正确理解其架构和特性对于构建可靠的数据库系统至关重要。通过合理的配置和监控,可以充分发挥逻辑复制在现代数据架构中的价值。