Oracle Database 9i, 10g闪回版本查询

news/2024/7/1 18:07:44
 
      不需要设置,立即识别对行的所有更改
 
    在 Oracle9i Database 中,我们看到它推出了以闪回查询形式表示的“时间机器”。该特性允许 DBA 看到特定时间的列值,只要在还原段中提供该数据块此前镜像的拷贝即可。但是,闪回查询只提供某时刻数据的固定快照,而不是在两个时间点之间被更改数据的运行状态表示。某些应用程序,如涉及到外币管理的应用程序,可能需要了解一段时期内数值数据的变化,而不仅仅是两个时间点的数值。由于闪回版本查询特性,Oracle Database 10g 能够更方便高效地执行该任务。
 
    查询对表的更改
 
    在本示例中,我使用了一个银行外币管理应用程序。其数据库含有一个名称为 RATES 的表,用于记录特定时间的汇率。
 
    SQL> desc rates
    Name              Null?Type
    ----------------- -------- ------------
    CURRENCY                   VARCHAR2(4)
    RATE                       NUMBER(15,10)
 
    该表显示 US$ 与各种其他货币的汇率,在 CURRENCY 列中显示。在金融服务行业中,汇率不但在变更时进行更新,而且被记录在历史中。需要这种方式的原因是银行交易可能在“过去时间”生效,以便适应由于汇款而耗费的时间。例如,对于一项在上午 10:12 发生但在上午 9:12 生效的交易,其有效汇率是上午 9:12 的汇率,而不是现在的汇率。
 
    直到现在,唯一的选择是创建一个汇率历史表来存储汇率的变更,然后查询该表是否提供历史记录。另一种选择是在 RATES 表本身中记录特定汇率适用性的开始和结束时间。当发生变更时,现有行中的 END_TIME 列被更新为 SYSDATE,并插入一个具有新汇率的新行,其 END_TIME 为 NULL。
 
    但是在 Oracle Database 10g 中,闪回版本查询特性不需要维护历史表或存储开始和结束时间。使用该特性,您不必进行额外的设置,即可获得某行在过去特定时间的值。
 
    例如,假定该 DBA 在正常业务过程中数次更新汇率 ,甚至删除了某行并重新插入该行:
 
    insert into rates values ('EURO',1.1012);
    commit;
    update rates set rate = 1.1014;
    commit;
    update rates set rate = 1.1013;
    commit;
    delete rates;
    commit;
    insert into rates values ('EURO',1.1016);
    commit;
    update rates set rate = 1.1011;
    commit;
 
    在进行了这一系列操作后,DBA 将通过以下命令获得 RATE 列的当前提交值
 
    SQL> select * from rates;
 
    CURR       RATE
    ---- ----------
    EURO     1.1011
 
    此输出显示 RATE 的当前值,没有显示从第一次创建该行以来发生的所有变更。这时使用闪回查询,您可以找出给定时间点的值;但我们对构建变更的审计线索更感兴趣 ? 有些类似于通过便携式摄像机来记录变更,而不只是在特定点拍摄一系列快照。
 
    以下查询显示了对表所做的更改:
 
    select versions_starttime, versions_endtime, versions_xid,
    versions_operation, rate
    from rates versions between timestamp minvalue and maxvalue
    order by VERSIONS_STARTTIME
    /
 
    VERSIONS_STARTTIME     VERSIONS_ENDTIME       VERSIONS_XID     V       RATE
    ---------------------- ---------------------- ---------------- - ----------
    01-DEC-03 03.57.12 PM 01-DEC-03 03.57.30 PM 0002002800000C61 I     1.1012
    01-DEC-03 03.57.30 PM 01-DEC-03 03.57.39 PM 000A000A00000029 U     1.1014
    01-DEC-03 03.57.39 PM 01-DEC-03 03.57.55 PM 000A000B00000029 U     1.1013
    01-DEC-03 03.57.55 PM                         000A000C00000029 D     1.1013
    01-DEC-03 03.58.07 PM 01-DEC-03 03.58.17 PM 000A000D00000029 I     1.1016
    01-DEC-03 03.58.17 PM                         000A000E00000029 U     1.1011
 
    注意,此处显示了对该行所作的所有更改,甚至包括该行被删除和重新插入的情况。VERSION_OPERATION 列显示对该行执行了什么操作 (Insert/Update/Delete)。所做的这些工作不需要历史表或额外的列。
 
    在上述查询中,列 versions_starttime、versions_endtime、versions_xid、versions_operation 是伪列,与 ROWNUM、LEVEL 等其他熟悉的伪列相类似。其他伪列  如 VERSIONS_STARTSCN 和 VERSIONS_ENDSCN  显示了该时刻的系统更改号。列 versions_xid 显示了更改该行的事务标识符。有关该事务的更多详细信息可在视图 FLASHBACK_TRANSACTION_QUERY 中找到,其中列 XID 显示事务 id。例如,使用上述的 VERSIONS_XID 值 000A000D00000029,UNDO_SQL 值显示了实际的语句。
 
    SELECT UNDO_SQL
    FROM FLASHBACK_TRANSACTION_QUERY
    WHERE XID = '000A000D00000029';
 
    UNDO_SQL
    ----------------------------------------------------------------------------
    insert into "ANANDA"."RATES"("CURRENCY","RATE") values ('EURO','1.1013');
 
    除了实际语句之外,该视图还显示提交操作的时间标记和 SCN、查询开始时的 SCN 和时间标记以及其他信息。
 
    找出一段时期中的变更
 
    现在,让我们来看如何有效地使用这些信息。假设我们需要找出下午 3:57:54 时 RATE 列的值。我们可以执行:
 
    select rate, versions_starttime, versions_endtime
    from rates versions
    between timestamp
    to_date('12/1/2003 15:57:54','mm/dd/yyyy hh24:mi:ss')
    and to_date('12/1/2003 16:57:55','mm/dd/yyyy hh24:mi:ss')
    /
 
    RATE VERSIONS_STARTTIME     VERSIONS_ENDTIME
    ---------- ---------------------- ----------------------
        1.1011
 
    此查询与闪回查询类似。在以上的示例中,开始和结束时间为空,表示汇率在该时间段中没有更改,而是包含一个时间段。还可以使用 SCN 来找出过去的版本值。可以从伪列 VERSIONS_STARTSCN 和 VERSIONS_ENDSCN 中获得 SCN 号。以下是一个示例:
 
    select rate, versions_starttime, versions_endtime
    from rates versions
    between scn 1000 and 1001
    /
 
    使用关键词 MINVALUE 和 MAXVALUE,可以显示还原段中提供的所有变更。您甚至可以提供一个特定的日期或 SCN 值作为范围的一个端点,而另一个端点是文字 MAXVALUE 或 MINVALUE。例如,以下查询提供那些只从下午 3:57:52 开始的变更,而不是全部范围的变更:
 
    select versions_starttime, versions_endtime, versions_xid,
    versions_operation, rate
    from rates versions between timestamp
    to_date('12/11/2003 15:57:52', 'mm/dd/yyyy hh24:mi:ss')
    and maxvalue
    order by VERSIONS_STARTTIME
    /
 
    VERSIONS_STARTTIME     VERSIONS_ENDTIME       VERSIONS_XID     V       RATE
    ---------------------- ---------------------- ---------------- - ----------
    01-DEC-03 03.57.55 PM                         000A000C00000029 D     1.1013
    01-DEC-03 03.58.07 PM 01-DEC-03 03.58.17 PM 000A000D00000029 I     1.1016
    01-DEC-03 03.58.17 PM                         000A000E00000029 U     1.1011
 
    最终的分析
 
    闪回版本查询随取随用地复制表变更的短期易变数值审计。这一优点使得 DBA 能够获得过去时间段中的所有变更而不是特定值,只要还原段中提供数据,就可以尽情使用。因此,最大的可用版本依赖于 UNDO_RETENTION 参数。
 
    有关闪回版本查询的更多信息,请参见 Oracle Database Concepts 10g Release 1 (10.1) 指南的相关部分。
