没有必胜的秘籍,没有方程式遵循~~ 要赢~~只有全身心的投入!

晶晶实验六自己动手构造CR块

上一篇 / 下一篇  2008-02-20 16:01:23 / 个人分类:晶晶oracle实验系列

查看( 1047 ) / 评论( 35 )
一、查询魔术
i7c:d v@0 步1:在会话17中发布如下声明:
A|M_O9|5O)y(a+C0 17> var x refcursorITPUB个人空间({ HE'bS"E:^ Po#_U
17> exec open :x for select substr(c,1,5),id from t8;
$s0{|H? sT0 PL/SQL 过程已成功完成。ITPUB个人空间Jw&qs[:W;m\~-x
步2:在会话13删除T8的所有记录且提交:
|\ R7\C!u0 13> delete t8 ;
K ]1\q?(Q(up7u0 已删除 10 行。ITPUB个人空间qi1eLd2X-f@ Lu
13> commit;ITPUB个人空间G| eb5R]!A
提交完成。ITPUB个人空间{L({@L5M`%F,|
步3:在会话17中输出游标X的所有行:
)fot S B3{u7J0 17> print x
$})J0LA0jsq0 SUBSTR(C,1         ID
%I1O'l;ai;T~ B(Z0 ---------- ----------
:mT$K ~4_ hg7zm0 g                   7
1FzY$Ycd8S"?0 h                   8
9I:w.r#l7Uyt l0 i                   9
g'\ntP4l-Q-Af `e0 J                  10ITPUB个人空间!zi j#tm N3V
AA                  1ITPUB个人空间urw@V M
B                   2
IE&Z4X[:[E(Ef'^O0 C                   3
5e Z#zU'pZ$u)m2y0 D                   4ITPUB个人空间kicA-P](S
E                   5ITPUB个人空间(gXr#j,b2J1x`d8}
f                   6
&RrW:Z\)Ef%O0 已选择10行。ITPUB个人空间5E.S.l-w?x ^(|/a*H?
我们在会话13中已删除且已提交,但在会话17中还是显示出了T8中的所有行,这是为什么呢?ITPUB个人空间|5x ue(FjG.p
1) 在步1打开游标,但此时并没有执行、执取,在会话17的PGA中,将会开辟一块内存存贮此游标。在游标的相关信息中,有一条就是游标打开是的SCN,假若此
XQL4]g1@0 ITPUB个人空间*h2o!J5u3S+~di
时的SCN是1000。
%x)uB.SG0lQ0 2) 在步2中对表T8进行了操作,并提交。Oracle每个数据块的头部,都记有此块当前的SCN值,此SCN值随着对块的更新而变化。假如,我们在步2更新T8表时,ITPUB个人空间 r1v tijU0i!q

\7|lz(w9c f\x V0 SCN是1200,这个值将被记入块头部的SCN值。
VUo5[9O9{-m8kb0 3) 在步3我们发布Print x声明,此声明将完成执行、抓取等步骤。在从T8表的相关块中抓取行时,Oracle会将打开游标时的SCN和块本身的SCN相比较,如果发现
@3[oz$\n0 ITPUB个人空间r8n Qk%[un2w3[q k;w
后者大于前者,证明打开游标是在更新表之前进行的,Oracle将会在回滚段中寻找小于游标SCN的信息,构造一个在打开游标之前的块,这就是CR块了。如果回滚
"G(x+eg%LrA]0
Ezj M+C B7z.z0 段中的T8表的信息已经被覆盖,将会报告一个ORA-01555 快照太老错误。ITPUB个人空间RCg4yU]$e P
        执行时间过长的查询,有时也会报出这个错误。
P|*bn8Z#}B0 二、SCNITPUB个人空间-H6J#FG{CC.a:w
        SCN就是Oracle内部的一个记时机值,也就是Oracle的内部时钟。在9i之后,我们可以通过如下的方式获得当前的SCN号:
xF R4m-W&T:\G0 scott@MYTWO> ITPUB个人空间 `p.cZ(`;lS'q
select scn,to_char(scn,’xxxxxxx’) from (select dbms_flashback.get_system_change_number SCN from dual);ITPUB个人空间/y!\CvH$~ h
   SCN   
z2X}{c0Fa0 ----------ITPUB个人空间 h\ @LZ7|
8727805
}W"@7n1Wc0 在几乎所有的地方,你都能见到SCN。在事务表、回滚块中的回滚记录、数据块、日志文件等等,我们上面曾提到过,在游标中,记录的也有游标打开时的SCN。
+f Wv7m Z/G0 (在eygle的深入浅出oracle中有关SCN号更详细的介绍,18页)ITPUB个人空间E6{*}fwbf
三、构造CR块ITPUB个人空间l%Ge.?fY
Oracle会在三种情况下去读回滚段构造CR块:
$d~V{8~!A"g?o0 1.  只要数据块上有锁,Oracle将会构造CR块。ITPUB个人空间l]d5U,Q
2.  游标的SCN小于块的SCN,证明块在游标打开之后又被修改过了,这就要去构造CR块。
6Gcj\0U+m7m*YCZ0 3.  闪回查询中,要求的SCN小于块的SCN,也要去构造CR块。
7O I"JK8~y8T&Lq0 ITPUB个人空间 u8lG @)~1j
构造CR块ITPUB个人空间_1|AMl
步1:先观察表T8的行分布情况:
4i\HH7v6@(f7o0 ROWID                  BLOCK# C                  ID
\ Q0l&A b7T%i0 ------------------ ---------- ---------- ----------ITPUB个人空间3| yj7`5a~.Y&x"a
AAAB3LAAFAAAf/mAAA     131046 a                   1
!t#ZLa-x{ZM0 AAAB3LAAFAAAf/mAAB     131046 b                   2ITPUB个人空间_s{-RT{/Ap"Iu
AAAB3LAAFAAAf/mAAC     131046 c                   3
c:K%Ff@;sa(Nj/{2i0 AAAB3LAAFAAAf/nAAA     131047 d                   4
g-}5c"Xi@6A;x0 AAAB3LAAFAAAf/nAAB     131047 e                   5
C$lD |4s2L&e%t t0 AAAB3LAAFAAAf/nAAC     131047 f                   6ITPUB个人空间 Qb'u+D,D R HSP
AAAB3LAAFAAAf/oAAA     131048 g                   7ITPUB个人空间 okJ@{D:S
AAAB3LAAFAAAf/oAAB     131048 h                   8
.guN ]+f|0 AAAB3LAAFAAAf/oAAC     131048 i                   9ITPUB个人空间&a:N'Hb[#r9v|
AAAB3LAAFAAAf/pAAA     131049 j                  10
YR I o5B,uw0 步2:发布更新命令
R _ W1svX0 13> update t8 set c=upper(c) where id<=2;ITPUB个人空间 Ae n3jNK
已更新2行。
!G3kkl`"i0 13> commit;ITPUB个人空间*IB4K4~j2m%w9G
提交完成。
0g pBI.f0 13> update t8 set c='A1' where id<=1;ITPUB个人空间'G W1a.B|I
已更新 1 行。
W0]Q/~9d yHb0 13> update t8 set c='A2' where id<=2;
(_i]W Z2v0 已更新2行。ITPUB个人空间%D}/kW'lk-Z
13> update t8 set c='B2' where id<=2;
z0}2x(Y:i0 已更新2行。ITPUB个人空间 q(l"Fz$k#`,B ^,Z
13> commit;
1G G}Dx0 提交完成。ITPUB个人空间0fb F-Z6M,v7G"p
换到其他会话,ITPUB个人空间1ey G3q.\)LzW5}
17> update t8 set c='aa1' where id<=1;
{9P N,h;|x^/b0 已更新 1 行。ITPUB个人空间;?F+nX/]B
17> update t8 set c='bb2' where id=2;
n^P{J3Gc0 已更新 1 行。
u%[`{faN\0 17> commit;ITPUB个人空间$vQ~g3S2T
提交完成。
RF jMr,Z0 17> update t8 set c='aaa1' where id<=1;
2{'V/oj+A M&\\0 已更新 1 行。ITPUB个人空间i`YT.]
17> update t8 set c='bbb2' where id=2;
"i5p3Y(EN-A Q0 已更新 1 行。ITPUB个人空间%F!lf7uKb(Y
17> update t8 set c='aaaa1' where id<=1;ITPUB个人空间-? L6BFe
已更新 1 行。ITPUB个人空间 zF9TQU0q6GL
17> update t8 set c='bbbb2' where id=2;
Z"qf8?C+q.Stc0 已更新 1 行。ITPUB个人空间)jW/R x7Y#ec'Js
17> commit;ITPUB个人空间.a)_*c'N8OnK3X
提交完成。
$t,qM5eUY1j0 再换个会话:ITPUB个人空间@Zsa.@W6k)o#|;D
10> update t8 set c='aaaaa10' where id=1;ITPUB个人空间?L%_;BE ?z.a6sQx
已更新 1 行。
MI6F"}qh0 10> update t8 set c='bbbbb10' where id=2;
6E,p-k gmbj*J0 已更新 1 行。ITPUB个人空间 z6E _se5@]%w*zzW
10> commit;ITPUB个人空间$auH2xMl;d:z)D
提交完成。
JW[8W0D%@0 10> update t8 set c='az' where id=1;ITPUB个人空间9h&sve L|B yV4|
已更新 1 行。
'g9g4A,B;z!_-}2v:Ql@0 10> update t8 set c='by' where id=2;ITPUB个人空间+k FYp7h_
已更新 1 行。ITPUB个人空间5]]Aa3~"v.sI#j
此时的SCN是ITPUB个人空间\EP6t|w1W6Hl
18> select dbms_flashback.get_system_change_number SCN from dual;ITPUB个人空间z `I0j9dbD)j
   SCNITPUB个人空间8U;[2B P``)~N
----------
bJ R(X2O?"Zy0 8729612ITPUB个人空间8t#f3p+q"t.o)g5R
总结一下
%|E'q&~({1N0 行1的变化a->A->A1 A2 B2->aa1->aaa1  aaaa1->aaaaa10->azITPUB个人空间 Ex3A2b6sByQz
行2的变化b->B->B2       ->bb2->bbb2  bbbb2->bbbbb10->by
]!iG |7I SEX0 下面开始构造CR块,首先说一下末提交时CR块的构造:
jx/Wu2Np"M0 步3:末提交时CR块的构造:
@%A(ubx;u0 接着上面的修改,如果我们在会话16发布查询T8表的声明:ITPUB个人空间L$d)U1bF%K
16> select * from t8 where id<=3;ITPUB个人空间MP&a.UOW
由于最后一次修改没有提交,假如此时有其他会话访问行1或行2,就回发生回滚操作,从而构造一个CR块。让我们自己来回滚一下,感受一下Oracle的回滚操作
g7l"~Hcj0
1o6_ D,Q}]0 到底做了什么:ITPUB个人空间-xG{s-q6u*N
首先DUMP块131046:ITPUB个人空间],Mw7Un6W0cI
alter system dump datafile 5 block 131046;
TE)F*q4^P%dN8y0 在事务的头部,有一块这样的结构:ITPUB个人空间 ]Bx_` s\
Itl           Xid                  Uba         Flag  Lck        Scn/FscITPUB个人空间 ~8T H9u}Z
0x01   0x0018.008.0000001a  0x03800073.000e.02  ----    2  fsc 0x0000.00000000ITPUB个人空间"rP)wAa7H%e
0x02   0x0019.007.00000020  0x03800053.0037.01  C---    0  scn 0x0000.008533f6ITPUB个人空间u9L~#z r#D.u oL ph
它被叫做ITL,Interested Transaction List,相关事务列表。此表中每一行,按Oracle惯用的说法,又叫一个槽,SLOT。当有事务修改此块中的数据时,或者ITPUB个人空间H?*{1b6JV U0H

,C{ap,{`-?X;C0 说此块中有事务发生时,就在ITL中占用一个槽。下面我们了解一下ITL中的信息。ITPUB个人空间 q Nc6U~t;Na KK"f
第一列,ITL编号,共有两个,分别是0x01,0x02,随着此块中事务的增多,槽数量也会增多。
(sR([V-D#q:T%Y0 第二列,Xid,事务Xid编号,Xid共分三段,我们在上文中已经讲过,回滚段编号.槽号.序列号。我们来看0x01事务,它占用24号回滚段的第8个槽,此槽的序列
T(v)F8HL0
|(M#CS7W{~ Y0 号是26,即24.8.26。
np*R%s C kFC`0 第三列,UBA,回滚块地址。也分三段,分别是回滚块地址,回滚块序列号,回滚链末记录号(即irb信息)。此处0x01事务占用14号文件,115号回滚块,块序列ITPUB个人空间 C:n@){$Ioj X/Yq

`;T5L.Kp.h4KI3K0 号是14,回滚链的末记录在115的第2条记录处。ITPUB个人空间 yR?EH {)y;]N
第四列,Flag,标志,共有四位,四位都是“----”,事务末提交,第一位是C,“C---”,事务已提交。
TSC!ST;p'a#J0 第五列,Lck,事务所修改的行的数量。这些行,都算是被事务锁住的行。ITPUB个人空间J]TP;jMm2\
第六列,SCN/Fsc,是事务的SCN信息。0x01事务尚末提交,故此列为0。
(Tz O:c9I%|%E"M5|0 通过上面ITL,我们可以了解到,此块中有一个末提交的事务,那么此事务影响了几行呢,或者说此事务修改了几行呢?在下面行信息中,有:
(g8e4wxc*T0 tab 0, row 0, @0xba7
c1x.i%dx$Un"C+t0 tl: 1009 fb: --H-FL-- lb: 0x1  cc: 2
nB\ OA4y0 col  0: [1000]
LQw h!l [7X!^hx0 61 7a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20ITPUB个人空间 `'qfv-g*J%t^
这其中的lb: 0x1,就是指此行对应事务0x01,或说此行是事务0x01修改的行,或说事务0x01锁住了此行。它现在的值是61 7a,正是“az”。ITPUB个人空间{\i9_o W0o~aT~
        如果在其他会话上发布查询,Oracle首先检查ITL,一但发现某块上尚有末提交的事务,根据其UBA,马上开始构造其CR块,而不管会话所检索的行,是
&?fQ? z)kX0 ITPUB个人空间1D+{]{\ Ok
否是事务相关的。ITPUB个人空间5V#`i4i&@4p~$y
        块131046上有末提交事务:ITPUB个人空间,_b E iH S$}}
0x01   0x0018.008.0000001a  0x03800073.000e.02  ----    2  fsc 0x0000.00000000ITPUB个人空间Ofp;mum
其UBA是0x03800073.000e.02,即14号文件,115块,序列号14,第2条回滚记录。下面DUMP115块:ITPUB个人空间&{5m;\-p-L.L"H
alter system dump datafile 14 block 115;
]9B_ ZH1S?0 在DUMP文件中找到根据irb: 0x2,找到115块中第2条回滚记录,它对应131046第1行,前映像值为 62 62 62 62 62 31 30 ,即“bbbbb10”。再根据其rci:0x01
Z2W ro i'[1W0
h:{+j%|;`5Yl0 ,向上找到第一条回滚记录,它对应131046第0行,前映像值为 61 61 61 61 61 31 30,即“aaaaa10”。
,U$i`@ Km7Y r2B2X4^f1Z0 131046块中当前值是:
Tg~Sm"Q,IO0 Slot 0(行1):61 7a         (“az”)          相关末提交事务0x1
I&s+V2M'|I \0 Slot 1(行2):62 79         (“by”)         相关末提交事务0x1
d Zb0h%r0u}LB1n c0 Slot 2(行3):63          (“c”)                 无相关事务
,i0SHU)h+Uz VB0 通过读事务0x1的回滚块,将前映像信息写进131046,替换事务0x1对应的行,在内存中生成一个新的块:ITPUB个人空间#a(];iU~-L
Slot 0(行1):61 61 61 61 61 31 30         (“aaaaa10”)         相关末提交事务0x1
S[3X`2m U?0 Slot 1(行2):62 62 62 62 62 31 30         (“bbbbb10”)        相关末提交事务0x1ITPUB个人空间'?-OW],Rbh
Slot 2(行3):63                                  (“c”)                        无相关事务
~] ^ n:hm0 这个新生成的块,块的编号仍是131046,在内存中,它的HASH位置会和原来的131046处于同一HASH Cache Buffer Chain。它就是131046的CR块。CR块的构造到现ITPUB个人空间/k`*[!gv0I"{!kz

a:o?9e aJ0 在还没有完成,我们用前像映像行值替换了当前的行值,我们最后一步所做的更新并仅仅修改了行的值,上面我们讲到,每个块头有一个ITL,它初始有两个槽,
n8\ ZG8BL]X W!e0
ku_uf6n0 每个末提交的事务,将占用一个槽,可以随事务增多而扩充。如果事务已提交,它占用的槽会被下一个事务覆盖。因此,我们最后在会话10中做的更新,将覆盖ITPUB个人空间'`:MJ)q2SD
ITPUB个人空间$\Fd/z"D
131046的一个已提事务的ITL槽,这个被覆盖的ITL槽被记进事务回滚链头部块中,如下所示:
g wy_m \EX&u&c0 op: L  itl: xid:  0x001a.010.00000011 uba: 0x03800085.000e.01ITPUB个人空间Y_c\6^;J
                      flg: C---    lkc:  0     scn: 0x0000.00853185ITPUB个人空间E3@"Bn h
我们应该用它替换131046中当前的0x01槽:
5b;Ah5d PC0 Itl           Xid                  Uba         Flag  Lck        Scn/FscITPUB个人空间 Y2Pq%zk Y
0x01   0x0018.008.0000001a  0x03800073.000e.02  ----    2  fsc 0x0000.00000000
l$i5Xj i0} VsHX0 0x02   0x0019.007.00000020  0x03800053.0037.01  C---    0  scn 0x0000.008533f6
@e,^;I0vE.M0 替换为:ITPUB个人空间;ETF$RT H}8p
Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
8JB6ux Zb0 0x01   0x001a.010.00000011  0x03800085.000e.01  C---    0  fsc 0x0000.00853185ITPUB个人空间D _(J;v-e p6N
0x02   0x0019.007.00000020  0x03800053.0037.01  C---    0  scn 0x0000.008533f6ITPUB个人空间T;Pi-AI~g
好了,到现在,我们终于构造了一个131046的CR块:ITPUB个人空间%H;oXpM*y_
Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
|%ha,KP0 0x01   0x001a.010.00000011  0x03800085.000e.01  C---    0  fsc 0x0000.00853185
(wVIV9{YX0 0x02   0x0019.007.00000020  0x03800053.0037.01  C---    0  scn 0x0000.008533f6
4pK_H$y;R}0 ITPUB个人空间7R q#HSNK7B-}'C
Slot 0(行1):61 61 61 61 61 31 30         (“aaaaa10”)         相关末提交事务0x1
1~`EE,zB9t0 Slot 1(行2):62 62 62 62 62 31 30         (“bbbbb10”)        相关末提交事务0x1ITPUB个人空间|#u@[W(BI yz
Slot 2(行3):63                                  (“c”)                        无相关事务
.|+~ A.~0Ny0 现在,131046的CR块中的ITL中,所有事务都已提交,我们的回滚是否可以到此为止呢?
@D{)x~G*h0 还不行,Oracle还要对比一下查询游标打开时的SCN,如果大于上面CR块中ITL的最大提交SCN:8533f6,证明查询发生在事务结束之后,查询时的SCN大致是:
K(w3?0Z/V W@"Y0 18> select scn,to_char(scn,'xxxxxxxxxx') from (select dbms_flashback.get_system_change_number SCN from dual);
`6u6]%T.F;C W0 SCN                 TO_CHAR(SCN
-~w2PU Qq(f*K0 ----------                 -----------
.i KF.^:z0 8734649      8547b9
E&}y A Y6MYb%?0 后于CR块ITL中最大提交SCN,好,到此为止,回滚结束。
fH)gK.X-_3Y$w|PK0 如果游标的SCN前于ITL中最大提交SCN,Oracle仍要继续回滚。ITPUB个人空间Jn.aYq8V
步4:闪回查询时CR块的构造:ITPUB个人空间DQ(C,C,n[ b
假如用户发布如下声明:
AMX ZY0 select substr(c,1,5),id from t8 as of scn 8728960 where id<=3;
F#d&jtpZy7yt0 此声明指定读取SCN为8728960时块中的行。这就是闪回查询。ITPUB个人空间 O`.pwB ^(Y
查询要求SCN:853180,前于步3时构造的CR块,因此,需要继续向前回滚。仍然根据ITL中的UBA信息,取出前映像,来构造另一个CR块。问题时,ITL有两个槽,
^%s.ZN {SV LW0 ITPUB个人空间#ol)w)e)v:i
我们该从哪个机槽的UBA回滚呢。最好的方法是从SCN最大的哪个。此处是槽0x02:
Qideix{%u T0 Itl           Xid                  Uba         Flag  Lck        Scn/FscITPUB个人空间@}RrI'^;_B
0x02   0x0019.007.00000020  0x03800053.0037.01  C---    0  scn 0x0000.008533f6
6w%ZnV?] ~-S0 UBA中显示,此事务的回滚链尾块在14号文件,83号块,中第1条记录,回滚块序列号是55。
}9]Cxq P:xm7k d0 alter system dump datafile 14 block 83;ITPUB个人空间*F)Xc(P#N:z&{
打开DUMP文件,首先要检查一下,此回滚块是否已被别的事务覆盖,检查方法,非常简单,看此UnDo块的Seq值:ITPUB个人空间&t[1v lM8w0U
UNDO BLK:  
Yt"S6J`0 xid: 0x0019.008.00000021  seq: 0x37  cnt: 0x11  irb: 0x11  icl: 0x0   flg: 0x0000ITPUB个人空间F'I,e9if4r
仍是0x37,和UBA中所记的一样,证明此回滚块还末被覆盖。取出前映像,对应5号文件131046块的Slot 1(行2)的第0列: 62 62 62 62 32,即“bbbb2”。继
/Ep x5uu;]Q F4w0
&D7Q"L"{:|,?{0 续沿回滚链向上,根据rdba: 0x03800052,回滚链上一块在82块中,继续DUMP:
/~8g Uls3^Q0 alter system dump datafile 14 block 82;ITPUB个人空间9O2Z[b] {:Ax9f
打开DUMP文件,检查块的Seq值,仍是37。取出前映像,对应5号文件131046块的Slot 0(行1)0列,值为:61 61 61 61 31,即“aaaa1”。ITPUB个人空间;i*t)G-jMQnS
此回滚记录已是回滚链头,被覆盖的ITL槽是:ITPUB个人空间zzkIKG
op: L  itl: xid:  0x0018.005.0000001a uba: 0x03800072.000e.08
E.FF.C(ak0                       flg: C---    lkc:  0     scn: 0x0000.00853171ITPUB个人空间,jG8Ds$a5W+unH
构造一个新的CR块:ITPUB个人空间7F&{ h LP/I#f
Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
:Wg5sp _6_0Tg1t%s1D0 0x01   0x001a.010.00000011  0x03800085.000e.01  C---    0  fsc 0x0000.00853185ITPUB个人空间D-t,[(f:]c8~ a
0x02   0x0018.005.0000001a  0x03800072.000e.08  C---    0  scn 0x0000.00853171
Et!Dmpu0 0x02   0x0019.007.00000020  0x03800053.0037.01  C---    0  scn 0x0000.008533f6
1bVA]jINlB0
b*}-P9_OO0 Slot 0(行1):61 61 61 61 61 31 30         (“aaaaa10”)         相关末提交事务0x1ITPUB个人空间L[nL/ia
Slot 1(行2):62 62 62 62 62 31 30         (“bbbbb10”)        相关末提交事务0x1    --红色字体为应该覆盖的信息
Zvz |w1],xe7j0
Slot 0(行1):61 61 61 61 31         (“aaaa1”)         
2m[r ikH~0 Slot 1(行2):62 62 62 62 32         (“bbbb2”)        
M'L x!RZ M1V0 Slot 2(行3):63                                  (“c”)                        ITPUB个人空间6Jjf%srj]
如果你发布如下声明:
Xj6U2h HmCm0 select substr(c,1,5),id from t8 as of scn 8728960 where id<=3;
d5Y/V"fp%[-Qp0 这将会先构造步3时的CR块,再构造此步中的CR块,这两个CR块都是131046的CR块,因此,步4时的CR块会覆盖步3时的CR块。也就是说,在一次查询中,Oracle对
m#I,F}%| v0
'Z q2bj{0 应一个数据块,只会在内存创建一个CR块。ITPUB个人空间B:@xY!W4N!X;UL
好了,我们的查询到此可以为止了吗,对比SCN,查询SCN:853180,ITL中最大SCN:853185。ITL中最大SCN仍后于查询SCN。继续回滚:ITPUB个人空间y {Ju _9g6{
步5:继续回滚:ITPUB个人空间4VS[&Lhg[)P
根据ITL中最大SCN槽的Uba,ITPUB个人空间jUv!g!]"[ p/eq
Itl           Xid                  Uba         Flag  Lck        Scn/FscITPUB个人空间(C TZ7d8^!w
0x01   0x001a.010.00000011  0x03800085.000e.01  C---    0  fsc 0x0000.00853185ITPUB个人空间1zNK#bh]K
回滚链尾块在14号文件,133回滚块,第1条回滚记录,序列号是14。DUMP133块:
)Z os#M#v(Y0 alter system dump datafile 14 block 133;
l\1L/E/L K+{0 打开DUMP文件,检查块的Seq值,仍是0xe。取出前映像,对应5号文件131046块的Slot 1(行2)0列,值为:62 62 62 32,即“bbb2”。回滚链上一块在rdba: ITPUB个人空间9~.@ |}#g+_
ITPUB个人空间(P'XxJ+RGi!R.@\
0x03800084,132块中:
0yV~$BK0 alter system dump datafile 14 block 132;
k.R6tU,m'wQ6u0 找到最后一条回滚记录,它的前映像对应5号文件131046块的Slot 0(行1)0列,值为 61 61 61 31,即“aaa1”,但它并是回滚链头,根据它的Rci  0x02,继ITPUB个人空间 T0s;uoJ%s
ITPUB个人空间gp-Gm,Yr$z.u%?d
续向上,找到0x02条回滚记录, 它对应对应5号文件131046块的Slot 1(行2)0列,62 62 32,即“bb2”,还没完,再向上,是131046块中Slot 0(行1)0列,
q'G-C.e ?L7r{0 ITPUB个人空间6T~ DI$U w(jW
61 61 31,即“aa1”,此条回滚记录的Rci已经是0了,已经到了回滚链头,被覆盖的ITL槽是:ITPUB个人空间&k)j2~4e{3E
op: L  itl: xid:  0x0017.003.00000045 uba: 0x03800021.0021.03
&g4l([aU!I3zc+i [ ~'o0                       flg: C---    lkc:  0     scn: 0x0000.008530fd
z1f_mFj2`*zk0 Itl           Xid                  Uba         Flag  Lck        Scn/FscITPUB个人空间b6|2I4}R7sVX
0x01   0x001a.010.00000011  0x03800085.000e.01  C---    0  fsc 0x0000.00853185ITPUB个人空间!c+d8@hW3o:]k
0x01   0x0017.003.00000045  0x03800021.0021.03  C---    0  fsc 0x0000.008530fd
MVAX5tECud"I {z$Z0 0x02   0x0018.005.0000001a  0x03800072.000e.08  C---    0  scn 0x0000.00853171ITPUB个人空间9_$r)Z})p R g
ITPUB个人空间+xY+K/G2s
Slot 0(行1):61 61 61 61 31         (“aaaa1”)       ITPUB个人空间m)c})m[)aF
Slot 1(行2):62 62 62 62 32         (“bbbb2”)
        ITPUB个人空间+x/^vTd(Kz
Slot 0(行1):61 61 31         (“aa1”)         
;E%rYT~ ~;b0 Slot 1(行2):62 62 32         (“bb2”)        ITPUB个人空间thzw#? F:}_k
Slot 2(行3):63                  (“c”)               
3Ij)d6Qg0 查询的SCN是853180,ITL中最大SCN是853171,查询SCN大于ITL中的SCN,说明查询发生在事务后,好了,到此,我们这一次CR块构造完毕。此次生成的131046的ITPUB个人空间(Baa%dg|"q5\
ITPUB个人空间a o8FA a.} Z&d
CR块会覆盖步4时生成的,一个块,在一次查询中,只会产生一个CR块。ITPUB个人空间 M7c,]*l4Av?T.aW{
根据我们的操作顺序:ITPUB个人空间1e1?J1t|]f
a->A->A1 A2 B2->aa1->aaa1  aaaa1->aaaaa10->azITPUB个人空间i5O9nWq4P P@@
b->B->B2       ->bb2->bbb2  bbbb2->bbbbb10->by
9b4`9C!?M5XA~ p0                      ↑
N#]"xeXwEA0 我们已经回到了箭头所指处。我们可以一直向前回塑,直到T8的行被插入131046时,或者,回滚段被覆盖时。假若我们又向前回塑,但回滚块的Seq和我们要求的
Km#E_T#}l@'W3p3L0
4gBn*DZr(w0N0 不一样,证明此块被覆盖了,此时Oracle会报告Ora-01555错误。我们只需让回滚段的区足够多,这样它每次绕回的时间必然加长。这样,回滚段必然可更长时间ITPUB个人空间%rhTj7{"s a aT
ITPUB个人空间`,_ LnD!H)R@`}
的保持已提交事务的回滚信息。
-h(}-x3g!}Q&^:~0 在X$BH视图中上,有一个CR_SCN_BAS列,显示CR块的最大SCN:ITPUB个人空间l/uI*AL
18> select file# ,DBABLK,state, tch ,cr_scn_bas,to_char(cr_scn_bas,'xxxxxxxx') SCN from x$bh
P'`r.tG#x4j0 where file#=5 and dbablk=131046;ITPUB个人空间%?%PbY6Q!s4p
     FILE#     DBABLK      STATE      TCH CR_SCN_BAS SCN   
HmXZ^6r:f|$U0 ---------- ---------- ---------- ---------- ---------- --------- -------------------- ----------
jJi3q3^^(fG0          5     131046          3          0    8728964    853184
vHxhPQTTi0 上面的0x853184就是咯。旁边的8728964是他的10进制值.

TAG:

netbbs发布于2008-02-20 16:02:35
小妹的沙发。
蚊子窝 foxmile 发布于2008-02-20 16:42:30
关于读一致性,我了解的不多,buffer cache的一个功能就是构造CR块,从而提供读一直性吧,这个构造是oracle自己呢?还是手工?
!nX T3LF        XC_'Vspace.itpub.net如果是oracle自己,手工构造的意义有多大。
^U$?,i} Te9D_E
.|,nC$r!{Ch在坛子看到一篇老文章,很不错。

E;hSQ mM r@m
http://www.itpub.net/viewthread. ... p;extra=&page=1
bluemoon0083发布于2008-02-20 16:50:00
up
晶晶小妹的个人空间 晶晶小妹 发布于2008-02-20 16:50:09

QUOTE:

原帖由 foxmile 于 2008-2-20 16:42 发表
9CU!^%Wq关于读一致性,我了解的不多,buffer cache的一个功能就是构造CR块,从而提供读一直性吧,这个构造是oracle自己呢?还是手工?#{|'nq0hxe[&jwe
如果是oracle自己,手工构造的意义有多大。@cT0f6t
bb0v8M%~ n
在坛子看到一篇老文章,很不错。
vQ.}|#q:k,S
b        N*fspace.itpub.net
http://www.itpub.net/viewthread. ... p;extra=&page=1

Xb*w!z._        M
v

oracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net9T#AL8@-L:`"e
QH-_Nvm@
自己跟踪一次,能更清楚的明白为什么会有01555错误.
蚊子窝 foxmile 发布于2008-02-20 16:58:40
ok。多谢!
晶晶小妹的个人空间 晶晶小妹 发布于2008-02-20 16:59:40
其实通过自己动手做一次实验,就清楚了当select一个有事务的块时,oracle在内部为我们做了什么操作.
9Pe        Xx^5^~
Uoracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net
我喜欢这种明白的感觉,也想让坛友分享我的感觉.
A;E6Yl?jy H'Espace.itpub.net^_^
蚊子窝 foxmile 发布于2008-02-20 17:06:34

QUOTE:

原帖由 晶晶小妹 于 2008-2-20 16:59 发表
f%Y`AiP\KdITPUB个人空间其实通过自己动手做一次实验,就清楚了当select一个有事务的块时,oracle在内部为我们做了什么操作.B7B~R-LE3O$Ja
我喜欢这种明白的感觉,也想让坛友分享我的感觉.
aU{#E7B%T|space.itpub.net^_^
4TPY:}
}ITPUB个人空间
有道理。实践是最好的老师
烟囱的个人空间 烟囱 发布于2008-02-20 17:42:02
今晚按照小妹的实验重复一次.J3`-}Q+i"}

\
B)lf+f7H yB,e
谢谢了啊~
蚊子窝 foxmile 发布于2008-02-20 17:46:02
今天在看书,等看完书,自己动手做一下。
shiri512003的个人空间 shiri512003 发布于2008-02-20 18:19:00
绝知此事要躬行 KrX*W/e
支持一把
玉面飞龙发布于2008-02-20 18:43:19
Li Hai
Alienovo的个人空间 Alienovo 发布于2008-02-20 21:50:58
支持原创!
西瓜 BTxigua 发布于2008-02-20 21:59:12
小妹越来越牛了。
bosonmaster的个人空间 bosonmaster 发布于2008-02-20 23:54:14
不错,第一次试了下构造CR块
蒙昭良的个人空间 mengzhaoliang 发布于2008-02-21 01:28:35
楼主很强啊,看过,有很多不懂。等明天做个实验!
wabjtam123的个人空间 wabjtam123 发布于2008-02-21 08:07:57
大鼻子大眼睛美女晶,真棒!
Zhao Yu of Oracle Life 赵宇 发布于2008-02-21 08:42:39
基础很强,也很深入,值得学习
football8675的个人空间 football8675 发布于2008-02-21 09:03:28
差距太遠ITPUB个人空间
E+YSbJN6Sn

要學的好多啊
bosonmaster的个人空间 bosonmaster 发布于2008-02-21 09:48:12
楼上的那么多福,送我个
晶晶小妹的个人空间 晶晶小妹 发布于2008-02-21 11:42:00

QUOTE:

原帖由 wabjtam123 于 2008-2-21 08:07 发表 oracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net        T2[u*]1c0M#R/|'Z^
大鼻子大眼睛美女晶,真棒!
Q5R
Z:Fa|e\


&@0iMNp
        jj5^3](D
C&n
kIc
俺那疙瘩人都说:大鼻子有福!哈哈
'{;b U\4MO-z
Lspace.itpub.net
ITPUB个人空间4?f_x i:N

bartfj的个人空间 bartfj 发布于2008-02-21 11:59:57
太牛了
晶晶小妹的个人空间 晶晶小妹 发布于2008-02-21 18:05:46
大家的支持 就是俺 最大的动力.
8H6mQ:`vO@!y!xTITPUB个人空间space.itpub.net"tZ`"X'a'TA
请大家的支持来的更猛烈些吧
8FAV4khAc@N e)_space.itpub.net
8I9a*i/by:bA哈哈
SingleLove的个人空间 SingleLove 发布于2008-02-21 18:40:49
强。。不得不服
maclean发布于2008-02-21 21:36:10
请问 cr中index是怎么样的?
晶晶小妹的个人空间 晶晶小妹 发布于2008-02-21 21:44:18

QUOTE:

原帖由 maclean 于 2008-2-21 21:36 发表
r.q)r$b-gP.`ITPUB个人空间请问 cr中index是怎么样的?
pw#F'@        X"^w%RK,n$t$R,~(wU%V QxM
ITPUB个人空间_/WaC&e9PY
你想了解什么?索引的CR块的格式??还是有索引时什么时候会产生CR块?
hanjs发布于2008-02-22 09:41:51
佩服!
wa0362发布于2008-02-22 10:26:45
DSI
solearn的个人空间 solearn 发布于2008-02-28 10:28:12
我们最后在会话10中做的更新,将覆盖131046的一个已提事务的ITL槽,这个被覆盖的ITL槽被记进事务回滚链头部块中,如下所示:space.itpub.netl*M?FK7D
op: L  itl: xid:  0x001a.010.00000011 uba: 0x03800085.000e.01
G }
[)v(M)ye N"CvITPUB个人空间
                      flg: C---    lkc:  0     scn: 0x0000.00853185
a%p0j Y*z#AVspace.itpub.net-------------------------------------------------------------------------------------------------------------------------------space.itpub.net^T)N$y4e6A
oracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net-gC:U3K*N;D"hy
请教楼主:ITPUB个人空间Rlv;nb6[!o
在哪里找到被覆盖的ITL槽信息?
,X)W9ir^1?NXX在回滚段头块里,没有类似的entry。所谓“事务回滚链头部块”指的是什么呢?
晶晶小妹的个人空间 晶晶小妹 发布于2008-03-01 23:52:12

QUOTE:

原帖由 solearn 于 2008-2-28 10:28 发表 a2iwAYy
我们最后在会话10中做的更新,将覆盖131046的一个已提事务的ITL槽,这个被覆盖的ITL槽被记进事务回滚链头部块中,如下所示:
9E,{Kp |Y1k'QC8Q}op: L  itl: xid:  0x001a.010.00000011 uba: 0x03800085.000e.01oracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net0E(D2P0X,Op5d
                      flg: C---    lkc:  0     scn: 0x0000.00853185oracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net
f$U
l+V QO_8S"a+m:|

-------------------------------------------------------------------------------------------------------------------------------)t_+STH6?)m-d+}!l

Y _)|%J#W$v!Doracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net请教楼主:
seLK&OAITPUB个人空间在哪里找到被覆盖的ITL槽信息? space.itpub.net)c2^p d[ x5aWe1m$Y
在回滚段头块里,没有类似的entry。所谓“事务回滚链头部块”指的是什么呢?
_WL*p.^-M"Soracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.netspace.itpub.netw(G*DL,@sn"t
[4x

  可以在块所对应的回滚块中找到被覆盖的ITL槽信息.比如说我修改了A块中的某一行,回滚信息被记录在U块中.那么在U块中就可以找到A块被覆盖的ITL槽信息.
anycall2010的个人空间 anycall2010 发布于2008-03-02 14:15:35
近段比较忙,很久没有发言了,这段时间有时候也关注关注,可爱的晶晶小妹妹,无论大家怎样评论,但是这种钻研的精神值得学习
我来说两句

(可选)

日历

« 2009-07-04  
   1234
567891011
12131415161718
19202122232425
262728293031 

数据统计

  • 访问量: 60693
  • 日志数: 32
  • 图片数: 4
  • 建立时间: 2008-02-15
  • 更新时间: 2008-05-29

RSS订阅

Open Toolbar