最近有同事遇到某客户数据库产生大量阻塞,等待事件为:enq HW - contention,最开始采用不断杀会话的方式,效果很差,问题一直高频反复。进一步确认SQL是大量的insert,且插入的表中含有LOB字段,根据经验最终采用设置44951 event缓解了该问题。html
具体关于Oracle的44951事件,可参考Maclean的文章:数据库
这篇文章中采用的设置方法是:并发
alter system set events '44951 trace name context forever, level 1024';
须要注意的是,这种设置方法在重启数据库后就会失效,若须要重启后永久生效,需设置event:oracle
alter system set event='44951 trace name context forever, level 1024' scope=spfile;
但说到这里就须要深刻了解下event和events的区别,这里大概测试总结有以下区别:ide
- 1.events当即生效,重启数据库后消失
- 2.events没法直接经过show parameter event查看
- 3.event后面必须有等号,重启数据库后生效,可经过show parameter event查看
- 4.event须要注意不要覆盖掉以前的event设置,若是这个知识点不理解很容易产生误操做,须要特别注意
补充说明: 好比在11g的最佳实践中,一般已经设置10949和28401event:oop
alter system set event='28401 trace name context forever,level 1','10949 trace name context forever,level 1' sid='*' scope=spfile;
因此若是有需求额外设置44951 event,就须要将以前的也写上(不然就会覆盖):测试
alter system set event='28401 trace name context forever,level 1','10949 trace name context forever,level 1','44951 trace name context forever,level 1024' sid='*' scope=spfile;
events设置的值如何查看?使用下面的脚本(注意循环的范围要包含要查询的events):优化
set serveroutput on declare event_level number; begin for i in 10000..50000 loop sys.dbms_system.read_ev(i,event_level); if (event_level > 0) then dbms_output.put_line('Event '||to_char(i)||' set at level '|| to_char(event_level)); end if; end loop; end; /
查询结果相似以下:spa
Event 10949 set at level 1 Event 28401 set at level 1 Event 44951 set at level 1024
附:Maclean使用的测试用例:code
create user maclean identified by maclean; grant resource, connect, dba to maclean; conn maclean/maclean CREATE TABLE "MACLEAN_LOB" ( "T1" VARCHAR2(200) NOT NULL , "T2" CLOB, "T3" CLOB) tablespace users LOB ("T2") STORE AS ( TABLESPACE "USERS" CHUNK 16K PCTVERSION 50 CACHE ) LOB ("T3") STORE AS ( TABLESPACE "USERS" CHUNK 16K PCTVERSION 50 CACHE ); select segment_space_management from dba_tablespaces where tablespace_name='USERS'; exec dbms_workload_repository.create_snapshot; --开3个进程并发插入LOB表 begin for i in 1..10000 loop insert into maclean.maclean_lob values ('ABC',rpad('Z',32000,'L'),rpad('Z',32000,'L')); end loop; commit; end; / exec dbms_workload_repository.create_snapshot; select bytes/1024,segment_name from dba_segments where segment_name in (select segment_name from dba_lobs where table_name='MACLEAN_LOB' and owner='MACLEAN'); truncate table maclean.maclean_lob; select bytes/1024,segment_name from dba_segments where segment_name in (select segment_name from dba_lobs where table_name='MACLEAN_LOB' and owner='MACLEAN'); alter system flush buffer_cache; alter system flush shared_pool; alter system set events '44951 trace name context forever, level 1024'; exec dbms_workload_repository.create_snapshot; --开3个进程并发插入LOB表 begin for i in 1..10000 loop insert into maclean.maclean_lob values ('ABC',rpad('Z',32000,'L'),rpad('Z',32000,'L')); end loop; commit; end; / exec dbms_workload_repository.create_snapshot; select bytes/1024,segment_name from dba_segments where segment_name in (select segment_name from dba_lobs where table_name='MACLEAN_LOB' and owner='MACLEAN'); 以上能够看到虽然设置了44951 level 1024,但并不会由于单次bump hwm的chunks数增长而致使大量空间的浪费。 对比AWR能够发现设置44961 level 1024后 enq HW - contention消耗的DB TIME明显减小: 此外在10.2.0.3以前还有一种方案即设置LOB的PCTVERSION 为0/100,可是该方案会致使LOB占用的SPACE大幅上升,因此不推荐,你有大量的理由至少升级DB到10.2.0.5.9。
经过这个测试用例实验效果,确实设置先后的效果明显:
**注意:**这里主要看enq HW - contention的优化效果,其余event也有调整优化空间,但不在本文讨论范围。
原文出处:https://www.cnblogs.com/jyzhao/p/10340237.html