Oracle:缓冲区忙等待

 

甲骨文 10 and 11

缓冲区繁忙等待通常在Oracle 10和11上发生,主要是因为将争用到表或索引中。旧式RBS段有一些其他罕见的争论,文件标题块和空档。
在Oracle 10和11之前,还有一个其他主要原因是等待读者的读者,即一个用户对存储器进行街道IO,并且第二用户想要读取该块。第二个用户等待直到IO由第一用户完成。从10g开始,这次等待已获得名称“其他会议读书“。在Oracle 10g之前,这也是一个“buffer busy wait”.
分析瓶颈和查找解决方案的最简单方法是使用Oracle 10g中可用的ASH(活动会话历史),并使用Dup Optimizer等产品使用模拟灰器使用模拟灰器。
可以在Ash中找到的数据块类是分析缓冲区繁忙等待时最重要的信息。如果我们知道块类,我们可以确定什么样的瓶颈:
 If CLASS=
    1. 数据块
      • 如果OType =.
      • 索引,然后插入索引叶块可能很热,解决方案是
        • 哈希分区索引
        • 使用反向密钥索引
      • 桌子, then insert block is hot,solutions
        • 使用免费列表
        • 将对象放在ASSM表空间中
    2. 段标题 – If “segment header”与类=同时发生“data block”在同一对象中,对象是otype =“TABLE”那么这只是一个确认表需要使用免费列表或截误。
    3. 文件标题块 –最有可能的范围分配问题,在表空间上查看范围大小,并增加范围大小,几乎没有几乎没有对文件标题块的争用和较少的争用。
    4. 免费清单 –将免费列表组添加到对象
    5. 撤消标题 –如果使用旧rbs,则不足以撤消段,然后切换到aum
    6. 撤消块 –撤消,应用问题的热点
我们如何找到块类?在ASH数据上快速查询:

select
       o.object_name obj,
       o.object_type otype,
       ash.SQL_ID,
       w.class
from v$active_session_history ash,
     ( select rownum class#, class from v$waitstat ) w,
      all_objects o
where event='buffer busy waits'
   and w.class#(+)=ash.p3
   and o.object_id (+)= ash.CURRENT_OBJ#
Order by sample_time;
例如

 

OBJ    OTYPE  SQL_ID        CLASS
------ ------ ------------- ------------------
TOTO1  TABLE  8gz51m9hg5yuf data block
TOTO1  TABLE  8gz51m9hg5yuf data block
TOTO1  TABLE  8gz51m9hg5yuf segment header
TOTO1  TABLE  8gz51m9hg5yuf data block
如果我们发现class = datablock,那么我们将需要更多信息来诊断,例如对象类型“OTYPE”,对象名称和对象存储的表空间是什么样的。以下查询提供了该信息:

set linesize 120

col block_type for a20
col objn for a25
col otype for a15
col filen for 9999
col blockn for 9999999
col obj for a20
col tbs for a10
select
       bbw.cnt,
       bbw.obj,
       bbw.otype,
       bbw.sql_id,
       bbw.block_type,
       nvl(tbs.name,to_char(bbw.p1)) TBS,
       tbs_defs.assm ASSM
from (
    select
       count(*) cnt,
       nvl(object_name,CURRENT_OBJ#) obj,
       o.object_type otype,
       ash.SQL_ID sql_id,
       nvl(w.class,'usn '||to_char(ceil((ash.p3-18)/2))||' '||
                    decode(mod(ash.p3,2),
                         1,'header',
                         0,'block')) block_type,
       --nvl(w.class,to_char(ash.p3)) block_type,
       ash.p1 p1
    from v$active_session_history ash,
        ( select rownum class#, class from v$waitstat ) w,
        all_objects o
    where event='buffer busy waits'
      and w.class#(+)=ash.p3
      and o.object_id (+)= ash.CURRENT_OBJ#
      and ash.session_state='WAITING'
      and ash.sample_time > sysdate - &minutes/(60*24)
      --and w.class# > 18
   group by o.object_name, ash.current_obj#, o.object_type,
         ash.sql_id, w.class, ash.p3, ash.p1
  ) bbw,
    (select   file_id, 
       tablespace_name name
  from dba_data_files
   ) tbs,
    (select
 tablespace_name    NAME,
        extent_management  LOCAL,
        allocation_type    EXTENTS,
        segment_space_management ASSM,
        initial_extent
     from dba_tablespaces 
   ) tbs_defs
  where tbs.file_id(+) = bbw.p1
    and tbs.name=tbs_defs.name
Order by bbw.cnt
/
并且输出看起来像

  CNT OBJ     OTYPE   SQL_ID        BLOCK_TYPE       TBS        ASSM

----- ------- ------- ------------- ---------------- ---------- ------
    3 TOTO1   TABLE   8gz51m9hg5yuf segment header   NO_ASSM    MANUAL
   59 TOTO1   TABLE   8gz51m9hg5yuf data block       NO_ASSM    MANUAL
甲骨文 7, 8 and 9

在Oracle 10之前,缓冲区繁忙等待,因为IO阻止了一个想要执行相同IO的用户。在Oracle 9上,缓冲区繁忙等待的主要原因是

1)IO读取争用(只有Oracle 9i和以下)

2)在表或索引上插入块争用
3)回滚段争用