1Oracle 9i的闪回查询功能

  在Oracle 9i之前,如果用户错误操作数据后,除了不完全恢复外,没有好的解决办法。Oracle 9i中提供闪回查询,由一个新的包DBMS_FLASH来实现。用户使用闪回查询可以及时取得误操作DMLDeleteUpdateInsert)前某一时间点数据库的映像视图,用户可以利用系统时间或系统改变号(SCNSystem Change Number)来指定这个只读视图,并可以针对错误进行相应的恢复措施。闪回查询功能完全依赖于自动回滚段管理(AUM),对于Drop等误操作不能恢复。闪回特性可应用在以下方面:

  (1)自我维护过程中的修复:当一些重要的记录被意外删除,用户可以向后移动到一个时间点,查看丢失的行并把它们重新插入现在的表内恢复。

  (2)恢复Email和声音Email:当用户意外删除了Email或者声音信息时,可以通过移回到固定时间点来恢复删除。

  (3)账号平衡状况:可以查看以前的历史数据。如银行外币管理中用于记录特定时间的汇率。在以前,汇率变更被记录在一个历史表中,现在就可以通过闪回功能进行查询。

  (4)用于趋势分析的决策支持系统:决策支持系统和联机分析应用必须执行一个长时间的事务。使用闪回查询,这些应用可以对历史数据执行分析和建模。例如,特定产品如矿泉水随季节变化需求情况的变化。

  2、回滚段概述


  回滚段用于存放数据修改之前的位置和值,回滚段的头部包含正在使用的该回滚段事务的信息。回滚段的作用如下:

  (1)事务回滚:当事务修改表中数据的时候,该数据修改前的值(即前影像)会存放在回滚段中,当用户回滚事务时,Oracle将会利用回滚段中的数据前影像来将修改的数据恢复到原来的值。

  (2)事务恢复:当事务正在处理的时候,例程失败,回滚段的信息保存在重做日志文件中,Oracle将在下次打开数据库时利用回滚来恢复未提交的数据。


  (3)读一致性:当一个会话正在修改数据时,其它的会话将看不到该会话未提交的修改。而且,当一个语句正在执行时,该语句将看不到从该语句开始执行后的未提交的修改(语句级读一致性)。

  3OracleDeleteCommit操作的流程分析

  (1)删除(Delete)流程


  ·OracleBlock(数据块)Buffer Cache(缓冲区)(如果该BlockBuffer中不存在)

  ·Redo Log Buffer(重做日志缓冲区)中记录Delete操作的细节;

  ·在相应回滚段段头的事物表中创建一个Undo(回滚)条目;

  ·把将要删除的记录创建前镜像,存放到Undo Block(回滚块)中;

  ·Buffer Cache中的相应数据块上删除记录,并且标记相应的数据块为Dirty(脏)。

  (2)提交(Commit)流程

  ·Oracle产生一个SCN

  ·在回滚段事物表中标记该事物状态为Commited

  ·LGWR(日志读写进程) Flush Log Buffer到日志文件;

  ·如果此时数据块仍然在Buffer Cache中,那么SCN将被记录到Block Header上,这被称为快速提交;


  ·如果Dirty Block已经被写回到磁盘,那么下一个访问这个Block的进程将会自回滚段中获取该事物的状态,确认该事物被提交。然后这个进程获得提交SCN并写回到Block Header上,这被称为延迟块清除。

  4Oracle 9i中闪回查询操作实例

  进行闪回查询必须设置自动回滚段管理,在init.ora设置参数UNDO_MANAGEMENT=AUTO,参数UNDO_RETENTION=n,决定了能往前闪回的最大时间,值越大就需要越多Undo空间。

  例:Oracle 9iFlashback Query操作。

  (1)创建闪回查询用户
