You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL单表查询卡顿、无法访问的故障原因咨询

问题根因

故障本质是强制终止导入脚本时,对应数据库连接未正常触发事务回滚和连接退出,残留了持有目标表AccessExclusiveLock的僵尸会话。所有对该表的读写、DDL操作都会排队等待这个排他锁释放,因此会无限期卡住。
日志中记录的WAL无效记录、异常自动恢复是实例此前异常关机的历史日志,对应恢复流程已经执行完成、实例正常对外提供服务,和本次单表访问故障无关联。

排查步骤
  • 连接数据库后执行以下SQL,定位持有锁的阻塞会话:
SELECT
  blocked.pid AS blocked_pid,
  blocked.query AS blocked_query,
  blocking.pid AS blocking_pid,
  blocking.query AS blocking_query,
  blocking.state AS blocking_state,
  blocking.wait_event_type AS blocking_wait_type,
  blocking.wait_event AS blocking_wait_event
FROM pg_locks blocked_lock
JOIN pg_stat_activity blocked ON blocked.pid = blocked_lock.pid
JOIN pg_locks blocking_lock 
  ON blocking_lock.locktype = blocked_lock.locktype
  AND blocking_lock.database IS NOT DISTINCT FROM blocked_lock.database
  AND blocking_lock.relation IS NOT DISTINCT FROM blocked_lock.relation
  AND blocking_lock.pid != blocked_lock.pid
JOIN pg_stat_activity blocking ON blocking.pid = blocking_lock.pid
WHERE NOT blocked_lock.granted;
  • 查询结果中重点筛选状态为idle in transaction、关联query为你之前执行的导入语句、无有效等待事件的会话,即为残留的锁持有会话。
修复方案
  • 拿到阻塞会话的pid后,执行以下SQL终止该僵尸会话,DigitalOcean托管数据库的默认管理员账号有权限执行该操作,无需重启实例:
SELECT pg_terminate_backend(替换为上一步查到的阻塞会话pid);
  • 执行完成后再次运行排查步骤的锁查询SQL,确认目标表无残留未释放的锁,此时对该表的查询、删除操作即可正常执行。
规避建议
  • 后续中断运行中的数据库操作脚本时,优先通过数据库侧终止对应会话,不要直接强杀本地脚本进程,避免连接未正常退出导致事务和锁残留。
  • 使用psycopg2编写导入脚本时,建议配置statement_timeout参数限制单语句最长执行时间,同时增加异常捕获逻辑,脚本异常退出时主动提交/回滚事务、关闭连接。

内容的提问来源于stack exchange,提问作者Zsámboki Attila

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 07:09:18