log buffer

来源:互联网 发布:手机5g网络怎么设置 编辑:程序博客网 时间:2024/04/30 16:00
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

0 0