redo是ORACLE在线重做日志文件中记录的信息,当数据库发生故障时,我们可以利用这些数据重做事物。undo是oracle在undon段中记录的信息,它主要用于取消或回滚事物。
1、Oracle维护着两类重做日志文件:在线(online)重做日志文件和归档(archived)重做日志文件。这两类重做日志文件都用于恢复;其主要目的是,万一实例失败或介质失败,它们能够恢复数据。由于数据库缓冲,对磁盘数据的更新不是实时的,但是对redo日志的更新会在commit之后确切发生。 如果在事务提交之后,磁盘数据更新之前,系统发生故障,在系统重启之后会将那些已经写入redo,但是还没有更新到磁盘的数据进行重做,这样系统就恢复到故障时间点之前了。 redo日志默认有3组,循环写入,第一组(每个组所有成员同时写入同样的信息)满了,切换到第二个,第二个满了切换到第三个,当所有组都写满之后,日志进程再次开始写第一个,后面的数据覆盖前面的数据,即为非归档模式。 鉴于redo如此重要,需要将已写满的日志归档,即复制内容到其他地方,生成数据库基本都是开启归档日志模式,但是会影响系统性能。
2、对数据执行修改时,数据库会生成undo信息,这样当你执行的事务或语句由于某种原因失败了,或者你用一条ROLLBACK语句请求回滚,就可以利用这些undo信息将数据放恢复到修改前的样子。redo用于在失败时重放事务(即恢复事务),undo则用于取消一条语句或一组语句的作用。undo保存在undo表空间中,且包含在redo日志中。当执行DML操作时,旧数据会写入undo中。事务回滚,未提交时,rollback,把undo中的旧数据重新写回数据段中;已提交时,进行闪回(flashback)操作 ,大多都是基于undo数据实现的。读一致性:用户检索数据时,ORACLE总是使用户只能看到被提交过的数据(当前事务中的其他语句可以看到未提交的数据),或者特定时间点的数据(select语句时间点)。当某个用户在此查询点之后修改了数据,此查询读到这个数据时,就是通过在undo中读取来实现的。oracle使用scn来实现读一致性,系统变化号(SCN)是一个数据结构,它定义了一个给定时刻提交的数据库版本,SCN可以被认为是oracle的逻辑时钟,每一次提交数值都要增加。
undo只是逻辑地恢复到原来的样子,所有修改都被逻辑地取消,但是数据结构以及数据库 块本身在回滚后可能大不相同。比如一个插入操作,新分配了一些数据块。后来事务失败,插入操作全部回滚,新分配的一些数据块还是存在的原因在于:在所有多用户系统中,可能会有数十、数百甚至数千个并发事务。数据库的主要功能之一就是协调对数据的并发访问。也 许我们的事务在修改一些块,而一般来讲往往会有许多其他的事务也在修改这些块。因此,不能简单地将一个块放回到我们的事务开始前的样子,这样会撤销其他事务的工作! 所以只有redo与undo如何协作保证数据完整与安全性!