非常尴尬,由于日志限制标题不能超过100个字符,所以这次没法把latch的名称写在标题里了,那经历了buffer cache和shared pool这两个内存结构以后,那今天自然而然的就是log buffer了,和redo相关的latch主要是以下三个:redo copy latch,redo allocation latch和redo writing latch。

还是老样子,先从redo和log buffer的原理入手。

所谓redo大家自然已是知晓,为了防止数据库的突然损坏,将数据库中所有改变数据块的操作都记录下来,并以文件的形式存放,这些文件被称为redo log,而log buffer则是oracle用来暂时存放这些redo信息的内存结构。

在 oracle中记录redo信息的最小单位是改动向量,也就是change vector,一个改动向量是指对单个数据块所做的一次改动,而当多个改动向量的按照先后顺序的组合成为重做记录,也就是redo record,redo record相当于操作系统所说的原子操作,也就是要么一个change vector都不做,要做就全做。

简单 介绍了一下原理之后,我们就看看一条sql语句所引起的一系列和redo相关的流程。当一个session提交的sql语句产生redo时,首先现在 pga之中产生,然后会有oracle的相关进程将其copy到log buffer中,而这个时候就会占有redo copy latch,在复制之前必须获得redo copy latch,而这个latch也是表明正在有进程向log buffer里面写入redo信息,那为什么要有这样一个latch存在来标识这样一个状态呢?

我们知道oracle中LGWR进程用来将 log buffer中的内容真正写到联机重做日志文件里面去,那如果一个redo的信息正在从pga copy到log buffer的时候那LGWR进程则必须等待,否则一边更改log buffer的内容一边写入日志文件会导致数据出错,所以这个redo copy latch是用来做这个保护的。redo copy latch有很多,而当LGWR必须等待所有的redo copy latch都空闲时才能启动。

在 获取到了redo copy latch以后,就要马上获取redo allocation latch,redo allocation latch是保护log buffer里的数据块的,也就是用来分配和释放空间的。需要注意的是一个实例只有一个redo allocation latch,也就是说一次只能有一个进程在log buffer里面分配空间,分配完空间以后就可以释放这个redo allocation latch了,但是redo copy latch还没有释放,一直到所有redo信息都写入到log buffer里面以后才会释放redo copy latch。

到这里还没完,log buffer总有用满的时候,那这个时候必须把log buffer里面的内容写到日志文件中或者session发出的commit的指令的时候,进程必须先获取redo writing latch,用来通知LGWR将log buffer的内容写入日志文件,同时也防止其他进程再次没有意义地频繁通知LGWR,毕竟LGWR不可能只刷新通知他的进程所占有的log buffer,既然已经启动了,干脆来个大的,o小白觉得更加偏向于对性能上的一种考虑吧。

和前几个latch不同,这几个latch几乎 没有什么好调整的,当然还是可以通过隐藏参数调整redo copy latch,_LOG_SIMULTANEOUS_COPIES,缺省值是cpu的两倍,而且也没什么好调整的,redo allocation latch在一个实例中也只能拥有一个,只能从这些latch的争用看出数据库的繁忙情况。而redo writing latch如果过高的话可能是没有必要的commit太多导致的,那和前几期介绍的latch不同,这期和redo相关的latch一般不会是性能所主要 考虑的问题,但是对它们做下了解还是很有好处的。

o小白的latch到这里应该是终结了,latch数量实在太多,在做实验的时候甚至有很多latch在网上都查不到的,那也算是抛砖引玉吧,希望大家有自己的心得体会也可以多交流。latch结束了之后应该会是lock,锁这个东西还远远没那么简单呢~