Oracle某用户连数据库很慢,用sqlplus也很慢,坑爹啊

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12798004/viewspace-1681965/

从Oracle 11.1开始,错误的用户名密码登录可能会导致在数据库层面看到显著的“row cache lock”等待。
很多用户认为这是一个bug,而实际上这是一个数据库保护机制。
Oracle的sqlplus工具会在3次错误密码输入后自动断开连接,但是外部应用程序却可以编码,不断调用登录API进行密码尝试。所以如果没有一个数据库层面的安全控制,这将是非常危险的。
从Oracle 11.1开始,数据库会在对同一个用户3次错误的密码尝试之后,开始锁定这个用户3秒钟,才允许下一次登录。这个锁定时间将从3秒逐渐延长,不断增加。
所有以该用户登录的session都会等待“row cache lock”,哪怕他是用正确的密码登录的。

很多用户不理解这样做是为了帮助用户避免风险,而对看到的“row cache lock”等待提出抱怨。
所以Oracle在Bug 7715339的修复中提供了一个方法(event 28401)来绕过这段代码,来供用户做不同选择。
event="28401 trace name context forever, level 1" # disable logon delay
必须说明的是,这实际上并不是一个bug,而是一个功能增强。用户必须清楚如果设置了这个事件,将使您的数据库暴露在密码猜测的风险之下。

Bug 7715339的修复被包含在11.2.0.1 PSU之中。而在11.1.0.7上打补丁7715339,默认已经相当于打开event 28401了。
在11.2.0.2之后,Oracle修改代码,将这一段“row cache lock”等待修改成了“library cache lock”等待。
总结一下:
1)11.1.0.X上,错误的用户名密码登录,将导致显著的“row cache lock”等待。
用户可以在11.1.0.7上打补丁7715339,不用设置event 28401,就可绕过这段安全控制代码。
2)11.2.0.1上,错误的用户名密码登录,将导致显著的“row cache lock”等待。
用户不用打补丁(因为已经包含在11.2.0.1中了),直接设置event 28401,就可绕过这段安全控制代码。
3)11.2.0.2以上的版本(包含11.2.0.2),错误的用户名密码登录,将导致显著的“library cache lock”等待。
用户不用打补丁(因为已经包含在11.2.0.1中了),直接设置event 28401,就可绕过这段安全控制代码。

必须再次说明的是,用户必须清楚如果打补丁或者设置了这个事件,将使您的数据库暴露在密码猜测的风险之下。

正题:
有用户反馈,即使设置了event 28401,仍会观察到错误的用户名密码登录导致“library cache lock”等待,这是为什么呢?为此,我们做了以下测试进行说明:

起10个进程,同时进行错误的用户名密码登录,并测试未设置event 28401和设置event 28401进行比较,从V$SYSTEM_EVENT中多次观察获取平均等待时间:
select total_waits,Time_waited_fg/total_waits
from V$SYSTEM_EVENT
where event='library cache lock'

未设置event 28401:
91    1395.252747252747252747252747252747252747
98    2352.959183673469387755102040816326530612
106    2687.698113207547169811320754716981132075
116    3495.862068965517241379310344827586206897

<========library cache lock的平均等待时间很快从13.95秒逐渐增加到34.95秒,并且持续增加。

设置event 28401之后:
23142    2.97325209575663296171463140610146054792
24329    3.03592420568046364421061284886349623906

<========即使在24329次等待之后,library cache lock的平均等待时间仍然稳定在0.03秒。

也就是说,event 28401是生效的,“等待时间从3秒逐渐增加的”的安全机制被绕过了,但是“library cache lock”却无法避免。
这是因为,错误的用户名密码登录仍会在数据库内部更新该用户的登录次数,错误登录次数,上次登录时间等信息,需要申请“library cache lock”。
而“library cache lock”的等待时间跟并发登录的进程数和数据库性能有关。
如果有多个用户进行不断的进行错误的密码尝试,可能仍会观察到较高的“library cache lock”等待。
因为“错误的密码尝试”应用程序的代码逻辑一般都是非常疯狂的,正确的登录可能一次就过了,而一旦错误会反复尝试并且没有sleep等待,这将导致一秒钟可能会发起几百次上千次的尝试,
而多个进程并发时就容易观察到平均等待几十毫秒甚至几百毫秒的“library cache lock”了。因为会不断尝试,在数据库层面会累积而很容易观察到。
但是设置event 28401之后,一般不会有几十秒上百秒的单次等待了,因为单次递增的等待机制被绕过了。

总体来讲,数据库管理员应该尽快发现并解决错误的用户名密码登录问题(它们一般是因为数据库密码被更改而应用程序没有及时同步造成的),而不应该过度依赖event 28401。
因为无论从哪个角度来看,错误的用户名密码登录都是一个应用层面的异常问题,是应该被避免的。

ALTER SYSTEM SET EVENT = '28401 TRACE NAME CONTEXT FOREVER, LEVEL 1' SCOPE = SPFILE;

你可能感兴趣的:(Oracle某用户连数据库很慢,用sqlplus也很慢,坑爹啊)