过着简单,真实的生活,喜欢收藏变形金刚(TFE,G1,SL系列),研究金融股市,KOF98,篮球,学习研究Oracle技术,我并不是一个全职的Oracle DBA,但是对于Oracle技术的热爱和研究,是一个不争的事实,愿意结交广大Oracle技术爱好者!MSN:oracle_kof_tf@hotmail.com

latch free(cache buffers chain)

上一篇 / 下一篇  2008-03-07 20:49:18 / 个人分类:Oracle数据库技术-数据库优化

         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     睡眠四次以上获得闩的次数.


TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

Open Toolbar