`

利用Flashback Query 恢复误操作的数据

阅读更多

利用Flashback Query 恢复误操作的数据
Author:Kamus Seraphim(张乐奕)
Date:2003-10
Mail:
kamus@itpub.net
转载请注明出处及作者
Oracle9i 中新增的闪回查询(Flashback Query)功能对于误删除或者误更新并且已经commit
了的情况,提供了简便快捷的恢复方法,而在Oracle 提供闪回查询之前,碰到这种情况只
能通过备份来进行基于时间点的恢复,无疑这比闪回查询要麻烦而且费时。
什么是Flashback Query
利用Oracle 多版本读一致的特性,在需要的时候通过undo 来提供所需的前镜像中的数据。
利用这个功能,可以看到历史数据(呵呵,就像时光倒流。月光宝盒?),甚至用历史数据
来修复误操作引起的错误。可以通过指定时间或者SCN 来检索需要的数据。
前提条件
数据库必须处于Automatic Undo Management 状态。
最大可以闪回查询的时间段由UNDO_RETENTION 初始化参数(单位为秒)指定
可以通过ALTER SYSTEM SET UNDO_RETENTION = <seconds>;来修改参数值
如何使用Flashback Query
通过SQL
使用SELECT 语句的AS OF 来进行闪回查询,语法如下:
SQL> show parameter undo_retention
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_retention integer 10800
SQL> show parameter undo_management
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
使用AS OF 关键字来对表,视图,或者物化视图进行Flashback Query,如果指定了SCN,
那么expr 部分必须是一个数字,如果指定了TIMESTAMP,那么expr 必须是一个timestamp
类型的值。查询结果将返回在指定的SCN 或者时间点上的数据。
下面我们使用scott 方案来作一个实验。
[zhangleyi@linux9 bin]$ sqlplus /nolog
SQL*Plus: Release 9.2.0.1.0 - Production on Thu Oct 9 23:44:07 2003
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
SQL> connect scott/tiger
Connected.
SQL> select sal from emp where empno=7369;
SAL
----------
800
SQL> update emp set sal=4000 where empno=7369;
1 row updated.
SQL> commit;
Commit complete.
SQL> select sal from emp where empno=7369;
SAL
----------
4000
备注:TIMESTAMP (SYSTIMESTAMP - INTERVAL ’1’ DAY)指查询距当前时间一天以
前的时间点的数据,如果我们要查询一小时以前的,那么需要将DAY 替换成HOUR 即可,
查询10 分钟以前的将’1’ DAY 替换’10’ MINUTE。
以上演示了对于误更新的字段进行恢复的方法,但是如果想在update 的子查询部分使用AS
OF 那么该查询只能返回一条记录,否则将会报错。如下:
SQL> select empno,sal from emp;
EMPNO SAL
---------- ----------
7369 800
7499 1600
7521 1250
7566 2975
7654 1250
7698 2850
7782 2450
7788 3000
SQL> select sal from emp
2 AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL ’1’ DAY);
3 where empno=7369;
SAL
----------
800
SQL> update emp set sal=
2 (select sal from emp
3 AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL ’1’ DAY)
4 where empno=7369)
5 where empno=7369;
1 row updated.
SQL> select sal from emp where empno=7369;
SAL
----------
800
SQL> commit;
7839 5000
7844 1500
7876 1100
EMPNO SAL
---------- ----------
7900 950
7902 3000
7934 1300
14 rows selected.
SQL> update emp set sal=4000;
14 rows updated.
SQL> commit;
Commit complete.
SQL> select empno,sal from emp;
EMPNO SAL
---------- ----------
7369 4000
7499 4000
7521 4000
7566 4000
7654 4000
7698 4000
7782 4000
7788 4000
7839 4000
7844 4000
7876 4000
EMPNO SAL
---------- ----------
7900 4000
7902 4000
7934 4000
14 rows selected.
SQL> select empno,sal from emp
2 AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL ’1’ DAY);
EMPNO SAL
---------- ----------
7369 800
7499 1600
7521 1250
7566 2975
7654 1250
7698 2850
7782 2450
7788 3000
7839 5000
7844 1500
7876 1100
EMPNO SAL
---------- ----------
7900 950
7902 3000
7934 1300
14 rows selected.
SQL> update emp a set sal =
2 (select sal from emp b
3 AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL ’1’ DAY)
4 where a.empno=b.empno);
AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL ’1’ DAY)
*
ERROR at line 3:
ORA-00907: missing right parenthesis
其实上面的语法是没有问题的,但是可能是因为闪回查询的特殊性导致上面的SQL 报错,
而这种错误update 了大量数据时候的恢复才真正是闪回查询的方便所在,对于这种情况我
们可以有两种处理方法,一种是使用DBMS_FLASHBACK 包,将在后面介绍,另外一种方
法仍然是直接使用SQL,但是添加一个临时表作为中转,如下:
SQL> create table empsal_temp as
2 select empno,sal from emp
3 AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL ’1’ DAY);
Table created.
SQL> update emp a set sal =
2 (select sal from empsal_temp b
3 where a.empno=b.empno);
14 rows updated.
SQL> select empno,sal from emp;
EMPNO SAL
---------- ----------
7369 800
7499 1600
7521 1250
7566 2975
7654 1250
7698 2850
7782 2450
7788 3000
7839 5000
7844 1500
7876 1100
EMPNO SAL
---------- ----------
7900 950
7902 3000
7934 1300
14 rows selected.
SQL> commit;
Commit complete.
SQL> drop table empsal_temp;
Table dropped.

 

这样我们就完成了错误数据的恢复。COOL!! RIGHT? :D
介绍DBMS_FLASHBACK 包
DBMS_FLASHBACK 包提供了以下几个函数:
ENABLE_AT_TIME:设置当前SESSION 的闪回查询时间
ENABLE_AT_SYSTEM_CHANGE_NUMBER:设置当前SESSION 的闪回查询SCN
GET_SYSTEM_CHANGE_NUMBER:取得当前数据库的SCN
比如:select dbms_flashback.get_system_change_number from dual;
DISABLE:关闭当前SESSION 的闪回查询
当将一个SESSION 设置为闪回查询模式之后,后续的查询都会基于那个时间点或者SCN 的
数据库状态,如果SESSION 结束,那么即使没有明确指定DISABLE,闪回查询也会自动失
效。
当SESSION 运行在闪回查询状态时,不允许进行任何DML 和DDL 操作。如果要用DML
操作来进行数据恢复就必须使用PL/SQL 游标。
即使SESSION 运行在闪回查询模式,SYSDATE 函数也不会受到影响,仍然会返回当前正
确的系统时间。
下面我们用一个例子说明如何使用DBMS_FLASHBACK 包来恢复数据。
假设由于误操作删除了SCOTT.EMP 表中的所有数据,现在我们要恢复。
SQL> delete from emp;
14 rows deleted.
SQL> commit;
Commit complete.
SQL> select count(*) from emp;
COUNT(*)
----------
0
然后执行下面的SQL 创建一个存储过程用于恢复数据
CREATE OR REPLACE PROCEDURE prc_recoveremp IS
CURSOR c_emp IS
SELECT * FROM scott.emp;
v_row c_emp%ROWTYPE;
BEGIN
DBMS_FLASHBACK.ENABLE_AT_TIME(SYSTIMESTAMP - INTERVAL ’1’ DAY);
OPEN c_emp;
DBMS_FLASHBACK.DISABLE;
LOOP
FETCH c_emp
INTO v_row;
EXIT WHEN c_emp%NOTFOUND;
INSERT INTO scott.emp
VALUES
(v_row.EMPNO,
v_row.ENAME,
v_row.JOB,
v_row.MGR,
v_row.HIREDATE,
v_row.SAL,
v_row.COMM,
v_row.DEPTNO);
END LOOP;
CLOSE c_emp;
COMMIT;
END prc_recoveremp;
SQL> execute prc_recoveremp;
PL/SQL procedure successfully completed.
SQL> select count(*) from emp;
COUNT(*)
----------
14
到此成功结束,检查EMP 表可以看到所有的数据已经全部都恢复了。
备注:在存储过程中我们创建了游标之后就将执行了DBMS_FLASHBACK.DISABLE,只
有这样我们才能在这个SESSION 中进行DML 操作。否则将产生ORA-08182 错误,In
Flashback mode, user cannot perform DML or DDL operations。
以上例子中的所有恢复都是基于时间点的,下面介绍基于SCN 的闪回查询。
既然已经有基于时间点的恢复,为什么还需要基于SCN 呢,我们先来看一个例子。
[zhangleyi@linux9 oralinux]$ sqlplus scott/tiger
SQL*Plus: Release 9.2.0.1.0 - Production on Sat Oct 11 02:26:20 2003
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.1.0 - Production
SQL> select * from dept;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL> set time on;
02:26:50 SQL> insert into dept values(60,’FLASH’,’BEIJING’);
1 row created.
02:27:53 SQL> commit;
Commit complete.
02:27:57 SQL> delete from dept where deptno=60;
1 row deleted.
02:28:19 SQL> commit;
Commit complete.
02:28:21 SQL> select * from dept as of TIMESTAMP (SYSTIMESTAMP -
INTERVAL ’1’ MINUTE);
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
02:29:49 SQL> select * from dept as of TIMESTAMP (SYSTIMESTAMP -
INTERVAL ’2’ MINUTE);
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
02:31:11 SQL> select * from dept as of TIMESTAMP (SYSTIMESTAMP -
INTERVAL ’3’ MINUTE);
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
02:31:19 SQL> select * from dept as of TIMESTAMP (SYSTIMESTAMP -
INTERVAL ’4’ MINUTE);
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
02:31:30 SQL> select * from dept as of TIMESTAMP (SYSTIMESTAMP -
INTERVAL ’5’ MINUTE);
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
02:31:39 SQL> select * from dept as of TIMESTAMP (SYSTIMESTAMP -
INTERVAL ’6’ MINUTE);
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
可以发现我们闪回查询了1 分钟到6 分钟之前的所有前镜像都没有找到新插入的那条
DEPTNO=60 的记录,虽然TIMESTAMP 可以精确到毫秒,但是很显然我们很难准确地
定位到毫秒级的时间点。至于为什么如此,biti 在论坛上的某个帖子中有所探讨,这里暂时
先不追究产生这种结果的原因。在这种情况下,使用基于SCN 的闪回查询是解决问题的最
好办法。
以往的一些测试例子,都是在insert 数据之后立刻使用DBMS_FLASHBACK 包中的
GET_SYSTEM_CHANGE_NUMBER 函数来返回当时的SCN,然后再利用AS OF SCN 来进
行闪回查询,但是实际应用中这是不可能的,因为在误操作之前不会运行这个函数。所以我
们要使用LOGMINER 来对redolog 进行分析,得到当时错误地update 或者delete 数据时的
SCN。
对于LOGMINER 的安装和使用方法本文不进行详细的叙述,请自行查阅文档。
下面是结合LOGMINER 进行闪回查询的例子,为了描述简便,假设从删除数据到目前
ONLINE REDO LOG 没有进行LOG SWITCH,也就是我们只需要分析当前ACTIVE 的
ONLINE REDO LOG 就可以了。
SQL> connect / as sysdba
Connected.
SQL> select b.MEMBER,a.STATUS from v$log a,v$logfile b where a.GROUP#=b.GROUP#;
MEMBER STATUS
-------------------------------------------- ----------------
/oracle/oradata/oralinux/redo01.log INACTIVE
/oracle/oradata/oralinux/redo02.log INACTIVE
/oracle/oradata/oralinux/redo03.log CURRENT
SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LogFileName =>
’/oracle/oradata/oralinux/redo03.log’,Options => DBMS_LOGMNR.NEW);
PL/SQL procedure successfully completed.
SQL> EXECUTE DBMS_LOGMNR.START_LOGMNR(DictFileName =>
’/oracle/admin/oralinux/orcldict.ora’);
PL/SQL procedure successfully completed.
SQL> select scn,sql_redo from (select * from v$logmnr_contents where
sql_redo like ’delete%’ order by scn desc) where rownum<2;
SCN SQL_REDO
---------- -------------------------------------------------------------------
543523 delete from "SCOTT"."DEPT" where "DEPTNO" = ’60’ and "D
现在我们已经找到了删除那条记录时候的SCN 是543523。
SQL> select * from scott.dept as of scn 543523;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
60 FLASH BEIJING
搞定!我们利用SCN 进行闪回查询找到了删除前的那条数据,此时利用上文描述过的SQL
方法或者DBMS_FLASHBACK 方法都可以进行数据恢复了。
几个注意点:
1. Flashback Query 对于DDL 操作(比如DROP)无效,只能适用于DML 的误操作
(UPDATE,DELETE)
2. SYS 用户不允许执行DBMS_FLASHBACK 包,将会产生ORA-08185 错误,
Flashback not supported for user SYS
3.可能需要给其它用户授权才能允许其它用户执行DBMS_FLASHBACK 包,需要执
行:GRANT EXECUTE ON DBMS_FLASHBACK TO SCOTT;
4.闪回查询的功能不止是适用于数据恢复,同样适用于DSS 和OLAP,比如需要查询
在前一个小时内生成的新订单,那么就可以利用AS OF 来取得两个时间点的查询结
果的差集。
5.如果结合使用LOGON TRIGGERS,那么可以实现不更改代码就支持各个时间点的
报表查询功能。
6. Flashback Query 的查询速度依赖于需要执行多少UNDO,也就是想查询多长时间以
前的数据库快照,回溯的时间越久可能执行的速度就越慢。
7. Flashback Query 不会真正的UNDO 任何数据,仅仅是一个查询的机制而已。
8. Flashback Query 不会告诉你到底数据发生了哪些变化,这是LOGMINER 的功能。
9.如果需要恢复的表中有巨大的数据量,那么闪回查询会是一个极为昂贵的操作,此
时可能作基于时间点的恢复反而更有效。

分享到:
评论

相关推荐

    Oracle对于误删误操作的数据进行恢复(flashback query、flashback drop、flashback table、flashback database)

    Oracle数据库提供了多种强大的工具,使得在发生误删误操作时能有效地恢复数据。这些工具包括Flashback Query、Flashback Drop、Flashback Table以及Flashback Database。以下是对这些特性的详细解释: 1. **...

    oracle 10g flashback(数据恢复)

    Oracle 10g 引入了强大的 Flashback 技术,这是一系列旨在帮助管理员和开发者在出现数据丢失或损坏时能够快速恢复数据的功能集合。该技术从 Oracle 9i 开始引入,并在 10g 版本中得到了显著增强和完善。Flashback ...

    dba数据恢复flashback

    Oracle Flashback技术是Oracle数据库10g及后续版本中的一项重要特性,它提供了一种快速、简单的方式来恢复数据,尤其适用于逻辑错误引起的数据库损坏场景。Flashback技术允许用户查看、查询和恢复数据至任意历史时间...

    Oracle Flashback在医院数据恢复中的应用.pdf

    但通过Flashback Database,可以将备库回退到误操作之前的状态,然后将这个修正后的备库提升为主库,从而快速恢复服务,降低业务中断的时间。 实施过程中,首先需要确保数据库有足够的undo表空间来存储历史更改信息...

    flashback——oracle

    "Oracle_FlashBack恢复数据.pdf"文件可能涵盖了使用`FLASHBACK QUERY`和`FLASHBACK TRANSACTION`等不同方法来恢复特定的数据行或事务。这些功能允许我们基于时间点或者事务ID来恢复数据,极大地增强了数据安全性和可...

    oracle flashback技术总结

    Oracle Flashback 技术为数据库管理和恢复提供了强大的工具,尤其是在应对数据丢失或误操作的情况下。通过合理配置和使用这些功能,可以显著提高数据库的可靠性和可用性。然而,也需要注意其限制条件,并确保有足够...

    Oracle_Flashback_技术_总结.pdf

    它们提供了对历史数据的访问,对于误操作和分析非常有用。 4. Flashback Drop: 这一特性允许恢复已被DROP的表,只需简单地使用Flashback Drop命令,前提是DROP操作还未被清理。 总的来说,Oracle Flashback技术...

    oracle 闪回 flashback

    - 用于恢复单个表到先前的状态,这在误操作后特别有用。 Oracle的闪回技术是其强大的数据保护和恢复机制的一部分,提供了灵活性和便利性,使数据库管理员能够在不影响其他用户的情况下恢复到特定时间点的数据状态...

    Less17_Flashback_TB3.pdf

    在Oracle 10g数据库管理工作中,Flashback技术是一项革命性的恢复功能,它能够帮助数据库管理员在遇到逻辑错误时快速有效地恢复数据。本文章将详细介绍Oracle 10g Flashback技术的各种应用及其优势,并通过具体的...

    利用oracle 闪回技术恢复数据

    综上所述,Oracle闪回技术是数据库管理和恢复的重要组成部分,通过充分利用这些工具,可以在面对数据丢失或错误时迅速、准确地恢复数据,极大地提高了数据安全性。然而,这也需要数据库管理员具备足够的知识和经验,...

    Oracle Flashback 技术总结

    总的来说,Oracle Flashback技术提供了一套全面的数据恢复和历史查询方案,它使得数据库管理员能够在不影响当前系统运行的情况下,轻松处理误操作和数据恢复需求,显著增强了数据库的灵活性和安全性。

    oracle 恢复表数据

    在Oracle数据库环境中,数据丢失可能由多种原因引起,如误操作、系统故障、硬件损坏等。为了最大限度地减少这些意外事件的影响,Oracle提供了丰富的工具和技术来帮助恢复数据。具体到“恢复刚删除的数据”这一场景,...

    第16章Oracle闪回(Flashback)技术.pptx

    Oracle 闪回(Flashback)技术是 Oracle 数据库提供的一系列人为错误更正技术,用于快速恢复逻辑误操作。闪回技术从 Oracle 9i 版本开始,逐步发展到 Oracle 11g 版本,成为数据库恢复的重要手段。 1. 闪回技术...

    FLASHBACK快速实用学习

    一旦误操作发生,DBA可以使用Flashback技术轻松地将表恢复到误操作之前的某一时间点。具体的恢复命令会根据实际情况有所不同,但一般形式如下: ```sql SELECT * FROM dba_table AS OF TIMESTAMP TO_TIMESTAMP('2023...

    oracle中truncate table后的数据恢复

    如果闪回数据库选项开启,可以尝试使用`FLASHBACK TABLE`命令来恢复数据: ```sql FLASHBACK TABLE table_name TO BEFORE TRUNCATE; ``` 请注意,这仅在`ALTER DATABASE ENABLE FLASHBACK ARCHIVE`已执行且未达到闪...

    Oracle 9i以上的闪回,用于误操作后的数据恢复

    下面将详细介绍如何利用Oracle 9i及后续版本中的闪回功能来处理数据误操作问题。 #### 一、闪回技术概述 Oracle的闪回功能主要包括以下几个方面: 1. **闪回查询(Flashback Query)**:允许用户查询表在特定时间...

    利用oracle闪回技术恢复误删除的表或误更新的记录.pdf

    为了使 Oracle 数据库从任何逻辑误操作中迅速地恢复,Oracle 推出了闪回技术。 该技术首 先以闪回查询( Flashback Query)出现在 Oracle 9i 版本中,后来 Oracle 在 10g 中对该技术 进行了全面扩展,提供了闪回...

    Oracle Flashback技术

    通过深入理解并熟练掌握Oracle Flashback技术,数据库管理员可以更高效地处理错误操作和数据恢复问题,提高系统的可用性和数据安全性。同时,配合源码分析和相关工具的使用,如在文档《OracleFlashback(闪回).doc》...

Global site tag (gtag.js) - Google Analytics