专注各种脚本编程
Baidu
加入收藏夹
本站内容有下面分类知识,欢迎您的到来^_^
shell相关:指令篇 基础篇 脚本欣赏 编程实例 shell问问 shell视频教程 技巧篇 水平测试 E文资料 vi编辑器 高级Bash脚本编程指南
其他:mysql perl c语言 oracle
当前位置:| 主页>oracle>

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

百度收藏 QQ搜藏

一、查询魔术
步1:在会话17中发布如下声明:
17> var x refcursor
17> exec open :x  for select substr(c,1,5),id from t8;
PL/SQL 过程已成功完成。
步2:在会话13删除T8的所有记录且提交:
13> delete t8 ;
已删除 10 行。
13> commit;
提交完成。
步3:在会话17中输出游标X的所有行:
17> print x
SUBSTR(C,1         ID
---------- ----------
g                   7
h                   8
i                   9
J                  10
AA                  1
B                   2
C                   3
D                   4
E                   5
f                   6
已选择10行。
我们在会话13中已删除且已提交,但在会话17中还是显示出了T8中的所有行,这是为什么呢?
1) 在步1打开游标,但此时并没有执行、执取,在会话17的PGA中,将会开辟一块内存存贮此游标。在游标的相关信息中,有一条就是游标打开是的SCN,假若此时的SCN是1000。
2) 在步2中对表T8进行了操作,并提交。Oracle每个数据块的头部,都记有此块当前的SCN值,此SCN值随着对块的更新而变化。假如,我们在步2更新T8表时,SCN是1200,这个值将被记入块头部的SCN值。
3) 在步3我们发布Print x声明,此声明将完成执行、抓取等步骤。在从T8表的相关块中抓取行时,Oracle会将打开游标时的SCN和块本身的SCN相比较,如果发现后者大于前者,证明打开游标是在更新表之前进行的,Oracle将会在回滚段中寻找小于游标SCN的信息,构造一个在打开游标之前的块,这就是CR块了。如果回滚段中的T8表的信息已经被覆盖,将会报告一个ORA-01555 快照太老错误。
        执行时间过长的查询,有时也会报出这个错误。
二、SCN
        SCN就是Oracle内部的一个记时机值,也就是Oracle的内部时钟。在9i之后,我们可以通过如下的方式获得当前的SCN号:
scott@MYTWO>
select scn,to_char(scn,’xxxxxxx’) from (select dbms_flashback.get_system_change_number SCN from dual);
   SCN  
----------
8727805
在几乎所有的地方,你都能见到SCN。在事务表、回滚块中的回滚记录、数据块、日志文件等等,我们上面曾提到过,在游标中,记录的也有游标打开时的SCN。
(在eygle的深入浅出oracle中有关SCN号更详细的介绍,18页)
三、构造CR块
Oracle会在三种情况下去读回滚段构造CR块:
1.  只要数据块上有锁,Oracle将会构造CR块。
2.  游标的SCN小于块的SCN,证明块在游标打开之后又被修改过了,这就要去构造CR块。
3.  闪回查询中,要求的SCN小于块的SCN,也要去构造CR块。

构造CR块
步1:先观察表T8的行分布情况:
ROWID                  BLOCK# C                  ID
------------------ ---------- ---------- ----------
AAAB3LAAFAAAf/mAAA     131046 a                   1
AAAB3LAAFAAAf/mAAB     131046 b                   2
AAAB3LAAFAAAf/mAAC     131046 c                   3
AAAB3LAAFAAAf/nAAA     131047 d                   4
AAAB3LAAFAAAf/nAAB     131047 e                   5
AAAB3LAAFAAAf/nAAC     131047 f                   6
AAAB3LAAFAAAf/oAAA     131048 g                   7
AAAB3LAAFAAAf/oAAB     131048 h                   8
AAAB3LAAFAAAf/oAAC     131048 i                   9
AAAB3LAAFAAAf/pAAA     131049 j                  10
步2:发布更新命令
13> update t8 set c=upper(c) where id<=2;
已更新2行。
13> commit;
提交完成。
13> update t8 set c='A1' where id<=1;
已更新 1 行。
13> update t8 set c='A2' where id<=2;
已更新2行。
13> update t8 set c='B2' where id<=2;
已更新2行。
13> commit;
提交完成。
换到其他会话,
17> update t8 set c='aa1' where id<=1;
已更新 1 行。
17> update t8 set c='bb2' where id=2;
已更新 1 行。
17> commit;
提交完成。
17> update t8 set c='aaa1' where id<=1;
已更新 1 行。
17> update t8 set c='bbb2' where id=2;
已更新 1 行。
17> update t8 set c='aaaa1' where id<=1;
已更新 1 行。
17> update t8 set c='bbbb2' where id=2;
已更新 1 行。
17> commit;
提交完成。
再换个会话:
10> update t8 set c='aaaaa10' where id=1;
已更新 1 行。
10> update t8 set c='bbbbb10' where id=2;
已更新 1 行。
10> commit;
提交完成。
10> update t8 set c='az' where id=1;
已更新 1 行。
10> update t8 set c='by' where id=2;
已更新 1 行。
此时的SCN是
18> select dbms_flashback.get_system_change_number SCN from dual;
   SCN
----------
8729612
总结一下
行1的变化a->A->A1 A2 B2->aa1->aaa1  aaaa1->aaaaa10->az
行2的变化b->B->B2       ->bb2->bbb2  bbbb2->bbbbb10->by

上一页12 3 4 下一页
上一篇:讨论锁_篇晶晶实验五 下一篇:没有了

power by soyo123 2007-2008