作者:dbtan |【转载时请以超链接形式标明文章出处作者信息】


Redo与Latch:

在一个多用户的并发系统中,大量用户进程都需要向Redo Log Buffer写入重做数据,Oracle通过Latch来保护和协调Redo Log Buffer的工作。同Redo相关的Latch主要有Redo Copy LacthRedo Allocation Latch等,Redo Allocation Latch用于管理Log Buffer内存空间的分配Redo Copy Lacth则用于写Redo内容到Redo Log Buffer过程的保护

一个进程在修改数据时产生Redo,Redo首先在PGA中保存,当进程需要将Redo信息Copy进入Redo Log Buffer时需要获得Redo Copy Latch,获得了该Latch以后才能把Redo拷贝到Log Buffer中。Redo Copy Latch表明进程正在把Redo拷贝入Log Buffer中,在此过程中,LGWR应该等待直到进程拷贝完成才能把目标Log Buffer Block写入磁盘。

初始化参数_LOG_SIMULTANEOUS_COPIES,定义允许同时写Redo的Redo Copy Latch的数量。在Oracle 7和Oracle 8里,_LOG_SIMULTANEOUS_COPIES缺省等于CPU的数量。从Oracle 8.1.3开始,_LOG_SIMULTANEOUS_COPIES缺省变成2倍的CPU数量,并且成为了一个隐含参数:

sys@NEI> @GetHidPar
Enter value for par: copies
old   4: AND x.ksppinm LIKE '%&par%'
new   4: AND x.ksppinm LIKE '%copies%'
NAME                           VALUE    DESCRIB
------------------------------ -------- ------------------------------------------------------------
_log_simultaneous_copies       8        number of simultaneous copies into redo buffer(# of copy lat
                                        ches)

v$latch视图中可以得到关于Redo Copy Latch的汇总信息:

sys@NEI> select name,gets,immediate_gets,immediate_misses,spin_gets
  2  from v$latch where name='redo copy';
NAME                                 GETS IMMEDIATE_GETS IMMEDIATE_MISSES  SPIN_GETS
------------------------------ ---------- -------------- ---------------- ----------
redo copy                              72         278406              100          0

对于Redo Copy Latch的多个子Latch,可以从v$latch_children视图获得更为详细的信息:

sys@NEI> select addr,latch#,child#,name,gets,immediate_gets,immediate_misses
  2  from v$latch_children where name='redo copy';
ADDR         LATCH#     CHILD# NAME             GETS IMMEDIATE_GETS IMMEDIATE_MISSES
-------- ---------- ---------- ---------- ---------- -------------- ----------------
42D506D8        147          1 redo copy           9         190085               62
42D50754        147          2 redo copy           9          89380               38
42D507D0        147          3 redo copy           9              0                0
42D5084C        147          4 redo copy           9              0                0
42D508C8        147          5 redo copy           9              0                0
42D50944        147          6 redo copy           9              0                0
42D509C0        147          7 redo copy           9              0                0
42D50A3C        147          8 redo copy           9              0                0
8 rows selected.

Redo Copy Latch获取以后,进程紧接着需要获取Redo Allocation Latch,分配Redo空间,空间分配完成以后,Redo Allocation Latch即被释放,进程把PGA里临时存放的Redo信息COPY入Redo Log Buffer,COPY完成以后,Redo Copy Latch释放。

在完成Redo Copy以后,进程可能需要通知LGWR去执行写出(如果Redo Copy是commit等因素触发的)。为了避免LGWR被不必要的通知,进程需要先获取Redo Writing Latch去检查LGWR是否已经激活或者已经被通知。如果LGWR已经激活或被Post,Redo Writing Latch将被释放。

sys@NEI> col name for a20
sys@NEI> select addr,latch#,name,gets,misses,immediate_gets,immediate_misses
  2  from v$latch where name='redo writing';
ADDR         LATCH# NAME                       GETS     MISSES IMMEDIATE_GETS IMMEDIATE_MISSES
-------- ---------- -------------------- ---------- ---------- -------------- ----------------
2000BAC8        146 redo writing             189535          3              0                0

如果Redo Writing Latch竞争过多,可能意味着用户的提交过于频繁。通过系统统计信息或Statspack可以获得这些信息,具体参考log file sync等待事件相关内容。

在执行Redo Copy的过程中,进程以Log File Sync事件处于等待。当进程从Log File Sync中等待中醒来以后,进程需要重新获得Redo Allocation Latch检查是否相应的Redo已经被写入Redo Log File,如果尚未写入,进程必须继续等待。这是一个大致简化的Latch处理过程,用以说明Latch的处理机制。

和Redo相关的另外一个常见Latch是Redo Allocation Latch,当进程需要向Redo Log Buffer写入Redo信息时需要获得此Latch,分配Redo Log Buffer空间。所以,如果对于一个繁忙的数据库系统,该Latch通常也是竞争激烈的Latch之一。

- The End -