通过闪回事务查看数据dml的情况

昨天有一个网友问我,怎么能够查询一个表中最后一条插入的记录,我大概回复了,可以通过闪回事务来实现,但是得看什么时候插入的数据,也需要一定的运气。
如果通过闪回事务来得到对应的undo_sql,可能多个dml语句对应一个事务,所以我们需要得到的是一个完整的事务的信息,里面包括对应的Undo_sql,这样才算得到比较完整的sql语句。

我在本地自己做了一个测试。
创建一个test表,然后插入一些记录,然后尝试修改一些数据。

SQL> DROP TABLE TEST;
Table dropped.

SQL> create table test (id number,name varchar2(29));
Table created.

SQL> insert into test values(1,'trx1');
1 row created.

SQL> insert into test values(2,'trx1');
1 row created.

SQL> commit;
Commit complete.

SQL> insert into test values(3,'trx2');
1 row created.

SQL> commit;
Commit complete.

SQL> update test set id=4,name='trx3' where name='trx1';
2 rows updated.

SQL> commit;
Commit complete.

通过闪回查询,能够得到一些相关的信息。I代表insert,U代表update,因为是测试,我直接把列值也列出来了。

SQL> set linesize 200
SQL> col VENDTIME format a22
SQL> col V_STARTTIME format a22
SQL> select versions_starttime v_starttime,versions_startscn v_startscn,versions_xid xid,versions_endtime vendtime,versions_endscn vendscn,versions_operation oper,id,name from test versions between scn minvalue and maxvalue;

V_STARTTIME            V_STARTSCN XID              VENDTIME                  VENDSCN O         ID NAME
---------------------- ---------- ---------------- ---------------------- ---------- - ---------- -----------------------------
19-AUG-14 05.30.14 AM     7233099 0A000F0070040000                                   U          4 trx3
19-AUG-14 05.30.14 AM     7233099 0A000F0070040000                                   U          4 trx3
19-AUG-14 05.29.44 AM     7233087 08001B00FD060000                                   I          3 trx2
19-AUG-14 05.29.38 AM     7233084 0700100091040000 19-AUG-14 05.30.14 AM     7233099 I          2 trx1
19-AUG-14 05.29.38 AM     7233084 0700100091040000 19-AUG-14 05.30.14 AM     7233099 I          1 trx1

得到了如上的信息之后,就开始使用闪回事务来查询,结果没有任何返回。

SQL> select operation,undo_sql from flashback_transaction_query where table_name='TEST' and table_owner='N1';

no rows selected

查看Undo的空间情况,undo还很充足。

Current Instance
~~~~~~~~~~~~~~~~

   DB Id    DB Name      Inst Num Instance
----------- ------------ -------- ------------
 3645037571 TEST01              1 TEST01

Tablespace   STA M A Init     Total MB    Free MB     Used MB  LrgstMB       MaxExt %Fr A
------------ --- - - ---- ------------ ---------- ----------- -------- ------------ --- -
POOL_DATA    OLN L S  64K          960        765         195       98   2147483645  80
SYSAUX       OLN L S  64K          325         96         229       91   2147483645  30
SYSTEM       OLN L S  64K          325         51         274       50   2147483645  16 *
TEMPTS1      OLN L U   1M          400        400           0      286              100
TEST_DATA1   OLN L S  64K            3          2           1        2   2147483645  67
UNDOTBS      OLN L S  64K          935        903          32      672   2147483645  97
                          ------------ ---------- -----------
sum                              2,948      2,217         731

使用闪回事务需要赋予一定的权限,赋一下权限。
使用dba连接,赋予权限

SQL> conn / as sysdba
Connected.
SQL> grant execute on dbms_flashback to n1;

Grant succeeded.

SQL> grant select any transaction to n1;
Grant succeeded.

再次查询验证,还是没有数据。

SQL> select operation,undo_sql from flashback_transaction_query where table_name='TEST' and table_owner='N1';

no rows selected

直接用sys看看,倒底是怎么回事,能看到Operation 显示为“unknown"而且对应的table_owner也是空。

conn / as sysdba
SQL> col undo_sql format a30
SQL> select table_owner,operation,undo_sql from flashback_transaction_query where table_name='TEST'
  2  /

TABLE_OWNER                      OPERATION                        UNDO_SQL
-------------------------------- -------------------------------- ------------------------------
                                 UNKNOWN
                                 UNKNOWN
                                 UNKNOWN
                                 UNKNOWN