在7.0– 8.1.5 see http://sites.google.com/site/embtdbo/oracle-buffer-busy-wait/oracle-buffer-busy-wait-7-8-1-5

在第8和9版本中,P3值具有不同的含义。而不是意味着块类型(这是最佳信息)它意味着那种缓冲区忙碌的等待。对我们来说只有两个值,值

100范围=读取等待(基本上只是一个等待)

读取器阻止读取器,即一个读者正在读取块,另一个人想要读取该块并等待缓冲区忙等待P3 = 130。

200范围=写入调整(与10g相同)

由于表中没有免费列表,或者因为每个人都插入相同的索引块,因此在执行插入时阻止其他作家的作家。

如果您已经使用S-ash设置了灰样式集合或具有像DB Optimizer这样的产品,您可以运行查询,如:

select

       count(*) cnt,
       o.object_name obj,
       o.object_type otype,
       ash.CURRENT_OBJ#,
       ash.SQL_ID,
       decode(substr(ash.p3,1,1),1,'read',2,'write',p3) p3
from v$active_session_history ash,
      all_objects o
where event='buffer busy waits'
   and o.object_id (+)= ash.CURRENT_OBJ#
group by o.object_name, o.object_type, ash.sql_id, ash.p3,ash.CURRENT_OBJ#
order by cnt
/
并看看忙碌的缓冲区等待有什么样的对象是什么:

 CNT OBJ     OTYPE   CURRENT_OBJ#     SQL_ID P3

--- ------- ------- ------------ ---------- ------
  1                           -1 1375352856 read
  2                           -1  996767823 read
  2                           -1 2855119862 write
 17                           -1 1375352856 write
 89 TOTO1   TABLE         296030 1212617343 write
109                       296022 1212617343 write

通常,current_obj#是-1所以我们可以’要弄清楚对象是什么。有一种替代方法

col block_type for a18

col objn for a25
col otype for a15
col event for a15
col blockn for 999999
col segment_name for a20
col partition_name for a15
col owner for a15
set timing on
/*
drop table myextents;
l
create table myextents as select * from dba_extents;
l
*/
select
       count(*),
       ext.owner,
       ext.segment_name,
       ext.partition_name,
      ext.segment_type,
        decode(substr(ash.p3,1,1),1,'read',2,'write',p3) p3
       --ash.p1,
       --ash.p2
from v$active_session_history ash,
     myextents ext
