ITPub博客

首页 > Linux操作系统 > Linux操作系统 > ORA_ROWSCN 伪列介绍和使用

ORA_ROWSCN 伪列介绍和使用

原创 Linux操作系统 作者:xz43 时间:2011-11-29 14:33:44 0 删除 编辑
ORA_ROWSCN伪列是Oracle10g引入的,可以查询表中记录最后变更的SCN。这个新的伪列在某些环境下会非常有用,比如执行乐观锁定,或者增量数据抽取的时候。但是,默认情况下,每行记录的ORA_ROWSCN是基于Block的,除非在建表的时候执行开启行级跟踪(createtable … rowdependencies)。
 
官方SQL Reference里的说明:

For each row,ORA_ROWSCN returns the conservative upper bound system change number (SCN) of the most recent change to the row. This pseudocolumn is useful for determining approximately when a row was last updated. It is not absolutely precise, because Oracle tracks SCNs by transaction committed for the block in which the row resides. You can obtain a more fine-grained approximation of the SCN by creating your tables with row-level dependency tracking.

Please refer to CREATE TABLE ... NOROWDEPENDENCIES | ROWDEPENDENCIES for more information on row-level dependency tracking.

You cannot use this pseudocolumn in a query to a view. However, you can use it to refer to the underlying table when creating a view. You can also use this pseudocolumn in the WHERE clause of an UPDATE or DELETE statement.

ORA_ROWSCN  is not supported for Flashback Query. Instead, use the version query pseudocolumns,
which are provided explicitly for Flashback Query.
Please refer to the SELECT ... flashback_query_clause for information on Flashback Query and
"Version Query Pseudocolumns" for additional information on those pseudocolumns.

简单说来就是默认情况,ora_rowscn记录的scn并不准确,记录的是block的scn;创建表的时候ROWDEPENDENCIES可以来使ora_rowscn真正记录行一级的scn;不能用在查询view时;不能用于flashback query。可以用来确认行所在块最后一次修改的scn;确认行所在块最后一次修改的大概时间;大部分的时候可以确定出两行记录创建的先后顺序(没在同一个块上);如果CREATE TABLE ... ROWDEPENDENCIES 可以精确到行。

乐观锁和ORA_ROWSCN

       需要select ... for update做悲观锁定的时候,通过使用ORA_ROWSCN可以改成乐观锁定。一开始select数据的时候将ORA_ROWSCN查出来,修改后如果要写回数据库之前再比对下最新的ORA_ROWSCN就可以知道这期间数据是否有发生变化。

增量数据抽取和ORA_ROWSCN

       每次抽取后记录最大的ORA_ROWSCN,下次抽取再基于上一次的SCN来获得最近修改过的数据即可。在10g之前,很多系统要实现增量数据抽取,要么通过解析日志,要么加触发器,要么就在表上加一个时间截字段。

       ORA_ROWSCN其实就是第三种方式,只是这个字段由Oracle来维护,这样可以避免一些应用绕过时间截去更新其他字段带来的问题。不过,如果系统中使用了逻辑备库或者streams等逻辑复制的方案,而数据抽取又是基于逻辑备库的话,ORA_ROWSCN就可能对抽取后的数据分析有影响了,因为通过这个得到的时间是逻辑备库上记录变更的时间,而不是源库的时间了。

       当然,如果纯粹只是做数据抽取,而不需要使用这个时间来做分析,还是问题不大的,但还是要考虑一旦逻辑备库出现故障需要重做的,则这个增量抽取要怎么来处理的问题。

测试

1、 基本测试,验证缺省情况Ora_rowscn只记录block级

SQL> create table rowscntest(id number,name varchar2(20));

Table created

SQL> insert into rowscntest values(1,'dave');

1 row inserted

SQL> insert into rowscntest values(1,'dave');

1 row inserted

SQL> commit;

Commit complete

SQL>
SQL> select dbms_rowid.rowid_relative_fno(rowid) REL_FNO,
  2         dbms_rowid.rowid_block_number(rowid) BLOCKNO,
  3         dbms_rowid.rowid_row_number(rowid) ROWNO,
  4         id,
  5         name
  6    from rowscntest;

   REL_FNO    BLOCKNO      ROWNO         ID NAME
---------- ---------- ---------- ---------- --------------------
         8     222701          0          1 dave
         8     222701          1          1 dave

SQL> select ora_rowscn,id from rowscntest;

ORA_ROWSCN         ID
---------- ----------
 155228124          1
 155228124          1

SQL>

默认情况下,使用的是block header的SCN,所以这时候,如果我们改变该表的信息,block header 的scn 发生改变,那么对应block上所有的ora_rowscn 也会发生改变。

2、通过增加创建表的选项rowdependencies/norowdependencies,来对ora_rowscn测试

SQL> create table rowscntest2(id number,name varchar2(20)) rowdependencies;

Table created

启动行级别的跟踪。

SQL> insert into rowscntest2 values(1,'dave');

1 row inserted

SQL> insert into rowscntest2 values(2,'jack');

1 row inserted

SQL> commit;

Commit complete

SQL>
SQL> select dbms_rowid.rowid_relative_fno(rowid) REL_FNO,
  2         dbms_rowid.rowid_block_number(rowid) BLOCKNO,
  3         dbms_rowid.rowid_row_number(rowid) ROWNO,
  4         id,
  5         name
  6    from rowscntest2;

   REL_FNO    BLOCKNO      ROWNO         ID NAME
---------- ---------- ---------- ---------- --------------------
         8     222709          0          1 dave
         8     222709          1          2 jack

SQL> select ora_rowscn,id from rowscntest2;

ORA_ROWSCN         ID
---------- ----------
 155228359          1
 155228359          2

2个ora_rowscn 是一样的。ora_rwscn 是在itl 发生cleanout 时刷到dscn的。 我们在进行一些事务操作查看一下。

SQL> update rowscntest2 set name='dave2' where id=1;

1 row updated

SQL> commit;

Commit complete

SQL> update rowscntest2 set name='jack2' where id=2;

1 row updated

SQL> commit;

Commit complete

SQL> select ora_rowscn,id from rowscntest2;

ORA_ROWSCN         ID
---------- ----------
 155228602          1
 155228609          2

测试的ora_rowscn已经发生改变,我们再做一些改变

SQL> insert into rowscntest2 values(3,'john');

1 row inserted

SQL> commit;

Commit complete

SQL> insert into rowscntest2 values(4,'jerry');

1 row inserted

SQL> commit;

Commit complete

SQL> select ora_rowscn,id from rowscntest2;

ORA_ROWSCN         ID
---------- ----------
 155228602          1
 155228609          2
 155228815          3
 155228820          4

3、最后执行一下与ORA_ROWSCN有关时间的测试

SQL> col SCN_TO_TIMESTAMP(ORA_ROWSCN) for a40
SQL> select scn_to_timestamp(ora_rowscn),id,name from rowscntest2;

SCN_TO_TIMESTAMP(ORA_ROWSCN)                     ID NAME
---------------------------------------- ---------- --------------------
29-11月-11 03.05.01.000000000 下午                1 dave2
29-11月-11 03.05.16.000000000 下午                2 jack2
29-11月-11 03.10.13.000000000 下午                3 john
29-11月-11 03.10.25.000000000 下午                4 jerry

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/9399028/viewspace-712353/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
鱼儿的学习空间

注册时间:2010-11-16

  • 博文量
    433
  • 访问量
    1863691