一、问题描述及分析
应用业务反馈应用响应缓慢。登录数据库检查,发现数据库响应慢,有大量enq:HW–contention等待事件。结合awr报告和ash报告,发现整体等待时间消耗在推高水位线征用上,如下awr top事件:
Ash消耗也是enq:HW–contention
检查enq:HW–contention的sql语句,发现集中在三条语句上,如下:
这三条语句是:
INSERT INTO CPOE_ORD_CA_SYSTEM_REL ( UNIQUE_ID, ORDER_ID, CA_CHECK_DATA, STAMP, ORDER_STATUS, OPERATION, SOURCE, URID ) VALUES( :1 , :2 , :3 , :4 , :5 , :6 , :7 , :8 )
INSERT INTO SDE_LOB_MEDICALRECORD ( LOB_ID, LOB_CONTENT, MODIFY_DATE, REMARK ) VALUES( :1 , :2 , :3 , :4 )
UPDATE SDE_LOB_MEDICALRECORD SET LOB_CONTENT=:1 , MODIFY_DATE=:2 WHERE LOB_ID=:3
经检查,该等待事件发生的表主要是CPOE_ORD_CA_SYSTEM_REL、SDE_LOB_MEDICALRECORD,这两个表均有CLOB字段,检查9点到10点的awr信息,其中消耗最高的CPOE_ORD_CA_SYSTEM_REL表插入244次,次数也不算多,但平均每次执行平均要消耗392.05秒,表信息中除了lob,其他占用量都不大的,消耗时间情况如下:
检查表空间IO情况:
表空间io延迟较高,一般正常情况下在8ms以内,不排除大lob插入导致io开销增加。
HWM理解:
Oracle 数据库通过跟踪段中的块状态来管理空间。 高水位标记 (HWM) 是段中的一个点,超过该点的数据块是未格式化和未使用过的。
“enq:HW–contention”理解:
HW enqueue用于管理高水位以上的空间分配。通常在执行insert操作时,当高水位线以下block不够用时,Oracle将会推进高水位线。当有多个进程在同时进行insert操作时,容易引起高水位线争用,主要表现为“enq: HW – contention”。
二、解决方案
短期解决方案:
手动扩展该表lob字段空间:
ALTER TABLE <lob_table> MODIFY LOB (<column_name>) (allocate extent (size ));
如:
ALTER TABLE CPOE_ORD_CA_SYSTEM_REL MODIFY LOB (STAMP) (allocate extent (size 10g));
该扩展相当于提前推动水位线,扩展区extent和段的空间,上面我提前分配了10G,正常情况下是用不够了才去推动扩展的,可以通过dba_extents视图查看
select * from dba_extents where segment_name=‘SYS_LOB0000234080C00004$$’
当前情况一次分配是64M,如果插入lob比较大的情况,可能会造成多次扩展还是不够。
长期解决方案:
(1)在对应业务高峰期前,提前手动allocate new空间。
ALTER TABLE <lob_table> MODIFY LOB (<column_name>) (allocate extent (size ));
(2)对该表所在的表空间设置更大的UNIFORM SIZE,使得每次allocate更多extent到表的HWM之上,避免高水位线争用时等待表空间的extent分配。
(3)设置隐含参数_bump_highwater_mark_count,该隐含参数可以控制HWM每次推进的block个数。
(4)检查IO子系统性能。 IO性能的变化也会导致空间分配缓慢,进而引发等待。