where
       event = 'buffer busy waits'
   and ( current_obj# = -1 or current_obj#=0  or current_obj# is null )
   --and sample_time > sysdate - &minutes/(60*24)
   --and session_state='WAITING'
   and  ext.file_id(+)=ash.p1 and
        ash.p2 between  ext.block_id and ext.block_id + ext.blocks
group by
       ext.owner,
       ext.segment_name,
       ext.partition_name,
       ext.segment_type,
       p3
       --ash.p1,
       --ash.p2,
       --ash.sql_id
Order by count(*)
/
因为查询dba_extents是一个缓慢的操作,所以我制作了一个dba_extents的副本,它将更快地查询。

CNT OWNER  SEGMENT_NAME   PARTITION_NAME  SEGMENT_TYPE  P3

--- ------ -------------- --------------- ------------- --------
  1 SYS    _SYSSMU2$                      TYPE2 UNDO    read
  1 SYS    _SYSSMU3$                      TYPE2 UNDO    write
从P1和P2(文件和块)获取对象的第二种选项可能只会与用户同意,因为我们必须创建一个可能需要很长时间的DBA_extent表的副本’s big.
没有灰烬?

如果你不’T有ASH数据,您必须做一些猜测。
块类(块类型)

找出缓冲区繁忙等待的第一步是在看

     V$waitstats
这将告诉我们我们有什么样的Datablocks。
争用文件

您还可以了解通过查看的缓冲区忙等文件包含哪些文件的想法:

    X$KCBFWAIT
对象与争用

从版本9i开始,有表

    v$segstat
这将列出具有缓冲区繁忙等待的对象。
如果您在第7版或8件良好的运气中找到对象而不设置ASH样式数据收集。
为什么缓冲区忙着等待?

要将其简洁地提出,缓冲区繁忙等待发生,因为两个用户希望同时更改块。两个用户可以更改相同的块,或甚至相同的行“at the same time”即没有承诺,但这’s不同于修改块的实际操作。在RAM或计算机内存中的块上的修改只能通过一个过程在时间完成,以避免内存损坏。不同的用户可以同时修改不同的块,但只有一个用户或进程一次可以修改相同的块。
为了真正明白什么’正在继续我们看看Oracle如何管理内存和阻止访问和修改。
这是布局
上面是一个图表显示了Oracle关于性能调整的一些基本部分。
在机器存储器中
  •     Oracle’S SGA或System Global Area,Oracle用户之间共享的内存
  •     LGWR – log writer process
  •     DBWR –数据库作家进程
  •     User1,2,3 … –用户进程,在这种情况下“shadow processes”

在机器文件系统上

  • 重做日志文件
  • 数据文件
SGA由(以及其他事物)组成
  • 日志缓冲区
  • 库缓存
  • 缓冲区缓存
什么’对于理解缓冲区忙等待的问题是如何管理缓冲区缓存。以下是具有更多组件的缓冲区缓存的视图:
为了访问块,用户(影子进程)必须获取锁存(缓存缓冲区链锁存),该锁存器(缓存缓冲区链锁存)保护缓冲报头的桶或链接列表。如果发现锁存器,则需要释放锁存器。缓冲标头指向内存中的实际数据块。在Memory中修改块之前,用户必须锁定缓冲标头。如果将块读入存储器或修改已在内存中的块,则锁定缓冲报头锁定任何时间。通常,标题仅锁定仅限短的时间,但是当有很多并发访问时,缓冲标头可以成为瓶颈。
阅读数据时BBW– 其他会议读书

在Oracle 7,8和9上可能会发生缓冲区忙,当一个用户读取存储器时,并且第二个用户想要读取该块。而不是第二个用户尝试将该块读入内存,他们只是等待第一个用户完成。从Oracle 10开始,这种等待是重命名“其他会议读书”

bbw in intern.
如果多个并发用户插入到表的表中’t有免费列表或不在assm表空间中,那么所有用户都将最终插入同一块,第一个在免费列表中,这个块将成为热块
通过添加免费列表或将表移动到ASSM表空间,我们将缓解瓶颈。
多个免费列表:
另一个选项是ASSM或自动段空间管理,其设置为表空间级别。
在这种情况下,空闲块信息保持在1级BMB(或位图块)。这些级别1 BMB由用户进程ID上的哈希选择,从而在表中分配插入物。
插入件看起来像这样(有些夸张的绘图)
ASSM BMB块在表中占用更多空间,每16个数据块约1个额外块,并且在标题/级别3 BMB块中有一个开销,然后进入级别2然后级别1,最后到达数据级别所有ASSM中所有人都值得管理管理经文的成本。
识别和创建ASSM表空间
哪些表空间是截误的?

select

        tablespace_name,
        extent_management  LOCAL,
        allocation_type    EXTENTS,
        segment_space_management ASSM,
        initial_extent
from dba_tablespaces

桌子SPACE_NAME LOCAL      EXTENTS   ASSM

--------------- ---------- --------- ------
SYSTEM          LOCAL      SYSTEM    MANUAL
UNDOTBS1        LOCAL      SYSTEM    MANUAL
SYSAUX          LOCAL      SYSTEM    AUTO
TEMP            LOCAL      UNIFORM   MANUAL
USERS           LOCAL      SYSTEM    AUTO
EXAMPLE         LOCAL      SYSTEM    AUTO
DATA            LOCAL      SYSTEM    MANUAL
创建ASSM表空间:

create tablespace data2 

datafile '/d3/kyle/data2_01.dbf' 
size 200M
segment space management auto;

索引上的bbw(因为插入)

如果用户正在插入具有上升键值的数据,尤其是单调上升的值,那么所有新插入件都必须更新索引的前沿叶块,并且具有高并发插入,这可能导致缓冲区繁忙等待。
解决方案
哈希分区索引
反向关键索引

BBW旧式RBS

如果块类> 18 it’旧式rbs段

Select  CURRENT_OBJ#||' '||o.object_name objn,

          o.object_type otype,
          CURRENT_FILE# filen,
          CURRENT_BLOCK# blockn,
          ash.SQL_ID,
          w.class ||' '||to_char(ash.p3) block_type
from v$active_session_history ash,
      (select rownum class#, class from v$waitstat ) w,
       all_objects o
where event='buffer busy waits'
    and w.class#(+)=ash.p3
    and o.object_id (+)= ash.CURRENT_OBJ#
Order by sample_time;    

OBJN        OTYPE  FILEN  BLOCKN SQL_ID        BLOCK_TYPE

----------- ------ ------ ------ ------------- ------------
54962 TOTO1 TABLE     16   45012 8gz51m9hg5yuf data block 
54962 TOTO1 TABLE     16     161 8gz51m9hg5yuf segment header
0                     14       9 8gz51m9hg5yuf  87
0                     14       9 8gz51m9hg5yuf  87

如果块是课程>18,那里没有对象名称,所以我们必须自己看待自己:

select  segment_name,  

            segment_type
from     dba_extents 
where
     &P2  between 
    block_id and block_id + blocks – 1
     and 
     file_id = &P1 ;

插入14对于P1文件#和9对于P2块编号:

SEGMENT_NAME   SEGMENT_TYPE

-------------- --------------
R2             ROLLBACK
解决方案
移动到新的AUM或自动撤消管理
alter system set undo_management=auto  scope=spfile;
BBW在文件标题上
ASH数据有两个不同的字段,指示文件#和块#当等待是缓冲区繁忙等待时。
对于缓冲区忙碌等待
    文件#= p1 *和*文件#= current_file#
    块#= p2 *和* block#= clust_block#
如果p1!= current_file#或p2!= current_block#然后使用p1和p2。他们更可靠。
例如

Time   P1  P2 OBJN OTYPE FN BLOCKN BLOCK_TYPE

----- --- --- ---- ----- -- ------ -----------------
11:44 202   2 -1          0      0 file header block
11:44 202   2 TOTO TABLE  1  60218 file header block
11:44 202   2 TOTO TABLE  1  60218 file header block
11:44 202   2 TOTO TABLE  1  60218 file header block
11:44 202   2 TOTO TABLE  1  60218 file header block
注意P1!= blockn(blockn是current_block#)和p2!= fn(fn是current_file#)
实际文件#是p1 = 202,块#是p2,是2
在我的数据库中,我只有10个文件,所以这个文件#202是什么?!
解决方案
如果您在临时文件标题块上忙于等待Quifile(临​​时表空间中的数据文件),则尝试增加“next extent”临时表空间中的大小。
当在临时表空间中分配大量范围时,可以发生这种等待。
什么 Would ADDM do?
足够的addm页面没有’T显示最近系统的新负载,但分析在那里。我点击了页面旁边的底线,“在数据库块上读写争用正在消耗重大的数据库时间。
以下是不同方案的输出。
 插入表争用
 插入索引争用的表中
 
 
rbs争用
 
文件标题争用

 

2 thoughts on “甲骨文 : buffer busy wait

评论被关闭。