前言

在一次系统迭代后用户投诉说无法成功登陆系统,经过测试重现和日志定位,最后发现是由于用户在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(至少我们系统遇到的情况是这样的)。

参考链接

  • pg_cancel_backend与pg_terminate_backend函数的区别
  • pg_cancel_backend()和pg_terminate_backend()

PostgreSQL - 如何杀死被锁死的进程相关推荐

  1. 检查并杀死mysql锁死的进程

    SHOW OPEN TABLES WHERE In_use > 0; # 检查锁死 SHOW PROCESSLIST # 查看进程 KILL 347383;# 杀死进程

  2. C#一键显示及杀死占用端口号进程

    private void t_btn_kill_Click(object sender, EventArgs e){int port;bool b = int.TryParse(t_txt_guard ...

  3. Linux中使用ps、awk、sh一起批量杀死所有的dotnet进程。

    一.操作 Linux中使用ps.awk.sh一起批量杀死所有的dotnet进程. 二.参考命令 ps -ef|grep dotnet|awk 'NR==2{print "kill " ...

  4. C#如何得到运行中和杀死运行中的进程?

    C#如何得到运行中和杀死运行中的进程? 得到所有进程且杀死QQ的进程: foreach (System.Diagnostics.Process thisproc in System.Diagnosti ...

  5. 教你两式妙招杀死“顽固不化”的病毒进程-

    来源:电脑报 根据进程名查杀 这种方法是通过WinXP系统下的taskkill命令来实现的,在使用该方法之前,首先需要打开系统的进程列表界面,找到病毒进程所对应的具体进程名. 接着依次单击" ...

  6. 帮你强行杀死顽固不化的病毒进程

    笔者在这里为大家提供两则小技巧,以便帮你强行杀死"顽固不化"的病毒进程. 根据进程名查杀 这种方法是通过WinXP系统下的taskkill命令来实现的,在使用该方法之前,首先需要打 ...

  7. 两式妙招 杀死“顽固不化”的病毒进程

    这种方法是通过WinXP系统下的taskkill命令来实现的,在使用该方法之前,首先需要打开系统的进程列表界面,找到病毒进程所对应的具体进程名. 接依次单击"开始→运行"命令,在弹 ...

  8. 教你两式妙招杀死“顽固不化”的病毒进程

    笔者在这里为大家提供两则小技巧,以便帮你强行杀死"顽固不化"的病毒进程. 根据进程名查杀 这种方法是通过WinXP系统下的taskkill命令来实现的,在使用该方法之前,首先需要打 ...

  9. 杀死所有的tomcat进程

    杀死所有的tomcat进程 大佛拈花 大佛拈花 今天 我们在平时使用tomcat的过程中需要杀死某个或者某几个tomcat进程,一般都使用的命令是  ps -ef|grep tomcat来获取对应的进 ...

最新文章

  1. 视频|深度相机与应用
  2. MVC应用程序播放RealPlayer(rmvb)视频
  3. 【NetApp】关于Snapmirror强制停止的一点记录
  4. Centos6.2上做nginx和tomcat的集成及负载均衡(已实践)
  5. Ext.data.reader.Json reader: json
  6. c语言boolean作为全局变量_最容易忽略的C语言知识点细节,编程大牛进阶之路!...
  7. python代码规范链接
  8. 3、Angular JS 学习笔记 – Controllers [翻译中]
  9. php国外地址生成,thinkphp url生成
  10. TCP 三次握手 和 四次挥手
  11. dirname和basename命令
  12. java 写入环境变量_Java环境变量配置 - import_key的个人空间 - OSCHINA - 中文开源技术交流社区...
  13. 2_C语言中的数据类型 (六)浮点数
  14. form表单属性名相同java_form表单提交 list对象给Java 后台结合
  15. Netty工作笔记0041---Netty入门--服务端2
  16. LeetCode:每日一题(2020.4.7)
  17. 寻找关键之年的榜样和标准
  18. 《麻省理工公开课:线性代数》中文笔记来了!
  19. openssl生成自签名证书流程
  20. 有看板娘的vuepress-theme-ting清新简易主题

热门文章

  1. 微软75亿美元收购ZeniMax及其旗下工作室;KPS同意21亿美元收购Garrett全部资产 | 美通企业日报...
  2. Java 数组和List的使用
  3. 如何为Win10开启DoH(DNS over HTTPS)
  4. 第十三课、类族的结构进化-------------------狄泰软件学院
  5. Google Play 商品详情,考试内容
  6. 9月赠书活动名单公布啦!
  7. 包和工具(读书笔记)
  8. 解决办法: Cannot resolve the collation conflict between Japanese_CI_AS and SQL_...
  9. QT人机交互(动态界面)
  10. 自制COREXY结构的3D打印机