UNDO段由两个组件组成:UNDO头和UNDO入口。UNDO段的第一块是UNDO头。UNDO被创建时仅有UNDO头被创建。
保留时间表(retention table):这是自动管理UNDO新增的一个组件。保存了UNDO段中每一个区最后一个事务提交的时间。
事务表(transaction table):保存在UNDO头中。由若干槽位(slot)和入口(entries)组成。
UNDO入口:保存了事务级别和列前象的信息。每一个事务对应一个由UNDO入口组成的回滚链式结构。
读一致性步骤:
读数据块,如果内存中有这个块把这个块放到UNDO段中。
读行头信息。
通过检查ITL入口的锁状态位来判断是否有事务入口。
通过读ITL来发现事务的ID。
读事务表。如果事务已提交并且系统提交号比查询改变号小,从UNDO段中清除数据块,读下一块。
读到最后一个UNDO块
对比事务表中和最后一个UNDO块的事务ID。如果这两个事务ID不相等则报ORA-1555错误。
从第一个事务入口开始更改数据块。
如果最后一个UNDO入口中保存的是另一个数据块的地址,将UNDO块读到内存中。重复7,8步,直到不包含数据块的值的地址。
如果没有前一个数据块的地址,则事务回滚。
如果UNDO入口包含:
一个指向前一个事务UNDO块地址的指针,读这个事务UNDO块头的事务ID和事务表入口,返回到5步。
有一个ITL记录,存储ITL记录到数据块,返回步4。
保留时间表(retention table):这是自动管理UNDO新增的一个组件。保存了UNDO段中每一个区最后一个事务提交的时间。
事务表(transaction table):保存在UNDO头中。由若干槽位(slot)和入口(entries)组成。
UNDO入口:保存了事务级别和列前象的信息。每一个事务对应一个由UNDO入口组成的回滚链式结构。
读一致性步骤:
读数据块,如果内存中有这个块把这个块放到UNDO段中。
读行头信息。
通过检查ITL入口的锁状态位来判断是否有事务入口。
通过读ITL来发现事务的ID。
读事务表。如果事务已提交并且系统提交号比查询改变号小,从UNDO段中清除数据块,读下一块。
读到最后一个UNDO块
对比事务表中和最后一个UNDO块的事务ID。如果这两个事务ID不相等则报ORA-1555错误。
从第一个事务入口开始更改数据块。
如果最后一个UNDO入口中保存的是另一个数据块的地址,将UNDO块读到内存中。重复7,8步,直到不包含数据块的值的地址。
如果没有前一个数据块的地址,则事务回滚。
如果UNDO入口包含:
一个指向前一个事务UNDO块地址的指针,读这个事务UNDO块头的事务ID和事务表入口,返回到5步。
有一个ITL记录,存储ITL记录到数据块,返回步4。