原来,需要使用alter database命令,启用对DML更改引用的列值和主键值的日志记录。

SQL> alter database add supplemental log data;

Database altered.

SQL> conn n1/n1
Connected.
启用之后,不会立即生效,我们来清空数据,重新插入一些数据。
SQL>  select table_owner,operation,undo_sql from flashback_transaction_query where table_name='TEST'
  2  /

TABLE_OWNER                      OPERATION                        UNDO_SQL
-------------------------------- -------------------------------- ------------------------------
                                 UNKNOWN
                                 UNKNOWN
                                 UNKNOWN
                                 UNKNOWN

SQL> truncate table test;
Table truncated.

SQL> insert into test values(1,'trx1');
1 row created.

SQL> insert into test values(2,'trx1');
1 row created.
SQL> commit;

Commit complete.
再次查询就能够成功显示了。
SQL> col undo_sql format a80
SQL> select table_owner,operation,undo_sql from flashback_transaction_query where table_name='TEST';

TABLE_OWNER                      OPERATION                        UNDO_SQL
-------------------------------- -------------------------------- --------------------------------------------------------------------------------
N1                               INSERT                           delete from "N1"."TEST" where ROWID = 'AAAEmOAAJAAABRjAAB';
N1                               INSERT                           delete from "N1"."TEST" where ROWID = 'AAAEmOAAJAAABRjAAA';
                                 UNKNOWN
                                 UNKNOWN
                                 UNKNOWN
                                 UNKNOWN
解决了这个问题,就可以使用闪回事务表来查看undo_sql了,我们根据start_timestamp来排列,得到最新的数据变化情况。
先使用闪回查询来看看。

SQL> select versions_starttime v_starttime,versions_startscn v_startscn,versions_xid xid,versions_endtime vendtime,versions_endscn vendscn,versions_operation oper,id,name from test versions between scn minvalue and maxvalue;

V_STARTTIME            V_STARTSCN XID              VENDTIME                  VENDSCN O         ID NAME
---------------------- ---------- ---------------- ---------------------- ---------- - ---------- -----------------------------
19-AUG-14 05.36.08 AM     7247547 05001A00C2050000                                   I          2 trx1
19-AUG-14 05.36.08 AM     7247547 05001A00C2050000                                   I          1 trx1

然后通过闪回事务来关联。

SQL> select table_owner,START_TIMESTAMP,operation,undo_sql from flashback_transaction_query where table_name='TEST' and table_owner='N1' and xid=hextoraw('05001A00C2050000'); 

TABLE_OWNER                      START_TIM OPERATION                        UNDO_SQL
-------------------------------- --------- -------------------------------- --------------------------------------------------------------------------------
N1                               19-AUG-14 INSERT                           delete from "N1"."TEST" where ROWID = 'AAAEmOAAJAAABRjAAB';
N1                               19-AUG-14 INSERT                           delete from "N1"."TEST" where ROWID = 'AAAEmOAAJAAABRjAAA';

在做undo之前,查看表里现有的数据作比对。

SQL> select *from test;

        ID NAME
---------- -----------------------------
         1 trx1
         2 trx1

 

SQL> delete from "N1"."TEST" where ROWID = 'AAAEmOAAJAAABRjAAB';
1 row deleted.

SQL> delete from "N1"."TEST" where ROWID = 'AAAEmOAAJAAABRjAAA';
1 row deleted.

SQL> select *from test;

no rows selected

时间: 2024-09-22 19:28:11

通过闪回事务查看数据dml的情况的相关文章

oracle闪回版本和闪回事务查询详解

  --- 说明闪回数据库 --- 使用闪回表将表内容还原到过去的特定时间点 --- 从删除表中进行恢复 --- 使用闪回查询查看截止到任一时间点的数据库内容 --- 使用闪回版本查询查看某一行在一段时间内的各个版本 --- 使用闪回事务查询查看事务处理历史记录或行 优点: 闪回技术由于只能处理更改数据,所以从根本上改变了恢复技术.使用这个技术时,从错误中恢复花费的时间等于制造错误所花费的时间.当闪回技术使用时,它与介质恢复相比,在易用性.可用性和还原时间方面有明显的优势. 闪回数据库使用闪回日

使用闪回查询备份数据

