PostgreSQL如何杀死被锁死的进程问题

 更新时间:2024年12月27日 11:43:25   作者:雨临Lewis  
文章总结:文章主要介绍了如何使用PostgreSQL提供的pg_cancel_backend()和pg_terminate_backend()函数来解决数据库表被锁住的问题,以及如何查询哪些表、哪些进程被锁住了

前言

在一次系统迭代后用户投诉说无法成功登陆系统,经过测试重现和日志定位,最后发现是由于用户在ui上进行了某些操作后,触发了堆栈溢出异常,导致数据库里的用户登陆信息表的数据被锁住,无法释放。

这个表里存放的是用户的session信息。

虽然后来解决了问题,但是数据库里这个用户登录信息表里被lock住的数据始终无法释放,这导致用户永远无法登陆成功,需要手动跑SQL把锁去掉才行。

杀掉指定进程

PostgreSQL提供了两个函数:pg_cancel_backend()pg_terminate_backend(),这两个函数的输入参数是进程PID,假定现在要杀死进程PID为20407的进程,

使用方法如下:

select pg_cancel_backend(20407);

--或者执行这个函数也可以:
select pg_terminate_backend(20407);

这两个函数区别如下:

pg_cancel_backend()

  1. 只能关闭当前用户下的后台进程
  2. 向后台发送SIGINT信号,用于关闭事务,此时session还在,并且事务回滚

pg_terminate_backend()

  1. 需要superuser权限,可以关闭所有的后台进程
  2. 向后台发送SIGTERM信号,用于关闭事务,此时session也会被关闭,并且事务回滚

那么如何知道有哪些表、哪些进程被锁住了?

可以用如下SQL查出来:

select * from pg_locks a
join pg_class b on a.relation = b.oid
join pg_stat_activity c on a.pid = c.pid
where a.mode like '%ExclusiveLock%';

这里查的是排它锁,也可以精确到行排它锁或者共享锁之类的。

这里有几个重要的column:

  • a.pid是进程id
  • b.relname是表名、约束名或者索引名
  • a.mode是锁类型

杀掉指定表指定锁的进程

select pg_cancel_backend(a.pid) from pg_locks a
join pg_class b on a.relation = b.oid
join pg_stat_activity c on a.pid = c.pid
where b.relname ilike '表名' 
and a.mode like '%ExclusiveLock%';

--或者使用更加霸道的pg_terminate_backend():
select pg_terminate_backend(a.pid) from pg_locks a
join pg_class b on a.relation = b.oid
join pg_stat_activity c on a.pid = c.pid
where b.relname ilike '表名' 
and a.mode like '%ExclusiveLock%';

另外需要注意的是:

pg_terminate_backend()会把session也关闭,此时sessionId会失效,可能会导致系统账号退出登录,需要清除掉浏览器的缓存cookie(至少我们系统遇到的情况是这样的)。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • PostgreSQL中的XML操作函数代码

    PostgreSQL中的XML操作函数代码

    PostgreSQL中的XML操作函数代码
    2009-09-09
  • springboot 没法扫描到repository的解决

    springboot 没法扫描到repository的解决

    这篇文章主要介绍了springboot 没法扫描到repository的解决,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • postgresql 实现将数组变为行

    postgresql 实现将数组变为行

    这篇文章主要介绍了postgresql 实现将数组变为行的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • 基于Postgresql 事务的提交与回滚解析

    基于Postgresql 事务的提交与回滚解析

    这篇文章主要介绍了基于Postgresql 事务的提交与回滚解析,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • PostgreSQL去掉表中所有不可见字符的操作

    PostgreSQL去掉表中所有不可见字符的操作

    这篇文章主要介绍了PostgreSQL去掉表中所有不可见字符的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • postgresql 中的几个 timeout参数 用法说明

    postgresql 中的几个 timeout参数 用法说明

    这篇文章主要介绍了postgresql中的几个timeout参数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • PostgreSQL11修改wal-segsize的操作

    PostgreSQL11修改wal-segsize的操作

    这篇文章主要介绍了PostgreSQL11修改wal-segsize的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • PostgreSQL数据库时间类型相加减操作

    PostgreSQL数据库时间类型相加减操作

    PostgreSQL提供了许多函数,这些函数返回与当前日期和时间相关的值,下面这篇文章主要给大家介绍了关于PostgreSQL数据库时间类型相加减操作的相关资料,需要的朋友可以参考下
    2023-10-10
  • 使用PostgreSQL数据库进行中文全文搜索的实现方法

    使用PostgreSQL数据库进行中文全文搜索的实现方法

    目前在PostgreSQL中常见的两个中文分词插件是zhparser和pg_jieba,这里我们使用zhparser,插件的编译和安装请查看官方文档 ,安装还是比较复杂的,建议找个现成docker镜像,本文给大家介绍了在PostgreSQL数据库使用中文全文搜索,需要的朋友可以参考下
    2023-09-09
  • PostgreSQL TIMESTAMP类型 时间戳操作

    PostgreSQL TIMESTAMP类型 时间戳操作

    这篇文章主要介绍了PostgreSQL TIMESTAMP类型 时间戳操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12

最新评论