Process 23178 Still Waiting For ShareLock on Transaction 693345717 After 1000.363 ms

昨天一生产库出现异常,短时间内负载较高( LOAD 达到 5 ), 查看了下数据库日志,发现了有大量以下日志。生产库日志

1
2011-11-03 06:50:30.459 CST,"mpc_db_account","mpc_db_account",23178,"192.168.104.51:51196",4eb112db.5a8a,65,"UPDATE waiting",2011-11-02 17:52:27 CST,42/1784416,693346019,LOG,00000,"process 23178 still waiting for ShareLock on transaction 693345717 after 1000.363 ms",,,,,,"update mpc_user_basic_info set nickname = '/<u?o/ay', sex = 1, birthday = '1991-01-01', mobile = '', province = '', city = '', signature = '', head_icon = 0, country_code = 452 where user_id = 229898411",,,""

备注:信息 process 23178 still waiting for ShareLock on transaction 693345717 after 1000.363 ms虽然知道这说明数据库有行锁等侍,但 transaction 后面的数值 693345717 是什么含义呢?是指事务ID么? 带着这个疑问在测试环境做一下测试。

创建测试表

创建测试表并插入数据

1
2
3
4
5
6
7
8
9
10
11
12
skytf=> create table test_65 (id integer,name varchar(32));  
CREATE TABLE
skytf=> insert into test_65 values (1,'a');
INSERT 0 1
skytf=> insert into test_65 values (2,'b');
INSERT 0 1
skytf=> insert into test_65 values (3,'c');
INSERT 0 1
skytf=> insert into test_65 values (4,'d');
INSERT 0 1
skytf=> insert into test_65 values (5,'e');
INSERT 0 1

session A

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
skytf=> begin;  
BEGIN

skytf=> select txid_current();
txid_current
--------------
21192006
(1 row)

skytf=> update test_65 set name='aaa' where id=1;
UPDATE 1
skytf=> update test_65 set name='bbb' where id=2;
UPDATE 1
skytf=> update test_65 set name='ccc' where id=3;
UPDATE 1

备注:首先开启 session A, 更新三条记录,并不提交,此时的事务ID为 21192006。

session B

1
2
3
4
5
6
7
8
9
skytf=> begin;  
BEGIN

skytf=> select txid_current();
txid_current
--------------
21192007

skytf=> update test_65 set name='aaa' where id=1;

备注:再开一个事务 session B, 更新 id=1 的记录,此时 session B 在等付, 事务ID为 21192007。

session C

session 主要负责监控当前会话

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
skytf=> select datname,procpid,current_query from pg_stat_activity where datname='skytf';  
datname | procpid | current_query
---------+---------+-----------------------------------------------------------------------------------
skytf | 7890 | select datname,procpid,current_query from pg_stat_activity where datname='skytf';
skytf | 16706 | <IDLE> in transaction
skytf | 16656 | update test_65 set name='aaa' where id=1;
(3 rows)

skytf=> select database,relation,pid,mode, granted,transactionid from pg_locks where relation=16920668;
database | relation | pid | mode | granted | transactionid
----------+----------+-------+------------------+---------+---------------
14203071 | 16920668 | 16656 | AccessShareLock | t |
14203071 | 16920668 | 16656 | RowExclusiveLock | t |
14203071 | 16920668 | 16706 | RowExclusiveLock | t |
14203071 | 16920668 | 16656 | ExclusiveLock | t |
(4 rows))

备注:事务 session C, 查询当前会话信息和锁等侍情况。

数据库日志 (csv log)

1
2011-11-04 11:07:11.120 CST,"skytf","skytf",16656,"127.0.0.1:53640",4eb3566b.4110,1,"UPDATE waiting",2011-11-04 11:05:15 CST,61/402,21192007,LOG,00000,"process 16656 still waiting for ShareLock on transaction 21192006 after 1000.962 ms",,,,,,"update test_65 set name='aaa' where id=1;",,,"psql"

备注: 注意信息 “process 16656 still waiting for ShareLock on transaction 21192006 after 1000.962 ms” ,transaction 后面的事务值为 21192006, 正好是会话 A 的事务ID。

原因分析

出现 “process 16656 still waiting for ShareLock on transaction 21192006 after 1000.962 ms” 问题的原因很多的,个人觉得主要是以下方面的原因:

  1. 应用程序逻辑设计不合理,没有及时提交更新(update)事务;
  2. 被更新的表上索引太多,降低表上的更新操作( update/delete/insert )性能;
  3. 数据库负载高,导致 update 语句执行效率降低,耗时增加,当前端页面没及时返回时,出现重复更新同一记录的情况。

原创文章,作者:506227337,如若转载,请注明出处:https://blog.ytso.com/237806.html

(0)
上一篇 2022年1月29日
下一篇 2022年1月29日

相关推荐

发表回复

登录后才能评论