今天在生产环境中,开发人员提交了一个脚本,是做update操作的,但是update操作的时候过滤条件有些大,本来预计修改的数据只有5000条,结果这个语句运行下来更改了500万条数据.对生产系统来说算是一个数据灾难,赶紧和开发确认了问题发生的时间,结果说是在半夜11点多,刚好在后半夜才开始做数据备份,这样这个变更也同时影响了备份,就算做紧急的数据恢复也是没有任何效果的.目前采用的备份都是全量的按天备份,备份收到影响,恢复还是比较困难的. 这个问题就在紧急的讨论中分为了两个步骤,我来尝试恢复昨天备

Oracle 闪回特性(Flashback Query、Flashback Table)

--================================================== -- Oracle 闪回特性(Flashback Query.Flashback Table) --==================================================       Oracle 闪回查询是指针对特定的表来查询特定的时间段内的数据变化情况来确定是否将表闪回到某一个特定的时刻以保证数据无讹误存在. 这个特性大大的减少了采用时点恢复所需的工作量以及

Oracle 闪回特性(FLASHBACK DROP & RECYCLEBIN)

--============================================== -- Oracle 闪回特性(FLASHBACK DROP & RECYCLEBIN) --==============================================       FLASHBACK DROP 特性允许在不丢失任何数据库的情况下将指定的表恢复至其被删除的时间点,并保持数据库为当前状态.闪回删除并不是 真正的删除表,而是把该表重命名并放入回收站,类似于Windows的

Oracle 闪回技术详细介绍及总结_oracle

Oracle闪回技术详解,这里整理了4种闪回技术,对Oracle 闪回技术做一个整理总结.  概述: 闪回技术是Oracle强大数据库备份恢复机制的一部分,在数据库发生逻辑错误的时候,闪回技术能提供快速且最小损失的恢复(多数闪回功能都能在数据库联机状态下完成).需要注意的是,闪回技术旨在快速恢复逻辑错误,对于物理损坏或是介质丢失的错误,闪回技术就回天乏术了,还是得借助于Oracle一些高级的备份恢复工具如RAMN去完成(这才是Oracle强大备份恢复机制的精髓所在啊)  撤销段(UNDO SEG

Oracle 闪回特性(Flashback Version、Flashback Transaction)

--========================================================== -- Oracle 闪回特性(Flashback Version.Flashback Transaction) --==========================================================         Oracle闪回特性为数据的快速回复某一对象的特定数据提供了更多的便利.前面介绍了闪回的几种特性,包括flashback dat

oracle闪回表详解

  --- 说明闪回数据库 --- 使用闪回表将表内容还原到过去的特定时间点 --- 从删除表中进行恢复 --- 使用闪回查询查看截止到任一时间点的数据库内容 --- 使用闪回版本查询查看某一行在一段时间内的各个版本 --- 使用闪回事务查询查看事务处理历史记录或行 优点: 闪回技术由于只能处理更改数据,所以从根本上改变了恢复技术.使用这个技术时,从错误中恢复花费的时间等于制造错误所花费的时间.当闪回技术使用时,它与介质恢复相比,在易用性.可用性和还原时间方面有明显的优势. 闪回数据库使用闪回日

性能-关于Oracle闪回的问题

问题描述 关于Oracle闪回的问题 请问Oracle闪回的数据是否可以按照时间设置多少小时内可闪回? 还是Oracle闪回的数据只能设置数据量的大小? 另:Oracle闪回空间的设置对数据库性能有哪些方面的影响? 解决方案 Oracle的闪回技术提供了一组功能,可以访问过去某一时间的数据并从人为错误中恢复.闪回技术是Oracle 数据库独有的,支持任何级别的恢复,包括行.事务.表和数据库范围.使用闪回特性,您可以查询以前的数据版本,还可以执行更改分析和自助式修复,以便在保持数据库联机的同时从逻

关于实现MySQL闪回的一个取巧的办法

            最近有关注MySQL的一些备份,恢复的事情,想试着在MySQL上类似于Oracle的闪回(flashback)的功能             首先想到的是解析Binlog,然后逆向编写对应的SQL,去网上翻了翻资料,发现已经有大神实现了!但是仔细想了想,不管是自己写,还是直接用别人的成果,好像都挺麻烦的,毕竟懒癌晚期,找点简单的办法来取巧好了_(:з」∠)_ -----------------------------------------------------关于闪回