PostgreSQL 12.7 DDL操作(删列/删Schema)阻塞问题求助
PostgreSQL 12.7中ALTER TABLE/DROP SCHEMA无响应问题的排查与解决
问题场景
- 使用PostgreSQL 12.7,多Schema对应不同测试环境
- Flyway执行
ALTER TABLE my_table DROP COLUMN my_column时超时,导致Spring Boot启动失败 - 手动执行删列操作一直无响应——目标表仅112行数据,正常应瞬间完成
- 此前同版本PostgreSQL执行
DROP TABLE也出现过类似问题,当时只能在AWS销毁重建数据库,但当前数据库关联多个测试环境,无法采用该方案 - 尝试
DROP SCHEMA my_schema CASCADE,等待10分钟仍无响应,只能取消操作
排查更新
执行了如下查询语句:
SELECT pid, usename, pg_blocking_pids(pid) as blocked_by FROM pg_stat_activity WHERE cardinality(pg_blocking_pids(pid)) > 0 AND query ='ALTER TABLE my_table DROP COLUMN my_column;';
得到结果:
pid | usename | blocked_by -------+----------+----------------------------------------- 29688 | dba_root | {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} (1 row)
取消ALTER TABLE ...操作后,上述查询无结果。
分析与解决步骤
1. 终止异常进程
pg_blocking_pids返回全0数组属于异常状态,说明该DDL进程29688处于非正常锁等待状态,直接终止该进程:
SELECT pg_terminate_backend(29688);
终止后重新尝试执行删列或删Schema操作。
2. 排查长事务
即使当前查询未显示阻塞,也可能存在未提交的长事务持有表锁,导致DDL无法执行。查询运行超过5分钟的长事务:
SELECT pid, usename, query, state, now() - query_start AS duration FROM pg_stat_activity WHERE state IN ('idle in transaction', 'active') AND now() - query_start > interval '5 minutes';
找到对应进程后,用pg_terminate_backend(pid)终止,再执行DDL操作。
3. 检查PostgreSQL日志
查看PostgreSQL日志文件,搜索ALTER TABLE或DROP SCHEMA相关条目,排查是否存在死锁、资源不足或其他错误信息,定位根本原因。
4. 版本升级建议
PostgreSQL 12.7是较老版本,后续12.x补丁版本修复了不少锁和DDL相关的bug。若条件允许,建议升级到12系列最新补丁版本(如12.17),避免同类问题再次发生。
5. 生产环境预验证
在生产环境操作前,务必在测试环境模拟相同场景,验证上述解决步骤的有效性,确保生产操作安全。
内容的提问来源于stack exchange,提问作者Julian
相关产品推荐
相关产品推荐

