[Oracle]记一次由sequence引发的enq sv-contention等待事件

[Oracle]记一次由sequence引发的enq sv-contention等待事件,第1张

概述数据库版本:11.2.0.4 RAC(1)问题现象从EM里面可以看到,在23号早上8:45~8:55时,数据库等待会话暴增,大约到了80个会话。通过查看EM的SQL信息,发现等待产生于SQL语句 (二

数据库版本:11.2.0.4 RAC
(1)问题现象
从EM里面可以看到,在23号早上8:45~8:55时,数据库等待会话暴增,大约到了80个会话。通过查看EM的sql信息,发现等待产生于SQL语句

@H_403_7@select TIMEKEYID.nextval from dual

 

(二)问题追踪
获取AWR报告观察,在top事件中,排名第二的enq:SV-contention

再去查看AWR报告,发现该语句执行频率非常的高,在8:00~9:00期间执行了51万多次。

从执行的语句可以看出,使用到的数据库对象是一个sequence,查询可看到该sequence的语法:

CREATE SEQUENCE MODMGR.TIMEKEYID START WITH 1000 MAXVALUE 999 MINVALUE 0 CYCLE CACHE 100 ORDER;

(1)定位哪些程序执行该sql

select to_char(sample_time,'yyyy-mm-dd hh24:mi:ss') timekey,ash.session_ID,ash."SESSION_SERIAL#",ash."MODulE" --count(*) as sql_countfrom dba_hist_active_sess_history ashwhere ash.instance_number = 1and ash."sql_ID" = 6ac0x1yudr8gq'and ash.sample_time between to_date(2018-12-23 08:00:00',1)">) and to_date(2018-12-23 09:00:00)group by to_char(sample_time,1)">),ash."MODulE"order by timekey;

(2)定位该语句的执行频率

ash.session_ID, ash."SESSION_SERIAL#",1)">ash."MODulE" count(*) as sql_count) ash."MODulE"by timekey;

(3)再把时间扩长一些,查看最近4天的该sql捕获记录,发现其它时间段该sequence的使用并不是如此频繁,真正出问题是在大约23日8:49

select sample_time,ash."MODulE",ash.event2018-12-20 00:00:002018-12-24 00:00:00by sample_time;

至此可以得出结论:
程序BIDmMES在早上8:49产生了大量的“select TIMEKEYID.nextval from dual”语句,导致缓存的100个sequcence快速使用完,缓存使用完后,数据库实例会为其分配新的缓存,异常就发生在分配缓存的时候,Oracle会更新sequence的字典信息,频繁的数据字典更新会导致要使用该sequence的session产生enq:SV-contention等待。

(三)解决方案

如果确认业务没问题,那么需要修改序列的最大值为9999和cache值为1000

alter sequence modmgr.TIMEKEYID maxvalue 9999 cache 1000;

另外,需要考虑,业务上是采用3位的sequence来与其它字符做连接,如果需要保持业务一致,需要截取数字。

(四)案例重现
(1)创建sequence

SEQUENCE b7dba.seq_test START 19999999910 ORDER;

(2)创建一个plsql来消耗seq_test

create or replace procedure p_seq_test is seq_value number ;begin for seq in 1..50 loop select seq_test.nextval into seq_value dual; end loop;end p_seq_test;

(3)创建400个job来调用该pl/sql

procedure create_more_job v_counter number;for v_counter in 1..400 loop declare job1 number; begin sys.dbms_job.submit(job => job1,what => p_seq_test;,next_date sysdate,interval sysdate + 1/(1440*60)' 每隔1s执行一次 ); commitend; end loop;end create_more_job;

(4)通过修改cache来查看等待
alter sequence b7dba.seq_test cache {cache数量};
(4.1)no cacahe

drop SEQUENCE b7dba.seq_test; CYCLE NOCACHE ORDER;

(4.2)cache = 2

drop SEQUENCE b7dba.seq_test;2 ORDER;

(4.3)cache = 10

alter sequence b7dba.seq_test cache 10;

(4.4)cache = 100

100;

(4.5)cache = 1000

1000;

【完】

总结

以上是内存溢出为你收集整理的[Oracle]记一次由sequence引发的enq sv-contention等待事件全部内容,希望文章能够帮你解决[Oracle]记一次由sequence引发的enq sv-contention等待事件所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1153883.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-01
下一篇 2022-06-01

发表评论

登录后才能评论

评论列表(0条)

保存