1 undo的作用
当进程更改数据库中的数据时,Oracle数据库服务器保存旧值(undo data)。它存储修改前的数据,捕获undo数据使能够回滚未提交的数据。undo支持读一致性和闪回查询。undo还可以用于闪回事务和表。
读一致性性查询提供的结果与查询开始时的数据一致。要使读一致性的查询成功,原始信息必须仍然作为undo信息存在。如果原始数据不再可用,则会收到“Snapshot too old”错误(ORA-01555)。只要保留了undo信息,Oracle数据库服务器就可以重新构造数据,以满足读取一致的查询。
闪回查询查询过去某个时间的版本。只要过去时间的undo信息仍然存在,闪回查询就可以成功完成。Oracle闪回事务使用undo创建补偿事务,以undo事务及其依赖事务。使用Oracle闪回表,可以将表恢复到特定的时间点。
undo数据还用于从失败的事务中恢复。当用户在决定提交或回滚事务之前,用户会话非正常结束(可能是由于网络错误或客户端计算机上的故障),发生失败的事务,当实例崩溃或发出SHUTDOWN ABORT命令时,也可能发生失败的事务。
2 活跃事务的数据空间优先
在事务失败的情况下,选择最安全的行为,Oracle数据库服务器将逆转用户所做的所有更改,从而恢复原始数据。
undo信息对所有正在进行的事务都保留,至少保留到由以下任一项结束:
用户撤销事务(事务回滚)。
用户结束事务(提交事务)。
用户执行DDL语句,如CREATE、DROP、RENAME或ALTER语句。如果当前事务包含任何DML语句,数据库服务器首先提交事务,然后执行并将DDL作为一个新事务提交。
保留的undo数据的数量和时间取决于数据库活动的数量和数据库配置。
3 undo与事务的关系
当一个事务开始时,它被分配给一个undo段。在事务的整个生命周期中,当数据被更改时,原始值(在更改之前)被复制到undo段中。通过检查V$TRANSACTION动态性能视图,可以看到哪些事务分配给了哪些undo段。
undo段是数据库服务器根据需要自动创建的专用段,以支持事务。与所有段一样,undo段由区组成,区又由数据块组成。undo段会根据需要自动增长和缩小,充当它们所分配事务的循环存储缓冲区。
事务填满它们的undo段中的区,直到事务完成或所有空间被消耗。如果一个区段已填满,需要更多的空间,则事务从段中的下一个区获得该空间。在使用完所有区之后,事务要么将其装载回第一个区,要么请求一个新的区分配给undo段。
注意:并行DML和DDL操作实际上会导致事务使用多个undo段。
4 undo段的创建
undo段只能存在于一种称为undo表空间的表空间的特殊形式中。(不能在undo表空间中创建其他段类型,比如表。)
数据库配置助手(DBCA)自动创建一个小文件undo表空间。还可以创建一个大文件undo表空间。但是,在具有许多短并发事务的高容量在线事务处理(OLTP)环境中,可能会在文件头发生争用。存储在多个数据文件中的undo表空间可以解决这个潜在问题。
尽管一个数据库可能有许多undo表空间,但是对于数据库中的任何实例,一次只能指定其中一个undo表空间。
undo段是自动创建的,并且总是由SYS拥有。因为undo段充当循环缓冲区,所以每个段至少有两个区。默认的最大区数取决于数据库块大小,但是这个值非常高(对于8 KB的块大小,为32,765)。
Undo表空间是永久的、本地管理的表空间,具有自动的区分配。它们由数据库自动管理。
因为需要从失败的事务(比如实例崩溃时可能发生的事务)中恢复undo数据,所以只能在实例处于挂载状态时恢复undo表空间。
5 undo与redo
undo数据和redo数据一开始看起来很相似,但它们的用途不同。如果需要undo更改,则需要undo数据,这是为了读取一致性和回滚。如果需要再次执行更改,并且由于某些原因丢失了数据,则需要重做数据。undo块更改也被写入重做日志。
提交过程需要验证事务中的更改是否已写入重做日志文件,该文件是磁盘上的持久存储,而不是内存。此外,重做日志文件通常是多路复用的。因此,磁盘上有重做数据的多个副本。虽然更改可能还没有写到实际存储表块的数据文件中,但写到持久重做日志足以保证数据库的一致性。
假设就在提交的更改反映到数据文件之前发生了断电。这种情况不会导致问题,因为事务已经提交。当系统再次启动时,它能够前滚在宕机时没有反映在数据文件中的任何重做记录