LATCH的产生过程

来源:互联网 发布:lovelace第一位程序员 编辑:程序博客网 时间:2024/05/18 15:06

本文:

一、LATCH的产生过程

 失败:请求-SPIN-休眠-请求-SPIN-休眠。。。

 成功:请求-获得latch-pin住块-释放buffer chains。。。

二、         

模拟buffer busy wait实验

模拟latch free:cache buffer chain latch实验

 

 

LATCH的产生过程
现在来看看进程获取Latch的详细过程,任何时候,只有一个进程可以访问内存中的某一个块(9I提出的Latch共享我不想考虑),如果进程因为别的进程正占用块而无法获得Latch时,他会对CPU进行一次spin(旋转),时间非常的短暂,spin过后继续获取,不成功仍然spin,直到spin次数到达阀值限制(这个由隐含参数_spin_count指定),此时进程会停止spin,进行短期的休眠,休眠过后会继续刚才的动作,直到获取块上的Latch为止。进程休眠的时间也是存在算法的,他会随着spin次数而递增,以厘秒为单位,如1,1,2,2,4,4,8,8,。。。休眠的阀值限制由隐含参数_max_exponential_sleep控制,默认是2秒,如果当前进程已经占用了别的Latch,则他的休眠时间不会太长(过长会引起别的进程的Latch等待),此时的休眠最大时间有隐含参数_max_sleep_holding_latch决定,默认是4厘秒。这种时间限制的休眠又称为短期等待,另外一种情况是长期等待锁存器(Latch Wait Posting),此时等待进程请求Latch不成功,进入休眠,他会向锁存器等待链表(Latch Wait List)压入一条信号,表示获取Latch的请求,当占用进程释放Latch时会检查Latch Wait List,向请求的进程传递一个信号,激活休眠的进程。Latch Wait List是在SGA区维护的一个进程列表,他也需要Latch来保证其正常运行,默认情况下share pool latch和library cache latch是采用这个机制,如果将隐含参数_latch_wait_posting设置为2,则所有Latch都采用这种等待方式,使用这种方式能够比较精确的唤醒某个等待的进程,但维护Latch Wait List需要系统资源,并且对Latch Wait List上Latch的竞争也可能出现瓶颈。

如果一个进程请求,旋转,休眠Latch用了很长时间,他会通知PMON进程,查看Latch的占用进程是否已经意外终止或死亡,如果是则PMON会清除释放占用的Latch资源。

现在大家可以明白,对Latch获取的流程了,请求-SPIN-休眠-请求-SPIN-休眠。。。占用,这里有人会问为什么要SPIN,为什么不直接休眠等待?这里要明白休眠意味着什么,他意味着暂时的放弃CPU,进行上下文切换(context switch),这样CPU要保存当前进程运行时的一些状态信息,比如堆栈,信号量等数据结构,然后引入后续进程的状态信息,处理完后再切换回原来的进程状态,这个过程如果频繁的发生在一个高事务,高并发进程的处理系统里面,将是个很昂贵的资源消耗,所以他选择了spin,让进程继续占有CPU,运行一些空指令,之后继续请求,继续spin,直到达到_spin_count值,这时会放弃CPU,进行短暂的休眠,再继续刚才的动作,Oracle软件就是这么设计的

 

 

 

模拟buffer busy wait实验

 


 

 

什么是buffer busy wait?

        A session that reads or modifies a buffer in the SGA must first acquire the cache buffers chains latch and traverse the buffer chain until it finds the necessary buffer header. Then it must acquire a buffer lock or a pin on the buffer header in shared or exclusive mode, depending on the operation it intends to perform. Once the buffer header is pinned, the session releases the cache buffers chains latch and performs the intended operation on the buffer itself. If a pin cannot be obtained, the session waits on the buffer busy wait event. This wait event does not apply to read or write operations that are performed in sessions’ private PGAs.

此实验是不断的去更新同一个块中的不同记录,通过这种方式可以造成buffer busy wait等待.

--创建测试表

create table test_db
(
   ID NUMBER,
   NICK VARCHAR2(30)
   );
   
SQL> insert into test_db values(1,'zhaolin');

1 row created.

SQL> commit;

Commit complete.

SQL> insert into test_db values(2,'nature');

1 row created.

SQL> commit;

Commit complete.

SQL> select rowid,t.* from test_db t;

ROWID                      ID NICK
------------------ ---------- ------------------------------
AAAByLAAFAAAASuAAA          1 zhaolin
AAAByLAAFAAAASuAAB          2 nature

--检查这两条记录是否在同一个块上

SQL> select dbms_rowid.ROWID_RELATIVE_FNO(rowid) file#,dbms_rowid.ROWID_BLOCK_NUMBER(rowid) block# f
rom test_db;

     FILE#     BLOCK#
---------- ----------
         5       1198
         5       1198

 

--session 1

SQL> select sid from v$mystat where rownum<2;

       SID
----------
        11

declare
   i number:=0;
begin
     loop

        update test_db set nick='session1' where id=1;

        i:=i+1;
        if mod(i,100)=0 then
            commit;
        end if;
     end loop;
end;

 

--session 2

SQL> select sid from v$mystat where rownum<2;

       SID
----------
        12

declare
   i number:=0;
begin
     loop

        update test_db set nick='session2' where id=2;

        i:=i+1;

        if mod(i,100)=0 then
            commit;
        end if;
     end loop;
end;   

 

--我们再启动会话session3

SQL> select s.sid,w.event from v$session s,v$session_wait w
  2                       where s.sid=w.sid
  3                       and s.status='ACTIVE';

       SID EVENT
---------- ----------------------------------------------------------------
         1 pmon timer
         2 rdbms ipc message
         3 rdbms ipc message
         4 control file sequential read
         5 smon timer
         6 rdbms ipc message
         7 rdbms ipc message
         8 wakeup time manager
         9 rdbms ipc message
        10 rdbms ipc message
        
11 buffer busy waits

       SID EVENT
---------- ----------------------------------------------------------------
        
12 latch free
        18 SQL*Net message to client

13 rows selected.

SQL> /

       SID EVENT
---------- ----------------------------------------------------------------
         1 pmon timer
         2 rdbms ipc message
         3 rdbms ipc message
         4 rdbms ipc message
         5 smon timer
         6 rdbms ipc message
         7 rdbms ipc message
         8 wakeup time manager
         9 rdbms ipc message
        10 rdbms ipc message
       
 11 latch free

       SID EVENT
---------- ----------------------------------------------------------------
        
12 buffer busy waits
        18 SQL*Net message to client

13 rows selected.

注:这里出现的latch free是cache buffer chain latch等待,当会话11正在更新块1198中记录时,会话12想去更新块1198中的不同记录时,这时会话12出现buffer busy waits等待事件。当会话11更新块1198中记录完成,释放排它性的pin,又要去获得cache buffer chain latch时,但此时会话12还没有以exclusive的方式pin住1198块,所以会话12还没有释放cache buffer chain,因为这样,会话11出现latch free等待!

 

原创粉丝点击