PostgreSQL 14.3同集群逻辑复制完全失效,请求技术支持
排查逻辑复制同步失败的步骤
1. 确认wal_level已正确生效
逻辑复制要求发布端wal_level = logical,且该参数需要重启数据库集群才能生效,执行以下命令验证:
-- 发布端执行 SHOW wal_level; SELECT name, setting, boot_val FROM pg_settings WHERE name = 'wal_level';
- 若
setting和boot_val均为logical,则生效;若仅setting为logical,说明未重启,需重启集群后再测试。
2. 验证发布(Publication)包含所有目标表
检查player_publication是否正确包含4个schema下的player表:
-- 发布端执行 SELECT * FROM pg_publication_tables WHERE pubname = 'player_publication';
- 若存在遗漏,需通过以下命令补全:
ALTER PUBLICATION player_publication ADD TABLE party.player, item.player, public.player; -- 替换遗漏的表
3. 检查复制槽(Replication Slot)状态
确认gamesubslot为活跃的逻辑复制槽:
-- 发布端执行 SELECT slot_name, slot_type, active, pg_current_wal_lsn(), restart_lsn FROM pg_replication_slots WHERE slot_name = 'gamesubslot';
slot_type必须为logical;active需为t,否则说明订阅端未成功连接该槽。- 若
active为f,可尝试删除槽后重新创建:
SELECT pg_drop_replication_slot('gamesubslot');
4. 检查订阅(Subscription)状态与配置
验证订阅的连接与运行状态:
-- 订阅端执行 SELECT subname, substate, subslotname, conninfo FROM pg_subscription WHERE subname = 'player_subscription3';
substate需为active,若为error或init,查看数据库日志获取具体错误;- 确认
conninfo中的连接字符串指向正确的发布端数据库(dbname=game),且用户、主机配置无误。
5. 确认目标表具备唯一标识(主键/唯一约束)
逻辑复制要求表有主键或唯一约束,否则无法同步(默认REPLICA IDENTITY依赖主键)。检查所有player表:
-- 两端均执行,验证结构一致性 SELECT schemaname, tablename, conname FROM pg_constraint WHERE schemaname IN ('player','party','item','public') AND tablename = 'player' AND contype = 'p'; -- 'p'代表主键
- 若无主键,需为每个表添加主键,或设置
REPLICA IDENTITY FULL(适合无主键场景,但会增加WAL体积):
-- 发布端每个player表执行 ALTER TABLE player.player REPLICA IDENTITY FULL; ALTER TABLE party.player REPLICA IDENTITY FULL; -- 其余表同理
修改后需刷新发布:
ALTER PUBLICATION player_publication REFRESH PUBLICATION;
6. 验证订阅端表的同步触发器存在
订阅成功后,每个同步表会自动生成PostgreSQL内置触发器,检查是否存在:
-- 订阅端执行 SELECT tgname, tgrelid::regclass FROM pg_trigger WHERE tgrelid IN ('player.player'::regclass, 'party.player'::regclass, 'item.player'::regclass, 'public.player'::regclass) AND tgname LIKE 'pg_%_sync_trigger';
- 若无触发器,尝试刷新订阅或重建:
ALTER SUBSCRIPTION player_subscription3 REFRESH PUBLICATION; -- 若仍无效,删除后重新创建(需保留数据可加copy_data=true) DROP SUBSCRIPTION player_subscription3; CREATE SUBSCRIPTION player_subscription3 CONNECTION 'dbname=game user=gameuser' PUBLICATION player_publication WITH (slot_name='gamesubslot', copy_data=true);
7. 检查数据库日志细节
查看发布端与订阅端的PostgreSQL日志文件(通常在pg_log目录下),搜索replication、subscription、slot相关关键字,定位具体错误(如权限不足、连接失败、表结构不匹配等)。
内容的提问来源于stack exchange,提问作者Skullruss
相关产品推荐
相关产品推荐