SQL> create user flashtest identified by flashtest;
SQL> grant connect, resource to flashtest;
SQL> grant execute on dbms_flashback to flashtest;
SQL> connect flashtest/flashtest;

  (2)创建测试表,插入测试记录
SQL> create table test(id number(3));
SQL> insert into test values (1);
SQL> insert into test values(2);
SQL> commit;
SQL> create table rec_date(date_scn);

  注意:在执行步骤3或者步骤4之前,等待5分钟。

  (3)删除记录
SQL> execute dbms_flashback.disable;
SQL> insert into rec_date select sysdate from dual;
SQL> commit;
SQL> delete from test where id=1;
SQL> commit;

  通过以上的操作,我们插入了两条记录,并删除了其中一条记录。在以下的操作中,我们将通过flashback query找到删除的记录

  (4)闪回查询
SQL> DECLARE
Restore_scn date;
BEGIN
Select date_scn into restore_scn from rec_date;
Dbms_flashback.enable_at_time (restore_scn);
END;
SQL> select * from test;
ID
1
2

  可以看出,虽然删除记录并提交,但是通过闪回操作,仍能查询到删除前的两条记录。需要注意Oracle5分钟记录一次SCN,并将SCN和对应时间的映射进行纪录。如果原来插入的记录到做闪回操作的时间在5分钟之内,用基于时间的闪回查询可能得不到记录,因为基于时间点的查询实际上是转化为最近的一次SCN,然后从这个SCN开始进行恢复。因此,如果需要精确的查询可以采用基于SCN的闪回查询,可精确闪回到需要恢复的时间。可以通过DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER语句获取SCN
  Oracle 10g的闪回查询概述

  与Oracle 9i相比Oracle 10g Flashback有了非常大的改进,从普通的Flashback Query发展到了多种形式,主要表现在如下几方面新特性:

  1 Flashback Database

  Oracle Flashback Database特性允许通过SQL语句Flashback Database语句,让 数据库前滚到当前的前一个时间点或者SCN,而不需要做时间点的恢复。闪回数据库可以迅速将数据库回到误操作或人为错误的前一个时间点,如Word中的"撤消"操作,可以不利用备份就快速的实现基于时间点的恢复。Oracle通过创建新的Flashback Logs(闪回日志),记录数据库的闪回操作。如果希望能闪回数据库,需要设置如下参数:DB_RECOVER_FILE_DEST日志的存放位置, DB_RECOVER_FILE_DEST_SIZE恢复区的大小。在创建数据库的时候,Oracle将自动创建恢复区,但默认是关闭的,需要执行 alter database flashback on命令。


  例:执行Flashback Database命令格式。
