buffer busy waits引起的会话突增

某天,客户反映其监控平台发现其一套数据库7月20日及24日在早晨7:03分和8:09分两个时间段节点1出现会话数突增情况,持续时间较短,问题时间段应用并未受到影响。这究竟是怎么回事呢?本文带你一探究竟。

作者 杨禹航·沃趣科技高级数据库技术专家
出品 沃趣科技

某天,客户反映其监控平台发现其一套数据库7月20日及24日在早晨7:03分和8:09分两个时间段节点1出现会话数突增情况,持续时间较短,问题时间段应用并未受到影响,客户希望帮其查找原因。

环境为11.2.0.4的双节点RAC。

通过收集的ASH信息我们可以在7月20日的07:03分和7月24日的08: 09分看到会话出现突增情况,其他时间段会话相对较平稳,问题时间点过后,会话数再次恢复平稳。

7月20日:

7月24日:

在对问题时间段等待事件进行查看,该时间段内出现大量的”buffer busy waits”等待事件,等待的会话并无blocking session,语句类型均为INSERT,SQL_ID均为:8qy4f5hpsrmu4,而对象为98866,在7月24日,问题时间段又伴有少量的”latch: cache buffers chains”和大量的”enq: HW -contention”。

7月20日:

7月24日:

对等待事件进行汇总后,等待次数排名第一位的等待事件均为”buffer busy waits”,如下:

7月20日

7月24日

通过上面的信息在表象中看到是由于系统中大量并发INSERT语句同时向98866对象插入数据,而引起的会话数突增,且会话均等待”buffer busy waits”。

那系统中为何同时出现大量INSERT语句的会话?该时间点内应用确实发出如此多的INSERT语句?而又同时向相同的对象中插入数据产生的”buffer busy waits”?还是由于”buffer busy waits”而引起的大量会话出现阻塞?

根据应用反馈,系统中的数据插入较平稳,问题时间段业务量并未发生变化,这样可以排除第一种可能性。

先看何为”buffer busy waits”,“buffer busy waits”等待事件的发生情况为当会话以独占模式持有buffer pin锁时,其他会话以非兼容模式申请buffer pin锁,此时申请buffer pin锁的会话产生的等待事件为buffer busy waits。引起系统”bufferbusy wiats”的原因很多,常见的情况有如下情况:

1.大量的并发DML语句,修改相同的数据块

  1. DML语句慢,导致以排他模式持有bufferpin时间过长(DML语句慢的原因可能由于系统redo量过高或者lgwr慢等原因导致)

另外,通过对等待事件所发生位置进行统计发现”buffer busy waits”均发生在少数的数据块中。

7月20日通过上面的信息在表象中看到是由于系统中大量并发INSERT语句同时向98866对象插入数据,而引起的会话数突增,且会话均等待”buffer busy waits”。

那系统中为何同时出现大量INSERT语句的会话?该时间点内应用确实发出如此多的INSERT语句?而又同时向相同的对象中插入数据产生的”buffer busy waits”?还是由于”buffer busy waits”而引起的大量会话出现阻塞?

根据应用反馈,系统中的数据插入较平稳,问题时间段业务量并未发生变化,这样可以排除第一种可能性。

先看何为”buffer busy waits”,“buffer busy waits”等待事件的发生情况为当会话以独占模式持有buffer pin锁时,其他会话以非兼容模式申请buffer pin锁,此时申请buffer pin锁的会话产生的等待事件为buffer busy waits。引起系统”bufferbusy wiats”的原因很多,常见的情况有如下情况:

1.大量的并发DML语句,修改相同的数据块

*2. DML语句慢,导致以排他模式持有bufferpin时间过长(DML语句慢的原因可能由于系统redo量过高或者lgwr慢等原因导致) *

另外,通过对等待事件所发生位置进行统计发现”buffer busy waits”均发生在少数的数据块中。

7月20日

7月24日

大量的会话又为何向同一个数据块中插入数据?通过对发生大量”buffer busy waits”的数据块进行dump,有如下发现:

218/4161664

19/8250

其中218/4161664为L1,19/8250为段头,L1与段头居然出现了大量的”buffer busy waits”,如果对数据插入时的机制有所了解,问题原因其实已经展现出来,在使用ASSM的段空间管理方式下,正常插入语句在向段中插入数据时,将会根据会话的pid信息计算hash值n,根据计算结果在L3/L2中选择第n个L1,这里需要注意插入时所选择的L1是在高水位线之下的L1,在根据pid计算hash值将数据插入到L1中的第n个数据块里,会话不同,插入的数据将分散到不同的块中,当L1中指向的数据块使用率出现变化(25% 50% 75% FULL)时将会修改L1中对该数据块空间使用情况标记位的修改,因其为修改,将以独占模式持有L1段头的buffer pin锁,在问题时间段内同时伴有大量的高水位推进”enq: HW - contention”等待事件,段的高水位线记录在段头,这样也解释了为什么段头会出现大量的”buffer busy waits”,其实根据上面的信息基本可以分析出是由于系统中持续插入数据,由于高水位线低(高水位线的推进是以L1中指向的块的数量进行推进),大量的数据插入时聚集在高水位线下L1中指向的数据块,而引起大量的“buffer busy waits”,导致会话突增,这种问题较少见,如果需要避免该问题,可以采用手工推高高水位的方式,这样可选择的L1数量,数据块的数量也随着增多,避免插入的数据块过于集中。

| 作者简介

杨禹航·沃趣科技高级数据库技术专家

熟悉Oracle数据库内部机制,丰富的数据库及RAC集群层故障诊断、性能调优、OWI、数据库备份恢复及迁移经验。

发表评论

电子邮件地址不会被公开。 必填项已用*标注