某政府客户,近期不断有数据库性能问题。某日,应用维护人员请求DBA介入杀会话, 因业务办理很不顺畅。
首先看到有严重的阻塞:

从gv$session_blockers可以看出,被阻塞的会话有156个。业务基本上已经进行不下去了。
通过以下SQL查询阻塞的源头:
select distinct b.blocker_instance_id, b.blocker_sid, b.blocker_sess_serial# from gv$session_blockers b where not exists (select 1 from gv$session_blockers a where a.inst_id=b.blocker_instance_id
and a.sid=b.blocker_sid and a.sess_serial# = b.blocker_sess_serial#);
定位了阻塞的会话之后,在数据库中kill掉会话,或者直接通过操作系统杀掉
定位操作系统进程编号:
Select spid from v$session s, v$process p where s.paddr = p.addr and s.sid = <查询到的阻塞者的会话SID>
通过确认会话属于客户端会话之后,在操作系统层面进行kill
杀掉若干会话之后,阻塞情况有好转。
接下来诊断为何会有如此之多的阻塞。查看gv$session, 发现很多会话存在SQL*Net message froom dblink的等待事件


此类等待的会话有293个之多,而且均来自于JDBC客户端。
通过gv$session_blockers视图中的blocker_instance_id, blocker_sid, blocker_serial#查了几个会话的等待,发现均是dblink。尝试杀掉一个会话,直接通过alter system kill session,提示session marked for kill, 无奈,只好找到会话的进程编号,从操作系统层面杀掉了。
相关会话最终全部被kill掉,系统也恢复了正常。
从AWR报告分析,很多SQL是通过dblink去查询其他数据库, 大部分的阻塞,也与执行dblink相关查询会话无法返回有关,会话hang住。这引起了我的思考。相关的SQL即使性能再糟糕,也不应当有如此之多的会话hang住,开始怀疑是Oracle的bug。搜索MOS, 发现疑似bug: 17308789


从数据库版本(客户数据库版本为11.2.0.3), 客户端是JDBC,故障现象是会话hang住这些方面来看,现象比较吻合。但是因为客户数据库在exadata之上,并无相关补丁。
最终给客户建议:
1. 修改应用, 避免在JDBC客户端中使用DBLINK。可以采用OGG等方式进行不同数据库之间的数据交互。
2. 尽量优化相关SQL
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/8520577/viewspace-2713271/ ,如需转载,请注明出处,否则将追究法律责任。