Home >Database >Mysql Tutorial > OCP知识点讲解 之 Undo的回滚和提交
一、回滚段块的使用总结:1.1Seq序列值:步骤1:在每个回滚块的块头,有一个SEQ值,当事务延伸到新区时,新区的SEQ是上一区SEQ加1。如:步骤2:步骤3:事务B提交
一、回滚段块的使用总结:
1.1 Seq序列值:
在每个回滚块的块头,有一个SEQ值,当事务延伸到新区时,新区的SEQ是上一区SEQ加1。如:
步骤2:
步骤4:事务A发布新的更新声明,它所占回滚块开始增长:
事务A增长,占用83、84、85、86、87块,但到达88块时,发现88、89块的序列值也是10,并不小于自身的序列值,事务A跳过88、89块,90块的序列值小于10,事务A占用90号块。
步骤5:
事务A继续增长,当事务A延伸至下一区时,香港虚拟主机,下一区块的序列值为11:
结论:只有当事务为块分配的序列值大于块本身的序列值时,事务才可占用此块。上例中事务 B已提交的块,只有当A事务提交后,另有其他事务从末尾区延伸到区0时,才会被占用。
1.2 区的膨胀(Extend):
事务A不断增长,已经占满了区0。事务A又请求新的回滚块,由于事务Z从区1开始,香港服务器,因此区1有“活动事务”,此时Oracle再分配一个新区作为区1,老的区1变为区2,如下:
就算老区1后还有空闲的老区2,此处还是会分配新区1的。
二、回滚和提交:
2.1 回滚:
如果某一事务回滚,其操作步骤是:
从上面的步骤可以看到,回滚的顺序,与你操作的顺序正相反,如果你删除了1,2,3,4,5条记录,然后回滚,Oracle从后向前,依次插入5,4,3,2,1条记录。
2.2 提交:
事务提交后,事务表上的事务状态列被置为非活动。此事务不可再回滚,因为回滚先要到事务表查出事务回滚链的末尾块。
但是,提交后,虽然事务表上已经标明此事务是非活动事务,不过回滚块中的信息还在,虽然不能回滚,但这些回滚块中的信息在被覆盖前,仍是可以被读取的。
关于这一点,我们可以找个事务,提交后再DUMP它占用的回滚块,根据回滚段循环使用原则,这些回滚记录到下一轮循环时才会被覆盖。
三、自己动手构造CR块:
3.1 查询魔术:
PL/SQL 过程已成功完成。
提交完成。
已选择10行。
执行时间过长的查询,有时也会报出这个错误。
3.2 SCN:
在几乎所有的地方,你都能见到SCN。在事务表、回滚块中的回滚记录、数据块、日志文件等等,我们上面曾提到过,在游标中,记录的也有游标打开时的SCN。
3.3 构造CR块:
3.闪回查询中,要求的SCN小于块的SCN,也要去构造CR块。
AAAB3LAAFAAAf/pAAA 131049 j 10
...
下面开始构造CR块,首先说一下末提交时CR块的构造:
第六列,SCN/Fsc,虚拟主机,是事务的SCN信息。0x01事务尚末提交,故此列为0。
18> select scn,to_char(scn,'xxxxxxxxxx') from (select dbms_flashback.get_system_change_number
SCN from dual);
关于CR块的构造过程,我们就讲到这里。在此过程中,我们一直很少用到事务表,在这里,ITL是重要的,我们靠它向前回滚。但在构造CR块的开始,Oracle仍然要读事务表。这一点从X$BH中的“接触点”可以看出来。每发布一次产生CR块的查询,回滚段头的TCH列都有增加。ITL在每个数据块的块头,它是针对块的,而事务表则是针对事务的。
在Rollback时,Oracle一定要去读取事务表,因为一个事务可能涉及很多回滚记录、很多回滚块,这些回滚记录被回滚链串起来,而只有在事务表中,才能找到回滚链尾记录的UBA。因此,回滚一定要从回滚链末尾开始。
本文出自 “叶绍琛” 博客,请务必保留此出处