PostgreSQL逻辑复制失败:无法删除不存在的复制槽及槽耗尽报错如何解决?
PostgreSQL逻辑复制报错:复制槽用尽+无效槽删除失败的处理
错误核心信息
ERROR: could not create replication slot "pg_148211637_sync_148178452_7161337762731575223": ERROR: all replication slots are in use May 2 07:43:01 psql-06 postgres[1195903]: [2] HINT: Free one or increase max_replication_slots. May 2 07:43:01 psql-06 postgres[1181479]: [1] LOG: background worker "logical replication worker" (PID 1195903) exited with exit code 1 May 2 07:43:01 psql-06 postgres[1195905]: [1] LOG: logical replication table synchronization worker for subscription "sub_production", table "products" has started May 2 07:43:01 psql-06 postgres[1195901]: [1] LOG: could not drop replication slot "pg_148211637_sync_148183118_7161337762731575223" on publisher: ERROR: replication slot "pg_148211637_sync_148183118_7161337762731575223" does not exist
问题原因
- 发布端复制槽配额耗尽:
max_replication_slots参数设置的值不足以支撑当前复制需求,新的表同步任务无法创建所需临时复制槽。 - 订阅端与发布端元数据不一致:之前的同步任务因异常中断(如网络故障、进程崩溃),订阅端本地记录了一个已在发布端被清理的复制槽ID,导致后续持续尝试删除不存在的槽,陷入循环报错。
解决步骤
1. 处理发布端复制槽不足问题
查看当前复制槽使用情况
登录发布端执行SQL:
SELECT slot_name, plugin, slot_type, active FROM pg_replication_slots;
active = true表示该槽正在使用,false表示闲置。
清理闲置复制槽
确认闲置槽无业务用途后,执行删除:
SELECT pg_drop_replication_slot('闲置槽的名称');
增大复制槽配额(无闲置槽可清理时)
修改postgresql.conf中的max_replication_slots参数(比如从默认10调整为20),然后重载配置或重启服务:
-- 动态修改(PostgreSQL 12+支持) ALTER SYSTEM SET max_replication_slots = 20; -- 重载配置生效 SELECT pg_reload_conf();
若动态修改不生效,直接修改配置文件后重启PostgreSQL服务。
2. 修复订阅端元数据不一致问题
暂停订阅
登录订阅端执行:
ALTER SUBSCRIPTION sub_production DISABLE;
重置订阅同步状态
执行刷新发布命令,清除无效槽记录:
ALTER SUBSCRIPTION sub_production REFRESH PUBLICATION WITH (copy_data = false);
copy_data = false用于避免重新全量复制数据(若订阅端表数据已与发布端一致),数据不一致则去掉此参数。
重启订阅并验证
ALTER SUBSCRIPTION sub_production ENABLE;
之后查看订阅端日志确认无报错,同时在发布端执行SELECT * FROM pg_replication_slots;验证同步槽正常创建并处于活跃状态。
3. 极端情况处理(上述步骤无效时)
若订阅端元数据损坏严重,可删除订阅后重新创建:
-- 删除订阅 DROP SUBSCRIPTION sub_production; -- 重新创建(根据实际发布配置调整参数) CREATE SUBSCRIPTION sub_production CONNECTION 'host=发布端IP port=5432 dbname=数据库名 user=用户名 password=密码' PUBLICATION pub_production WITH (copy_data = false); -- 数据一致时用此参数,否则去掉
内容的提问来源于stack exchange,提问作者Niels Kristian
相关产品推荐
相关产品推荐

