8.1 enq:HW-contention
为防止多个进程同时修改HWM而提供的锁称为HW锁,想要移动HWM的进程必须获得HW锁。若在获取HW锁过程中发生争用,
则等待enq:HW-contention事件。
HW锁争用大部分是因为大量执行Insert所引起的,偶尔也会因大量执行Update在回滚段中发生HW锁争用现象。若是Upate,表中段的扩展的大小虽然不多,
但在创建回滚数据的过程中,需要回滚段的急速扩张。HW锁争用是在段的急速空间扩展时普遍出现的等待现象,有时也会引发严重的性能下降。
HW锁的ID1值是表空间的编号,ID2值是段头块的DBA。因此利用v$lock视图或v$session_wait视图,可以确认发生HW锁争用的表空间和段。
与之前讨论的内容相同,段空间管理方法大体上分为FLM和ASSM(segemnet管理方法)
使用FLM时,特别是HW锁争用称为问题的情况较多,这是因为在使用FLM时,决定HWM移动的FREELIST属性的缺省值设置为1.
接下来测试一下,同时大量执行Inert操作引发的enq:HW-contention 等待的情况,测试方案如下:
1)创建使用FLM的表孔空间HWM_TEST_TBS
2)表空间HWM_TEST_TBS里创建表HWM_TEST,为了增加Insert的负荷,表HWM_TEST的每个块都将存储一个行
3)确认6个会话上同时执行Insert时发生的HW锁争用
【测试32】FLM和HW锁争用:
---创建使用FLM的表空间:
create tablespace hwm_test_tbs
datafile '/u03/oradata/hwm01.dbf' size 100M
autoextend on
extent management local uniform size 1M
segment space management manual;
--因为块大小等于8K,每个块存储一个行
--因为块大小等于8K,所以创建7.K的行,则一个行占据一个块。
--PCTFREE=10,因此一个行在8K*0.9=7.2K以上,就可以占据一个块。
drop table hwm_test purge;
create table hwm_test(
name1 char(2000) default '',
name2 char(2000) default '',
name3 char(2000) default '',
name4 char(1500) default '')
tablespace hwm_test_tbs;
---执行大量Insert操作的Procedure
SQL> create or replace procedure massive_insert
is
begin
loop
insert into hwm_test(name1) values(' ');
commit;
end loop;
end;
2 3 4 5 6 7 8 9
10 /
Procedure created.
---5个会话同时执行大量的Insert
SQL> select sid,event,p1,p1raw,p2,p3 from v$session where event not like '%message%';
SID EVENT P1 P1RAW P2 P3
---------- ---------------------------------------------------------------- ---------- ---------------- ---------- ----------
1588 enq: HW - contention 1213661190 0000000048570006 13 67108873
1589 enq: HW - contention 1213661190 0000000048570006 13 67108873
1617 enq: HW - contention 1213661190 0000000048570006 13 67108873
1623 Streams AQ: qmn slave idle wait 0 00 0 0
1624 buffer busy waits 16 0000000000000010 2059 1
1630 jobq slave wait 0 00 0 0
1634 Streams AQ: waiting for time management or cleanup tasks 0 00 0 0
1636 enq: HW - contention 1213661190 0000000048570006 13 67108873
1641 enq: HW - contention 1213661190 0000000048570006 13 67108873
1643 Streams AQ: qmn coordinator idle wait 0 00 0 0
1649 smon timer 300 000000000000012C 0 0
SID EVENT P1 P1RAW P2 P3
---------- ---------------------------------------------------------------- ---------- ---------------- ---------- ----------
1651 log file parallel write 1 0000000000000001 80 2
1654 pmon timer 300 000000000000012C 0 0
13 rows selected.
SQL> select * from v$lock where type in ('TM','TX');
ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
0000000088182D88 0000000088182DB0 1589 TM 167011 0 3 0 0 0
0000000088182E88 0000000088182EB0 1588 TM 167011 0 3 0 0 0
0000000088182F88 0000000088182FB0 1617 TM 167011 0 3 0 0 0
0000000088183088 00000000881830B0 1624 TM 167011 0 3 0 0 0
0000000088183188 00000000881831B0 1641 TM 167011 0 3 0 0 0
0000000088183288 00000000881832B0 1636 TM 167011 0 3 0 0 0
6 rows selected.
SQL>
select object_name from dba_objects where object_id=167011SQL> ;
OBJECT_NAME
--------------------------------------------------------------------------------------------------------------------------------
HWM_TEST
利用enq: HW - contention 的p1,p2,p3参数来确定
SQL> select parameter1,parameter2,parameter3 from v$event_name where name='enq: HW - contention';
PARAMETER1 PARAMETER2 PARAMETER3
---------------------------------------------------------------- ----------------------------------------------------------------
name|mode table space # block
p3 是block
SQL> select dbms_utility.data_block_address_file(67108873) file_id,dbms_utility.data_block_address_block(67108873) block_id from dual;
FILE_ID BLOCK_ID
---------- ----------
16 9
SQL> select segment_name from dba_extents where file_id=16 and 9 between block_id and block_id+blocks;
SEGMENT_NAME
---------------------------------------------------------------------------------
HWM_TEST