Oracle redo 原理
Redo Log Buffer位于sga_max_size之中,其保存数据库变更的相关信息。这些信息以重做条目(Redo Entries)形式存储(Redo Entries也经常被称为Redo Records)。Redo Entries包含重构、重做数据库变更的重要信息,这些变更包括INSERT、UPDATE、DELETE、CREATE、ALTER或都DROP等。
Redo Entries的内容被Oracle数据库进程从用户的内存空间(PGA)复制到sga_max_size中的Redo Logo Buffer之中。Redo Entries在内存中占用连续的顺序空间,由于Redo Log Buffer是循环使用的。
Log Switch会触发一个检查点,促使DBWR进程将写满的日志文件保护的变更数据写回到数据库。
Oracle通过Latch来保护和协调Redo Logo Buffer的工作。同Redo相关的Latch主要有Redo Copy Latch、Redo Allocation Latch等,Redo Allocation Latch用于管理Log Buffer内存空间的分配,Redo Copy Latch则用于写Redo Log Buffer过程的保护。
## _log_simultaneous_copies用来定义允许同时写的Redo的Redo Copy latch的数量。缺省为CPU的2倍。
SYS@ orcl> @GetHidPar
Enter value for par: log_simultaneous
NAME VALUE PDESC
------------------------------ --------------- --------------------------------------------------
_log_simultaneous_copies 2 number of simultaneous copies into redo buffer(# o
f copy latches)
从v$latch视图可以得到关于Redo Copy Latch的汇总信息:
SYS@ orcl> select name, gets, immediate_gets, immediate_misses, spin_gets from v$latch where name = 'redo copy';
NAME GETS IMMEDIATE_GETS IMMEDIATE_MISSES SPIN_GETS
------------------------------ ---------- -------------- ---------------- ----------
redo copy 10 54084 6 0
SYS@ orcl> select addr, latch#, child#, name, gets, immediate_gets, immediate_misses from v$latch_children where name = 'redo copy';
ADDR LATCH# CHILD# NAME GETS IMMEDIATE_GETS IMMEDIATE_MISSES
-------- ---------- ---------- ---------- ---------- -------------- ----------------
506E3CFC 181 2 redo copy 5 0 0
506E3C84 181 1 redo copy 5 54628 6
Redo Copy Latch获取以后,进程紧接着需要获取Redo Allocation Latch,分配Redo空间,空间分配完成以后,Redo Allocation Latch即被释放,进程把PGA里临时存放的Redo信息COPY入Redo Logo Buffer,COPY完成以后,redo copy latch释放。
为了避免LGWR被不必要的通知,进程需要先获取Redo Writing Latch去检查LGWR是否已经激活或都已经被通知。如果LGWR已经激活或被Post,Redo Writing Latch将被释放。
SYS@ orcl> select addr, latch#, name, gets, misses, immediate_gets, immediate_misses from v$latch where name = 'redo writing';
ADDR LATCH# NAME GETS MISSES IMMEDIATE_GETS IMMEDIATE_MISSES
-------- ---------- -------------------- ---------- ---------- -------------- ----------------
20011204 180 redo writing 503 0 0 0
在执行Redo Copy的过程中,进程以Log File Sync事件处于等待。当进程从Log File Sync中等待醒来以后,进程需要重新获得Redo Allocation Latch检查是否相应的Redo已经被写入Redo Log File,如果尚未写入,进程必须继续等待。
如果对于一个繁忙的数据库系统,该Latch通常也是竞争激烈的Latch之一。
Oracle 9i Redo的增强
在9iR2中,Oracle通过LOG_PARALLELISM定义Oracle中redo allocation的并发级别。如果定义LOG_PARALLELISM大于1,那么数据库将分配多个共享的Redo Log Buffer区域,每个共享Buffer都有独立的Redo Allocation Latch进行保护,从而提高了Redo的并发性能,多个Redo Log Buffer可是被看作是Redo Log Buffer的子池,与Shared Pool的多个Subpool原理类似。多个Redo Log Buffer以被称为Public Redolog Strands。
SYS@ orcl> select name, gets, misses, immediate_gets, immediate_misses from v$latch where name in ('redo allocation', 'redo copy');
NAME GETS MISSES IMMEDIATE_GETS IMMEDIATE_MISSES
---------------- ---------- ---------- -------------- ----------------
redo copy 14 0 96869 10
redo allocation 5400 3 96869 0
如果miss对gets比率超过1%,或都immediate_misses对(IMMEDIATE_MISSES + IMMEDIATE_GETS)比率超过1%,那么通常认为存在Latch竞争。
当主机拥有16~64个CUP时,Oracle推荐设置LOG_PARMLLELISM在2~8之间,这个参数可以提高应用的性能。
SYS@ orcl> select addr, latch#, name, gets, misses, immediate_gets, immediate_misses from v$latch where name = 'redo allocation';
ADDR LATCH# NAME GETS MISSES IMMEDIATE_GETS IMMEDIATE_MISSES
-------- ---------- -------------------- ---------- ---------- -------------- ----------------
200112D4 182 redo allocation 6100 3 97027 0