SQL>flashback database to time to_timestamp(xxx);
SQL>flashback database to scn xxx

  2 Flashback Table

  Oracle Flashback Table特性允许利用Flashback Table语句,确保闪回到表的前一个时间点。与Oracle 9i中的Flashback Query相似,利用回滚段信息来恢复一个或一些表到以前的一个时间点(一个快照)。要注意的是,Flashback Table不等于Flashback QueryFlashback Query仅仅是查询以前的一个快照点而已,并不改变当前表的状态,而Flashback Table将改变当前表及附属对象一起回到以前的时间点。


  语法:
flashback table tablename to timestamp xxx
flashback table tablename to scn xxx

  注意:如果需要闪回一个表,需要以下条件:

  ·需要有flashback any table的系统权限或者是该表的flashback对象权限;

  ·需要有该表的select,insert,delete,alter权限;

  ·必须保证该表row movement

  例:执行将test表闪回到200557下午3点。
SQL>flashback table test to timestamp to_timestamp(’2005-05-07 15:00:00’,’yyyy-mm-dd hh24:mi:ss’);

  3 Flashback Drop

  Oracle Flashback Drop特性提供一个类似回收站的功能,用来恢复不小心被删除的表。当删除表时,Oracle 10g并不立刻释放被删除的表所占用的空间,而是将这个被删除的表进行自动重命名(为了避免同类对象名称的重复)并放进回收站中。所谓的回收站类似于 Windows系统中的回收站,是一个虚拟的容器,用于存放所有被删除的对象,在回收站中被删除的对象将占用创建时的同样的空间。如果这个被删除的表需要进行恢复,就可利用Flashback Drop功能。


  例:进行一个删除表后恢复的简单测试。

  (1)显示回收站信息
