HelloDBA [English]
搜索Internet 搜索 HelloDBABA
  Oracle技术站。email: fuyuncat@gmail.com  MSN: fuyuncat@hotmail.com   acoug  acoug 

关于事务对数据块的操作过程的分析和试验(3)

[English]

作者: fuyuncat

来源: www.HelloDBA.com

日期: 2007-01-07 14:50:11

分享到  新浪微博 腾讯微博 人人网 i贴吧 开心网 豆瓣 淘宝 推特 Facebook GMail Blogger Orkut Google Bookmarks

回滚

如果事务一旦回滚,则会清除数据块上的所有标志,就不存在延迟块清除了。

还是看看试验吧,回更清楚一些。

先做更新操作,在提交/回滚前dump

SQL> conn demo/demo
Connected.
SQL>
SQL> alter system flush buffer_cache;
 
System altered.
 
SQL>
SQL> update t_multiver set b=115 where a=1;
 
1 row updated.
 
SQL>
SQL> alter system dump datafile 5 block 50959;
 
System altered.

 

看看数据块上的变化:

Block header dump:  0x0140c70f
 Object id on Block? Y
 seg/obj: 0xe46c  csc: 0x00.a4a49e6b  itc: 2  flg: E  typ: 1 - DATA
     brn: 0  bdba: 0x140c709 ver: 0x01 opc: 0
     inc: 0  exflg: 0
 
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0012.01b.000009ae  0x02c0007c.0372.27  ----    1  fsc 0x0000.00000000
0x02   0x000c.017.00000a25  0x02c0001f.0396.21  C---    0  scn 0x0000.a4a4a07b
 
... ...
block_row_dump:
tab 0, row 0, @0x1f5e
tl: 10 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 2]  c1 02
col  1: [ 3]  c2 02 10
tab 0, row 1, @0x1f4a
... ...

注意到XidUbaLck标志已经被打上,但是FlagSCN还没有。

 

然后回滚事务:

SQL> rollback;
 
Rollback complete.
 
SQL>
SQL> alter system dump datafile 5 block 50959;
 
System altered.

 

再看数据块内容:

Block header dump:  0x0140c70f
 Object id on Block? Y
 seg/obj: 0xe46c  csc: 0x00.a4a49e6b  itc: 2  flg: E  typ: 1 - DATA
     brn: 0  bdba: 0x140c709 ver: 0x01 opc: 0
     inc: 0  exflg: 0
 
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x000e.00a.000007f5  0x02c0003f.02cc.1e  C---    0  scn 0x0000.a4a49c89
0x02   0x000c.017.00000a25  0x02c0001f.0396.21  C---    0  scn 0x0000.a4a4a07b
 
... ...
block_row_dump:
tab 0, row 0, @0x1f5e
tl: 10 fb: --H-FL-- lb: 0x0  cc: 2
col  0: [ 2]  c1 02
col  1: [ 3]  c2 02 10
tab 0, row 1, @0x1f4a
... ...

所有锁标志被清除,Itl都已经被还原(这个测试是接着前面的进行的,可以对比前面dump出来的内容,发现XidUbaScn是一样的,所以说是“还原”)。

 

一致性读

当一个读操作读到某一个数据块上,发现该数据块有被修改过的痕迹(事务标志、锁标志),会需要通过SCN来检查是读取当前数据还是修改前的数据,以保证读取到的所有数据都是读操作开始发生那一时刻(快照)的数据来保证数据的一致性。如果数据块上事务的SCN<读操作的SCN,说明数据块上的更改是发生在读操作之前的(所有SCN是唯一的,并且是累加的),就可以直接读取数据块上修改过的数据;否则,就需要从回滚段中读取修改前的数据,以保持数据的一致性。这就是一致性读。

下面是一个一致性读的例子:

SQL> select * from t_multiver;
 
         A          B
---------- ----------
         1        115
         2        115
         3        222
 
SQL> var cc refcursor
SQL>
SQL> begin
  2  open :cc for select * from t_multiver;
  3  end;
  4  /
 
PL/SQL procedure successfully completed.
 
SQL>
SQL> update t_multiver set b=115 where a=3;
 
1 row updated.
 
SQL> print :cc
 
         A          B
---------- ----------
         1        115
         2        115
         3        222
 
SQL>  select * from t_multiver;
 
         A          B
---------- ----------
         1        115
         2        115
         3        115

 

从这个例子可以看到,读取操作只会读取读取查询开始时那一时刻的数据,如果数据在读取操作以后发生了变化,则从回滚段中读取老数据镜像。如果修改事务已经提交,并且在读取操作读到该数据块时,回滚段中的信息已经被覆盖,则会发生1555错误。我另外一篇文章介绍了1555错误,这就不再赘述了。

事务在数据块的微观操作过程

总结以上,我们可以绘制出一个更新事务在数据块上微观操作流程图了。当然,这个流程图并不能反映出所有细节,毕竟Oracle还有很多内部的东西是我们没办法知道的。

 

 

Top

Copyright ©2005,HelloDBA.Com 保留一切权利

申明
by fuyuncat