关于读一致性的一个测试案例

首先构造产生读一致性的案例环境,本例采用2个session来构造读一致性案例(当然一个session也可完成该实验)。为力求效果明了,本次排除延时块清除以及itl重用等情况。

Session 1:

SQL> conn mecoyoo/mecoyoo@test
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as mecoyoo

SQL> create table test_cr (id number, value number) tablespace test;
Table created

SQL> insert into test_cr values(1,10′);
1 row inserted

SQL> insert into test_cr values(2,20′);
1 row inserted

SQL> commit;
Commit complete

SQL> exec pro_test_cr;

执行pro_test_cr,在此过程中,开启session 2 并执行相应 DML操作,等待session 1 产生结果。



           pro_test_cr脚本如下:
create or replace procedure pro_test_cr as
n_value_1 varchar2(20);
n_value_2 varchar2(20);
n_scn number;
type cr_cur_type is ref cursor;
cr_cur cr_cur_type;
begin
select dbms_flashback.get_system_change_number into n_scn from dual;
open cr_cur for ’select value from test_cr where id=1′;
dbms_lock.sleep(120);
fetch cr_cur into n_value_1;
select value into n_value_2 from test_cr where id=1;
dbms_output.put_line(’query scn just nearly…………….’||n_scn);
dbms_output.put_line(’consistent read value ………’||n_value_1);
dbms_output.put_line(’current read value …………’||n_value_2);
close cr_cur;
end;

发布以下语句

SQL> update test_cr set value=1 where id=1;
已更新 1 行。
SQL> commit;

SQL> exec pro_test_cr;


切换到session1,等待,查看执行结果

SQL> exec pro_test_cr;

query scn just nearly……………. 653239            —-发布查询时刻的近似scn
consistent read value ………10                      —-一致读获取的value
current read value …………1                         —-当前的实际value

可见,oracle获取了一致读值。下面,对上述这个过程从dump block的角度稍加分析

SQL> select dbms_rowid.rowid_relative_fno(rowid) file_id,dbms_rowid.rowid_block_number(rowid) block_id,dbms_rowid.rowid_object(rowid) object_id from test_cr;

FILE_ID   BLOCK_ID OBJECT_ID
———- ———- ———-
         5       2210      49234
         5       2210      49234

对 datafile 5 block 2210 dump,我们来观察itl部分。

SQL> alter system dump datafile 5 block 2210;

*** 2008-04-10 21:55:29.847

*** ACTION NAME) 2008-04-10 21:55:29.831

*** MODULE NAMESQL*Plus) 2008-04-10 21:55:29.831

*** SERVICE NAMESYS$USERS) 2008-04-10 21:55:29.831

*** SESSION ID132.1324) 2008-04-10 21:55:29.831

Start dump data blocks tsn: 5 file#: 5 minblk 2210 maxblk 2210

buffer tsn: 5 rDBA: 0×014008a2 (5/2210)

scn: 0×0000.0009f7c7 seq: 0×01 flg: 0×02 tail: 0xf7c70601

frmt: 0×02 chkval: 0×0000 type: 0×06=trans data

Block header dump: 0×014008a2

Object id on Block? Y

seg/obj: 0xc052 csc: 0×00.9f7bb itc: 2 flg: O typ: 1 - DATA

     fsl: 0 fnx: 0×0 ver: 0×01

Itl           Xid                  Uba         Flag Lck        Scn/Fsc

0×01   0×0001.013.00000462 0×00800a68.00cb.3e C—    0 scn 0×0000.0009f7ac ->scn 653228

0×02   0×0002.00f.00000471 0×00800d3c.00dd.2b –U-    1 fsc 0×0000.0009f7c7 ->scn 653255,判断这就是session 2 刚才发布的对应事务

接下来转储对应的undo block,可以采取如下2种方式:

1.通过itl上的xid 0×0002.00f.00000471 对应XIDUSN,XIDSLOT,XIDSQN 分别为 2,15,1137

SQL> ALTER SYSTEM DUMP UNDO BLOCK "_SYSSMU2$" XID 2 15 1137

2.通过itl上的Uba记录,我们得知该事务使用的undo block 地址为0×00800d3c,对应为datafile 2 block 3388

SQL> ALTER SYSTEM DUMP datafile 2 block 3388;

UNDO BLK:

xid: 0×0002.00f.00000471 seq: 0xdd cnt: 0×2b irb: 0×2b icl: 0×0   flg: 0×0000

Rec Offset      Rec Offset      Rec Offset      Rec Offset      Rec Offset

—————————————————————————

0×01 0×1f68     0×02 0×1f0c     0×03 0×1eb0     0×04 0×1e70     0×05 0×1e24   

0×06 0×1dd8     0×07 0×1d34     0×08 0×1c90     0×09 0×1be8     0×0a 0×1b44   

0×0b 0×1aa0     0×0c 0×19dc     0×0d 0×1938     0×0e 0×1894     0×0f 0×17ec   

0×10 0×1784     0×11 0×171c     0×12 0×1674     0×13 0×15cc     0×14 0×1564   

0×15 0×14c0     0×16 0×1418     0×17 0×1374     0×18 0×12cc     0×19 0×1228   

0×1a 0×1180     0×1b 0×1118     0×1c 0×10b0     0×1d 0×1048     0×1e 0×0fa0   

0×1f 0×0ef8     0×20 0×0e90     0×21 0×0dec     0×22 0×0d44     0×23 0×0cdc   

0×24 0×0c5c     0×25 0×0bd4     0×26 0×0b40     0×27 0×0a60     0×28 0×09fc   

0×29 0×09a8     0×2a 0×0928     0×2b 0×0878   

*—————————–

* Rec #0×2b slt: 0×0f objn: 49234(0×0000c052) objd: 49234 tblspc: 5(0×00000005)

*       Layer: 11 (Row)   opc: 1  rci 0×00

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

Temp Object: No

Tablespace Undo: No

rdba: 0×00000000

*—————————–

uba: 0×00800d3c.00dd.2a ctl max scn: 0×0000.0009f5d6 prv tx scn: 0×0000.0009f5e5 –>scn 652773 小于 query scn,满足读一致性条件

txn start scn: scn: 0×0000.0009f7bb logon user: 57

prev brb: 8391989 prev bcl: 0

KDO undo record:

KTB Redo

op: 0×04 ver: 0×01

op: L itl: xid: 0×0003.01a.0000047c uba: 0×008004e9.00d0.04

                      flg: C—    lkc: 0     scn: 0×0000.0009f66d

Array Update of 1 rows:

tabn: 0 slot: 0(0×0) flag: 0×2c lock: 0 ckix: 1

ncol: 2 nnew: 1 size: 0

KDO Op code: 21 row dependencies Disabled

xtype: XAxtype KDO_KDOM2 flags: 0×00000080 bdba: 0×014008a2 hdba: 0×014008a1

itli: 2 ispac: 0 maxfr: 4863

vect = 3

col 1: [ 2] c1 0b ――这就是前映像的值,也就是我们读一致性查到的value

      当然,在读取block header上 itl信息后还有一步对比 undo header 上的 transaction table的 过程,由于本例产生的是fast commit cleanout,故将此步骤简化省略。对于itl重用以及同个事务多次更新发布的情况,此篇不再做验证。
标签: 暂无标签
oraunix

写了 199 篇文章,拥有财富 1026,被 339 人关注

转播转播 分享分享 分享淘帖
回复

使用道具

成为第一个吐槽的人

您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

意见
反馈