昨天一生产库出现异常,短时间内负载较高( 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 |
skytf=> create table test_65 (id integer,name varchar(32)); |
session A
1 |
skytf=> begin; |
备注:首先开启 session A, 更新三条记录,并不提交,此时的事务ID为 21192006。
session B
1 |
skytf=> begin; |
备注:再开一个事务 session B, 更新 id=1 的记录,此时 session B 在等付, 事务ID为 21192007。
session C
session 主要负责监控当前会话
1 |
skytf=> select datname,procpid,current_query from pg_stat_activity where datname='skytf'; |
备注:事务 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” 问题的原因很多的,个人觉得主要是以下方面的原因:
- 应用程序逻辑设计不合理,没有及时提交更新(
update
)事务; - 被更新的表上索引太多,降低表上的更新操作(
update/delete/insert
)性能; - 数据库负载高,导致 update 语句执行效率降低,耗时增加,当前端页面没及时返回时,出现重复更新同一记录的情况。
原创文章,作者:506227337,如若转载,请注明出处:https://blog.ytso.com/237806.html