深入剖析oracle一致性读

首先开两个窗口:
transaction one:

Select * from users;

USERID USERNAME

------ --------------------

    1 zbcxy

 

Transaction two:
select * from users;

USERID USERNAME

------ --------------------

    1 zbcxy

 

Transaction one:

Update users set username=’xiongge’ whereuserid=1;

Select * from users;

USERID USERNAME

------ --------------------

    1 xiongge

 

Transaction two:

Select * from users;

USERID USERNAME

------ --------------------

    1 zbcxy

 

相信了解一致性读的朋友对上面的结果并不惊讶

下面我来剖析内部机制:
首先我们dump 当前block:
select id,name,dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid)from users;

DBMS_ROWID.ROWID_RELATIVE_FNO(DBMS_ROWID.ROWID_BLOCK_NUMBER(

------------------------------------------------------------

                             4                            670

 

然后dump该数据块:
alter system dump datafile 4 block 670;

 

Block header dump:  0x0100029e

 Object id onBlock? Y

 seg/obj:0x126bb  csc: 0x00.2ed461  itc: 2 flg: E  typ: 1 - DATA

     brn:0  bdba: 0x1000298 ver: 0x01 opc: 0

     inc:0  exflg: 0

 

 Itl           Xid                  Uba         Flag Lck        Scn/Fsc

0x01  0x0004.021.00000641 0x00c00163.0147.2d  C---    0  scn 0x0000.002e816a

0x02  0x0004.015.0000064f 0x00c0043d.0152.05  ----    1 fsc 0x0000.00000000

bdba: 0x0100029e

data_block_dump,data header at 0x1fdc7064

===============

tsiz: 0x1f98

hsiz: 0x14

pbl: 0x1fdc7064

     76543210

flag=--------

ntab=1

nrow=1

frre=-1

fsbo=0x14

fseo=0x1f64

avsp=0x1f76

tosp=0x1f76

0xe:pti[0] nrow=1    offs=0

0x12:pri[0]        offs=0x1f64

block_row_dump:

tab 0, row 0, @0x1f64

tl: 14 fb: --H-FL-- lb: 0x2  cc: 2

col  0: [2]  c1 02

col  1: [ 7] 78 69 6f 6e 67 67 65

end_of_block_dump

End dump data blocks tsn: 4 file#: 4 minblk 670maxblk 670

 

select UTL_RAW.CAST_TO_varchar2(replace(' 78 69 6f6e 67 67 65 ',' ')) from dual;

UTL_RAW.CAST_TO_VARCHAR2(REPLA

--------------------------------------------------------------------------------

Xiongge

 

可以看到数据块中的内容已经被修改,那么我们为什么在另一个会话中可以访问到原数据呢?
这取决与undo segment

 

Dump undo block:

Uba中保存着回滚快的地址

Alter system dump datafile 3 block 1085;

这里不明白的朋友请移步至:

http://www.hangger.com/index.php/archives/241

下面贴出undo block中的部分内容:
*-----------------------------

* Rec #0x5 slt: 0x15  objn:75451(0x000126bb)  objd: 75451  tblspc: 4(0x00000004)

*      Layer:  11 (Row)   opc: 1  rci 0x00  

Undo type: Regular undo    Begin trans    Last buffer split:  No

Temp Object:  No

Tablespace Undo:  No

rdba: 0x00000000Ext idx: 0

flg2: 0

*-----------------------------

uba: 0x00c0043d.0152.01 ctl max scn:0x0000.002ec673 prv tx scn: 0x0000.002ec67d

txn start scn: scn:0x0000.00000000 logon user: 84

 prevbrb: 12583992 prev bcl: 0

KDO undo record:

KTB Redo

op: 0x03 ver: 0x01 

compat bit: 4 (post-11) padding: 0

op: Z

KDO Op code: URP row dependencies Disabled

 xtype: XA flags: 0x00000000  bdba:0x0100029e  hdba: 0x0100029a

itli: 2 ispac: 0  maxfr: 4858

tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0ckix: 0

ncol: 2 nnew: 1 size: -2

col  1: [ 5] 7a 62 63 78 79

 

select UTL_RAW.CAST_TO_varchar2(replace('7a 62 63 78 79 ',' ')) from dual;

UTL_RAW.CAST_TO_VARCHAR2(REPLA

--------------------------------------------------------------------------------

Zbcxy

 

这儿保存着我以前的数据。

 

那oracle是怎么判断该给用户什么数据呢?

当用户发出一条SQL语句,ORACLE就知道了它的结果,其实原因就在于ITL中记录的SCN,和Uba. 当发出一条sql语句时,ORACLE会记录下这个时刻(SCN),然后在buffer cache中查找需要的BLOCK,或者从磁盘上读,当别的会话修改了数据,或者正在修改数据,就会在相应的block上记录ITL,此时ORACLE发现ITL中记录的SCN大于SELECT时刻的SCN,那么ORACLE就会根据block中ITL中的Uba找到UNDO信息获得该block的前镜像,然后在buffer cache 中构造出CR块,此时ORALCE 也会检查构造出来的BLOCK中ITL记录的SCN,如果SCN还大于select时刻的SCN,那么一直重复构造前镜像,然后ORACLE找到前镜像BLOCK中的ITL的SCN是否小于select的SCN,同时检查这个事物有没有提交或者回滚,如果没有,那么继续构造前镜像,直到找到需要的BLOCK,如果在构造前镜像的过程中所需的UNDO信息被覆盖了,就会报快照过旧的错误。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值