简述undo,redo与Recovery概念

简述undo,redo与Recovery概念
By Jonathan Lewis, Translated By Jametong

简述回滚(undo),重做(redo)恢复(Recovery)概念.(标题中的”1”可能只是个乐观的说法,我不保证还有后续的简述.)

当你修改一个数据块时(修改表中的一条记录,或者标记一个索引条目为deleted状态),Oracle会做如下的事情:

• 生成一些redo(称为改变向量,change vector)来描述对应表数据块的变更

• 生成一些undo来描述数据修改前的版本

o 这实际上还意味着生成一些redo(另外一个改变向量)来描述如何生成undo

• 将上述改变信息写入redo log buffer

o 上述的改变向量对一起(回滚块的改变向量靠前)组成一个重做记录(redo record)

• 修改回滚数据块(undo block)

• 修改表数据块

在将表数据块与回滚数据块写到磁盘之前,必须确保重做日志已经写到磁盘.尽管如此,回滚数据块与修改后的表数据块最终还是会写到磁盘上,即使这次改变并没有被提交也是如此.

一个常见问题: 如果在事务提交之前,数据库就crash了,如果新的未提交的数据已经覆盖了磁盘上的旧有版本,Oracle将如何恢复数据.

答案: 当数据库crash后,恢复进程知道每个文件的最后的检查点时间,并应用重做日志恢复每个文件到最新状态.这个机制也会将回滚表空间恢复到最新状态,如同处理其它持久的表空间一样.

一旦数据库被恢复到最新状态,恢复进程就可以看到表数据块与回滚数据块的最新版本.由于回滚表空间(包含回滚段头(undo segment header)块,进而事务表(transaction table))是最新的,恢复进程可以发现这个事务没有提交,因此它可以做一次回滚操作以从回滚数据块上恢复表原来的数据.

脚注:

上面对数据改变的描述是最普遍的例子,还有一些显著提高这个机制的复杂性的特殊情况.特别是,如果你的变化是发生在事务开始的时候,还需要一些特殊的处理,在Oracle 10g的单实例数据库中,可以利用”私有重做线程(private redo thread)”与”基于内存的回滚(in-memory undo)”,对一个事务的最初几个变更做特别的优化.

请参考”Oracle词汇表”中”回滚段头(undo segment header)”与”事务表(transaction table)”的相关说明.

你可能感兴趣的:(undo)