`

10g:ora_rowscn伪列介绍和使用

阅读更多

10g里为表新增加了一个伪列ora_rowscn
下面一段英文是官方SQL Reference里的说明:

 

For each row,ORA_ROWSCNreturns 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 toCREATE TABLE ... NOROWDEPENDENCIES | ROWDEPENDENCIESfor 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 anUPDATE or DELETEstatement.

ORA_ROWSCNis 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.

 

主要是这么几点:
1.默认情况,ora_rowscn记录的scn并不准确,记录的是block的scn。
2.创建表的时候ROWDEPENDENCIES可以来使ora_rowscn真正记录行一级的scn。
3.不能用在查询view时。
4.不能用于flashback query。

可以用来:
1.确认行所在块最后一次修改的scn
2.确认行所在块最后一次修改的大概时间
3.大部分的时候可以确定出两行记录创建的先后顺序(没在同一个块上)
4.如果CREATE TABLE ... ROWDEPENDENCIES 可以精确到行


下面的实验涉及:
1.验证缺省情况Ora_rowscn只记录block级
2.通过scn_to_timestamp 来查询update/insert时间
3.CREATE TABLE ... ROWDEPENDENCIES让ora_rowscn精确到行一级

1.验证缺省情况Ora_rowscn只记录block级
1.1 创建表
SQL> create table emptt as select empno,ename from emp where empno>7700;

表已创建。

1.2 查询ora_rowscn:
SQL> select ora_rowscn,empno,ename from emptt;

ORA_ROWSCN      EMPNO ENAME
---------------------- ---------- ----------
    794054              7782      CLARK
    794054               7788       SCOTT
    794054              7839      KING
    794054              7844       TURNER
    794054              7876       ADAMS
    794054              7900       JAMES
    794054             7902       FORD
    794054              7934       MILLER

已选择8行。

1.3 修改一行:
SQL> update emptt set ename='CLARKCLARK' where empno=7782;

已更新 1 行。

1.4 发现所有行的ora_rowscn都相同,并且rowid显示这些行都在同一个块:
SQL> select rowid,ora_rowscn,empno,ename from emptt;

ROWID                               ORA_ROWSCN EMPNO ENAME
--------------------------------- ----------              ---------- ----------
AAAM2dAAEAAAAG8AAA     794099            7782     CLARKCLARK
AAAM2dAAEAAAAG8AAB     794099            7788     SCOTT
AAAM2dAAEAAAAG8AAC     794099            7839     KING
AAAM2dAAEAAAAG8AAD     794099            7844    TURNER
AAAM2dAAEAAAAG8AAE     794099           7876      ADAMS
AAAM2dAAEAAAAG8AAF     794099            7900     JAMES
AAAM2dAAEAAAAG8AAG     794099          7902      FORD
AAAM2dAAEAAAAG8AAH     794099           7934      MILLER

已选择8行。


1.5 再向表里插入一些数据:
SQL> insert into emptt
2 select empno,ename from emp;

已创建14行。

SQL> commit;

提交完成。

1.6 现在表在两个块上,不同块上的行ora_rowscn分别不同:
SQL> select rowid,ora_rowscn,empno,ename from emptt;

ROWID                                ORA_ROWSCN EMPNO ENAME
--------------------------------- ---------------        ---------- ----------
AAAM2dAAEAAAAG8AAA     794099            7782     CLARKCLARK
AAAM2dAAEAAAAG8AAB     794099            7788     SCOTT
AAAM2dAAEAAAAG8AAC     794099           7839     KING
AAAM2dAAEAAAAG8AAD     794099           7844     TURNER
AAAM2dAAEAAAAG8AAE     794099           7876     ADAMS
AAAM2dAAEAAAAG8AAF     794099           7900     JAMES
AAAM2dAAEAAAAG8AAG     794099           7902     FORD
AAAM2dAAEAAAAG8AAH     794099           7934     MILLER
AAAM2dAAEAAAAG9AAA     794170           7369     SMITH
AAAM2dAAEAAAAG9AAB     794170           7499     ALLEN
AAAM2dAAEAAAAG9AAC     794170           7521     WARD
AAAM2dAAEAAAAG9AAD     794170           7566    JONES
AAAM2dAAEAAAAG9AAE     794170           7654    MARTIN
AAAM2dAAEAAAAG9AAF     794170           7698    BLAKE
AAAM2dAAEAAAAG9AAG     794170           7782    CLARK
AAAM2dAAEAAAAG9AAH     794170           7788    SCOTT
AAAM2dAAEAAAAG9AAI       794170           7839    KING
AAAM2dAAEAAAAG9AAJ     794170            7844    TURNER
AAAM2dAAEAAAAG9AAK     794170           7876    ADAMS
AAAM2dAAEAAAAG9AAL     794170           7900    JAMES
AAAM2dAAEAAAAG9AAM     794170           7902    FORD
AAAM2dAAEAAAAG9AAN     794170           7934    MILLER

已选择22行。

1.7 更新一行再次验证:
SQL> update emptt set ename='CLARKtt' where ename='CLARKCLARK';

已更新 1 行。

SQL> commit;

提交完成。

SQL> select rowid,ora_rowscn,empno,ename from emptt;

ROWID                                ORA_ROWSCN   EMPNO ENAME
----------------------------------   ----------            ---------- ----------
AAAM2dAAEAAAAG8AAA     794199           7782        CLARKtt
AAAM2dAAEAAAAG8AAB     794199           7788        SCOTT
AAAM2dAAEAAAAG8AAC     794199           7839        KING
AAAM2dAAEAAAAG8AAD     794199           7844        TURNER
AAAM2dAAEAAAAG8AAE     794199            7876        ADAMS
AAAM2dAAEAAAAG8AAF     794199           7900        JAMES
AAAM2dAAEAAAAG8AAG     794199          7902         FORD
AAAM2dAAEAAAAG8AAH     794199           7934        MILLER
AAAM2dAAEAAAAG9AAA     794170           7369        SMITH
AAAM2dAAEAAAAG9AAB     794170           7499        ALLEN
AAAM2dAAEAAAAG9AAC     794170           7521        WARD
AAAM2dAAEAAAAG9AAD     794170          7566           JONES
AAAM2dAAEAAAAG9AAE     794170          7654           MARTIN
AAAM2dAAEAAAAG9AAF     794170          7698           BLAKE
AAAM2dAAEAAAAG9AAG     794170          7782          CLARK
AAAM2dAAEAAAAG9AAH     794170          7788          SCOTT
AAAM2dAAEAAAAG9AAI      794170           7839          KING
AAAM2dAAEAAAAG9AAJ     794170           7844          TURNER
AAAM2dAAEAAAAG9AAK     794170          7876          ADAMS
AAAM2dAAEAAAAG9AAL     794170          7900          JAMES
AAAM2dAAEAAAAG9AAM     794170         7902          FORD
AAAM2dAAEAAAAG9AAN     794170         7934          MILLER

已选择22行。


2. 通过scn_to_timestamp 来查询update/insert时间

此功能很有用。
SQL> col update_time format a40
SQL> select scn_to_timestamp(ora_rowscn) update_time,empno,ename from emptt;

UPDATE_TIME                                            EMPNO    ENAME
------------------------------------------------       ----------    ----------
08-5月 -08 10.45.12.000000000 上午             7782   CLARKtt
08-5月 -08 10.45.12.000000000 上午             7788   SCOTT
08-5月 -08 10.45.12.000000000 上午             7839   KING
08-5月 -08 10.45.12.000000000 上午             7844   TURNER
08-5月 -08 10.45.12.000000000 上午             7876   ADAMS
08-5月 -08 10.45.12.000000000 上午             7900   JAMES
08-5月 -08 10.45.12.000000000 上午             7902   FORD
08-5月 -08 10.45.12.000000000 上午             7934 MILLER
08-5月 -08 10.44.09.000000000 上午             7369   SMITH
08-5月 -08 10.44.09.000000000 上午             7499   ALLEN
08-5月 -08 10.44.09.000000000 上午             7521   WARD
08-5月 -08 10.44.09.000000000 上午             7566   JONES
08-5月 -08 10.44.09.000000000 上午             7654   MARTIN
08-5月 -08 10.44.09.000000000 上午             7698   BLAKE
08-5月 -08 10.44.09.000000000 上午             7782 CLARK
08-5月 -08 10.44.09.000000000 上午             7788   SCOTT
08-5月 -08 10.44.09.000000000 上午             7839   KING
08-5月 -08 10.44.09.000000000 上午             7844   TURNER
08-5月 -08 10.44.09.000000000 上午             7876   ADAMS
08-5月 -08 10.44.09.000000000 上午             7900   JAMES
08-5月 -08 10.44.09.000000000 上午             7902 FORD
08-5月 -08 10.44.09.000000000 上午             7934   MILLER

已选择22行。

 

3.CREATE TABLE ... ROWDEPENDENCIES让ora_rowscn精确到行一级

3.1 创建表
SQL> create table empaa rowdependencies as select empno,ename from emp where empno>7700;

表已创建。

3.2 查询
SQL> select rowid,ora_rowscn,empno,ename from empaa;

ROWID                      ORA_ROWSCN      EMPNO ENAME
------------------------------     ----------      ----------    ----------
AAAM3qAAEAAAAJFAAA     799250       7782       CLARK
AAAM3qAAEAAAAJFAAB     799250       7788       SCOTT
AAAM3qAAEAAAAJFAAC     799250       7839       KING
AAAM3qAAEAAAAJFAAD     799250       7844       TURNER
AAAM3qAAEAAAAJFAAE     799250       7876       ADAMS
AAAM3qAAEAAAAJFAAF     799250       7900       JAMES
AAAM3qAAEAAAAJFAAG     799250       7902       FORD
AAAM3qAAEAAAAJFAAH     799250       7934       MILLER

已选择8行。

3.3更新一行并查看结果
SQL> update empaa set ename='CLARKCLARK' where empno=7782;

已更新 1 行。

没有commit的时候ora_rowscn为空
SQL> select rowid,ora_rowscn,empno,ename from empaa;

ROWID                                  ORA_ROWSCN   EMPNO ENAME
-------------------------------      ----------             ---------- ----------
AAAM3qAAEAAAAJFAAA                               7782       CLARKCLARK
AAAM3qAAEAAAAJFAAB     799250             7788       SCOTT
AAAM3qAAEAAAAJFAAC     799250             7839       KING
AAAM3qAAEAAAAJFAAD     799250             7844       TURNER
AAAM3qAAEAAAAJFAAE     799250             7876       ADAMS
AAAM3qAAEAAAAJFAAF     799250             7900       JAMES
AAAM3qAAEAAAAJFAAG     799250             7902       FORD
AAAM3qAAEAAAAJFAAH     799250             7934       MILLER

已选择8行。

SQL> commit;

提交完成。

Commit之后同一块上的ora_rowscn也能对应到独立行:

SQL> select rowid,ora_rowscn,empno,ename from empaa;

ROWID                                  ORA_ROWSCN      EMPNO ENAME
---------------------------------   ----------             ---------- ----------
AAAM3qAAEAAAAJFAAA     799302             7782        CLARKCLARK
AAAM3qAAEAAAAJFAAB     799250             7788        SCOTT
AAAM3qAAEAAAAJFAAC     799250             7839       KING
AAAM3qAAEAAAAJFAAD     799250             7844        TURNER
AAAM3qAAEAAAAJFAAE     799250             7876        ADAMS
AAAM3qAAEAAAAJFAAF     799250             7900        JAMES
AAAM3qAAEAAAAJFAAG     799250             7902        FORD
AAAM3qAAEAAAAJFAAH     799250             7934        MILLER

已选择8行。

 

 

附:一个使用ora_rowscn辅助闪回的例子

--创建测试表
create table test (id int,name varchar2(20)) rowdependencies;
--插入测试数据
insert into test values(1,'a');
insert into test values(2,'b');
insert into test values(3,'c');
insert into test values(4,'d');
insert into test values(5,'e');
insert into test values(6,'f');
insert into test values(7,'g');
insert into test values(8,'h');

commit;
--查看数据
select * from test;

/*ID  NAME
-- -------
1   a
2   b
3   c
4   d
5   e
6   f
7   g
8   h*/

--查看当前ora_rowscn
select id,name,ora_rowscn,dbms_rowid.rowid_block_number(rowid) blockno from test;

/*ID NAME ORA_ROWSCN BLOCKNO
1 a 8249759 288
2 b 8249759 288
3 c 8249759 288
4 d 8249759 288
5 e 8249759 288
6 f 8249759 288
7 g 8249759 288
8 h 8249759 288*/

--执行更新
update test set name='8' where id=8;

commit

--查看更新后的数据
select * from test;

/*ID  NAME
-- -------
1   a
2   b
3   c
4   d
5   e
6   f
7   g
8   8*/

--查看更新后的ora_rowscn
select id,name,ora_rowscn,dbms_rowid.rowid_block_number(rowid) blockno from test;

/*ID NAME ORA_ROWSCN BLOCKNO
1 a 8249759 288
2 b 8249759 288
3 c 8249759 288
4 d 8249759 288
5 e 8249759 288
6 f 8249759 288
7 g 8249759 288
8 8 8249896 288*/

--现在可以通过闪回查询恢复这条记录
select id,name,ora_rowscn,to_char(scn_to_timestamp(ora_rowscn),'yyyy-mm-dd hh24:mi:ss') time,dbms_rowid.rowid_block_number(rowid) blockno from test;
/*ID NAME ORA_ROWSCN TIME BLOCKNO
1 a 8249759 2008-08-01 10:04:19 288
2 b 8249759 2008-08-01 10:04:19 288
3 c 8249759 2008-08-01 10:04:19 288
4 d 8249759 2008-08-01 10:04:19 288
5 e 8249759 2008-08-01 10:04:19 288
6 f 8249759 2008-08-01 10:04:19 288
7 g 8249759 2008-08-01 10:04:19 288
8 8 8249896 2008-08-01 10:08:22 288
*/
select * from test as of timestamp to_date('2008-08-01 10:08:22','yyyy-mm-dd hh24:mi:ss')

--然后删除这条错误记录
delete from test where id=8
--将闪回查询的数据插入原表
insert into test select * from test as of timestamp to_date('2008-08-01 10:08:22','yyyy-mm-dd hh24:mi:ss') where id=8
--查看数据
select * from test

--至此借助ora_rowscn恢复完毕

--如果这个这个表包含LONG数据类型,就采用EXP/IMP方式进行恢复

C:\>exp test/test@acf file=test.dmp tables=test flashback_scn=8249896 query=\"where id=8\"

--然后删除这条错误记录
delete from test where id=8;

--最后倒入这条记录完成恢复
C:\>imp test/test@acf file=test.dmp ignore=y

 

分享到:
评论

相关推荐

    ORA_ROWSCN伪列在Oracle历史数据迁移中的应用研究.pdf

    ORA_ROWSCN伪列是Oracle10g中的一种伪列,可以用来跟踪数据库中的每一行数据的最后修改时间。通过使用ORA_ROWSCN伪列,我们可以高效地进行数据迁移,并且可以保证数据库的完整性和一致性。 在本文中,我们将详细...

    ORACLE中查找定位表最后DML操作的时间小结

     ORA_ROWSCN伪列是Oracle 10g开始引入的,可以查询表中记录最后变更的SCN。然后通过SCN_TO_TIMESTAMP函数可以将SCN转换为时间戳,从而找到最后DML操作时SCN的对应时间。但是,默认情况下,每行记录的ORA_ROWSCN是...

    用Oracle 10g新的行时间戳捕捉变化

    Oracle 10g引入了一项新特性,即`ORA_ROWSCN`伪列,这是一个非常有用的工具,尤其对于数据仓库的维护和跟踪数据变化。在传统的数据库管理中,要跟踪行的变化,通常需要在表中添加一个“最后更新时间”列,并在每次...

    Ora_10G_DBA_Reference

    《Ora_10G_DBA_Reference》是一个关于Oracle 10g数据库管理的重要参考资料,主要面向DBAs(数据库管理员)和技术人员,旨在提供全面、深入的Oracle 10g数据库管理和维护知识。该资源包含两个文件:一本CHM格式的手册...

    Oracle分析函数 示例数据

    Oracle分析函数的示例数据 其实也就是Mastering oracle sql书的SQL脚本

    ORA-00904: "WM_CONCAT": 标识符无效

    WM_CONCAT是Oracle 10g及更早版本中用于字符串合并的一个非标准函数,但在11g版本中被废弃,取而代之的是新的标准SQL聚合函数LISTAGG。 在Oracle 11g R2及更高版本中,WM_CONCAT函数不再可用,因此在19c中遇到这个...

    oracle 11G 月巡检手册

    00:10:31 ora_ckpt_CKDB oracle 2972 10 May 07 ? 00:03:45 ora_smon_CKDB oracle 2974 10 May 07 ? 00:00:00 ora_reco_CKDB oracle 2976 10 May 07 ? 00:01:24 ora_cjq0_CKDB oracle 2978 10 May 07 ? 00:06:17 ...

    Oracle 报错ORA-00845 MEMORY_TARGET not supported on this system

    MEMORY_TARGET是Oracle 11g引入的一个动态内存管理特性,用于自动管理SGA和PGA内存的大小。 首先,需要了解MEMORY_TARGET参数的作用。在Oracle中,SGA(System Global Area)和PGA(Program Global Area)是两个...

    需安装Oracle客户端:Instant_Client_11.2.0.3_win_x64.zip

    PLSQL13.0.4.196版本连接Oracle时使用免安装Oracle客户端,发现怎么也获取不到oracle主目录,用低版本的PLSQL配置免安装客户端,就可以顺利获取到主目录。 但是想用PLSQL13,那就试试安装oracle客户端吧,安装过后...

    Ora_10G_DBA_Reference.chm

    9. **网格计算**:介绍Oracle 10G的网格计算概念,如何在网格环境中部署和管理数据库,实现资源的灵活分配和负载均衡。 10. **自动管理特性**:10G引入了许多自动化功能,如自动内存管理、自动存储优化等,手册将...

    ora_migrator:从Oracle到PostgreSQL迁移的工具

    ora_migrator为插件使用迁移Oracle数据库到PostgreSQL。 请阅读db_migrator文档以获取用法说明。 本自述文件仅涵盖插件的安装和设置以及常规文档中未涉及的其他功能。 除此之外, ora_migrator还提供了从Oracle到...

    ora_convert_mysql.tar.gz

    标题“ora_convert_mysql.tar.gz”表明这是一个用于转换Oracle数据库数据的工具,以便它们可以在MySQL数据库中使用的压缩包。描述提到,这是一个由个人编写的shell脚本,它能够生成在MySQL中执行的INSERT语句,这...

    oracle特有的错误:ORA-01036:非法的变量名/编号

    在Oracle数据库系统中,"ORA-01036:非法的变量名/编号"是一个常见的错误,通常出现在PL/SQL代码或者SQL查询语句中,当你尝试使用一个不正确或者未定义的变量时,Oracle数据库会抛出这个错误。这个错误可能是由于...

    Oracle_instant_client_10_2

    2、在oracle安装路径(C:\oracle\product\10.2.0\db_1\network\ADMIN)中找tnsnames.ora 复制到C:\Oracle_instant_client_10_2路径下 3、第一次启动plsql,点击取消 设置oracle目录名为C:\Oracle_instant_client_10_2 ...

    ora_error大全.doc

    10. **ORA-12010**: 系统权限问题,可能尝试执行无权进行的操作。 11. **ORA-12011**: 一个异常错误导致了子程序的执行被中断。 12. **ORA-12012** 和 **ORA-12013**: 都与游标有关,可能是尝试访问未打开或未定义...

    ogg112101_ggs_Windows_x86_ora10g_32bit

    标题 "ogg112101_ggs_Windows_x86_ora10g_32bit" 提供的信息表明,这是一个与Oracle GoldenGate (OGG)相关的软件包,适用于Windows 32位操作系统,且与Oracle数据库10g版本兼容。Oracle GoldenGate是一款实时数据...

    ogg112101_fbo_ggs_Linux_x64_ora11g_64bit

    在“ogg112101_fbo_ggs_Linux_x64_ora11g_64bit”这个压缩包中,我们可以推测这包含了Oracle Golden Gate的版本11.2.1.0.1,专为Linux 64位操作系统设计,且与Oracle 11g数据库兼容。以下将详细介绍Oracle Golden ...

    ora_dbbak.rar_oracle

    Oracle数据库是全球广泛使用的大型企业级关系型数据库管理系统,RMAN(Recovery Manager)是Oracle提供的一个强大的数据备份和恢复工具。本压缩包"ora_dbbak.rar_oracle"包含了与Oracle RMAN加密备份和恢复相关的...

    文档五、安装配置Oracle10g.pdf

    ORACLE_SID=ora10g export ORACLE_BASE ORACLE_HOME ORACLE_SID ADMIN_HOME LOCAL_HOME NLS_DATE_FORMAT export MSGVERB NOMSGLABEL NOMSGSERVERITY NLS_LANG ORA_NLS33 DISPLAY LD_LIBRARY_PATH 五、磁盘空间分配 ...

Global site tag (gtag.js) - Google Analytics