首先构造产生读一致性的案例环境,本例采用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重用以及同个事务多次更新发布的情况,此篇不再做验证。
|
|