Home > Database > Mysql Tutorial > Oracle Dba必须了解的buffer busy waits等待

Oracle Dba必须了解的buffer busy waits等待

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
Release: 2016-06-07 17:17:21
Original
937 people have browsed it

虽然LATCH的持有是排他的,但是这个时间极端,引起争用的可能性不大,如果大家都是来读数据块的,那么BUFFER LOCK的S模式之间都是

Buffer Busy Waits是怎么产生的?

作为一个Oracle Dba,如果你从未遇到过Buffer Busy Waits等待,那么你算不上一个真正的Oracle Dba。Buffer Busy Waits是Oracle 数据库非常常见的一个等待,特别是在并发写比较频繁的环境里。说起为什么会产生这个等待,首先要描述下,Oracle读写数据块的过程:

1)首先依据数据块地址计算出(HASH算法)数据块所在的HASH BUCKET。

2)根据桶的编号,计算出保护这个桶的CBC LATCH,然后申请CBC LATCH,找寻数据块在不在桶里(内存里),我们这里假设在内存里。

3)读取/修改数据块。

4)释放CBC LATCH。

以上的描述看似是非常通畅,但是存在一个问题,CBC LATCH的持有是排他的(我们暂时不考虑复杂情况:共享LATCH的持有情况),如果在排他持有CBC LATCH的情况下,读取数据块内容,那么这个LATCH的持有时间就会比较长,因为相对于LATCH的获取和释放这种CPU原子操作,读取数据块的内容是非常耗时的,因此在持有CBC LATCH的情况下,读取数据块,对于读写频繁的数据库/块,那么势必会造成CBC LATCH的争用。为了解决这个问题,Oracle引入了buffer pin(buffer lock)的功能。

我们有必要对读取数据块的内容重新做下描述,大致步骤如下:

1)首先需要判断数据块所在的HASH BUCKET。

2)然后申请CBC LATCH,,定位到数据块。

3)以S/X模式获取数据块的buffer pin/lock。(读取获得s模式,修改获得x模式,S和S模式具有兼容性,S和X、X和X模式不具有兼容性)。

4)释放CBC LATCH

5)在PIN的保护下,读取/修改数据块。

6)获得CBC LATCH。

7)释放(UNPIN)BUFFER PIN(BUFFER LOCK)。

8)释放CBC LATCH。

看似步骤复杂了,CBC LATCH获取/释放了两次,可是却大大的提高了并发度。上面描述的步骤里,持有CBC LATCH的目的变得单纯,只是为了修改BUFFER的PIN模式,然后依靠PIN的模式兼容性来保护数据块,例如:S和S模式的PIN是兼容的,可以并发的读取,S和X模式是不兼容的,后来的会话需要产生等待。

虽然LATCH的持有是排他的,但是这个时间极端,引起争用的可能性不大,如果大家都是来读数据块的,那么BUFFER LOCK的S模式之间都是具有共享性的,不会产生争用。但是同一个时刻,如果一个进程以S模式持有了数据块的BUFFER LOCK,另一个进程想以X模式持有,那么就会出现争用,因为道理很简单,S模式的BUFFER LOCK和X模式的BUFFER LOCK不兼容。同理,两个同时欲修改同一个数据块的进程,也会遭遇BUFFER LOCK冲突.这个冲突以ORACLE 等待事件表示出来就是Buffer Busy Waits,也就是说Buffer Busy Waits等待的本质是buffer lock的争用导致的。

我们平时经常说读不阻塞写,写不阻塞读,那是在物理的数据块级别,在内存里,读写/写写在同一个时刻都是互相阻塞的。只有读读不阻塞。

为了方便理解,上面很多步骤做了简化,下面对某些点做些补充:

1)一旦你PIN住了一个数据块,不需要立即去UNPIN(移除PIN)它。ORACLE认为你的本次调用后还有可能去访问这个数据块,因此保留了PIN,直到本次调用结束再UNPIN。

2)Oracle在对唯一索引/undo块/唯一索引的回表/索引root、branch块的设计上,在访问(读取)的时候,获取的是共享的CBC LATCH,不需要去PIN数据块,在持有共享CBC LATCH的情况下读取数据块。可能的原因是这些块修改的可能性比较小,因此Oracle单独的采用这种机制。因此对于普通数据块的读取都是需要获取2次CBC LACTH,而对于这种特殊的数据块,只获取一次共享CBC LATCH就OK 了。

3)我们上面所说的情况都是在数据块已经存在在内存里的情况。如果数据块不在内存,有可能会产生READ BY OTHER SESSION争用等待。有时间我们再看这个等待的原因。

4)上面描述只符合10G后的版本。在10G前读读也会产生BUFFER BUSY WAITS,10G后把这方面的BUFFER BUSY WAITS归到了READ BY OTHER SESSION等待里。

5)上面的描述基本都采用了数据块这个词,更准确的表达应该是buffer block。

linux

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template