没有必胜的秘籍,没有方程式遵循~~
要赢~~只有全身心的投入!
晶晶实验六自己动手构造CR块
上一篇 / 下一篇 2008-02-20 16:01:23 / 个人分类:晶晶oracle实验系列
查看( 721 ) /
评论( 35 )
一、查询魔术ITPUB个人空间1H^{ax
步1:在会话17中发布如下声明:ITPUB个人空间&S#U9iL(vg_p
17> var x refcursor
cxgV|{?l0 17> exec open :x for select substr(c,1,5),id from t8;ITPUB个人空间!X W3zVDQ;l#d6t
PL/SQL 过程已成功完成。ITPUB个人空间!CS(y"H+@h
步2:在会话13删除T8的所有记录且提交:
Mm^)tA$BZ0 13> delete t8 ;
3m&NZ6AD0 已删除 10 行。ITPUB个人空间A"ZV}%C z$oc ?|k
13> commit;
~.IDt'y-k]$eK+V0 提交完成。
cw|]DHg Lv0 步3:在会话17中输出游标X的所有行:ITPUB个人空间EbM8\!ZK
17> print xITPUB个人空间"f;|$M+pGE s.|#VX
SUBSTR(C,1 IDITPUB个人空间TRq-[|6L;lk6k
---------- ----------
!a?\.`@VI7}0 g 7
c@zPc0 h 8ITPUB个人空间v#tF,bUu
i 9
*L,pj M-\0 J 10ITPUB个人空间;Wkb$Sl2mC
AA 1ITPUB个人空间.nUHv nR
B 2ITPUB个人空间!WpTi&Er!\!\:i
C 3
]X;i9[a%zugUn0 D 4ITPUB个人空间Glwv(OdYWby"K
E 5ITPUB个人空间!z%Q,p MndD
f 6ITPUB个人空间QOV"J4LdM4x&\)k
已选择10行。ITPUB个人空间-B(bT,z1p8f"V As;f
我们在会话13中已删除且已提交,但在会话17中还是显示出了T8中的所有行,这是为什么呢?
tw)pCjz8c(Q0 1) 在步1打开游标,但此时并没有执行、执取,在会话17的PGA中,将会开辟一块内存存贮此游标。在游标的相关信息中,有一条就是游标打开是的SCN,假若此
;h}FW!Y0 ITPUB个人空间]1fq#S&Yu
时的SCN是1000。
Ahi2H;O"^yS/Q0 2) 在步2中对表T8进行了操作,并提交。Oracle每个数据块的头部,都记有此块当前的SCN值,此SCN值随着对块的更新而变化。假如,我们在步2更新T8表时,ITPUB个人空间1o8kv;F@+bi q!o5M?
ITPUB个人空间4s,hxf.K0Whv q%z4A'\
SCN是1200,这个值将被记入块头部的SCN值。
`'OL#N2lF)D&]]2U$Rq0 3) 在步3我们发布Print x声明,此声明将完成执行、抓取等步骤。在从T8表的相关块中抓取行时,Oracle会将打开游标时的SCN和块本身的SCN相比较,如果发现ITPUB个人空间$[x0Acp6H8~4xF/XP
6qT:s(H1F!KY0 后者大于前者,证明打开游标是在更新表之前进行的,Oracle将会在回滚段中寻找小于游标SCN的信息,构造一个在打开游标之前的块,这就是CR块了。如果回滚ITPUB个人空间0x_ j#[];ZCS8w3n`
.]u:fI*X*U2s^a0 段中的T8表的信息已经被覆盖,将会报告一个ORA-01555 快照太老错误。ITPUB个人空间JX^QBoI2v8u.g
执行时间过长的查询,有时也会报出这个错误。ITPUB个人空间:uJ$qt7u
二、SCN
Z(g;F6FL'X/|0 SCN就是Oracle内部的一个记时机值,也就是Oracle的内部时钟。在9i之后,我们可以通过如下的方式获得当前的SCN号:
1J2C[ss,f0 scott@MYTWO>
JqFZ8J4K1Id0d'pI0 select scn,to_char(scn,’xxxxxxx’) from (select dbms_flashback.get_system_change_number SCN from dual);ITPUB个人空间7a8RZa*UEw7r
SCN ITPUB个人空间|6jP:Pmfi [{ya
----------ITPUB个人空间K;p;L+l9L_&U-Jo%A
8727805
j$~1w3Z!y$fqW"S0 在几乎所有的地方,你都能见到SCN。在事务表、回滚块中的回滚记录、数据块、日志文件等等,我们上面曾提到过,在游标中,记录的也有游标打开时的SCN。ITPUB个人空间2V+y7df*N1uy Pp
(在eygle的深入浅出oracle中有关SCN号更详细的介绍,18页)
!F;v)S%R%VDRu1Ey0 三、构造CR块
v{*Cn%H7rZ {0 Oracle会在三种情况下去读回滚段构造CR块:
(X(Cg+@|d0 1. 只要数据块上有锁,Oracle将会构造CR块。
9eS5O*}F1W0 2. 游标的SCN小于块的SCN,证明块在游标打开之后又被修改过了,这就要去构造CR块。
$^r*R@w8Epz9W0 3. 闪回查询中,要求的SCN小于块的SCN,也要去构造CR块。
q)Mg6E.G4~A0 ITPUB个人空间;l/u)_ juMqJE8x
构造CR块ITPUB个人空间/X9wz gf'z"Fc(e-RQ
步1:先观察表T8的行分布情况:
lu9fV"?g6x2n0 ROWID BLOCK# C ID
M ?DyDtpJ0 ------------------ ---------- ---------- ----------ITPUB个人空间6j+F]%\f'Z4i2Q
AAAB3LAAFAAAf/mAAA 131046 a 1ITPUB个人空间4l;C!q8TM$b U&?q#d9~
AAAB3LAAFAAAf/mAAB 131046 b 2
WY9H] DRM0 AAAB3LAAFAAAf/mAAC 131046 c 3ITPUB个人空间&j x1L M1};}d$dm
AAAB3LAAFAAAf/nAAA 131047 d 4
A`3By"rOP,y0 AAAB3LAAFAAAf/nAAB 131047 e 5
R,ln#\!r&DF,|0 AAAB3LAAFAAAf/nAAC 131047 f 6
#QIj/CTSVy0 AAAB3LAAFAAAf/oAAA 131048 g 7ITPUB个人空间,H,{C$tC3i2_2cZ
AAAB3LAAFAAAf/oAAB 131048 h 8ITPUB个人空间RI~[}L0s7i
AAAB3LAAFAAAf/oAAC 131048 i 9
#rOw!@?;Z(I0 AAAB3LAAFAAAf/pAAA 131049 j 10ITPUB个人空间&Y
步1:在会话17中发布如下声明:ITPUB个人空间&S#U9iL(vg_p
17> var x refcursor
cxgV|{?l0 17> exec open :x for select substr(c,1,5),id from t8;ITPUB个人空间!X W3zVDQ;l#d6t
PL/SQL 过程已成功完成。ITPUB个人空间!CS(y"H+@h
步2:在会话13删除T8的所有记录且提交:
Mm^)tA$BZ0 13> delete t8 ;
3m&NZ6AD0 已删除 10 行。ITPUB个人空间A"ZV}%C z$oc ?|k
13> commit;
~.IDt'y-k]$eK+V0 提交完成。
cw|]DHg Lv0 步3:在会话17中输出游标X的所有行:ITPUB个人空间EbM8\!ZK
17> print xITPUB个人空间"f;|$M+pGE s.|#VX
SUBSTR(C,1 IDITPUB个人空间TRq-[|6L;lk6k
---------- ----------
!a?\.`@VI7}0 g 7
c@zPc0 h 8ITPUB个人空间v#tF,bUu
i 9
*L,pj M-\0 J 10ITPUB个人空间;Wkb$Sl2mC
AA 1ITPUB个人空间.nUHv nR
B 2ITPUB个人空间!WpTi&Er!\!\:i
C 3
]X;i9[a%zugUn0 D 4ITPUB个人空间Glwv(OdYWby"K
E 5ITPUB个人空间!z%Q,p MndD
f 6ITPUB个人空间QOV"J4LdM4x&\)k
已选择10行。ITPUB个人空间-B(bT,z1p8f"V As;f
我们在会话13中已删除且已提交,但在会话17中还是显示出了T8中的所有行,这是为什么呢?
tw)pCjz8c(Q0 1) 在步1打开游标,但此时并没有执行、执取,在会话17的PGA中,将会开辟一块内存存贮此游标。在游标的相关信息中,有一条就是游标打开是的SCN,假若此
;h}FW!Y0 ITPUB个人空间]1fq#S&Yu
时的SCN是1000。
Ahi2H;O"^yS/Q0 2) 在步2中对表T8进行了操作,并提交。Oracle每个数据块的头部,都记有此块当前的SCN值,此SCN值随着对块的更新而变化。假如,我们在步2更新T8表时,ITPUB个人空间1o8kv;F@+bi q!o5M?
ITPUB个人空间4s,hxf.K0Whv q%z4A'\
SCN是1200,这个值将被记入块头部的SCN值。
`'OL#N2lF)D&]]2U$Rq0 3) 在步3我们发布Print x声明,此声明将完成执行、抓取等步骤。在从T8表的相关块中抓取行时,Oracle会将打开游标时的SCN和块本身的SCN相比较,如果发现ITPUB个人空间$[x0Acp6H8~4xF/XP
6qT:s(H1F!KY0 后者大于前者,证明打开游标是在更新表之前进行的,Oracle将会在回滚段中寻找小于游标SCN的信息,构造一个在打开游标之前的块,这就是CR块了。如果回滚ITPUB个人空间0x_ j#[];ZCS8w3n`
.]u:fI*X*U2s^a0 段中的T8表的信息已经被覆盖,将会报告一个ORA-01555 快照太老错误。ITPUB个人空间JX^QBoI2v8u.g
执行时间过长的查询,有时也会报出这个错误。ITPUB个人空间:uJ$qt7u
二、SCN
Z(g;F6FL'X/|0 SCN就是Oracle内部的一个记时机值,也就是Oracle的内部时钟。在9i之后,我们可以通过如下的方式获得当前的SCN号:
1J2C[ss,f0 scott@MYTWO>
JqFZ8J4K1Id0d'pI0 select scn,to_char(scn,’xxxxxxx’) from (select dbms_flashback.get_system_change_number SCN from dual);ITPUB个人空间7a8RZa*UEw7r
SCN ITPUB个人空间|6jP:Pmfi [{ya
----------ITPUB个人空间K;p;L+l9L_&U-Jo%A
8727805
j$~1w3Z!y$fqW"S0 在几乎所有的地方,你都能见到SCN。在事务表、回滚块中的回滚记录、数据块、日志文件等等,我们上面曾提到过,在游标中,记录的也有游标打开时的SCN。ITPUB个人空间2V+y7df*N1uy Pp
(在eygle的深入浅出oracle中有关SCN号更详细的介绍,18页)
!F;v)S%R%VDRu1Ey0 三、构造CR块
v{*Cn%H7rZ {0 Oracle会在三种情况下去读回滚段构造CR块:
(X(Cg+@|d0 1. 只要数据块上有锁,Oracle将会构造CR块。
9eS5O*}F1W0 2. 游标的SCN小于块的SCN,证明块在游标打开之后又被修改过了,这就要去构造CR块。
$^r*R@w8Epz9W0 3. 闪回查询中,要求的SCN小于块的SCN,也要去构造CR块。
q)Mg6E.G4~A0 ITPUB个人空间;l/u)_ juMqJE8x
构造CR块ITPUB个人空间/X9wz gf'z"Fc(e-RQ
步1:先观察表T8的行分布情况:
lu9fV"?g6x2n0 ROWID BLOCK# C ID
M ?DyDtpJ0 ------------------ ---------- ---------- ----------ITPUB个人空间6j+F]%\f'Z4i2Q
AAAB3LAAFAAAf/mAAA 131046 a 1ITPUB个人空间4l;C!q8TM$b U&?q#d9~
AAAB3LAAFAAAf/mAAB 131046 b 2
WY9H] DRM0 AAAB3LAAFAAAf/mAAC 131046 c 3ITPUB个人空间&j x1L M1};}d$dm
AAAB3LAAFAAAf/nAAA 131047 d 4
A`3By"rOP,y0 AAAB3LAAFAAAf/nAAB 131047 e 5
R,ln#\!r&DF,|0 AAAB3LAAFAAAf/nAAC 131047 f 6
#QIj/CTSVy0 AAAB3LAAFAAAf/oAAA 131048 g 7ITPUB个人空间,H,{C$tC3i2_2cZ
AAAB3LAAFAAAf/oAAB 131048 h 8ITPUB个人空间RI~[}L0s7i
AAAB3LAAFAAAf/oAAC 131048 i 9
#rOw!@?;Z(I0 AAAB3LAAFAAAf/pAAA 131049 j 10ITPUB个人空间&Y