latch free(cache buffers chain)

         Oracle在buffer cache内存管理中利用hash table来提高进程检索数据的速度,一般来说oracle利用hash算法将buffer cache分割成不同的hash bucket,每hash bucket都会有一个hash链(cache buffers chains)来管理buffer cache中的每一个buffer,那么这些buffer的header就是存放在这个cache buffers chains上面的,因此进程根据pid的hash算法,来访问某一个hash bucket中的buffer header时,首先要获得每一个hash bucket中cache buffers chains的一个latch,也就是我们所谓的闩。latch其实就是一种非常低级的串行化设备,和锁的数据结构有着截然不同的特点,只所以说他是低级的,就是因为相比锁来讲他的获得和释放都非常的快。同时latch的存在会使的我们的共享设备在进程并发访问的情况下对其进行数据结构的保护。
下面来做个实验就是,让一个block很热,从而观察cache buffers chains上面latch的竞争。

SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.8.0 - Production
PL/SQL Release 9.2.0.8.0 - Production
CORE    9.2.0.8.0       Production
TNS for 32-bit Windows: Version 9.2.0.8.0 - Production
NLSRTL Version 9.2.0.8.0 - Production

SQL> select file_name from dba_data_files;

FILE_NAME
----------------------------------------------------------------------

D:\ORACLE\ORA92\ICMNLSDB\SYSTEM01.DBF
D:\ORACLE\ORA92\ICMNLSDB\UNDOTBS01.DBF
D:\ORACLE\ORA92\ICMNLSDB\INDX01.DBF
D:\ORACLE\ORA92\ICMNLSDB\TOOLS01.DBF
D:\ORACLE\ORA92\ICMNLSDB\USERS01.DBF

SQL> create tablespace assm
  2  datafile 'D:\ORACLE\ORA92\ICMNLSDB\assm.dbf' size 10M
  3  extent management local uniform. size 1M
  4  segment space management auto;

表空间已创建。

SQL> create table t
  2  (id number,
  3   name char(10)) tablespace assm;

表已创建。

SQL> insert into t values (1,'A');

已创建 1 行。

SQL> commit;

提交完成。

SQL> select id,rowid from t;

        ID ROWID
---------- ------------------
         1 AAAGP5AAGAAAAAXAAA

这里我们只插入一行的数据,然后频繁的针对这个block进行并发访问,导致这个block header所在的cache buffers chains上的latch产生竞争。

创建测试脚本
SQL> create or replace procedure latch_test
  2  as
  3  cursor my_cursor is select id from t where rowid='AAAGP5AAGAAAAAXAAA';
  4  t_result number(5);
  5  begin
  6  for i in 1..700000 loop
  7  open my_cursor;
  8  fetch my_cursor into t_result;
  9  close my_cursor;
 10  end loop;
 11  end;
 12  /

过程已创建。

在3个session上面同时运行测试脚本,并进行监控:

运行脚本之前......

SQL> select sid,event,time_waited,time_waited_micro,total_timeouts,total_waits
  2  from v$session_event
  3  where sid in (7,8,9) and event like '%latch%';

未选定行

SQL> select misses,gets,sleeps,spin_gets,sleep1,sleep2,sleep3,sleep4
  2  from v$latch where name='cache buffers chains';

    MISSES       GETS     SLEEPS  SPIN_GETS     SLEEP1     SLEEP2     SLEEP3
---------- ---------- ---------- ---------- ---------- ---------- ----------
    SLEEP4
----------
         0       8241          0          0          0          0          0
         0

开始在3个不同的session同时运行脚本......

继续观察

SQL> select sid,event,time_waited,time_waited_micro,total_timeouts,total_waits
  2  from v$session_event
  3  where sid in (8,9,10) and event like '%latch%';

       SID EVENT
---------- ----------------------------------------------------------------
TIME_WAITED TIME_WAITED_MICRO TOTAL_TIMEOUTS TOTAL_WAITS
----------- ----------------- -------------- -----------
         8 latch free
         84            838857             15          24

         9 latch free
         80            803321             15          28

        10 latch free
        101           1011249             17          30

这里出现了三个等待事件,正好是我们在运行脚本时的三个session 8,9,10。

SQL> select misses,gets,sleeps,spin_gets,sleep1,sleep2,sleep3,sleep4
  2  from v$latch where name='cache buffers chains';

    MISSES       GETS     SLEEPS  SPIN_GETS     SLEEP1     SLEEP2     SLEEP3
---------- ---------- ---------- ---------- ---------- ---------- ----------
    SLEEP4
----------
        78    4209205         81          0         75          3          0
         0

因为三个session都在并发的去争夺同一个cache buffer chains上的latch,从而会导致latch的竞争。

如果是单读一个session对block进行访问,我们可以只看到这个latch被gets.而竞争消失。
SQL> /

    MISSES       GETS     SLEEPS  SPIN_GETS     SLEEP1     SLEEP2     SLEEP3
---------- ---------- ---------- ---------- ---------- ---------- ----------
    SLEEP4
----------
        78    5609271         81          0         75          3          0

参考这个
http://space.itpub.net/13095417/viewspace-172809

记录一下sleeps和sleep 1,2,3,4的关系:
sleeps=sleep1*1 + sleep2 * 2 + sleep3 * 3 + ........

v$latch的字段描述
gets       以愿意等待模式请求闩,并获得的次数.
misses     以愿意等待模式请求闩,自旋或睡眠后获得的次数.
sleeps     以愿意等待模式请求闩,睡眠的次数.
spin_gets  第一次自旋即成功获得闩的次数.
sleep1     睡眠一次后获得闩的次数.
sleep2     睡眠两次后获得闩的次数.
sleep3     睡眠三次后获得闩的次数.
sleep4     睡眠四次以上获得闩的次数.

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12361284/viewspace-201610/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/12361284/viewspace-201610/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值