我们已经知道,日志缓冲区用来存放事务对数据块的变化的日志信息。那么这里的日志信息到底包含哪些内容,是由哪些结构组成的呢?
Oracle记录数据库变化(也就是记录日志信息)的最小单位是改动向量(change vector)。改动向量用来描述对数据库中任何单个数据块所做的一次改动。改动向量的内容包括被改动的数据块的版本号、事务操作代码、被改动的数据块的地址等。这里的版本号非常重要,它能够帮助数据块始终能够体现当前最新的状态。Oracle在建立改动向量时,会从数据块中复制其版本号。而当恢复期间,Oracle读取改动向量并将改动应用于相应的数据块以后,被恢复的数据块的版本号加1。这里的数据块可以属于表或数据索引,也可以属于回滚段。但是对于临时表空间里的临时段,不会生成改动向量。
当多个改动向量按照先后顺序组合在一起,从而完成对数据库的一次改动时,Oracle称这组改动向量为重做记录(redo record)。重做记录用来描述对数据库的一个原子改动。所谓原子改动,就是说,当应用改动中的改动向量时,要么全部成功,要么全部失败,不存在部分成功部分失败的情况。重做记录能够帮助整个数据库体现当前最新的状态。
一个事务至少产生一个重做记录,也可能产生多个重做记录。而Oracle在应用日志记录进行恢复的过程中,以事务作为恢复的最小单位。要么恢复整个事务,要么回滚整个事务。也就是说,要么运用事务重做记录里的所有改动向量,要么一个改动向量都不运用。
因此,日志缓冲区就是许多重做记录按照发生的先后顺序组成的。同时,日志文件也就是由许多重做记录按照先后顺序排列在一起而组成的文件。
我们举个实例来说明重做记录和改动向量产生的过程。比如我们发出如下更新语句(假设表redo_test的NAME列上没有建立索引):
SQL> select * from redo_test;
ID NAME
----- ----------
1 abc
2 abc
SQL> update redo_test set name='cdf' where id=1;
该语句发出以后,会产生一个重做记录,用来描述对表中数据块进行的修改。包括下面三个改动向量。
对回滚段事务表的改动,这发生在回滚段段头。事务表中包含被修改的数据块的地址、该事务的状态(commit或active),以及存有该事务所使用的回滚段的地址。如果事务表被修改,就会产生针对它的改动向量。
对回滚段数据块的改动。将修改前的旧值(abc)存放到回滚段的数据块里。这时回滚段发生改变,于是产生改动向量。
对redo_test表的数据块所做的改动。将修改后的新值(cdf)存放到表的数据块里。这时数据块发生改变,于是产生改动向量。
从这个过程可以看到,对于这个update事务,重做记录中会有三个改动向量。当然可能还有其他情况会产生新的重做记录,比如修改的列如果有索引,则必须修改索引。这时就会产生第二个重做记录,用来描述对索引数据块的修改。这时候的重做记录还是和第一个重做记录一样,包含多个改动向量。此外,在事务完成之后运行commit或rollback语句时,就会产生第三个重做记录。该重做记录只有一个改动向量,用来记录对回滚段事务表的更改,因为commit或rollback时,需要更新事务表里记录的该事务的状态。
转载于:https://blog.51cto.com/19880614/1180461