PostgreSQL强制删除存在运行中复制的数据库方法
PostgreSQL 强制删除存在活跃复制槽的目标数据库操作方案
之前操作未生效的核心原因有两点:一是仅在订阅端操作无法清理发布端残留的复制槽,二是复制槽被walsender进程持有时,常规删订阅操作无法释放槽位占用。按以下顺序操作即可完成强制删除:
1. 定位并清理所有关联复制槽
首先连接到实例下的postgres默认库,查询目标库关联的所有复制槽信息:
SELECT slot_name, slot_type, active, active_pid, database FROM pg_replication_slots WHERE database = '待删除的目标数据库名';
对查询结果中状态为active=t的活跃复制槽,先终止其持有的后端进程:
-- 将{pid}替换为查询结果中对应active_pid的实际值 SELECT pg_terminate_backend({pid});
确认所有关联复制槽的active状态变为f后,手动删除残留复制槽:
-- 将{slot_name}替换为查询结果中对应slot_name的实际值 SELECT pg_drop_replication_slot('{slot_name}');
注意:逻辑复制的复制槽是存在于发布端实例上的,如果你的复制关系跨实例,必须登录发布端所在的PostgreSQL实例执行上述复制槽清理操作,仅在订阅端执行禁用、删订阅操作不会自动清理发布端的残留槽位,这是绝大多数同类操作失效的核心原因。
2. 清理本地残留的复制关联对象
登录目标库所在实例,清理残留的订阅、发布对象:
-- 连接到目标库执行,删除残留订阅 DROP SUBSCRIPTION IF EXISTS aaa; -- 删除不需要的残留发布对象 DROP PUBLICATION IF EXISTS 关联的发布名;
3. 终止残留连接后执行删库
回到postgres库,先终止目标库上的所有残留连接,再执行删库操作:
-- 终止目标库所有非当前进程的连接 SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '待删除的目标数据库名' AND pid <> pg_backend_pid(); -- 执行删库,PostgreSQL 13及以上版本可加FORCE参数强制断开连接 DROP DATABASE 待删除的目标数据库名 WITH (FORCE);
- 不要通过直接修改pg_database等系统表的方式删除数据库,会造成实例元数据不一致,触发后续集群故障。
- 操作前确认目标库无需要留存的业务数据,删库操作不可逆。
内容的提问来源于stack exchange,提问作者user1409708
相关产品推荐
相关产品推荐

