求助:两个经openquery执行的PostgreSQL查询会话卡在killed/rollback状态
解决OpenQuery调用PostgreSQL后会话僵死+内存占用无法释放的问题
这种跨库调用后出现的僵死会话+内存泄漏问题我之前踩过好几次坑,给你几个实用的排查和解决方向:
先清理PostgreSQL端的残留进程
OpenQuery本质是SQL Server作为客户端发起PG查询,有时候SQL Server这边标记会话为killed/rollback,但PG服务器上的查询进程还在后台跑,反过来拖着SQL Server的会话没法结束。你可以登录到PG服务器,执行:SELECT pid, query, state FROM pg_stat_activity WHERE query LIKE '%你的OpenQuery相关内容%';找到对应的进程ID(pid),然后用下面的命令杀掉它:
SELECT pg_terminate_backend(<找到的pid>);做完这个再回去看SQL Server的会话,大概率会自动清理掉。
尝试直接KILL会话SPID(而非UOW)
既然事务GUID是全0,KILL UOW肯定没用,试试直接杀会话的SPID,加上WITH STATUSONLY还能查看回滚进度:KILL <你的会话SPID> WITH STATUSONLY;如果执行后能看到回滚百分比在增长,就耐心等它完成;如果完全没反应,再考虑下一步。
临时释放SQL Server占用的内存
如果内存一直居高不下,可在低峰期手动触发内存回收:DBCC FREESYSTEMCACHE('ALL'); DBCC FREEPROCCACHE;注意这会清空系统缓存和执行计划缓存,可能导致短时间内查询性能下降,所以尽量在业务空闲时操作。另外也检查下SQL Server的
max server memory配置,是不是设得过高导致系统内存被耗尽没法释放。长期避免这类问题的方案
下次用OpenQuery调用PG时,提前做好超时控制:- 在PG的连接字符串里添加
CommandTimeout=300(单位秒,这里设5分钟),避免查询无限制跑下去; - 或者在OpenQuery的SQL语句开头加
SET statement_timeout = 300000;(单位毫秒),直接在PG端限制查询超时; - 尽量避免在OpenQuery中执行大事务,一旦中途取消,回滚过程很容易卡住。
- 在PG的连接字符串里添加
内容的提问来源于stack exchange,提问作者skk
相关产品推荐
相关产品推荐

