10G之ORA_ROWSCN
链接:http://www.dbaroad.me/archives/2009/05/10g_ora_rowscn.html
Oracle 10G中,使用ora_rowscn可以查询到记录最后变更的SCN。不过,默认是基于块级维护(norowdependencies),也就是说,一个BLOCK上的所有行会共享同一个SCN,如果一个BLOCK上的某一行更新了,该BLOCK上的其它行的SCN也会推进,这是因为此时的SCN是从BLOCK头部获取的。另外也可以实现行级维护,在建表时通过加上rowdependencies选项来指定,这样Oracle会为每一行存储各自的SCN。
我们可以通过dump数据块来看看两者的区别:
基于块级维护(norowdependencies):
SQL> create table test (a number);
Table created.
SQL> insert into test values (1);
1 row created.
SQL> commit;
Commit complete.
SQL> select a,ora_rowscn from test;
A ORA_ROWSCN
---------- ----------
1 29683946
SQL> insert into test values (2);
1 row created.
SQL> commit;
Commit complete.
SQL> select a,ora_rowscn,
2 dbms_rowid.ROWID_BLOCK_NUMBER(rowid) block#
3 from test;
A ORA_ROWSCN BLOCK#
---------- ---------- ----------
1 29683963 69298
2 29683963 69298
SQL>
这里,BLOCK,69298里的行的SCN由29683946推进行到29683963,通过dump这个块,可以看出,这个SCN,是来自BLOCK 头部的:
Start dump data blocks tsn: 0 file#: 1 minblk 69298 maxblk 69298 buffer tsn: 0 rdba: 0x00410eb2 (1/69298) scn: 0x0000.01c4f0fb seq: 0x02 flg: 0x02 tail: 0xf0fb0602 frmt: 0x02 chkval: 0x0000 type: 0x06=trans data Hex dump of block: st=0, typ_found=1 ................... ................... ................... block_row_dump: tab 0, row 0, @0x1f9a tl: 6 fb: --H-FL-- lb: 0x1 cc: 1 col 0: [ 2] c1 02 tab 0, row 1, @0x1f94 tl: 6 fb: --H-FL-- lb: 0x2 cc: 1 col 0: [ 2] c1 03 end_of_block_dump
scn: 0×0000.01c4f0fb,高位为0,低位通过转化为29683963,与ORA_ROWSCN得到的结果相同:
SQL> select to_number('1c4f0fb','xxxxxxxx') from dual;
TO_NUMBER('1C4F0FB','XXXXXXXX')
-------------------------------
29683963
基于行级维护(rowdependencies):
SQL> create table test_r (a number) rowdependencies;
Table created.
SQL> insert into test_r values(1);
1 row created.
SQL> commit;
Commit complete.
SQL> select a,ora_rowscn from test_r;
A ORA_ROWSCN
---------- ----------
1 29685282
SQL> insert into test_r values(2);
1 row created.
SQL> commit;
Commit complete.
SQL> select a,ora_rowscn,
2 dbms_rowid.ROWID_BLOCK_NUMBER(rowid) block#
3 from test_r;
A ORA_ROWSCN BLOCK#
---------- ---------- ----------
1 29685282 69330
2 29685523 69330
SQL>
使用rowdependencies选项后,同一个BLOK内,行的SCN已不同,我们DUMP出来,看看区别:
Start dump data blocks tsn: 0 file#: 1 minblk 69330 maxblk 69330 buffer tsn: 0 rdba: 0x00410ed2 (1/69330) scn: 0x0000.01c4f713 seq: 0x02 flg: 0x02 tail: 0xf7130602 frmt: 0x02 chkval: 0x0000 type: 0x06=trans data Hex dump of block: st=0, typ_found=1 ................... ................... ................... Itl Xid Uba Flag Lck Scn/Fsc 0x01 0x0008.01f.00002955 0x00801793.0a65.01 --U- 1 fsc 0x0000.01c4f622 0x02 0x000a.016.0001cb67 0x00803e45.3be0.04 --U- 1 fsc 0x0000.01c4f713 ................... ................... ................... block_row_dump: tab 0, row 0, @0x1f94 tl: 12 fb: --H-FL-- lb: 0x1 cc: 1 dscn 0x0000.00000000 col 0: [ 2] c1 02 tab 0, row 1, @0x1f88 tl: 12 fb: --H-FL-- lb: 0x2 cc: 1 dscn 0x0000.00000000 col 0: [ 2] c1 03 end_of_block_dump
DUMP出来的BLOCK中,我们发现,block_row_dump部份,多记录一行dscn,其实也就是记录行变更的SCN,当前还为0,实际上我们查询得到的ORA_ROWSCN是从Scn/Fsc上获得的:
SQL> select to_number('1c4f622','xxxxxxxx') from dual;
TO_NUMBER('1C4F622','XXXXXXXX')
-------------------------------
29685282
SQL> select to_number('1c4f713','xxxxxxxx') from dual;
TO_NUMBER('1C4F713','XXXXXXXX')
-------------------------------
29685523
而随着ITL的清除,会把Scn/Fsc写到dscn中。我们再insert一条数据,DUMP出来观察下:
SQL> insert into test_r values(3);
1 row created.
SQL> commit;
Commit complete.
SQL> select a,ora_rowscn,
2 dbms_rowid.ROWID_BLOCK_NUMBER(rowid) block#
3 from test_r;
A ORA_ROWSCN BLOCK#
---------- ---------- ----------
1 29685282 69330
2 29685523 69330
3 29686226 69330
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0002.025.00002629 0x00802f83.08d6.07 --U- 1 fsc 0x0000.01c4f9d2
0x02 0x000a.016.0001cb67 0x00803e45.3be0.04 C--- 0 scn 0x0000.01c4f713
...................
...................
...................
block_row_dump:
tab 0, row 0, @0x1f94
tl: 12 fb: --H-FL-- lb: 0x0 cc: 1
dscn 0x0000.01c4f622
col 0: [ 2] c1 02
tab 0, row 1, @0x1f88
tl: 12 fb: --H-FL-- lb: 0x0 cc: 1
dscn 0x0000.01c4f713
col 0: [ 2] c1 03
tab 0, row 2, @0x1f7c
tl: 12 fb: --H-FL-- lb: 0x1 cc: 1
dscn 0x0000.00000000
col 0: [ 2] c1 04
end_of_block_dump
这时已经刷新到dscn中了。
这里需要注意的是,打开行级维护,不能通来alter table实现,只能在建表时指定,因为BLOCK的物理结构已经不同了。
— The End —


站内搜索