用户误操作的恢复之FLASHBACK

用户误操作的恢复之FLASHBACK

Oracle中难免会遇到用户的误操作,如误删除/修改大量的数据并且已经提交。没有提交可以在事物一级使用rollback来回滚未提交的事物。

恢复用户的误操作的一般方式有如下几种:

1.flashback

flashback最早是oracle 9i开始引入的,好处多多。

1.1 flashback database

Flashback database的功能从oracle 10g开始引入。默认是关闭的如需启动,需将数据库置入归档模式,在mount状态下修改。

SQL> select NAME,FLASHBACK_ON from v$database;

 

NAME      FLASHBACK_ON

--------- ------------------

SZSCDB    NO

 

oracle@rac1:/home/oracle>srvctl stop database -d szscdb

oracle@rac1:/home/oracle>srvctl start database -d szscdb -o mount

SQL> ALTER DATABASE ARCHIVELOG;

oracle@rac1:/home/oracle>srvctl stop database -d szscdb

oracle@rac1:/home/oracle>srvctl start database -d szscdb -o mount

SQL> ALTER DATABASE FLASHBACK ON;

ALTER DATABASE FLASHBACK ON

*

ERROR at line 1:

ORA-38706: Cannot turn on FLASHBACK DATABASE logging.

ORA-38709: Recovery Area is not enabled

oracle@rac2:/home/oracle>oerr ora 38709

38709, 00000, "Recovery Area is not enabled."

// *Cause:  An ALTER DATABASE FLASHBACK ON command failed because the

//          Recovery Area was not enabled.

// *Action: Set DB_RECOVERY_FILE_DEST to a location and retry.

 

SQL>  ALTER SYSTEM SET DB_RECOVERY_FILE_DEST_SIZE=2G SCOPE=BOTH SID='*';

System altered.

 

SQL> ALTER SYSTEM SET DB_RECOVERY_FILE_DEST='+DATA' SCOPE=BOTH SID='*';  

System altered.

 

 

SQL> ALTER DATABASE FLASHBACK ON;

SQL> SELECT FLASHBACK_ON FROM V$DATABASE;

 

FLASHBACK_ON

------------------

YES

 

FROM ALERT.log

ALTER DATABASE FLASHBACK ON

Starting background process RVWR

Fri Aug 02 21:08:06 2013

RVWR started with pid=21, OS id=2912

Allocated 3981204 bytes in shared pool for flashback generation buffer

Flashback Database Enabled at SCN 958062

Completed: ALTER DATABASE FLASHBACK ON

 

SQL> SELECT * FROM v$sgastat s

  2  WHERE s.POOL='shared pool' AND s.BYTES='3981204';

 

POOL         NAME                            BYTES

------------ -------------------------- ----------

shared pool  KCB Table Scan Buffer         3981204

shared pool  flashback generation buff     3981204

flashback database能闪回的时间长度受DB_FLASHBACK_RETENTION_TARGET控制,其默认值为1400(min),正好是一天。

DB_FLASHBACK_RETENTION_TARGET specifies the upper limit (in minutes) on how far

back in time the database may be flashed back. How far back one can flashback a

database depends on how much flashback data Oracle has kept in the fast recovery

area.

该参数来控制flashback log的存在与否的,当然需要配合DB_RECOVERY_FILE_DEST_SIZE参数来衡量。如果产生的flashback log的大小大于DB_RECOVERY_FILE_DEST_SIZE所指定的值,那么oracle可以保证的是你可以恢复到DB_FLASHBACK_RETENTION_TARGET所指定的时间点,因为他要删除文件了。换句话说,oracle可以保证你的数据至少可以恢复到DB_FLASHBACK_RETENTION_TARGET参数所指定的时间内。

 

SQL> SHOW PARAMETER DB_FLASHBACK_RETENTION_TARGET

 

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

db_flashback_retention_target        integer     1440

 

SQL> ALTER SYSTEM SET DB_FLASHBACK_RETENTION_TARGET=3 SCOPE=BOTH;

SQL> CREATE TABLE T AS SELECT * FROM ALL_OBJECTS;

Table created.

SQL> SELECT TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS') CURRENT_TIME FROM DUAL;

CURRENT_TIME

-------------------

2013-08-02 21:23:41

 

Wait three mins….

 

SQL> SELECT TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS') CURRENT_TIME FROM DUAL;

 

CURRENT_TIME

-------------------

2013-08-02 21:28:56

 

SQL> TRUNCATE TABLE T;

SQL> shutdown immediate;

SQL> startup mount;

SQL> FLASHBACK DATABASE TO TIMESTAMP TO_DATE('2013-08-02 21:23:41','YYYY-MM-DD HH24:MI:SS');

