在一个多用户的并发系统中,大量用户进程都需要向Redo Log Buffer写入重做数据,Oracle通过Latch来保护和协调Redo Log Buffer的工作。同Redo相关的Latch主要有Redo Copy Lacth、Redo 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之一。
我总结一下:很多人说一个实例redo copy latch只能有一个,也有说redo allocation latch只能有一个的。但是通过对v$latch_children的检查,发现可以是多个。redo copy latch防止一组change vector在copy了一半的时候就被LGWR写入redo log file。redo allocation latch用于一次性分配change vector所需要的block。
|
|