根据开发反馈,最近每天早上7:30应用会报警,应用的日志显示数据库连接池满了,新的连接被拒绝。
首先,我做了ASH报告(报告区间:7:25 ~ 7:35),从ASH的等待事件发现enq: TX - row lock contention居然高达76.54%,如下所示:
Top User Events
Event |
Event Class |
% Event |
Avg Active Sessions |
enq: TX - row lock contention |
Application |
76.54 |
0.81 |
CPU + Wait for CPU |
CPU |
12.76 |
0.14 |
db file sequential read |
User I/O |
7.40 |
0.08
|
enq: TX - row lock contention等待事件是一种行的等待事件,也就是说同一时刻有多个session请求修改同一行。
下一步就是找这个等待事件主要由哪些SQL引起的:
Top SQL with Top Events
SQL ID |
Planhash |
Sampled # of Executions |
% Activity |
Event |
% Event |
Top Row Source |
% RwSrc |
SQL Text |
4rm17788qwxuy |
1272661853 |
54 |
69.45 |
enq: TX - row lock contention |
69.45 |
UPDATE |
69.45 |
update shift_case set expertId... |
1cqbcdr0ufyk6 |
1272661853 |
10 |
5.20 |
enq: TX - row lock contention |
5.20 |
UPDATE |
5.20 |
update shift_case set daySecti... |
1anu5c146v8d7 |
1272661853 |
4 |
1.89 |
enq: TX - row lock contention |
1.89 |
UPDATE |
1.89 |
update shift_case set daySecti... |
gbw4zk8jv0n0u |
2588599834 |
10 |
1.57 |
CPU + Wait for CPU |
0.79 |
TABLE ACCESS - BY GLOBAL INDEX ROWID |
0.47 |
select sc.scId, sc.estId, ct.c... |
dvmk92c1umc97 |
905317021 |
9 |
1.42 |
CPU + Wait for CPU |
1.42 |
CONNECT BY - NO FILTERING WITH START-WITH |
0.63 |
select h.hospitaluuid id, h.pl...
|
从上表可以得出,SQL_ID=4rm17788qwxuy的SQL语句是罪魁祸首,改SQL语句如下:
4rm17788qwxuy |
update shift_case set expertId = :1 , shiftDate = :2 , daySection = :3 , rcLimit = :4 , orderingCount = :5 , shareRccount = :6 , clinicTypeUuid = :7 , fee = :8 , isTimeDivision = :9 , state = :10 , isopen=:11 , stateTime = :12 , updateTime = sysdate where scId
=:13 |
scid是shift_case的主键,也就是说同一时刻有非常多的session在请求更新同一行。
好了,既然已经定位到问题就好办了,马上把应用开发人员找来一问,真相大白:原来该应用需要从外部系统获取数据,为了让内部的数据库和外部的尽量保持一致,每次查询外部系统时,会在数据库里执行update语句。
解决办法也简单:由于每次的Update都会把前一次的update覆盖(等于前面的update做的都是无用功),所以根本没必要每次查询都update,只要最后一次查询做update就可以了。
作者:u010415792 发表于2014-6-4 9:28:56
原文链接