日志文件的操作部分总结
1 性能调整的重点是减少磁盘的物理i/o。
2 频繁执行更新处理,代表对数据文件(磁盘)会产生频繁的I/O,也就是会数据文件频繁的写入和读取。每次执行写入和读取的时候,磁盘head就会移动到目的位置,也就是发生“seek overhead”。如果统计 seek overhead所花费的时间(计入磁盘I/O),你就会发现,这就可能是降低性能的原因。
然而,对日志文件的读取操作完全不会发生(数据库出现故障执行复原处理的情况除外),因此REDO日志文件因读取而发生的seek overhead完全不存在。再则,REDO日志文件都是顺序写入的,即总是从head的所在位置开始写入。 因此,无须将head移到要写入的位置而产生seek overhead,所以相较于对数据文件的写入,REDO日志文件执行写入处理更快
对于数据库内所有被更改的数据块,Oracle会把所有更改内容记录在REDO日志缓冲区。更改内容包括数据段,索引段和回滚段(rollback segment)。 数据库内任意数据块所产生的一次更改,会被记录为一个变更向量(Change Vector)。 变更向量里包含了发生变化的数据块的地址和更新前的数据。
数据库记录变更的最小单位是变更向量,一系列相关变更向量的集合称为重做记录 (REDO Record)。有些事务(transaction)会产生不止一个重做记录, 每个重做记录里都包含了一连串的变更向量。下面,我们就以实例追踪变更向量和重做记录产生的过程。
──SQL语句──
*************************************************************
UPDATE WORK03
SET EMPNO = 9999
WHERE EMPNO = 1111 ;
※ EMPNO项目尚未创建索引
*************************************************************
运行上面的UPDATE语句之后,会产生下面的变更向量。
1. 对于回滚段的事务表(header)的变更向量
事务表中包含被修改的数据块的地址、该事务的状态(commit或active)、 以及存有该事务的UNDO的回滚段的位置,如果事务表被修改,就会产生针对于它的变更向量。
2. 对于回滚段的数据块的变更向量
将修改前的值(1111)存储(修改)到回滚段里的数据块时,就会产生变更向量。
3. 对于WORK03表内的数据块的变更向量
将修改后的值(9999)覆盖(修改)到WORK03表内的数据块时,就会产生变更向量。
由上面的例子可知,对于这个事务,重做记录中会有三个变更向量。当然可能有其他情况会产生重做记录, 例如修改的项目如果有索引,就必须修改索引,这时候就会产生第二个重做记录。 这时候的重做记录还是和第一个重做记录一样,包含不止一个变更向量。此外, 在事务完成之后运行commit语句,就会产生第三个重做记录。
把REDO信息写入到REDO日志缓冲时,Oracle必须取得REDO allocation latch和REDO copy latch这两个latch。
REDO allocation(分配) latch:在REDO日志缓冲内,分配空间给要存入的REDO entry时所需的latch。
REDO copy latch:当REDO entry太大,无法以REDO allocation latch执行copy时,REDO copy latch会代替REDO allocation latch执行copy。
这两个latch的功能和作用请参考下图的说明。图中提到REDO entry的大小,主要取决于初始设定参数LOG_SMALL_ENTRY_MAX_SIZE。
http://www.performance-insight.com/html/ora3/ora3_ref/ref85.gif
假设这个参数设定为80 (Oracle7.2之前是800),也就是说,对于80 byte以下的REDO entry由REDO allocation latch执行copy,超过80 byte的REDO entry就由REDO copy latch执行copy。
这种结构是因为REDO allocation latch只有一个,所以当REDO allocation latch在copy比较大的REDO entry时,又发生下一个REDO entry,就必须等到REDO allocation latch恢复闲置才能进行copy,也就是存在时间等待。 因此,把copy任务交给多个REDO copy latch处理,可以预防REDO信息的copy中断。
此外,因为决定REDO copy latch数目是由初始设定参数LOG_SIMULTANEOUS_COPIES决定,这个参数的预设值是实际上CPU的个数,可以增加到CPU个数的2倍。(可以通过初始化参数CPU_COUNT动态指定为CPU的个数)
此外,在单CPU系统下这个参数的数值会设定为0,所以没有REDO copy latch。因此,不论REDO entry有多大,所有的空间锁定和copy任务都由REDO allocation latch完成。(如果LOG_SIMULTANEOUS_COPIES大于1的话LOG_SMALL_ENTRY_MAX_SIZE就会有效)