SQL> ALTER DATABASE OPEN READ ONLY;

SQL> SELECT COUNT(*) FROM T;

  COUNT(*)

----------

     72733

flashback database在如下情况下不可以闪回数据库:

Drop tablesapce           

Shrink data file

Re-create control file

 

1.2. Flashback drop

可以使用flashback drop来实现删除表的恢复

使用flashback drop需要开启recyclebin功能,该功能在10g中是默认开启的

本次试验同时验证flashback drop后,索引,约束是否还在

SYSTEM表空间对象不支持flashback功能

SQL> archive log list;

Database log mode              No Archive Mode

Automatic archival             Disabled

Archive destination            /RECO/arch/szscdb

Oldest online log sequence     2

Current log sequence           4

----回收站的功能已经开启

SQL> show parameter recyclebin

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

recyclebin                           string      on

SQL> conn hr/oracle

 

-----创建表,创建主键及索引

CREATE TABLE T AS SELECT * FROM ALL_OBJECTS;

ALTER  TABLE T ADD CONSTRAINT T_PK_OBJID primary key (OBJECT_ID);

CREATE INDEX T_OBJNAME ON T(OBJECT_NAME);

SQL> SELECT i.INDEX_NAME,i.TABLE_NAME

    FROM USER_INDEXES i

    WHERE i.TABLE_NAME='T';

 

INDEX_NAME                     TABLE_NAME

------------------------------ ------------------------------

T_OBJNAME                      T

T_PK_OBJID                     T

 

---删除表T

SQL> DROP TABLE T;

SQL> set linesize 1000

SQL> set pagesize 1000

SQL> SELECT r.object_name,r.original_name,r.droptime

    FROM DBA_RECYCLEBIN r

    WHERE r.owner='HR';

 

OBJECT_NAME                    ORIGINAL_NAME                    DROPTIME

------------------------------ -------------------------------- -------------------

BIN$41s39ZfTC5jgQwEAAH+pHg==$0 T_OBJNAME                        2013-08-07:19:55:32

BIN$41s39ZfUC5jgQwEAAH+pHg==$0 T_PK_OBJID                       2013-08-07:19:55:32

BIN$41s39ZfVC5jgQwEAAH+pHg==$0 T                                2013-08-07:19:55:32

 

SQL> SELECT COUNT(*) FROM "BIN$41s39ZfVC5jgQwEAAH+pHg==$0";

 

  COUNT(*)

----------

     56323

 

 

SQL> FLASHBACK TABLE T TO BEFORE DROP;

 

Flashback complete.

SQL> SELECT COUNT(*) FROM T;

 

  COUNT(*)

----------

     56323

 

SQL> SELECT r.object_name,r.original_name,r.droptime

  2      FROM DBA_RECYCLEBIN r

  3      WHERE r.owner='HR';

 

no rows selected

 

SQL> SELECT i.INDEX_NAME,i.TABLE_NAME

  2      FROM USER_INDEXES i

  3      WHERE i.TABLE_NAME='T';

 

INDEX_NAME                     TABLE_NAME

------------------------------ ------------------------------

BIN$41s39ZfTC5jgQwEAAH+pHg==$0 T

BIN$41s39ZfUC5jgQwEAAH+pHg==$0 T

 

-------表和索引及主键都被闪回了,名字有变化不影响使用

1.3Flashback table

Flashback table功能允许我们将数据表恢复到过去的某个点,不需要进行数据库一级别的不完全恢复

SQL> show user

USER is "HR"

CREATE TABLE T (ID INT,NAME VARCHAR2(20));

SQL> SELECT dbms_flashback.get_system_change_number SCN,TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS') "DATE" FROM DUAL;

       SCN DATE

---------- -------------------

   1001369 2013-08-07 20:46:25

--插入测试数据

INSERT INTO T VALUES(1,'SZSCKJ');

INSERT INTO T VALUES(2,'SZSCKJ');

INSERT INTO T VALUES(3,'SZSCKJ');

INSERT INTO T VALUES(4,'SZSCKJ');

INSERT INTO T VALUES(5,'SZSCKJ');

COMMIT;

SQL> SELECT dbms_flashback.get_system_change_number SCN,TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS') "DATE" FROM DUAL;

 

       SCN DATE

---------- -------------------

   1001455 2013-08-07 20:46:50

--删除测试数据

DELETE FROM T

WHERE ID>3;

COMMIT;

SQL> SELECT dbms_flashback.get_system_change_number SCN,TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS') "DATE" FROM DUAL;

 

       SCN DATE

---------- -------------------

   1001469 2013-08-07 20:47:12

 

