UNDO三大作用
1.一致性读(consistent read)
2.事务回滚(Rollback Transaction)
3.实例恢复(Instance Recovery)
一致性读
当会话发出一条SQL查询,将当前时间的SCN号记录下来,当进程扫描到表T的数据块,再与该块头部的ITL槽(事务槽)的SCN号比较,如果发现该块SCN号较小,则该块没有被更新过所以可用;如果该块SCN号较大,则该块被更新过,要借助UNDO块了,该块的ITL槽会记录了对应的UNDO块的地址,就取出对应的UNDO块,如果发现该UNDO块的ITL槽的SCN号也较大,证明也不可用,则在该块的ITL槽寻找再上一个块的UNDO块地址,层层递归,最终找到SCN号比发出查询的SCN号小的UNDO块。
因为UNDO块记录的是逻辑改变的值,例如INSERT操作记录在UNDO块就是DELETE,过程中,全部UNDO块一个一个地找出来,这有点增量改变的意思,再全部组成一起构成CR块以交给用户使用。
ORA-1555 snapshot too old错误,须用UNDO块的时候,发现UNDO块被其他事务覆盖了,找不回了而出现的。
事务回滚
DML后,用户发出rollback,ORACLE利用在数据块ITL槽记录的UNDO块地址,找到该UNDO块,应用其中的DML语句,从而对所作的改变进行回滚。
实例恢复
SMON进程完成判断和前滚后,查看undo segment的头部,会将没有提交也没有回滚的事务全部回滚。(每个事务在使用UNDO块时,首先要在该UNDO块所在的undo segment的头部记录一个条目,该条目记录了该事务相关的信息,包括是否提交)
自动undo管理(AUM,Automatic Undo Management)
手动undo管理(MUM,Manual Undo Management)
show parameter undo_management
两个取值auto,manual。
alter system set undo_tablespace=undoabc;
如果不指定某个UNDO表空间做默认的undo表空间,则系统会查找第一个undo表空间。数据库可以同时存在多个undo表空间,但一个时间点只能用一个undo表空间,切换时,如果旧的Undo表空间还有事务在执行,则变pending offline状态。新事务在新的undo表空间执行,旧的表空间会等到事务都提交以后,就变成Offline状态。
至于undo segment,AUM采用的是事务绑定segment的算法。(尽量一个事务一个undo segment)
首先尝试每个undo segment绑定一个事务,每个undo segment只被一个事务使用。
如果发现undo segment都用了,则会尝试使脱机的undo segment联机以使用。
如果发现没有可用的undo segment联机,则会尝试创建一个新的undo segment。
如果都不成功,比如没有可用空间了,这种情况下,不同的事务才会在一个undo segment里同时运行。
既然有undo segment的扩张,就有undo segment的收缩
SMON负责
每12小时收缩一次,删除那些idle状态的extents;
当DML需要用到UNDO时,发现不够空间,会唤醒SMON进行一次收缩,也就是说将其他undo segment里暂时没被使用的extents拿来用。
为避免ORA-1555快照太旧的错误,出现了undo_retention参数,表示当事务提交或回滚后,该事务所使用的undo块里的数据需要保留多长时间,秒为单位。当保留的时间超过undo_retention所指定的时间以后,该undo块才能被其他事务覆盖。
默认情况下,ORACLE10g会每隔30秒就收集统计信息来自动调整undo retention,如果我们设定undo_retention为0,或不设定,则启动此种模式,900秒为最低值;如果我们手动设定了undo_retention,则用我们指定的时间为undo保留的时间;
alter tablespace undoabc retention guarantee;
就保证了undo块一定能保留那么多时间。
alter tablespace undoabc retention noguarantee;
取消。
转载:http://blog.csdn.net/whiteoldbig/article/details/6975276