UNDO管理
UNDO段是用于存储还原数据的特殊段,在发生实例故障的时候,UNDO段用来对数据进行恢复。本章内容包括介绍UNDO段的工作原理,并进行自动和手工的UNDO段的管理。
1 UNDO段的作用
RDBMS(关系数据库管理系统)必须要提供一致性的数据,以确保不会丢失数据或导致数据混乱。例如,当用户去银行取款时,需要在用户储蓄账户上减去取款额,而在银行支出账户上增加取款额,以使得收支平衡。当使用关系数据库处理以上过程时,储蓄账户、支出账户分别对应于数据库表。当用户提款时,分别会在储蓄账户表、支出账户表上使用UPDATE语句执行增减款操作,最终提交事务,以确保收支平衡。
大家设想一下,假设当在储蓄账户上减去取款额之后,因为机器断电导致数据库停止工作,怎么办?你可能会想这会导致收支不平衡,不会的,关系数据库通过事务(Transaction)实现了数据一致性。因为断电时事务尚未完成,所以将来在启动数据库时系统会自动回退未提交操作,并最终保证数据的一致性。从数据库的角度看,如果储蓄账户执行了UPDATE操作后出现断电,那么当重新启动数据库时系统会自动执行还原操作,将修改的数据恢复成原有数据。此时大家可能会问,那么原有数据存放在哪儿呢?当执行INSERT、UPDATAE、DELETE等DML操作时,服务器进程会将原有数据(称为UNDO数据)存放到UNDO段中,UNDO段是专门用于存储还原数据的段。
UNDO数据也被称为回滚(ROLLBACK)数据,它用于确保数据的一致性。当执行DML操作(INSERT、UPDATE、DELETE等)时,操作前的数据被称为UNDO记录。例如, 当执行UPDATE emp SET sal=1000 WHERE empno=7788
语句时,假定雇员7788原有工资为800,原有数据800就是UNDO数据,并且该数据会被存放到还原段中,而新数据1000则会存放到EMP数据段中。还原段用于在进程更改数据库中的数据时保存数据的旧值(可能还原的数据)。它按数据被修改之前的原样存储数据的位置及数据本身。许多并发事务处理可以写入一个UNDO段。
UNDO段有如下几个用途,如下图所示。
- 事务处理回退
当某事务处理修改表中某行时,被修改的列的旧值(要还原的数据)将存储在UNDO段中,新数据被存入到数据段中。如果将该事务处理回退,即执行ROLLBACK命令,则Oracle服务器通过将还原段中的值写回到该行来恢复原始值。例如用户A在执行了语句UPDATE emp SET sal=1000 WHERE empno=7733
后发现应该修改7868号雇员的工资而不是7733号雇员的工资,那么通过执行“ROLLBACK”语句可以取消事务,此时系统将回滚段中的UNDO数据800从UNDO段中又写回数据段中。
- 事务处理恢复
事务恢复是由ORACLE SERVER自动完成的。如果实例在事务处理正在进行时失败(INSTANCE FAILURE),那么Oracle服务器需要在数据库再次打开时回退所有未提交的事务。这种回退操作是事务处理恢复的一部分。之所以有可能恢复事务处理,原因在于对还原段所做的更改同样受重做日志文件的保护。
- 读一致性
当用户检索数据库数据时,Oracle总是使提用户只能看到被提交过的数据(读取提交)或者特定时间点的数据(SELECT语句时间点),这样可以确保数据的一致性。读一致性是由ORALCE提供的,并且该特征是通过UNDO记录来实现有。还原段中的旧值(要回退的数据)用于保证数据的读一致性。Oracle服务器保证一条语句所看到的数据来自一致的时间,即使其它事务处理修改了该数据。
例如,当Oracle服务器开始执行SELECT语句时,首先确定当前系统更改号(SCN),并确保这个SCN之前未提交的任何修改不会被这条语句处理。如果在这次查询开始时某行有未提交的数据更改,Oracle服务器会从还原段检索这些更改的旧值,并显示该旧值,如下图所示。
2 自动UNDO空间管理
在Oracle9i以前,管理UNDO数据需要DBA建立专门的还原段,但这种方法相当复杂;为了简化UNDO数据的管理,从Oracle9i开始,管理UNDO数据有两种方法,一种是自动管理模式,通过UNDO表空间可以自动管理UNDO数据,另外一种是手工管理方式,即使用UNDO段管理UNDO数据。顾名思义,UNDO表空间是指专门存放UNDO数据的表空间,并且只能存放回滚段而不能存放其它的数据段。当使用UNDO表空间时,Oracle会自动在该表空间上建立还原段,以供事务操作使用。
如果使用自动管理模式,则必须要将初始化参数UNDO_MANAGEMENT设置为AUTO。这样ÿ