前言

在一次系统迭代后用户投诉说无法成功登陆系统,经过测试重现和日志定位,最后发现是由于用户在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 - 如何杀死被锁死的进程的更多相关文章

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

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

  2. 杀死正在运行的进程: linux

    1:杀死正在运行的进程:使用ps -aux|grep labor   查出进程PID 2:使用kill  PID  将进程杀死.

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

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

  4. webdriver杀死浏览器和Chromedriver进程

    /**     * 执行dos命令     * @param command     */    public static void command(String command) {       ...

  5. 转:shell杀死指定名称的进程

    #!/bin/sh #根据进程名杀死进程 ] then echo "缺少参数:procedure_name" exit fi PROCESS=`|grep -v grep|grep ...

  6. Windows中杀死某个端口的进程

    最近写项目,总是出现端口被占用的问题,原来傻傻的把电脑重启一下,终于有一天受不了了,想要想办法解决.刚开始从网上找了好多教程,发现不行.开始自己尝试,终于,成功的将占用端口的进程杀掉.在此记录下过程( ...

  7. windows查看和杀死占用端口的进程

    1.首先使用 netstat -ano查看占用端口的进程号 2.然后使用 taskkill /PID (进程号)杀死进程

  8. oracle杀死正在执行的进程

    1 查询目前正在执行的终端和进程, SELECT /*+ rule */ s.username,decode(l.type,'TM','TABLE LOCK','TX','ROW LOCK',NULL ...

  9. windows平台下杀死指定端口的进程(转载)

    在windows命令行窗口下执行: 1.查看所有的端口占用情况 C:\>netstat -ano 协议    本地地址                     外部地址              ...

随机推荐

  1. windows下搭建nginx负载均衡

    学习笔记,第一次记录避免忘记 首先介绍一下本地环境是windows2008 R2-64位. 1.  到nginx官网上下载最新稳定版的安装包,http://nginx.org/en/download. ...

  2. JVM性能优化--类加载器,手动实现类的热加载

    一.类加载的机制的层次结构 每个编写的".java"拓展名类文件都存储着需要执行的程序逻辑,这些".java"文件经过Java编译器编译成拓展名为". ...

  3. 【转载】网站配置Https证书系列(二):IIS服务器给网站配置Https证书

    针对网站的Https证书,即SSL证书,腾讯云.阿里云都提供了免费的SSL证书申请,SSL证书申请下来后,就需要将SSL证书配置到网站中,如果网站使用的Web服务器是IIS服务器,则需要在IIS服务器 ...

  4. HTML5页面介绍

    1.<!DOCTYPE html>     文档声明:用于告诉浏览器使用html哪个版本的标准解析页面,此写法代表使用html5的标准去解析 2.<html>     根标签, ...

  5. for循环的耗时问题

    结论——用变量来缓存数组长度,效率会更高

  6. Django之简介

    一.MVC模型与MTV模型 MVC模型就是Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的.松耦合的方式连接在一起 ...

  7. 数据库管理工具-Navicat Premium 12

    首先感谢下github上大佬,我才能使用这个软件.也可以直接浏览https://github.com/DoubleLabyrinth/navicat-keygen进行安装,非常详细. 1.https: ...

  8. 修改虚拟机磁盘uuid

    cd 到这个目录: C:\Program Files\Oracle\VirtualBox> ####  sethduuid 后为 路径+文件名. VBoxManage internalcomma ...

  9. 2019-ACM-ICPC-徐州站网络赛- I. query-二维偏序+树状数组

    2019-ACM-ICPC-徐州站网络赛- I. query-二维偏序+树状数组 [Problem Description] ​ 给你一个\([1,n]\)的排列,查询\([l,r]\)区间内有多少对 ...

  10. Stock Exchange (最大上升子子串)

    /* 题意: 给定L个整数A1,A2,...,An,按照从左到右的顺序选出尽量多的整数, 组成一个上升序列(子序列可以理解为:删除0个或者多个数,其他的数的吮吸不变). 例如,1,6,2,3,7,5, ...