等待事件之enq: HW - contention
作者:互联网
等待事件之enq: HW - contention
SELECT *
FROM V$EVENT_NAME
WHERE NAME IN
('enq: HW - contention');
SELECT * FROM V$LOCK_TYPE D WHERE D.TYPE='HW';
主要用来控制特定对象空间分配时的并发操作。v$lock中的id1为表空间编号ts#,id2为需要分配空间的对象segment header的相对DBA(Data Block Address)位置。
争用主要发生在高并发大量插入时,甚至表中若有LOB字段时情况更糟,或手工对该对象ALLOCATE/DEALLOCATE空间时。HWM的推进分配新空间的速度赶不上并发会话所需空间的速度时,就会发生在HW的ENQ上的等待。
TABLE的High WaterMark(即高水位线)标识table segment中已用空间和未用空间的边界,具体来讲,HWM以上的block的状态是:unformattedand have never been used; HWM以下的block的状态是:Allocated, but currentlyunformatted and unused、 Formatted and contain data、Formatted and empty because the data was deleted。当HWM以下的block都无空闲空间可以使用时,Oracle会推进HWM来申请分配新的block到segment里面,而HW enqueue锁被用来管理推进HWM分配新空间时的串行操作。
解决思路:
?删除无用索引。
?改造为HASH分区表。同一时间的并发的空间分配需求会被打散到多个分区段上。
?提前手工allocatenew空间(可以做成定期自动任务)。
?主动shrink回收可以重用的空间,避免业务高峰期的自动allocate竞争。
?设置表空间更大的UNIFORM SIZE,每次allocate更多extent到表的HWM之上,避免HWM剧烈时偶尔还会等在表空间的extent分配上。
?确保使用ASSM (Automatic segment spacemanagement) tablespace。
?隐含参数_bump_highwater_mark_count,可以控制HWM每次推进的block个数。但是设置该隐含参数应该得到Oracle的支持,而且对其它小表有负面影响。
?检查IO子系统性能,有时候IO性能的变化也会导致空间分配操作缓慢,进而引发等待。
?LOB段空间的频繁重回收,可能也会导致该竞争,针对LOB可以适当增加chunk,每次分配更多空间;也可以主动allocate 或shrink
?另外针对使用ASSM表空间的LOB有一个Bug 6376915注意检查是否已applied fixed patch,并且要通过设置event来启用。此event用于控制1次LOB chunk回收操作时的chunk个数(default是1),进而可以减少HWM enq等待发生的次数。
?EVENT="44951 TRACE NAME CONTEXT FOREVER, LEVEL < 1 -1024 >"
为防止多个进程同时修改HWM而提供的锁称为HW锁(官方文档解释:Space management operations on a specific segment)。想要移动HWM的进程必须获得HW锁。HW锁争用大部分是因为大量执行insert所引发的,偶尔也会因大量执行update在回滚段中发生HW锁争用现象。若是update,表中段的扩展的大小虽然不多,但在创建回滚数据的过程中,需要回滚段的急速扩张。HW锁争用是在段的急速空间扩张时普遍出现的等待现象,有时也会引发严重的性能下降。
oracle 10g起添加了in-memory undo(以下称IMU)功能,将回滚段的数据存于共享池内的KTI-UNDO区域的功能。KTI-UNDO区域上存储的回滚数据会由oracle被转到(flush)回滚段。因此,从10g起,回滚段引起的HW锁争用比以前版本有所减少。期待撤销块的读写工作减少会给整个系统带来改善新能的效果,但对于IMU的性能问题还不被人所知,IMU被多个in-memory undo 锁存器保护。为了使用相同的KTI-UNDO区域,在发生争用等待latch:in memory latch事件,关于IMU的跟多信息参照我的博客:http://blog.csdn.net/changyanmanman/article/details/7983162
问题1:请问如何理解"HW Enqueue是用于segment的HWM的, 可以通过手工分配extents来解决"
在手动段管理的时代,可以通过这个ALLOCATION EXTENT把新的BLOCK加入FREELIST中,也就是提高了HWM。来避免HW ENQUEUE
自动段管理我觉得这个方法已经不适用了吧~当初freelist时代,解决HW enq的办法,就是减少hwm的提升次数~,通过alter table extent + instance子句 把新的extent中的block都加入freelist中,来达到目的。
问题2:HWM越高,每次寻找具体数据块时就要找得越多, HW Enqueue应该越严重吧? 不了解HW Enqueue的工作方式,期望高手解答!!!
只有当新的extents需要分配的时候,才会发生HW锁的争用,主要明确HW锁不是使用新的extents时候等待,而是分配extents的时候,也就是提高HWM的时候争用,所以,一次分配更大的extents可以减少这个锁的争用哦。。
问题3:那是我在系统分配extents的时候存在这个等待吗?
HW enqueue The HW enqueue is used to serialize the allocation of space beyond the high water mark of a segment.
如文档所说,HW enqueue 是发生在一个段的HWM连续提升的状况下~ 提升HWM要做什么工作呢?
首先HWM的位置是存储在段头块,并且HWM的提升会增加Freelist中的free blocks,而freelist中的块数的纪录,也存储在段头(当然如果freelist group=n>1,那么存储在段头后面的n个块中~),所以这个时候要修改的是段头块(以及freelist 所在的块),还有一个地方要修改,就是原来freelist中最后一个block,这个里面记录了freelist单项列表的最后一个地址,要把他修改,指向新加入freelist的块的地址~还要在所有新加入freelist的块上建立freelist单项链表~ 可见提高HWM是需要修改很多块的~
但是如果新加入一个extent呢?对于字典管理表空间,需要修改数据字典等待为ST enqueue(印象中)~ 而本地管理表空间,仅仅需要修改以下数据文件头上的位图~这个工作量是非常小的~ 我不认为分配extent会造成多大的等待~ 当然就算有等待也不是hw enqueue
问题4:对于assm,可以采用uniform,分配更大的extent——metalink的确有这个说法~ 但是我觉得更主要的是assm本身的段管理机制使用位图管理本身提高了free block的并发性~ 较少了等待的发生~
但是为什么要分配大extent我就不是很明白了~按理说大extent和hwm的提升没什么关系呀~
而且assm下有两条hwm~ 所以我觉得high hwm low hwm的机制是不是也可以减少hwm变化的开销
通过不同大小uniform测试可以看出extent大的好处。
原因应该是不必过多的分配extent,减少对HW enquence的争用
对于HHWM和LHWM,可以参见tanel的一段话
ASSM high-HWM extensions(扩张) are not done over extent boundaries(边界) IIRC, thus with small extents you'd have lots of extensions to do, each requiring HW-enqueue get.ASSM relieves(解除,降低) HW-enqueue contention by increasing HHWM in large sizes (depending on extent and current segment size),so less HW operations have to be done.
The LHWM extensions can be done without having HW-enqueue as they involve(包含) only changing few records in a BMB block (我估计应该是位图块,不确定)and the BMB is pinned(钉住) for that exclusively anyway. The actual batch formatting(批量格式化) of datablocks is done while having FB enqueue, allowing finer(出色的) granularity(粒度) of locking block ranges in case of multiple parallel inserts.
相关讨论:http://www.itpub.net/thread-1242093-1-1.html
如何找到'事件:enq: HW - contention'对应的热点segment
HW enqueue
The HW enqueue is used to serialize the allocation of space beyond the high water mark of a segment.
V$SESSION_WAIT.P2/V$LOCK.ID1is the tablespace number.
V$SESSION_WAIT.P3/V$LOCK.ID2is the relative dba of segment header of the object for which space is being allocated.
If this is a point of contention for an object, then manual allocation of extents solves the problem.
SQL> select p1, p2, p3 from v$session_wait where event = 'enq: HW - contention';
P1 P2 P3
---------- ---------- ----------
1213661190 7 140003563
1213661190 7 140003563
1213661190 7 140003563
1213661190 7 140003563
1213661190 7 140003563
1213661190 7 140003563
1213661190 7 140003563
7 rows selected
SQL> select dbms_utility.data_block_address_block(140003563),
dbms_utility.data_block_address_file(140003563)
from dual ;
DBMS_UTILITY.DATA_BLOCK_ADDRES DBMS_UTILITY.DATA_BLOCK_ADDRES
------------------------------ ------------------------------
1591531 33
SQL> select name from v$tablespace where ts#=7;
NAME
------------------------------
INFORES
通过下面语句找到热点segment
select *
from dba_extents.segment_name
where tablespace_name = 'INFORES'
and FILE_ID = 33
and 1591531 between block_id and block_id + blocks
经典故障分析 - ASSM引发的索引争用与 enq HW -contention 等待事件
2017-09-05 孙加鹏 DBGeeK
请点击此处输入图片描述
转载自 数据和云(ID:OraNews)
作者 孙加鹏
一、故障概述
2017年07月24日11:58左右,客户核心数据库出现大量活动会话,导致数据库负载急剧加大,从而导致业务出现延时,DBA通过查看SESSION信息发现有大量的“enq: HW - contention”等待事件。
一直持续约有3分钟,数据库负载下降:
请点击此处输入图片描述
下面是详细的故障分析诊断过程,以及详细的解决方案描述。
二、故障分析
1故障现象
ENMODB数据库出现大量活动会话,数据库负载急剧加大,通过V$SESSION能看到大量enq:HW contention的活动会话信息,客户紧急采集了ASH信息,方便后期故障分析。
2分析过程
从AWR和ASH两个维度来分析此故障,先整体后局部,首先从AWR分析入手。
1、AWR分析
首先看一下故障时间段的AWR报告:
请点击此处输入图片描述
请点击此处输入图片描述
半小时的采样时间,DB Time 215mins,其中等待时间“enq: HW - contention”占据近36%,为TOP 10 events中最主要的非空闲等待事件。
请点击此处输入图片描述
等待事件“enq: HW - contention”的解释:
The HW enqueue is used to manage the allocation of space beyond the high water mark of a segment. The high water mark of a segment is the boundary between used and unused space in that segment. If contention is occurring for "enq: HW - contention" it is possible that automatic extension is occuring to allow the extra data to be stored since the High Water Mark has been reached. Frequent allocation of extents,reclaiming chunks,and sometimes poor I/O performance may be causing contention for the LOB segments high water mark.
The HW enqueue is used to serialize the allocation of space beyond the high water mark of a segment. If lots of data is being added to an object concurrently, then multiple processes may be trying to allocate space above the high water mark at the same time, leading to contention.
简而言之,HW锁是在分配高水位线以上的空闲空间时,多个进程同时为了分配高水位线上空闲空间而修改HWM,修改HWM需要持有HW锁,该锁又属于排他锁(mode=6)。
如果大量数据被并发插入某个对象时,那多个进程可能会试图在高水位线以上同时申请可用空间,大并发的申请HW锁,从而导致HW enqueue争用。HW – contention等待事件的P1,P2,P3参数参考下表;
Event | P1 Parameter | P2 Parameter | Parameter 3 |
enq: HW - contention | name|mode | table space | # block |
请点击此处输入图片描述
发现这个时间段确实有大量的INSERT操作,半小时采用中,该SQL执行了约近24w次。
下一步看看HW竞争是在表段还是在索引段上?
请点击此处输入图片描述
请点击此处输入图片描述
大量的物理读/物理写请求也都发生在表TAB_ENMO的索引上。这里可以猜测HW竞争可能不在表上,而在这几个索引上面,IO读写请求非常高。
2、ASH分析
通过客户采集的ASH分析发现,等待事件“enq: HW - contention”是从07月24日11:57:12秒左右开始的,此类session全部被session id为1191的会话阻塞。
请点击此处输入图片描述
查看1191会话信息,发现11:57:12的时候没有被任何会话阻塞(NOT IN WAIT),Session状态是ON CPU:
请点击此处输入图片描述
这个时间点11:57:12的时候会话1191在执行以下的INSERT操作,这个就是源头,并且这个SQL一直在执行。
请点击此处输入图片描述
INSERT操作从11:57:11开始,后续该会话一直都是HW竞争,并且跟其他SESSION争相持有HW锁。
请点击此处输入图片描述
这个时间点大量的SESSION都在持续申请HW锁,因此都在相互blocking sessions。从p1,p2,p3参数中发现P3值并不代表争用块的RDBA(data block address)(36730这个值太小了,这是为啥?先思考下)。
请点击此处输入图片描述
既然P3找不到RDBA,那就从ash中字段CURRENT_FILE#和CURRENT_BLOCK#上寻找争用块:
请点击此处输入图片描述
请点击此处输入图片描述
发现所有的HW竞争都发生在索引IDX_TAB_ENMO_SEQ上,该索引就是表TAB_ENMO上的索引,HW竞争的SQL语句也是上面AWR中发现的SQL。
请点击此处输入图片描述
既然是大并发持有HW锁,多个进程是持续不断的申请HW锁,说明不断的发现free space不足,一般ASSM管理都是一次性分配多个extent,根据对象大小一个extent下面又会有多个block。除非指定storage参数next size 大小:
请点击此处输入图片描述
表空间ENMO_DATA是ASSM(自动段空间管理),并且是本地管理表空间,获取表空间的定义语句:
请点击此处输入图片描述
表空间自动扩展NEXT SIZE 100M。段管理方式使用自动段空间管理(ASSM)。这里有个地方值得关注下,这个表空间属于bigfile tablespace,这就是为什么通过等待事件中的p1,p2,p3参数无法精确定位到具体发生争用的block了。
具体可以参考Mos文档:ID 2098543.1。
因此上面的P3参数指的datafile中的block number,其实就是这个索引段的段头(segment header)所在的block。
请点击此处输入图片描述
所以HW竞争还是发生在索引的段头上,因为段头会记录HWM信息,进程修改HWM就必须要持有HW锁,并修改索引段头上的HWM。所以P3=36730是准确的,只是这个P3参数代表是bigfile tablespace上的block number,dump出file_id=6 block_id=36730的块,可以看出就是索引IDX_TAB_ENMO_SEQ的Segment header。
现在问题基本明朗了,所有的争用都发生在索引的Segment Header上面,进程为了需要更多的空间(unformatted),通过持有HW锁来修改高水位线(HWM),大量的进程并发从而导致HW锁上的竞争。
那既然是ASSM管理,为何新的extent分配的时候还会出现HWM上的竞争呢?不都是bitmap管理了吗?比之前freelist管理要好很多啊,看看这个索引的DDL语句:
请点击此处输入图片描述
索引的stroage参数中NETX=1M,即每次分配空间以每次1M大小来分配,8k块大小即相当于每次分配
128个blocks。难道是客户创建索引的时候指定extent分配大小?问题是不是发生在这个NEXT 1M上面呢?
显然不是的,自动段管理表空间(ASSM)下这个NEXT扩展字句应该是不生效的,不会按照这样来初始化extent的。
可以检查下索引的extent分布,看看extent下面包含多少个blocks。
请点击此处输入图片描述
上面信息可以看出索引的extent并不是只有128个块,跟ASSM的extent分配机制匹配的,segment后期会按照64M的大小分配extent,即每个extent有64*1024/8=8192个block。
7月24日故障之后几天,又不间断的出过2~3次同样的故障,那为何不间断的会发生这种故障?索引真的有这么需要unformatted空间吗?表上有大量的INSERT操作的同时也需要维护索引,同时索引也会进行分裂,不论是leaf node split还是branch node split,都需要新块来满足分裂,实验证明索引分裂只请求unformatted的块,未满块或空闲块都不会使用。下面来看看索引上unformatted块的使用情况,这个show_space存储过程来自TOM大师的分享:
请点击此处输入图片描述
请点击此处输入图片描述
请点击此处输入图片描述
同时12点12分左右又出现一次HW竞争严重的情况,导致AAS飙高,系统负载急剧升高。因此每次出现HW竞争都是因为Unformatted Blocks不够用的时候,多个进程修改索引段头的HWM的时候持有HW锁。
所以问题原因主要是多个进程同时修改索引段头上的HWM而导致的争用,针对这种问题一般采用HASH分区索引,通过将索引改造成HASH分区索引来缓解索引段头的争用,这样从原来的在单个段头修改HWM,到现在的在多个分区索引的段头上修改HWM。将原先索引从一个L3位图管理块,到多个L3层位图管理块。
先看一下ASSM的extent三层位图管理结构:
请点击此处输入图片描述
整个位图三级位图结构是一个树形结构,L3往往代表的就是Segment Header,L3中记录了所包含的所有L2位图块的地址,L2位图块中又包含了所属L1位图块地址。L1位图块中记录了具体数据块的地址和使用情况。
L3,L2,L1三层结构均以树形结构,一对多的关系。
下面我们来dump出索引的段头(Segment Header)信息。
请点击此处输入图片描述
请点击此处输入图片描述
索引目前已经有2323个extents,现在的高水位线在extent_id 2322 block_id 8192位置。”L2 Hint for inserts”这表名INSERT插入的记录从这个L2(后面跟的是bigfile的block_id)开始。
Dump出这个L2位图块:
请点击此处输入图片描述
请点击此处输入图片描述
如上,这个L2中包含有1007个L1,free L1有77个,L1共有三个状态值,分别为Free 1,Free 3和Free 5,3和5都代表该L1下面有空块。
请点击此处输入图片描述
ASSM管理表空间的Table Block的状态有7种,分别是:
0 = unformatted
1 = logically full (per pctfree)
2 = 0-25% free
3 = 25-50% free
4 = 50%-75% free
5= 75-100% free
对于Block的DUMP有兴趣的可以研究研究。
三、故障解决
问题原因主要是多个进程同时修改索引段头上的HWM而导致的争用,针对这种问题一般采用HASH分区索引,通过将索引改造成HASH分区索引来缓解索引段头的争用,这样从原来的在单个段头修改HWM,到现在的在多个分区索引的段头上修改HWM。
引入思考,当初设计表的时候,从业务角度出发,知道这是一个业务流水表,流水表的特点就是大量的DML操作,特别是INSERT操作的存在,表级别做了分区设计,索引上未考虑到位采用了普通索引,导致后期性能下降和故障发生。因此好的数据库结构设计是有多么重要。
标签:HWM,contention,索引,HW,enq,点击,extent,block 来源: https://blog.51cto.com/lhrbest/2701855