访问buffer cache里的数据块时需要先以独占模式申请管理hash bucket的latch,这个latch的名称就是所谓的cache buffers chains,系统中出现latch:cache buffers chains争用往往意味着以下两种可能:
1、多个会话并发访问相同的数据块(这是最常见的一种情况)
2、不同的数据块挂载在同一个hash bucket下,或者虽然挂载在不同的hash bucket下但这些hash bucket恰好受同一个cache buffer chains latch管理(一个latch可以管理多个hash bucket)
以上只是概念上的笼统描述,是否真会引起latch:cache buffers chains等待还与SQL语句的访问路径有关:Full Table Scan的访问路径下确实同上面所描述的,
但在用到索引的情况下是否会触发latch:cache buffers chains取决于以下5种因素:
1、如果是针对于唯一性索引的叶块的等值访问,这里包括仅访问唯一性索引本身和既访问唯一性索引又通过唯一性索引访问数据表两种情况,访问时都会以共享模式申请管理hash bucket的latch,所以即便多个会话并发访问buffer cache里的同一个唯一性索引的块,也不会出现latch:cache buffers chains等待事件,这时能观察到的等待事件一般是"cursor: pin S"
2、如果是针对于唯一性索引的叶块的非等值访问,当然也包含仅访问索引和既访问索引又访问数据表两种情况,访问时都会以独占模式申请管理hash bucket的latch,多个会话并发访问buffer cache里的同一个唯一性索引的块,会出现latch:cache buffers chains等待事件
3、对于非唯一性索引的叶块,和表里的数据块一样会以独占模式申请cache buffers chains latch
4、对于唯一性索引里的同一个索引块如果两个session同时以等值方式访问不会出现latch:cache buffers chains等待
5、对于唯一性索引里的同一个索引块如果分别被两个session以等值、非等值方式访问时会出现latch:cache buffers chains等待
6、没有索引
这里之所以强调叶块,是因为索引里的非叶块访问时都是以共享方式持有cache buffers chains latch的,对于唯一性和非唯一性索引均是如此
以下我们构造几个测试场景了解一下Oracle是如何管理cache buffers chains latch的:其中1~3测试在不同block被同一个latch管理的场景下进行;4~5测试在同一个block被多个session并发访问的场景下进行
#####场景1:一个非唯一性索引的数据块、一个表的数据块被不同的session访问引起latch: cache buffers chains争用
---创建表和索引
create table scott.t1119_cb1 tablespace ts1116 as select * from all_users;
create index scott.ind_t1119_cb1 on scott.t1119_cb1(user_id) tablespace ts1116 ;
---执行计划用到了索引
explain plan for select * from scott.t1119_cb1 where user_id=0;
set linesize 120 pagesize 100
select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1836694578
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 39 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T1119_CB1 | 1 | 39 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IND_T1119_CB1 | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------
---获取表、索引的object_id
select * from dba_objects where object_name in ('T1119_CB1','IND_T1119_CB1');
OWNER OBJECT_NAME SUBOBJECT_NAME OBJECT_ID
SCOTT IND_T1119_CB1 41332
SCOTT T1119_CB1 41331
set linesize 150
select obj,indx,addr,hladdr,flag,lru_flag,class,state,dbarfil,dbablk,ba,tch from x$bh where obj=41332;
OBJ INDX ADDR HLADDR FLAG LRU_FLAG CLASS STATE DBARFIL DBABLK BA TCH
---------- ---------- ---------------- ---------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------------- ----------
41332 82300 00000001109A5358 07000001BCD67618 35651584 0 9 1 5 60713 070000012ACE6000 1
41332 156749 00000001109A5358 07000001BCE25910 35651584 0 1 1 5 60715 0700000123020000 5 select obj,indx,addr,hladdr,flag,lru_flag,class,state,dbarfil,dbablk,ba,tch from x$bh where obj=41332;
OBJ INDX ADDR HLADDR FLAG LRU_FLAG CLASS STATE DBARFIL DBABLK BA TCH
---------- ---------- ---------------- ---------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------------- ----------
41332 82300 00000001109A5358 07000001BCD67618 35651584 0 9 1 5 60713 070000012ACE6000 1
41332 156750 00000001109A5358 07000001BCE25910 35651584 0 1 1 5 60715 0700000123020000 6
当前位置: 数据库>oracle
使用了索引就一定能避免cache buffers chains争用吗
来源: 互联网 发布时间:2017-06-22
本文导语: 访问buffer cache里的数据块时需要先以独占模式申请管理hash bucket的latch,这个latch的名称就是所谓的cache buffers chains,系统中出现latch:cache buffers chains争用往往意味着以下两种可能:1、多个会话并发访问相同的数据块(这是最常见的...