锁查询及处理

目录
环境
症状
问题原因
解决方案

环境
系统平台:N/A
版本:6.0
症状
数据库锁表后,对锁住的表无法进行改动,严重时会影响业务正常运转。

问题原因
多个会话在同一时间段对相同的数据做了改动,且第一个会话没有立即释放。

解决方案
1、创建测试表

highgo=# select * from hgjob_test033;

 id | name  |         timestart          | count 

----+-------+----------------------------+-------

  1 | job02 | 2021-03-05 17:44:40.885468 |     5

  2 | job02 | 2021-03-05 17:55:30.621806 |     5

  3 | job02 | 2021-03-05 17:59:24.859304 |     5

  4 | job02 | 2021-03-05 17:59:24.859304 |     5

  5 | job02 | 2021-03-05 17:59:24.859304 |     5

  6 | job02 | 2021-03-05 17:59:24.859304 |     5

  7 | job02 | 2021-03-05 17:59:24.859304 |     5

(7 rows)

2、模拟锁情况
窗口一:

highgo=# begin;

BEGIN

highgo=# update hgjob_test033 set name = 'newjob3' where id=2;

UPDATE 1

窗口二:

highgo=# begin ;

BEGIN

highgo=# update hgjob_test033 set name = 'newjob4' where id=2;

【此时会一直卡住不动】

窗口三:

创建锁状态视图

create view viewlocks as

SELECT

    waiting.locktype           AS waiting_locktype, --可锁定对象的类型:relation, extend, page, tuple,transactionid, virtualxid,object, userlock, advisory

    waiting.relation::regclass AS waiting_table,        --等待表

    waiting_stm.query          AS waiting_query,        --等待查询

    waiting.mode               AS waiting_mode,            --这个进程持有的或者是期望持有的锁模式

    waiting.pid                AS waiting_pid,            --持有或者等待这个锁的服务器进程的进程ID ,如果锁是被一个预备事务持有的,那么为空

    other.locktype             AS previous_locktype,        --当前锁的上层锁

    other.relation::regclass   AS previous_table,

    other_stm.query            AS previous_query,

    other_stm.state               AS previous_state,

    other.mode                 AS Previous_mode,

    other.pid                  AS previous_pid,            --等待该pid完成(kill)

    other.GRANTED              AS previous_granted            --如果持有锁,为真,如果等待锁,为假

FROM

    pg_catalog.pg_locks AS waiting

JOIN

    pg_catalog.pg_stat_activity AS waiting_stm

    ON (

        waiting_stm.pid = waiting.pid

    )

JOIN

    pg_catalog.pg_locks AS other

    ON (

        (

            waiting."database" = other."database"

        AND waiting.relation  = other.relation

        )

        OR waiting.transactionid = other.transactionid

    )

JOIN

    pg_catalog.pg_stat_activity AS other_stm

    ON (

        other_stm.pid = other.pid

    )

WHERE

    NOT waiting.GRANTED

AND

    waiting.pid <> other.pid;

3、查询锁状态

highgo=# select * from viewlocks;

 waiting_locktype | waiting_table |                     waiting_query                     | waiting_mode | waiting_pid | previous_locktype | previous_table |    

                previous_query                     |   previous_state    | previous_mode | previous_pid | previous_granted 

------------------+---------------+-------------------------------------------------------+--------------+-------------+-------------------+----------------+----

---------------------------------------------------+---------------------+---------------+--------------+------------------

 transactionid    |               | update hgjob_test033 set name = 'newjob4' where id=2; | ShareLock    |        4384 | transactionid     |                | upd

ate hgjob_test033 set name = 'newjob3' where id=2; | idle in transaction | ExclusiveLock |         4207 | t

(1 row)

4、取消对应操作进程

highgo=# select  pg_cancel_backend(4384);

 pg_cancel_backend 

-------------------

 t

(1 row)



日志打印:

ERROR:  canceling statement due to user request

CONTEXT:  while updating tuple (0,2) in relation "hgjob_test033"

数据状态:

highgo=# select * from hgjob_test033;

 id |  name   |         timestart          | count 

----+---------+----------------------------+-------

  1 | job02   | 2021-03-05 17:44:40.885468 |     5

  3 | job02   | 2021-03-05 17:59:24.859304 |     5

  4 | job02   | 2021-03-05 17:59:24.859304 |     5

  5 | job02   | 2021-03-05 17:59:24.859304 |     5

  6 | job02   | 2021-03-05 17:59:24.859304 |     5

  7 | job02   | 2021-03-05 17:59:24.859304 |     5

  2 | newjob3 | 2021-03-05 17:55:30.621806 |     5

(7 rows)
上一篇:第042讲:魔法方法:算术运算 | 课后测试题及答案


下一篇:C++ 11特性深入学习