1. 关于log buffer大小设置的误区
大小不要超过3m,因为log buffer中脏数据超过1m 就会触发lgwr进行去写,同时超过1/3 log buffer大小时,也会触发。
因此,网上流传的结论是1*3=3m,认为超过3m 的log buffer大小设置是毫无意义的?
早期的原理的直接写入redo logfile中,为了避免IO问题能在sga中引入了一块 共享的内存区域,即log buffer。 即当满足一定
条件之后,lgwr进程再从log buffer中写出到logfile中去
从上图我们可以看出,redo log buffer位于Oracle SGA中,且与log buffer相关的就2类进程,Server Process和LGWR进程。 其中
Server Process进程负责将redo entry从pga中copy到log buffer中,而lgwr进程负责将log buffer中的redo条目信息写出到logfile文
件中。
对于Redo Log buffer 的结构,我们将上图中的部分进行放大,如下图所示:
我们可以看出,redo log buffer这个内存区域的结构是一个环状结构,由于log buffer是覆盖重复利用的,因此,虽然存在多种
lgwr触发的机制,但是如果log buffer区域设置过小,那么redo log buffer区域在被覆盖之前必须要进行等待。
因此,Redo log buffer设置大一点,是没有任何坏处的。
Oracle 9.2版本之前的redo entry信息是在PGA中的产生,然后由User Server Process进程copy到log buffer中去。大概是这样一个流
程:
PGA中产生Redo Enrey -&get;
Server Process获取Redo Copy latch(存在多个---CPU_COUNT*2) -&get;
Server Process获取redo allocation latch(仅1个) -&get;
在log buffer中分配空间 -&get;
释放redo allocation latch -&get;
将Redo Entry写入Log Buffer -&get;
释放Redo Copy latch;
从上面的流程我们可以看出,Oracle 9.2版本之前,redo allocation latch 只有一个,Oracle 为了降低redo allocation latch的争
用,从9.2版本
引入了一个新的机制:redo log buffer并行机制。
何为log buffer 并行机制 ? ----&get;其实就是类似9.2版本引入的shared pool的subpool机制。 将redo log buffer划分为多个
相同的log buffer子池。
每一个小的log buffer被称为strand,每个strand都有一个redo allocation latch。 这样就提高了并发机制。
对于log buffer子池(或称shared strand)的个数,在9.2版本中受如下的参数控制:
SQL&get; show parameter log_paral
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
log_parallelism integer 1
SQL&get; show parameter cpu_count
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
_cpu_count integer 0
cpu_count integer 1
为什么说private strands的引入,基本上彻底解决了redo allocation latch争用的问题呢 ?
首先我们来看下10gR2中的redo allocation latch的个数:
SQL&get; select count(1),name from v$latch_children where name='redo allocation' group by name;
COUNT(1) NAME
---------- --------------------------------------------------
62 redo allocation