SQL>show recyclebin;

  可以看到,回收站中是没有任何结果的,表示没有任何表在回收站中。

  (2)创建一个表,并删除,再次显示回收站信息
SQL>create table test_drop(name varchar2(10));
SQL>drop table test_drop;
SQL>show recyclebin;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
TEST_DROP BIN$b+XkkO1RS5K10uKo9BfmuA==$0 TABLE 2005-05-07:14:30:47

  (3)对被删除的表进行恢复
SQL>flashback table test_drop to before drop;
SQL>flashback table "BIN$b+XkkO1RS5K10uKo9BfmuA==$0" to before drop;

  (4)管理回收站

  清除回收站中的单个表: purge table test_drop

  清除整个回收站:
purge recyclebin

  清除不同的对象回收站:purge user_recyclebin
purge dba_recyclebin

  (5)确认删除一个表
SQL>drop table test_drop purge;

  如果删除一个表且不放到回收站中不能进行恢复,在drop语句中可以利用purge选项。

  4 Flash Version Query

  Oracle Flashback Version Query特性,利用保存的回滚信息,可以看到特定的表在时间段内的任何修改,如电影的回放一样,可以了解表在该期间的任何变化。Flashback version query一样依赖于AUM,提供了一个查看行改变的功能,能找到所有已经提交了的行的记录,分析出过去时间都执行了什么操作。Flashback version query采用VERSIONS BETWEEN语句来进行查询,常用的方法:


  ·VERSIONS_SCN - 系统改变号

  ·VERSIONS_TIMESTAMP - 时间

  例如:在test表中,时间1插入一条记录,时间2删除了这条记录,对于时间3执行select * from test当然查询不到这条记录,只能看到该表最后的提交记录。这时如果利用Flash Table或者是Flash Query,只能看到过去的某一时间点的一个快照,而利用Flashback Version Query,能够把时间1、时间2的操作给记录下来,并详细的查询出对表进行的任何操作。
SQL>select versions_starttime,versions_endtime, versions_xid,versions_operation,id
from test versions
between timestamp minvalue and maxvalue
order by versions_starttime;

  在上述查询中,列 versions_starttimeversions_endtimeversions_xidversions_operation是伪列,还有一些伪列,如versions_startscnversions_endscn显示了该时刻的系统更改号。列versions_xid显示了更改该行的事务标识符。

  当然,除了分析以上所有的变更之外,可以根据需要指定时间段,如显示在2005-05-07时间在15:3016:30之间test表的所有变更。
SQL>select id from test
versions between timestamp to_date(’2005-05-07 15:30:00’,’yyyy-mm-dd hh24:mi:ss’) and to_date(’2005-05-07 16:30:00’,’yyyy-mm-dd hh24:mi:ss’)

  5 Flashback Transaction Query

  Oracle Flashback Transaction Query特性确保检查数据库的任何改变在一个事务级别,可以利用此功能进行诊断 问题、性能分析和审计事务。它其实是Flashback Version Query查询的一个扩充,Flashback Version Query说明了可以审计一段时间内表的所有改变,但是也仅仅是能发现问题,对于错误的事务,没有好的处理办法。而Flashback Transaction Query提供了从FLASHBACK_TRANSACTION_QUERY视图中获得事务的历史以及Undo_sql(回滚事务对应的sql语句),也就是说审计一个事务到底做了什么,甚至可以回滚一个已经提交的事务。


  例:Flashback Transaction Query的操作实例。

  (1)在test表中删除记录,获得事务的标识XID,然后提交。
SQL>delete from test where id=2;
SQL>select xid from v$transaction;
XID
----------------
04001200AE010000
SQL>commit;

  在测试中方便起见,在事务没有提交的时候,获得事务的XID04001F0035000000。实际情况下,不可能去跟踪每个事务,想要获得已提交事务的XID,就必须通过上面的Flashback Version Query

  (2)进行Flashback Transaction Query