---执行flashback table

SQL> FLASHBACK TABLE T TO SCN  1001455;

FLASHBACK TABLE T TO SCN  1001455

                *

ERROR at line 1:

ORA-08189: cannot flashback the table because row movement is not enabled

SQL> ALTER TABLE T ENABLE ROW MOVEMENT;

SQL> FLASHBACK TABLE T TO SCN  1001455;

 

SQL> SELECT COUNT(*) FROM T;

 

  COUNT(*)

----------

         5

 

SQL> SELECT COUNT(*) FROM T;

 

  COUNT(*)

----------

         3

SQL> FLASHBACK TABLE T TO TIMESTAMP TO_DATE('2013-08-07 20:46:25','YYYY-MM-DD HH24:MI:SS');

 

SQL> SELECT COUNT(*) FROM T;

 

  COUNT(*)

----------

         0

----可以看到在特定的时间内可以随便闪

----flashback table 不支持sys用户的表,也不支持跨DDL语句

1.4Flashback Query

SQL> SELECT * FROM T AS OF SCN 1001455;

 

        ID NAME

---------- --------------------

         1 SZSCKJ

         2 SZSCKJ

         3 SZSCKJ

         4 SZSCKJ

         5 SZSCKJ

 

SQL> CREATE TABLE T_HISTORY AS SELECT * FROM T AS OF SCN 1001455;

----创建中间表T_HISTORY插入SCN1001455时刻的数据

1.5Flashback Version

SQL> alter database add supplemental log data;

SQL> CREATE TABLE ZGH AS SELECT * FROM ALL_OBJECTS WHERE ROWNUM<6;

SQL> DELETE FROM ZGH WHERE OBJECT_ID<20;

Commit complete.

 

SELECT VERSIONS_STARTSCN,VERSIONS_ENDSCN,VERSIONS_XID,VERSIONS_OPERATION

FROM SYS.ZGH VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE;

 

VERSIONS_STARTSCN VERSIONS_ENDSCN VERSIONS_XID     V

----------------- --------------- ---------------- -

          1026142                 060005001B030000 D

 

 

 

                          1026142

 

通过该视图可以查询到作用于该表T的事物,并且可以看到事物的开始SCN,结束SCN以及事物的操作类型VERSIONS_OPERATION。可以通过获得的XID,利用flashback transaction来闪回该事物。

注:在oracle 11g中需要开启supplemental log data才可以得到undo SQL;

 

1.6Flashback Transaction

SQL> set autotrace on

SQL> SELECT f.xid,f.operation,f.undo_sql

  2  FROM FLASHBACK_TRANSACTION_QUERY f

  3  WHERE F.xid='060005001B030000';

 

 

XID              OPERATION

---------------- --------------------------------

UNDO_SQL

--------------------------------------------------------------------------------

060005001B030000 DELETE

insert into "SYS"."ZGH"("OWNER","OBJECT_NAME","SUBOBJECT_NAME","OBJECT_ID","DATA

_OBJECT_ID","OBJECT_TYPE","CREATED","LAST_DDL_TIME","TIMESTAMP","STATUS","TEMPOR

ARY","GENERATED","SECONDARY","NAMESPACE","EDITION_NAME") values ('SYS','UNDO$',N

ULL,'15','15','TABLE',TO_DATE('18-SEP-11', 'DD-MON-RR'),TO_DATE('18-SEP-11', 'DD

-MON-RR'),'2011-09-18:17:33:48','VALID','N','N','N','1',NULL);

 

060005001B030000 BEGIN

 

 

XID              OPERATION

---------------- --------------------------------

UNDO_SQL

--------------------------------------------------------------------------------

 

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1115820779

 

------------------------------------------------------------------------------

| Id  | Operation        | Name      | Rows  | Bytes | Cost (%CPU)| Time     |

------------------------------------------------------------------------------

|   0 | SELECT STATEMENT |           |     1 |  2026 |     0   (0)| 00:00:01 |

|*  1 |  FIXED TABLE FULL| X$KTUQQRY |     1 |  2026 |     0   (0)| 00:00:01 |

------------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - filter(RAWTOHEX("XID")='060005001B030000')

 

 

Statistics

----------------------------------------------------------

      21330  recursive calls

         10  db block gets

     176167  consistent gets

          2  physical reads

          0  redo size

        992  bytes sent via SQL*Net to client

        419  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

        374  sorts (memory)

          0  sorts (disk)

          2  rows processed

---查询XID060005001B030000UNDO SQL,执行返回的结果可以恢复数据。只是耗时比较长,该表没有走索引- -

 

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

转载于:http://blog.itpub.net/26169542/viewspace-768009/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值