ORA_ROWSCN就是Oracle10g中引入的一个新的内建函数,这个函数可以用于返回相关行记录的SCN值。
我看通过数据看一下这个ORA_ROWSCN的用法:
SQL> connect eygle/eygle
已连接。
SQL> create table test
2 as select user_id,username,password,rpad(DEFAULT_TABLESPACE,2000,'*') tablespce
3 from dba_users;
表已创建。
SQL> select username,ora_rowscn,dbms_rowid.rowid_block_number(rowid) blockno from test
2 where rownum <8;
USERNAME ORA_ROWSCN BLOCKNO
------------------------------ ---------- ----------
MGMT_VIEW 465191 204
SYS 465191 204
SYSTEM 465191 204
DBSNMP 465191 205
SYSMAN 465191 205
EYGLE 465191 205
PROXY 465191 206
已选择7行。
可以注意到,通过ORA_ROWSCN可以得到每一行记录的SCN值,由于SCN通常在COMMIT时被增进,所以来测试一下数据变更时SCN的变更情况:
SQL> update test set username='DBA' where username='SYS';
已更新 1 行。
SQL> select username,ora_rowscn,dbms_rowid.rowid_block_number(rowid) blockno from test
2 where rownum <8;
USERNAME ORA_ROWSCN BLOCKNO
------------------------------ ---------- ----------
MGMT_VIEW 465191 204
DBA 465191 204
SYSTEM 465191 204
DBSNMP 465191 205
SYSMAN 465191 205
EYGLE 465191 205
PROXY 465191 206
已选择7行。
SQL> commit;
提交完成。
SQL> select username,ora_rowscn,dbms_rowid.rowid_block_number(rowid) blockno from test
2 where rownum <8;
USERNAME ORA_ROWSCN BLOCKNO
------------------------------ ---------- ----------
MGMT_VIEW 465340 204
DBA 465340 204
SYSTEM 465340 204
DBSNMP 465191 205
SYSMAN 465191 205
EYGLE 465191 205
PROXY 465191 206
已选择7行。
我们注意到,虽然只更新了一条记录,但是在BLOCK 204上的3条记录SCN都被增进了。这是因为在缺省条件下创建的数据表,ORA_ROWSCN所获得的SCN来自数据块头部,所以同一数据块上的记录的SCN会同时被增进,也只有一个SCN,可以转储一下相关的数据块简单了解一下:
SQL> select segment_name,file_id,block_id,blocks from dba_extents where segment_name='TEST';
SEGMENT_NAME FILE_ID BLOCK_ID BLOCKS
-------------------- ---------- ---------- ----------
TEST 4 201 8
SQL> alter system dump datafile 4 block 204;
系统已更改。
找到生成的trace文件:
SQL>@gettrcname
TRACE_FILE_NAME
-------------------------------------------------------------------------------
C:\ORACLE\ADMIN\EYGLE\UDUMP\eygle_ora_3364.trc
简要摘录跟踪文件:
Start dump data blocks tsn: 4 file#: 4 minblk 204 maxblk 204
buffer tsn: 4 rdba: 0x010000cc (4/204)
scn: 0x0000.000719bc seq: 0x02 flg: 0x06 tail: 0x19bc0602
frmt: 0x02 chkval: 0x63ae type: 0x06=trans data
……………………..
Block header dump: 0x010000cc
Object id on Block? Y
seg/obj: 0x38bf csc: 0x00.71927 itc: 3 flg: E typ: 1 - DATA
brn: 0 bdba: 0x10000c9 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0xffff.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.00071927
0x02 0x0008.02c.000000d4 0x00800541.004e.05 --U- 1 fsc 0x0000.000719bc
0x03 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
data_block_dump,data header at 0x8da227c
这里数据块头的“SCN 0x0000.000719bc”就正是ORA_ROWSCN的来源:
SQL> select to_number('719bc','xxxxxx') from dual;
TO_NUMBER('719BC','XXXXXX')
---------------------------
465340
那么如果建表时启用了ROWDEPENDENCIES,那么情况就会完全不同。重新做一个测试,使用ROWDEPENDENCIES选项重新创建测试表:
SQL> drop table test;
表已删除。
SQL> CREATE TABLE TEST ROWDEPENDENCIES
2 AS SELECT user_id,username,PASSWORD,RPAD(default_tablespace,2000,'*') tablespce
3 FROM dba_users;
表已创建。
SQL> SELECT username, ora_rowscn, DBMS_ROWID.rowid_block_number (ROWID) blockno
2 FROM TEST
3 WHERE ROWNUM < 7;
USERNAME ORA_ROWSCN BLOCKNO
------------------------------ ---------- ----------
MGMT_VIEW 466578 212
SYS 466578 212
SYSTEM 466578 212
DBSNMP 466578 213
SYSMAN 466578 213
EYGLE 466578 213
已选择6行。
更新数据再来查看ROWSCN的变化:
SQL> update test set username='DBA' where username='SYS';
已更新 1 行。
SQL> commit;
提交完成。
SQL> SELECT username, ora_rowscn, DBMS_ROWID.rowid_block_number (ROWID) blockno
2 FROM TEST
3 WHERE ROWNUM < 7;
USERNAME ORA_ROWSCN BLOCKNO
------------------------------ ---------- ----------
MGMT_VIEW 466578 212
DBA 466635 212
SYSTEM 466578 212
DBSNMP 466578 213
SYSMAN 466578 213
EYGLE 466578 213
已选择6行。
注意到此时仅有被更新记录的ROWSCN发生了变化,这是如何实现的呢?通过转储block就可以很容易地发现Oracle的这个秘密:
Block header dump: 0x010000d4
Object id on Block? Y
seg/obj: 0x38c0 csc: 0x00.71e92 itc: 3 flg: E typ: 1 - DATA
brn: 0 bdba: 0x10000d1 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0xffff.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.00071e92
0x02 0x0006.01c.000000d3 0x0080178a.0043.33 --U- 1 fsc 0x0000.00071ecb
0x03 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
data_block_dump,data header at 0x8da227c
……
tab 0, row 0, @0x1786
tl: 2042 fb: --H-FL-- lb: 0x0 cc: 4
dscn 0x0000.00071e92
……
tab 0, row 1, @0xf93
tl: 2035 fb: --H-FL-- lb: 0x2 cc: 4
dscn 0x0000.00071e92
……
tab 0, row 2, @0x79c
tl: 2039 fb: --H-FL-- lb: 0x0 cc: 4
dscn 0x0000.00071e92
……
此时,每条记录种都包含了额外的信息,即DSCN,这就是每条记录的SCN,由于Oracle采用延时写出,当前记录的SCN未被更新,ORA_ROWSCN查询的SCN信息来自ITL中的Scn/Fsc信息。
SQL> select to_number('71ecb','xxxxxx') from dual;
TO_NUMBER('71ECB','XXXXXX')
---------------------------
466635
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