SQL>select * from FLASHBACK_TRANSACTION_QUERY
where xid=’04001F0035000000’;
UNDO_SQL
insert into "FLASHTEST"."TEST"("ID") values (’2’);

  注意:这个删除语句对应的是1Insert语句,如果想回滚这个事务,执行这个Insert语句即可。

  可以看到,Flashback Transaction Query主要用于审计一个事务,并可以回滚一个已经提交的事务。如果确定出错的事务是最后一个事务,我们利用Flashback Table或者Flashback Query就可以解决问题。但是,如果执行了一个错误的事务之后,又执行了一系列正确的事务,那么上面的方法就无能为力,利用Flashback Transaction Query可以查看或回滚这个错误的事务。

  结束语

  通过上面的描述,可以看出闪回功能使用户恢复偶然的错误删除更加容易,增强了系统的可用性与读一致性。
 

http://www.niftyadmin.cn/n/4411700.html

相关文章

oracle date 操作

使用oracle的date类型时,最好使用24小时制。date类型精确的秒。oracle的日期在24小时制中00:00:00 在Oracle中表示为叫做上午12点,也就是零点。我们中午12点叫做下午12点。呵呵。世界是这样循环的 : 上午12点 -上午12点…

【刷题】华为笔试面试机考 [HJ29] - 字符串加解密

题目地址 点击跳转 题目描述 1、对输入的字符串进行加解密,并输出。 2、加密方法为: 当内容是英文字母时则用该英文字母的后一个字母替换,同时字母变换大小写,如字母a时则替换为B;字母Z时则替换为a; 当内容是数字…

update 把两个表关联后把B表一列的值更新A表的某一列

执行update语句把两个表关联后把B表的一列更新A表中的某一列, 语句如下: update a set a.pd_mobile_phone (select g_telephone from b where G_idcode a.pd_idcard_no) where exists (select 1 from b …

【实现一套爬虫数据抓取平台】[3-5-01] 相似文章分析

文章目录零、系列目录一、背景二、技术点三、实现步骤1、将文本分词2、将分词结果向量化3、计算两个向量的余弦相似度四、核心代码五、总结零、系列目录 写这套文章的时候,不会完全按照目录的顺序一篇一篇写, 大家可以到目录中直接找到对应的章节进行查…

undo tablespace介绍

undo tablespace介绍 <script src"http://blog.csdn.net/count.aspx?ID1576926&TypeRank" type"text/javascript"> </script> select segment_name, blocks, bytes/1024, status,BLOCK_ID,BLOCK_IDblocks-1 from dba_undo_extents wher…

【实现一套爬虫数据抓取平台】[3-3-01] 部署 Docker+Nginx+uWSGI+Flask 应用

文章目录零、系列目录一、基本概念1、Docker2、Nginx3、uWSGI4、Flask二、部署结构三、结构分析四、实现步骤1、编写 Flask 应用2、编写 uWSGI 配置文件3、编写 Nginx 配置文件4、编写 Docker 启动脚本5、编写 Docker 镜像构建文件6、编写 docker-compose 文件五、测试1、运行2…

逐渐的废掉——所谓的真理

1。好好规划自己的路&#xff0c;不要跟着感觉走&#xff01;根据个人的理想决策安排&#xff0c;绝大部分人并不指望成为什么院士或教授&#xff0c;而是希望活得滋润一些&#xff0c;爽一些。那么&#xff0c;就需要慎重安排自己的轨迹。从哪个行业入手&#xff0c;逐渐对该行…

【刷题】华为笔试面试机考 [HJ30] - 字符串合并处理

题目地址 点击跳转 题目描述 按照指定规则对输入的字符串进行处理。 详细描述&#xff1a; 将输入的两个字符串合并。 对合并后的字符串进行排序&#xff0c;要求为&#xff1a;下标为奇数的字符和下标为偶数的字符分别从小到大排序。这里的下标意思是字符在字符串中的位…