oracle 19c 仍然采用密码延时特性,第一次输错延时1秒,第二次输错延时2秒,为了防止暴力破解,延长验证时间。但有些中间件如果因用户改了密码后,建立连接池时会大量连接,就会遇到library cache lock事件导致数据库很卡。
诊断方法如下:
检查问题时段等待事件,如果是library cache lock,找出p3对应的值进行转换,确认命名空间类别(问题出在哪方面),得到对象。
演示脚本
conn.sh:
sqlplus a/b@db1/pdb3 #这里故意用错误密码,正确密码是a
run.sh:
for i in {1..500}
do
nohup sh /tmp/conn.sh &
done
执行:
nohup /tmp/run.sh &
估计30秒结束,top可以看到 cpu的sys%比较高,我猜是因为大量fork进程导致,先不管它。
看看数据库什么状态。
第一步:等待事件:
select event,count(0) cnt
from v$active_session_history where sample_time>sysdate-1/24/60
group by event order by 2;
EVENT CNT
--------------------------- --------------------
Failed Logon Delay 16
library cache lock 120
等待次数很多的就是library cache lock事件。
第二步:获取P3
set num 20
select p3,count(0) cnt from v$active_session_history where event='library cache lock' group by p3 order by 2;
P3 CNT
-------------------- --------------------
5177346 185
5177347 18808
这个p3需要转为16进制
select to_char(5177347,'xxxxxxxxxxxxxxxxxx') p3 from dual;
P3
--------------------------------------
4f0003
经验丰富的就已经知道是啥原因了。
经验不丰富的把4f转换为10进制,确认一下到底问题出在哪个方面。
select to_number('4f','xxxxxxx') p3 from dual;
P3
--------------------
79
确认 namespace 类别
col KGLHDNSD for a35
select distinct KGLHDNSP,KGLHDNSD from x$kglob where KGLHDNSP=79;
KGLHDNSP KGLHDNSD
-------------------- -----------------------------
79 ACCOUNT_STATUS
已经知道答案了吧?
就是在验证密码时会锁定对象。
解决方案是:
alter system set events '28401 trace name context forever,level 1';
进一步验证,抓取awr报告看等待事件。
在19c的awr中明显看到了Failed Logon Delay事件,且Time Model Statistics等待统计中,connection management call elapsed time占比最高。
参考:https://blogs.oracle.com/database4cn/library-cache-lock
如果namespace 是82,说明是语句解析方面可能出了问题。
KGLHDNSP KGLHDNSD
---------- -----------------------------------
82 SQL AREA BUILD
想把错误的sql输出到alert.log,需要设置事件
alter system set events '10035 trace name context forever,level 3';
然后tail -f alert.log等待错误信息输出。
当然,还可以从awr中验证,
Time Model Statistics等待统计中failed parse elapsed time占比较高。
阅读(1809) | 评论(0) | 转发(0) |