步4:闪回查询时CR块的构造: 假如用户发布如下声明: select substr(c,1,5),id from t8 as of scn 8728960 where id<=3; 此声明指定读取SCN为8728960时块中的行。这就是闪回查询。 查询要求SCN:853180,前于步3时构造的CR块,因此,需要继续向前回滚。仍然根据ITL中的UBA信息,取出前映像,来构造另一个CR块。问题时,ITL有两个槽,我们该从哪个机槽的UBA回滚呢。最好的方法是从SCN最大的哪个。此处是槽0x02: Itl Xid Uba Flag Lck Scn/Fsc 0x02 0x0019.007.00000020 0x03800053.0037.01 C--- 0 scn 0x0000.008533f6 UBA中显示,此事务的回滚链尾块在14号文件,83号块,中第1条记录,回滚块序列号是55。 alter system dump datafile 14 block 83; 打开DUMP文件,首先要检查一下,此回滚块是否已被别的事务覆盖,检查方法,非常简单,看此UnDo块的Seq值: UNDO BLK: xid: 0x0019.008.00000021 seq: 0x37 cnt: 0x11 irb: 0x11 icl: 0x0 flg: 0x0000 仍是0x37,和UBA中所记的一样,证明此回滚块还末被覆盖。取出前映像,对应5号文件131046块的Slot 1(行2)的第0列: 62 62 62 62 32,即“bbbb2”。继续沿回滚链向上,根据rdba: 0x03800052,回滚链上一块在82块中,继续DUMP: alter system dump datafile 14 block 82; 打开DUMP文件,检查块的Seq值,仍是37。取出前映像,对应5号文件131046块的Slot 0(行1)0列,值为:61 61 61 61 31,即“aaaa1”。 此回滚记录已是回滚链头,被覆盖的ITL槽是: op: L itl: xid: 0x0018.005.0000001a uba: 0x03800072.000e.08 flg: C--- lkc: 0 scn: 0x0000.00853171 构造一个新的CR块: Itl Xid Uba Flag Lck Scn/Fsc 0x01 0x001a.010.00000011 0x03800085.000e.01 C--- 0 fsc 0x0000.00853185 0x02 0x0018.005.0000001a 0x03800072.000e.08 C--- 0 scn 0x0000.00853171 0x02 0x0019.007.00000020 0x03800053.0037.01 C--- 0 scn 0x0000.008533f6
Slot 0(行1):61 61 61 61 61 31 30 (“aaaaa10”) 相关末提交事务0x1 Slot 1(行2):62 62 62 62 62 31 30 (“bbbbb10”) 相关末提交事务0x1 --红色字体为应该覆盖的信息 Slot 0(行1):61 61 61 61 31 (“aaaa1”) Slot 1(行2):62 62 62 62 32 (“bbbb2”) Slot 2(行3):63 (“c”) 如果你发布如下声明: select substr(c,1,5),id from t8 as of scn 8728960 where id<=3; 这将会先构造步3时的CR块,再构造此步中的CR块,这两个CR块都是131046的CR块,因此,步4时的CR块会覆盖步3时的CR块。也就是说,在一次查询中,Oracle对应一个数据块,只会在内存创建一个CR块。 好了,我们的查询到此可以为止了吗,对比SCN,查询SCN:853180,ITL中最大SCN:853185。ITL中最大SCN仍后于查询SCN。继续回滚: 步5:继续回滚: 根据ITL中最大SCN槽的Uba, Itl Xid Uba Flag Lck Scn/Fsc 0x01 0x001a.010.00000011 0x03800085.000e.01 C--- 0 fsc 0x0000.00853185 回滚链尾块在14号文件,133回滚块,第1条回滚记录,序列号是14。DUMP133块: alter system dump datafile 14 block 133; 打开DUMP文件,检查块的Seq值,仍是0xe。取出前映像,对应5号文件131046块的Slot 1(行2)0列,值为:62 62 62 32,即“bbb2”。回滚链上一块在rdba:
|