一次postgresql锁事件:找到有影响的进程pid并杀掉进程的3种方法

背景:某一个功能测试时发现执操作数据库某张表报错,具体报错信息记不住了。可以查到该数据库中该功能进程的事务信息,该事务操作被其他事务给阻塞了。

以杀掉锁表的进程为例

1) 查询待操作数据库表锁表的进程id

方法1.1)

select oid from pg_class where relname='可能锁表了的表';

select pid from pg_locks where relation='上面查出的oid';

方法1.2)

2) 死锁进程查看pg_stat_activity

方法2.1)

SELECT * FROM pg_stat_activity WHERE datname='数据库名称' and waiting=true;

方法2.2)

3) 杀掉锁表进程,在确认以上pid不影响系统的情况下

select pg_cancel_backend(上面查到的pid);

pg_stat_activity

pg_stat_activity是一个非常有用的视图,可以分析排查当前运行的SQL任务以及一些异常问题。pg_stat_activity 每行展示的是一个“process” 的相关信息,“process”可以理解为一个用户连接。

几个重要的字段:

datname 后端连接到的数据库的名称

procpid  后端的进程id(4.3版本)

pid  后端的进程id(6.0版本)

current_query当前正在执行的查询(4.3版本)

query 如果state为active,为当前正在执行的查询(6.0版本)

state 后端目前的状态包括 active、idle、idle in transaction、idle in transaction  (aborted)、fastpath function call、disabled (6.0版本)。active:后端正在执行一个查询。idle:后端正在等待一个新的客户端命令。idle in transaction:后端在一个事务中,但是当前没有正在执行一个查询。idle in transaction (aborted):与idle  in transaction相似,在该事务中的一个语句导致了一个错误。fastpath function call:后端正在执行一个fast-path函数。 disabled:如果后端中track_activities被禁用,则报告这个状态。

state_change 上次状态切换的时间点(6.0版本)

waiting True当前SQL在锁等待,否则false

waiting_reason 当前执行等待的原因,可能是等锁或者等待节点间数据的复制

client_addr 连接到后端的客户端的IP地址。如果这个域为空,表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程。

client_port 客户端和后端通信的TCP端口号,如果使用 Unix 套接字则为-1

应用场景

1) 查看当前运行中的耗时较长的SQL语句

4.3 版本

select current_timestamp - query_start as  runtime, datname, usename, current_query

    from pg_stat_activity

    where current_query != '<IDLE>'

    order by 1 desc;

6.0 版本

select current_timestamp - query_start as  runtime, datname, usename, query

    from pg_stat_activity

    where state != 'idle'

    order by 1 desc;

2) 异常SQL诊断及修复

4.3 版本

SELECT datname,usename,current_query

  FROM pg_stat_activity

  WHERE waiting;

6.0 版本

SELECT datname,usename,query

  FROM pg_stat_activity

  WHERE waiting;

只能获取当前block的SQL,但找不到原因。相互block的SQL信息

SELECT

      w.current_query as waiting_query,

      w.procpid as w_pid,

      w.usename as w_user,

      l.current_query as locking_query,

      l.procpid as l_pid,

      l.usename as l_user,

      t.schemaname || '.' || t.relname as tablename

    from pg_stat_activity w

    join pg_locks l1 on w.procpid = l1.pid and not l1.granted

    join pg_locks l2 on l1.relation = l2.relation and l2.granted

    join pg_stat_activity l on  l2.pid = l.procpid

    join pg_stat_user_tables t on l1.relation = t.relid

    where w.waiting;

session是query,杀掉阻塞的进程id: SELECT pg_cancel_backend(pid);

session是idle,杀掉阻塞的进程id:SELECT pg_terminate_backend(pid);

pg_locks

pg_locks提供了数据库服务器上打开事务中保持的锁的信息。pg_locks是对每一个活动可锁对象、请求锁模式和相关事务的组合。如果多个事务持有或正在等待一个可锁对象上的锁,同一个可锁对象可能出现很多次。

有多种不同类型的可锁对象:整个关系(如表)、关系的单个页、关系的单个元组、事务ID(包括虚拟和永久ID)和普通数据库对象(由类OID和对象OID标识,和pg_description或pg_depend中的相同方式)。扩展一个关系的权力也被表示为一个独立的可锁对象。"咨询"锁可以具有用户定义的意义。

几个重要的字段:

locktype:可锁对象的类型: relation,  extend, page, tuple, transactionid, virtualxid, object, userlock, or advisory

relation:pg_class.oid 锁目标的关系的OID

pid :保持这个锁或者正在等待这个锁的服务器进程的PID

pg_class

pg_class记载表和几乎所有有字段或者是那些类似表的东西。 包括索引、序列、视图、物化视图、 复合类型和一些特殊关系类型。

几个重要字段:

oid:  行标识符(隐藏属性; 必须明确选择)

relname:表、索引、视图等的名字。

relfilenode:这个关系在磁盘上的文件的名字,0表示这是一个"映射的"关系, 它的文件名取决于行级别的状态。

relpersistence : p = permanent table(永久表), u = unlogged table(未加载的表), t = temporary table (临时表)

relkind :r = ordinary table(普通表) ,  i =  index(索引), S = sequence(序列),  v =  view(视图), m = materialized view (物化视图), c = composite type(复合类型), t =  TOAST table(TOAST 表), f = foreign table(外部表)

pg_cancel_backend和pg_terminate_backend

pg_cancel_backend() 取消后台操作,回滚未提交事物

pg_terminate_backend() 中断session,回滚未提交事物

pg_cancel_backend(pid)杀掉某条sql,是温柔的杀,向后台发送sigint信号,关闭当前后台进程,用户只能关闭自己的后台进程,事务回滚。

pg_terminate_backend(pid)杀掉某条sql,是强杀,向后台发送sigterm信号,关闭当前后台进程,需要有超级用户权限,超级用户可以关闭所有后台进程,事务回滚。

使用pg_cancel_backend杀不掉的进程,但是其实pg_terminate_backend有时也无法杀掉某条sql,笔者在生产环境遇到过,这时我们可能会抓一下该连接的堆栈,然后我们可能想尽快杀掉该sql,问题原因后面再分析,这时我们就要从操作系统层面使用kill命令来杀掉连接了。通过上面查到的pid,在操作系统上ps -ef |grep pid查看当前连接的状态,然后kill -9 pid杀掉该连接。

参考

PostgreSQL死锁进程及慢查询处理

PostgreSQL锁查询与杀掉进程说明

通过pg_stat_activity分析诊断正在执行的SQL

不同版本的pg_stat_activity

pg-locks

pg_cancel_backend和pg_terminate_backend

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,125评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,293评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,054评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,077评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,096评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,062评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,988评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,817评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,266评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,486评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,646评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,375评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,974评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,621评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,642评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,538评论 2 352

推荐阅读更多精彩内容