读一致性测试一例

     首先构造产生读一致性的案例环境,本例采用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 NAME:(SQL*Plus) 2008-04-10 21:55:29.831

*** SERVICE NAME:(SYS$USERS) 2008-04-10 21:55:29.831

*** SESSION ID:(132.1324) 2008-04-10 21:55:29.831

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

buffer tsn: 5 rdba: 0x014008a2 (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: 0x014008a2

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 0x00800a68.00cb.3e C—    0 scn 0×0000.0009f7ac ->scn 653228

0×02   0×0002.00f.00000471 0x00800d3c.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 地址为0x00800d3c,对应为datafile 2 block 3388

SQL> ALTER SYSTEM DUMP datafile 2 block 3388;

UNDO BLK:

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

Rec Offset      Rec Offset      Rec Offset      Rec Offset      Rec Offset

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

0×01 0x1f68     0×02 0x1f0c     0×03 0x1eb0     0×04 0x1e70     0×05 0x1e24   

0×06 0x1dd8     0×07 0x1d34     0×08 0x1c90     0×09 0x1be8     0x0a 0x1b44   

0x0b 0x1aa0     0x0c 0x19dc     0x0d 0×1938     0x0e 0×1894     0x0f 0x17ec   

0×10 0×1784     0×11 0x171c     0×12 0×1674     0×13 0x15cc     0×14 0×1564   

0×15 0x14c0     0×16 0×1418     0×17 0×1374     0×18 0x12cc     0×19 0×1228   

0x1a 0×1180     0x1b 0×1118     0x1c 0x10b0     0x1d 0×1048     0x1e 0x0fa0   

0x1f 0x0ef8     0×20 0x0e90     0×21 0x0dec     0×22 0x0d44     0×23 0x0cdc   

0×24 0x0c5c     0×25 0x0bd4     0×26 0x0b40     0×27 0x0a60     0×28 0x09fc   

0×29 0x09a8     0x2a 0×0928     0x2b 0×0878   

*—————————–

* Rec #0x2b slt: 0x0f objn: 49234(0x0000c052) 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: 0x00800d3c.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: 0x008004e9.00d0.04

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

Array Update of 1 rows:

tabn: 0 slot: 0(0×0) flag: 0x2c 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: 0x014008a2 hdba: 0x014008a1

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重用以及同个事务多次更新发布的情况,此篇不再做验证。

bookmark

相关文章 随机文章