上周五,接到项目组同事电话通知,说某客户应用系统无法登陆。我在应用服务器端用PL/SQL Developer尝试连接数据库服务器时,报错“ORA-00018:maximum number of sessions exceeded”,显然又是连接数不够用了。
就电话回复同事说,赶紧检查一下各应用服务器的连接情况,原因是数据库连接数又不够用了。结果,同事接完电话之后,直接关闭了其中的一台IIS应用服务器,然后再启动这台IIS应用服务器。结果是,应用系统恢复了使用,大约20分钟后,却带了整个数据库的性能急剧下降,数据库Hung住,几乎不可用的状态。
这是一套Windows 2003+10.2.0.5 X64的双节点RAC系统,接下来,就迅速抓取AWR报告,进行问题的定位:
节点1的报告头:
Snap Id | Snap Time | Sessions | Cursors/Session | |
---|---|---|---|---|
Begin Snap: | 6981 | 01-3月 -13 14:00:17 | 64 | 14.9 |
End Snap: | 6982 | 01-3月 -13 15:00:13 | 186 | 17.2 |
Elapsed: | 59.94 (mins) | |||
DB Time: | 2,215.01 (mins) |
节点2的报告头:
Snap Id | Snap Time | Sessions | Cursors/Session | |
---|---|---|---|---|
Begin Snap: | 6981 | 01-3月 -13 14:00:14 | 65 | 14.2 |
End Snap: | 6982 | 01-3月 -13 15:14:21 | 178 | 25.0 |
Elapsed: | 74.12 (mins) | |||
DB Time: | 2,991.16 (mins) |
从上可以看到,在每个节点上,这一时段的数据库负载都很高,至少要比正常业务期间负载高出很多。同时,也看到,数据库连接数出现较为不太正常的连接。
节点1的Top 5事件:
Event | Waits | Time(s) | Avg Wait(ms) | % Total Call Time | Wait Class |
---|---|---|---|---|---|
db file sequential read | 210,093 | 48,731 | 232 | 36.7 | User I/O |
enq: US – contention | 73,040 | 36,420 | 499 | 27.4 | Other |
log file sync | 146,401 | 14,330 | 98 | 10.8 | Commit |
row cache lock | 11,636 | 13,801 | 1,186 | 10.4 | Concurrency |
CPU time | 9,314 | 7.0 |
节点2的Top 5事件:
Event | Waits | Time(s) | Avg Wait(ms) | % Total Call Time | Wait Class |
---|---|---|---|---|---|
row cache lock | 33,305 | 49,524 | 1,487 | 27.6 | Concurrency |
enq: US – contention | 94,368 | 46,710 | 495 | 26.0 | Other |
db file sequential read | 450,346 | 38,795 | 86 | 21.6 | User I/O |
CPU time | 16,797 | 9.4 | |||
direct path write temp | 18,587 | 13,857 | 746 | 7.7 | User I/O |
看到,在2个节点上均出现了row cache lock和enq: US – contention的等待事件,尤其是第2个节点上更为严重。对于row cache lock等待事件,之前曾遇到过相关案例,原因同样是由于高并发的RAC环境下,sequence没有CACHE,迅速定位并解决了这个问题。
那么,这个enq: US – contention等待事件究竟是什么呢?Google之,找到了类似的案例:异常终止会话导致系统被Hung,以及ITPUB上的一篇帖子:row cache lock+us contention=宕机
原来,导致enq: US – contention等待事件的原因是Undo表空间不够导致的。结合上述案例的提示,原来是因为同事直接停止IIS应用服务器,导致Oracle需要回滚之间的事务,这样,如果之前的事务比较大的话,那么整个回滚的时间也将越长。同时,还有一种可能就是,当初的ACTIVE事务因为停止IIS导致了被强制终止,这样一来,该事务占有的回滚段资源没有释放出来。等到IIS重启之后,新连接上来的会话因为事务操作,需要分配新的UNDO表空间,结果导致了enq: US – contention等待事件。
参照上述的两则案例,找出紧急解决办法,由于是RAC,这里交叉重启了2个节点,最后问题得到解决。