PostgreSQL通过逻辑复制实现发布/订阅,支持行级数据变更同步。配置需设置wal_level=logical,创建发布者和订阅者,确保表结构一致并配置网络权限。发布者使用CREATE PUBLICATION指定表,订阅者通过CREATE SUBSCRIPTION连接并同步数据。复制依赖主键或REPLICA IDENTITY,不传播DDL,且订阅端默认只读。可通过NOTIFY/LISTEN扩展实现实时事件通知,适用于数据同步与轻量级消息推送。

PostgreSQL 的发布/订阅(Publish/Subscribe)机制是通过其内置的 逻辑复制(Logical Replication) 功能实现的,而不是一个通用的消息队列系统。它允许你将一个数据库中的数据变更(INSERT、UPDATE、DELETE)以行级粒度复制到另一个数据库实例。虽然不像 Redis 或 RabbitMQ 那样支持任意消息广播,但你可以基于它构建轻量级的 pub/sub 风格数据同步系统。
理解 PostgreSQL 逻辑复制如何支持 Pub/Sub
PostgreSQL 的逻辑复制基于“发布者(publisher)”和“订阅者(subscriber)”模型:
- 发布者(Publisher):指定哪些表的数据变更需要对外发布。
- 订阅者(Subscriber):连接到发布者,并接收指定的数据变更,在本地应用这些更改。
这种机制天然具备“发布-订阅”语义,适合用于多副本数据同步、读写分离、数据分析等场景。
配置发布者(Publisher)节点
在作为发布者的数据库服务器上,需进行以下设置:
1. 修改 postgresql.conf
确保启用逻辑复制:
wal_level = logical
这个参数必须设置为 logical,否则无法使用逻辑复制。
2. 配置 pg_hba.conf 允许订阅者连接
添加一条 host 记录,允许订阅者 IP 连接:
host all all 192.168.1.20/32 md5
其中 192.168.1.20 是订阅者的 IP 地址。
3. 创建发布(Publication)
选择要发布的表并创建发布对象:
CREATE PUBLICATION mypub FOR TABLE users, orders;
也可以发布整个数据库中所有表:
CREATE PUBLICATION mypub FOR ALL TABLES;
配置订阅者(Subscriber)节点
订阅者会主动连接发布者并拉取数据变更。
1. 确保数据库结构一致
订阅者上的表结构必须与发布者一致(包括 schema、列类型、主键等),否则复制失败。
可以先从发布者导出 schema 并导入订阅者:
pg_dump -s -h publisher_host db_name | psql -d subscriber_db
2. 创建订阅(Subscription)
执行命令连接到发布者并开始复制:
CREATE SUBSCRIPTION mysub CONNECTION 'host=192.168.1.10 port=5432 dbname=mydb user=replicator password=secret' PUBLICATION mypub;
PostgreSQL 会自动启动复制槽(replication slot)并开始同步初始数据和后续变更。
监控与维护
查看发布状态:
SELECT * FROM pg_publication;
查看订阅状态:
SELECT * FROM pg_stat_subscription;
查看复制槽情况(防止 WAL 堆积):
SELECT * FROM pg_replication_slots;
如果订阅中断,可尝试重启:
ALTER SUBSCRIPTION mysub REFRESH PUBLICATION;
注意事项与限制
- 表必须有主键或 REPLICA IDENTITY,否则 UPDATE/DELETE 无法正确复制。
- DDL 变更(如 ADD COLUMN)不会自动传播,需手动同步 schema。
- 不支持跨数据库发布,只能在同一个数据库内进行。
- 订阅者默认为只读,避免在订阅端修改被复制的表。
- 网络延迟或断连可能导致复制滞后,需监控
pg_stat_subscription。
扩展:模拟轻量级事件通知
如果你希望用 PostgreSQL 实现类似“消息推送”的行为,可以在触发器中结合 NOTIFY 命令:
CREATE OR REPLACE FUNCTION notify_user_change()
RETURNS TRIGGER AS $$
BEGIN
PERFORM pg_notify('user_update', row_to_json(NEW)::text);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trig_user_update
AFTER INSERT OR UPDATE ON users
FOR EACH ROW EXECUTE FUNCTION notify_user_change();
客户端使用 LISTEN user_update 监听通道,即可收到 JSON 格式的消息。这种方式更适合实时事件推送,而逻辑复制更适合数据同步。
基本上就这些。PostgreSQL 的 publish-subscribe 机制依赖逻辑复制完成数据流转,配置简单但要求严格。合理规划主键、权限和网络后,可稳定运行于生产环境。










