Oracle闪回(flashback)功能详解
Tags: Oracle闪回闪回事务查询闪回删除闪回数据库闪回数据归档闪回查询闪回版本查询闪回表
什么是闪回?闪回有哪些分类?
Oracle闪回技术从根本上改变了数据恢复策略,利用闪回技术,可以使更正错误的时间大大缩短,而且它简单易用,使用一条短命令便可恢复整个数据库,而不必执行复杂的程序。闪回技术是Oracle数据库独有的特性,支持各级恢复,包括行、事务、表、表空间和数据库范围。采用闪回技术,可以针对行级和事务级发生过变化的数据进行恢复,减少了数据恢复的时间,而且操作简单,通过SQL语句就可以实现数据的恢复,大大提高了数据库恢复的效率。
Oracle中闪回技术分类图如下所示:
闪回技术分类:
(1)闪回查询(Flashback Query):查询过去某个时间点或某个SCN值对应的表中的数据信息,即从回滚段中读取一定时间内对表进行操作的数据,恢复错误的DML操作。
(2)闪回版本查询(Flashback Version Query):查询过去某个时间段或某个SCN段内表中数据的变化情况。
(3)闪回事务查询(Flashback Transaction Query):查看某个事务或所有事务在过去一段时间对数据进行的修改。
(4)闪回表(Flashback TABLE):将表恢复到过去的某个时间点或某个SCN值时的状态。
(5)闪回删除(Flashback DROP):将已经删除的表及表上的索引恢复到删除前的状态,但索引名不会恢复到删除前的状态。
(6)闪回数据库(Flashback Database):将数据库恢复到过去某个时间点或某个SCN值时的状态。
有关闪回需要注意以下几点:
(1)闪回查询、闪回版本查询、闪回事务查询以及闪回表主要是基于回滚(Undo)表空间中的回滚信息实现的。
(2)闪回删除是基于Oracle中的回收站(Recycle Bin)特性实现的。
(3)闪回数据库是基于闪回恢复区(Flash Recovery Area)中的闪回日志来实现的。
(4)闪回数据归档是基于闪回归档区中的数据来实现的。
闪回查询(Flashback Query)
闪回查询分为基于AS OF TIMESTAMP和基于AS OF SCN的闪回查询,如下所示:
1 2 3 4 | SELECT * FROM SCOTT.EMP AS OF TIMESTAMP(SYSTIMESTAMP - INTERVAL '6' MINUTE) WHERE ENAME = 'LHR'; SELECT ENAME, SAL FROM SCOTT.EMP AS OF TIMESTAMP(SYSDATE - 6 / 1440) WHERE ENAME = 'LHR'; SELECT * FROM SCOTT.EMP AS OF TIMESTAMP TO_TIMESTAMP('2017-11-14 11:41:22','YYYY-MM-DD HH24:MI:SS') WHERE WHERE ENAME = 'LHR'; INSERT INTO SCOTT.EMP select * from t AS OF SCN 67830969; |
闪回查询示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | SQL> set timing on; SQL> set serveroutput on; SQL> set sqlblanklines on; SQL> set linesize 800 SQL> set time on; 11:40:54 SQL> select * from old_t; ID NAME ---------- -------------------- 1 li 已用时间: 00: 00: 00.02 11:41:05 SQL> update old_t set name='lih' where id=1; 已更新 1 行。 已用时间: 00: 00: 00.01 11:41:16 SQL> commit; 提交完成。 已用时间: 00: 00: 00.03 11:41:20 SQL> update old_t set name='lihu' where id=1; 已更新 1 行。 已用时间: 00: 00: 00.01 11:41:31 SQL> commit; 提交完成。 已用时间: 00: 00: 00.01 11:41:34 SQL> update old_t set name='lihua' where id=1; 已更新 1 行。 已用时间: 00: 00: 00.01 11:41:39 SQL> commit; 提交完成。 已用时间: 00: 00: 00.01 11:41:43 SQL> update old_t set name='lihuar' where id=1; 已更新 1 行。 已用时间: 00: 00: 00.02 11:42:24 SQL> commit; 提交完成。 已用时间: 00: 00: 00.01 11:42:26 SQL> select * from old_t; ID NAME ---------- -------------------- 1 lihuar 已用时间: 00: 00: 00.02 ------查询5分钟之前的数据 11:45:53 SQL> select * from old_t as of timestamp sysdate-5/24/60 where id=1; ID NAME ---------- -------------------- 1 li 已用时间: 00: 00: 00.02 ------查询第一个事务提交,第二个事务还没有提交时的数据 11:55:13 SQL> select * from old_t as of timestamp to_timestamp('2012-11-14 11:41:22','YYYY-MM-DD HH2 4:MI:SS') where id=1; ID NAME ---------- -------------------- 1 lih 已用时间: 00: 00: 00.02 ------查询第二个事务提交,第三个事务还没有提交时的数据 12:23:33 SQL> select * from old_t as of timestamp to_timestamp('2012-11-14 11:41:38','YYYY-MM-DD HH2 4:MI:SS') where id=1; ID NAME ---------- -------------------- 1 lihu 已用时间: 00: 00: 00.01 12:24:01 SQL> |
闪回版本查询(Flashback Version Query)
查询语句一般为:
1 2 3 | SELECT TO_CHAR(VERSIONS_STARTTIME,'YYYY-MM-DD HH24:MI:SS') VERSIONS_STARTTIME,VERSIONS_STARTSCN,TO_CHAR(VERSIONS_ENDTIME,'YYYY-MM-DD HH24:MI:SS') VERSIONS_ENDTIME ,VERSIONS_ENDSCN,VERSIONS_XID,VERSIONS_OPERATION,EMPNO FROM T_FVQ_20170617_LHR VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE ORDER BY VERSIONS_STARTTIME; |
其中,VERSIONS BETWEEN用于指定闪回版本查询时查询的时间段或SCN段;AS OF用于指定闪回查询时查询的时间点或SCN。在闪回版本查询的目标列中,可以使用下列几个伪列返回版本信息:
VERSIONS_STARTTIME:基于时间的版本有效范围的下界;
VERSIONS_STARTSCN:基于SCN的版本有效范围的下界;
VERSIONS_ENDTIME:基于时间的版本有效范围的上界;
VERSIONS_ENDSCN:基于SCN的版本有效范围的上界;
VERSIONS_XID:操作的事务ID,唯一的标识行;
VERSIONS_OPERATION:执行操作的类型,I 表示INSERT,D 表示DELETE,U 表示UPDATE。
闪回版本查询注意事项:
① VERSIONS子句不能用于查询的表包括外部表、临时表和固定表。
② 不能使用VERSIONS子句查询视图。但是,在视图定义中可使用VERSIONS子句。
③ SELECT语句中的VERSIONS子句不能跨多个DDL语句(这些语句会更改相应表的结构)。
闪回版本查询示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | LHR@orclasm > SHOW PARAMETER UNDO NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ _undo_autotune boolean FALSE undo_management string AUTO undo_retention integer 900 undo_tablespace string UNDOTBS1 LHR@orclasm > CREATE TABLE T_FVQ_20170617_LHR AS SELECT * FROM SCOTT.EMP WHERE 1=2;--创建表T_FVQ_20170617_LHR Table created. LHR@orclasm > SELECT TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS'),TIMESTAMP_TO_SCN(SYSDATE) FROM DUAL;--查询时间作为TIMESTAMP开始时间 TO_DATE(SYSDATE,'YY TIMESTAMP_TO_SCN(SYSDATE) ------------------- ------------------------- 2017-06-17 14:49:58 67842991 LHR@orclasm > INSERT INTO T_FVQ_20170617_LHR SELECT * FROM SCOTT.EMP WHERE EMPNO=7902;--插入EMPNO=7902 1 row created. LHR@orclasm > COMMIT; --插入一行提交作为一个版本 Commit complete. LHR@orclasm > INSERT INTO T_FVQ_20170617_LHR SELECT * FROM SCOTT.EMP WHERE EMPNO=7788; 1 row created. LHR@orclasm > INSERT INTO T_FVQ_20170617_LHR SELECT * FROM SCOTT.EMP WHERE EMPNO=7698; 1 row created. LHR@orclasm > COMMIT; --插入两行提交作为一个版本 Commit complete. LHR@orclasm > UPDATE T_FVQ_20170617_LHR SET SAL=8888 WHERE EMPNO=7788; 1 row updated. LHR@orclasm > COMMIT; --再次更改EMPNO=7788的行提交,使这行有旧版本 Commit complete. LHR@orclasm > SELECT TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS'),TIMESTAMP_TO_SCN(SYSDATE) FROM DUAL;--查询时间作为TIMESTAMP结束时间 TO_DATE(SYSDATE,'YY TIMESTAMP_TO_SCN(SYSDATE) ------------------- ------------------------- 2017-06-17 14:51:46 67843218 LHR@orclasm > SELECT TO_CHAR(VERSIONS_STARTTIME,'YYYY-MM-DD HH24:MI:SS') VERSIONS_STARTTIME,VERSIONS_STARTSCN,TO_CHAR(VERSIONS_ENDTIME,'YYYY-MM-DD HH24:MI:SS') VERSIONS_ENDTIME ,VERSIONS_ENDSCN,VERSIONS_XID,VERSIONS_OPERATION,EMPNO 2 FROM T_FVQ_20170617_LHR VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE 3 ORDER BY VERSIONS_STARTTIME; VERSIONS_STARTTIME VERSIONS_STARTSCN VERSIONS_ENDTIME VERSIONS_ENDSCN VERSIONS_XID V EMPNO ------------------- ----------------- ------------------- --------------- ---------------- - ---------- 2017-06-17 14:50:04 67843038 050007009F9F0000 I 7902 2017-06-17 14:50:57 67843139 07000D0018830000 I 7698 2017-06-17 14:50:57 67843139 2017-06-17 14:51:34 67843209 07000D0018830000 I 7788 2017-06-17 14:51:34 67843209 07001F0019830000 U 7788 |
闪回事务查询(Flashback Transaction Query)
闪回事务查询提供了一种查看事务级数据库变化的方法。它是SQL的扩展,能够看到事务带来的所有变化。此外,返回补充SQL语句,并用于撤消由事务引起的各行变化。使用闪回事务查询的权限:
1 2 | GRANT SELECT ANY TRANSACTION TO LHR; GRANT EXECUTE ON DBMS_FLASHBACK TO LHR; |
开启补全日志:
1 2 | ALTER DATABASE ADD SUPPLEMENTAL LOG DATA; ALTER DATABASE ADD SUPPLEMENTAL LOG DATA(PRIMARY KEY,UNIQUE INDEX) COLUMNS; |
闪回事务查询实际上是查询的数据字典FLASHBACK_TRANSACTION_QUERY。可以根据该视图的UNDO_SQL列值返回数据以前版本。
闪回事务查询示例说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | SQL> conn / as sysdba SQL> alter database add supplemental log data; Database altered. SQL> alter database add supplemental log data (primary key) columns; Database altered. SQL> grant select any transaction to lhr; Grant succeeded. SQL> conn lhr/lhr LHR@orclasm > SELECT TO_DATE(SYSDATE,'YYYY-MM-DD HH24:MI:SS'),TIMESTAMP_TO_SCN(SYSDATE) FROM DUAL; TO_DATE(SYSDATE,'YY TIMESTAMP_TO_SCN(SYSDATE) ------------------- ------------------------- 2017-06-17 16:27:29 67854536 LHR@orclasm > CREATE TABLE T_FTQ_20170617_LHR AS SELECT * FROM SCOTT.EMP WHERE EMPNO=7902; Table created. LHR@orclasm > SELECT * FROM T_FTQ_20170617_LHR; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- ------------------- ---------- ---------- ---------- 7902 FORD ANALYST 7566 1981-12-03 00:00:00 3000 20 LHR@orclasm > UPDATE T_FTQ_20170617_LHR SET SAL=9999 WHERE EMPNO=7902; 1 row updated. LHR@orclasm > COMMIT; Commit complete. LHR@orclasm > SELECT TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS'),TIMESTAMP_TO_SCN(SYSDATE) FROM DUAL; TO_DATE(SYSDATE,'YY TIMESTAMP_TO_SCN(SYSDATE) ------------------- ------------------------- 2017-06-17 16:28:25 67854637 LHR@orclasm > UPDATE T_FTQ_20170617_LHR SET SAL=99999 WHERE EMPNO=7902; 1 row updated. LHR@orclasm > COMMIT; Commit complete. LHR@orclasm > SELECT TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS'),TIMESTAMP_TO_SCN(SYSDATE) FROM DUAL; TO_DATE(SYSDATE,'YY TIMESTAMP_TO_SCN(SYSDATE) ------------------- ------------------------- 2017-06-17 16:28:41 67854673 LHR@orclasm > col UNDO_SQL format a100 LHR@orclasm > col TABLE_NAME format a30 LHR@orclasm > SELECT START_SCN, COMMIT_SCN, LOGON_USER, OPERATION, TABLE_NAME, UNDO_SQL 2 FROM FLASHBACK_TRANSACTION_QUERY V 3 WHERE XID IN ('08000000AFA50000', '020014002C9F0000') 4 ORDER BY V.START_SCN; START_SCN COMMIT_SCN LOGON_USER OPERATION TABLE_NAME UNDO_SQL ---------- ---------- ------------ ----------- -------------------- ---------------------------------------------------------------------------------------------------- 67854610 67854626 LHR UPDATE T_FTQ_20170617_LHR update "LHR"."T_FTQ_20170617_LHR" set "SAL" = '3000' where ROWID = 'AAAnyVAAEAAAACDAAA'; 67854610 67854626 LHR BEGIN 67854645 67854656 LHR UPDATE T_FTQ_20170617_LHR update "LHR"."T_FTQ_20170617_LHR" set "SAL" = '9999' where ROWID = 'AAAnyVAAEAAAACDAAA'; 67854645 67854656 LHR BEGIN LHR@orclasm > update "LHR"."T_FTQ_20170617_LHR" set "SAL" = '9999' where ROWID = 'AAAnyVAAEAAAACDAAA'; 1 row updated. LHR@orclasm > SELECT * FROM T_FTQ_20170617_LHR; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- ------------------- ---------- ---------- ---------- 7902 FORD ANALYST 7566 1981-12-03 00:00:00 9999 20 |
闪回表(Flashback TABLE)
1 2 3 | alter table TRUNTAB enable row movement; flashback table TRUNTAB to timestamp to_date('2014/12/31 17:33:00','YYYY/MM/DD HH24:MI/SS'); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | LHR@orclasm > CREATE TABLE T_FT_20170617_LHR (A NUMBER,B NUMBER); Table created. LHR@orclasm > INSERT INTO T_FT_20170617_LHR VALUES(1,1); 1 row created. LHR@orclasm > COMMIT; Commit complete. LHR@orclasm > SELECT DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER FROM DUAL; GET_SYSTEM_CHANGE_NUMBER ------------------------ 67902120 LHR@orclasm > INSERT INTO T_FT_20170617_LHR VALUES(2,2); 1 row created. LHR@orclasm > COMMIT; Commit complete. LHR@orclasm > SELECT * FROM T_FT_20170617_LHR; A B ---------- ---------- 1 1 2 2 LHR@orclasm > SELECT DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER FROM DUAL; GET_SYSTEM_CHANGE_NUMBER ------------------------ 67902215 LHR@orclasm > FLASHBACK TABLE T_FT_20170617_LHR TO SCN 67902120;----闪回表的时候,需要对表执行ROW MOVMENT FLASHBACK TABLE T_FT_20170617_LHR TO SCN 67902120 * ERROR at line 1: ORA-08189: cannot flashback the table because row movement is not enabled LHR@orclasm > ALTER TABLE T_FT_20170617_LHR ENABLE ROW MOVEMENT; Table altered. LHR@orclasm > FLASHBACK TABLE T_FT_20170617_LHR TO SCN 67902120; Flashback complete. LHR@orclasm > SELECT * FROM T_FT_20170617_LHR; A B ---------- ---------- 1 1 LHR@orclasm > FLASHBACK TABLE T_FT_20170617_LHR TO SCN 67902215;---闪回到最后的位置 Flashback complete. LHR@orclasm > SELECT * FROM T_FT_20170617_LHR; A B ---------- ---------- 1 1 2 2 |
下面是验证索引在FLASHBACK TABLE TO SCN中的情况:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | LHR@orclasm > DROP TABLE T_FT_20170617_LHR; Table dropped. LHR@orclasm > CREATE TABLE T_FT_20170617_LHR (A NUMBER,B NUMBER); Table created. LHR@orclasm > INSERT INTO T_FT_20170617_LHR VALUES(1,1); 1 row created. LHR@orclasm > COMMIT; Commit complete. LHR@orclasm > SELECT DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER FROM DUAL; GET_SYSTEM_CHANGE_NUMBER ------------------------ 67902871 LHR@orclasm > INSERT INTO T_FT_20170617_LHR VALUES(2,2); 1 row created. LHR@orclasm > COMMIT; Commit complete. LHR@orclasm > CREATE INDEX IDX_T_LHR ON T_FT_20170617_LHR(A); Index created. LHR@orclasm > SELECT DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER FROM DUAL;---该SCN表中存在索引 GET_SYSTEM_CHANGE_NUMBER ------------------------ 67902969 LHR@orclasm > INSERT INTO T_FT_20170617_LHR VALUES(3,3); 1 row created. LHR@orclasm > COMMIT; Commit complete. LHR@orclasm > SELECT DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER FROM DUAL; GET_SYSTEM_CHANGE_NUMBER ------------------------ 67903002 LHR@orclasm > SELECT INDEX_NAME,STATUS FROM USER_INDEXES WHERE TABLE_NAME='T_FT_20170617_LHR'; INDEX_NAME STATUS ------------------------------ -------- IDX_T_LHR VALID LHR@orclasm > ALTER TABLE T_FT_20170617_LHR ENABLE ROW MOVEMENT; Table altered. LHR@orclasm > FLASHBACK TABLE T_FT_20170617_LHR TO SCN 67902871; Flashback complete. LHR@orclasm > SELECT * FROM T_FT_20170617_LHR;--恢复到没有创建索引之前的SCN A B ---------- ---------- 1 1 LHR@orclasm > SELECT INDEX_NAME,STATUS FROM USER_INDEXES WHERE TABLE_NAME='T_FT_20170617_LHR';--此时索引仍然存在 INDEX_NAME STATUS ------------------------------ -------- IDX_T_LHR VALID LHR@orclasm > FLASHBACK TABLE T_FT_20170617_LHR TO SCN 67903002;--闪回到最后的SCN Flashback complete. LHR@orclasm > SELECT * FROM T_FT_20170617_LHR; A B ---------- ---------- 1 1 2 2 3 3 LHR@orclasm > DROP INDEX IDX_T_LHR; Index dropped. LHR@orclasm > FLASHBACK TABLE T_FT_20170617_LHR TO SCN 67902969;--闪回到创建索引的SCN ,但是经过闪回后索引已经不再存在了 Flashback complete. LHR@orclasm > SELECT INDEX_NAME,STATUS FROM USER_INDEXES WHERE TABLE_NAME='T_FT_20170617_LHR'; no rows selected LHR@orclasm > |
闪回删除(Flashback DROP)
从Oracle 10g开始,为了支持闪回删除(Flashback Drop)功能,Oracle引入了回收站(Recycle Bin)的概念。它的全称叫Tablespace Recycle Bin。回收站实际是一个逻辑容器(逻辑区域),原理有点类似于Windows系统的回收站。它以表空间中现有已经分配的空间为基础,而不是从表空间上物理划出一个固定区域用作回收站。这意味着回收站和表空间中的对象共用存储区域、系统没有给回收站预留空间。
从原理上来说,回收站就是一个数据字典表,放置用户已删除的的数据库对象信息。用户进行DROP操作的对象并没有被数据库删除,仍然会占用空间,除非是由用户手工进行PURGE或者因为存储空间不够而被数据库清除掉。在回收站功能被打开的情况下,当某个表被删除时,它就被移动到了回收站中。该对象一直保存在回收站中,直到清除回收站为止。因此,如果使用类似“DROP TABLE T_LHR;”的语句,那么T_T_LHR表就被移动到了回收站中。如果希望彻底删除T_LHR表,而不是保存在回收站中,那么可以在DROP TABLE命令中使用PURGE参数,命令为“DROP TABLE T_LHR PURGE;”。
闪回删除需要使用到回收站,打开回收站的命令如下所示:
1 2 | 系统级别:ALTER SYSTEM SET RECYCLEBIN = ON SCOPE=SPFILE; 会话级别:ALTER SESSION SET RECYCLEBIN = ON; |
关于闪回删除需要注意以下几点:
① 只能用于非系统表空间和本地管理的表空间。在SYSTEM表空间中的表被DROP后不会进入回收站。
② 对象的参考约束不会被恢复,指向该对象的外键约束需要重建。
③ 对象能否恢复成功,取决于对象空间是否被覆盖重用。
④ 当删除表时,依赖于该表的物化视图也会同时被删除,但是由于物化视图并不会被放入回收站,因此,当执行FLASHBACK TABLE TO BEFORE DROP时,也不能恢复依赖于该表的物化视图,这个时候就需要DBA手工介入重新创建物化视图。
⑤ 对于回收站中的对象,只支持查询。
⑥ 表被恢复以后,表上的索引,需要重建,虽然索引可以随着表的闪回而闪回,但是闪回后的索引仍然使用回收站中的名称,因此,需要重建索引。
⑦ 在使用“FLASHBACK TABLE ... TO BEFORE DROP”命令从回收站恢复表及其所有可能的相关对象时,可以指定表的原始名称或删除对象时分配给对象的系统生成名称。如果指定原始名称,且回收站包含多个具有该名称的对象,那么Oracle会最先恢复最晚移动到回收站的对象(LIFO:后进先出)。如果删除原始表后又在同一用户中创建了同名的新表,那么这个时候再执行FLASHBACK TABLE时会返回错误,此时需要指定RENAME TO子句。
闪回回收站中指定的表:
1 | FLASHBACK TABLE "BIN$zltzJRsMB0PgRAAY/i3Kdw==$0" TO BEFORE DROP; |
在使用“FLASHBACK TABLE ... TO BEFORE DROP”命令从回收站恢复表及其所有可能的相关对象时,可以指定表的原始名称或删除对象时分配给对象的系统生成名称。如果指定原始名称,且回收站包含多个具有该名称的对象,那么Oracle会最先恢复最晚移动到回收站的对象(LIFO:后进先出)。如果删除原始表后又在同一用户中创建了同名的新表,那么这个时候再执行FLASHBACK TABLE时会返回错误,此时需要指定RENAME TO子句。
下面给出一个使用回收站的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | SYS@oralhr> SHOW PARAMETER RECYCLEBIN NAME TYPE VALUE ------------------------------------ ---------------------- ------------------------------ recyclebin string OFF SYS@oralhr> alter system set recyclebin=on scope=spfile; System altered. SYS@oralhr> STARTUP FORCE; ====》慎用,不推荐 ORACLE instance started. Total System Global Area 3089920000 bytes Fixed Size 2250360 bytes Variable Size 721422728 bytes Database Buffers 2348810240 bytes Redo Buffers 17436672 bytes Database mounted. Database opened. SYS@oralhr> SHOW PARAMETER RECYCLEBIN NAME TYPE VALUE ------------------------------------ ---------------------- ------------------------------ recyclebin string ON SYS@oralhr> CREATE TABLE TB_20160627_LHR AS SELECT * FROM DUAL; Table created. SYS@oralhr> DROP TABLE TB_20160627_LHR; Table dropped. SYS@oralhr> SELECT * FROM DBA_RECYCLEBIN; no rows selected SYS@oralhr> CREATE TABLE TB_20160627_LHR TABLESPACE USERS AS SELECT * FROM DUAL; Table created. SYS@oralhr> DROP TABLE TB_20160627_LHR; Table dropped. SYS@oralhr> SELECT * FROM DBA_RECYCLEBIN; OWNER OBJECT_NAME ORIGINAL_NAME --------- ------------------------------ ---------------- SYS BIN$Njoq6PZtAGzgUxa8wKsAbA==$0 TB_20160627_LHR |
需要特别注意的是,SYSTEM表空间的表被DROP后不会进入回收站空间。
闪回数据库(Flashback Database)
闪回数据库就是当数据库出现逻辑错误时,能够将整个数据库回退到出错前的那个状态。应用场景包括:
① 系统管理员误删除了用户。
② 用户截断了表(TRUNCATE)。
③ 用户错误地执行了某个批处理任务,或者该批处理任务的脚本编写有问题,使得多个表的逻辑出现问题,无法采用闪回表的方式进行恢复。
闪回数据库是进行时间点恢复的新战略。它能够快速将Oracle数据库恢复到以前的时间,以正确更正由于逻辑数据损坏或用户错误而引起的任何问题。闪回日志可用于捕获旧版本的变化块。当需要执行恢复时,可快速重放闪回日志,以将数据库恢复到错误前的时间点,并且只恢复改变的块。这一过程非常快,可将恢复时间从数小时缩短至几分钟。此外,它还非常易用。通过发出以下简单的命令,可将数据库恢复到2:05PM。
FLASHBACK DATABASE to '2:05 PM';
要想启动Flashback Database的功能,那么需要满足以下几个条件:
① 数据库在Archivelog模式
② 数据库在MOUNT或OPEN状态
③ 使用闪回恢复区,参数db_recovery_file_dest_size和db_recovery_file_dest都必须配置,因为flashback log必须要求放在flash recovery area里,如下所示:
1 2 3 4 5 6 | alter system set db_recovery_file_dest_size=4g; alter system set db_recovery_file_dest='/u01/app/oracle/fast_recovery_area'; alter database add supplemental log data; alter database add supplemental log data(primary key,unique index) columns; alter database FLASHBACK on;--如果要关闭使用alter database flashback off; |
在Flashback DB功能启用之后,Oracle启动了一个后台进程RVWR(Recovery Writer)负责把位于SGA中的Flashback Buffer中的Flashback Log写出到闪回恢复区中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | --flashback buffer的大小: SQL> select * from v$sgastat where lower(name) like '%flash%'; POOL NAME BYTES ------------ -------------------------- ---------- shared pool flashback generation buff 3981204 SQL> --后台启动的RVWR进程: SQL> select addr,program from v$process where background=1 and program like '%RVWR%'; ADDR PROGRAM -------- ---------------------------------------------------------------- 8FACC870 ORACLE.EXE (RVWR) SQL> select paddr,description from v$bgprocess where paddr<>'00' AND paddr='8FACC870'; PADDR DESCRIPTION -------- ---------------------------------------------------------------- 8FACC870 Recovery Writer SQL> |
在启用闪回数据库功能的过程中,生成的告警日志如下所示:
1 2 3 4 5 6 7 8 9 | Tue Feb 06 11:17:07 2018 alter database FLASHBACK on Starting background process RVWR Tue Feb 06 11:17:07 2018 RVWR started with pid=31, OS id=12594 Allocated 3981120 bytes in shared pool for flashback generation buffer Flashback Database Enabled at SCN 2010282 Completed: alter database FLASHBACK on |
与闪回数据库有关的几个重要视图如下所示:
1 2 3 4 5 6 | SELECT * FROM V$FLASHBACK_DATABASE_LOG;-- 记录闪回日志信息,包括最早可以回复的SCN,闪回日志的大小 SELECT * FROM V$FLASHBACK_DATABASE_STAT;-- 用于监视闪回数据库日志中记录闪回数据的开销,包含24小时的信息,每行代表一个小时的时间间隔,可以确定数据生成的变化,FLASHBACK_DATA和REDO_DATA分别表示时间间隔内写入的闪回字节数和Redo日志字节数 SELECT * FROM V$FLASHBACK_DATABASE_LOGFILE ;-- 闪回数据库日志文件信息 |
闪回数据归档(Flashback Data Archive)
在Oracle 11g中,对闪回技术再次进行了扩展,提供了一个全新的FLASHBACK方式,称之为闪回数据归档(Flashback Data Archive)。闪回数据归档通过将变化数据另外存储到创建的闪回归档区(Flashback Archive)中,用来和Undo区别开来,这样就可以为闪回归档区单独设置存储策略,使之可以闪回到指定时间之前的旧数据而不影响Undo策略。闪回数据归档可以根据需要指定哪些数据库对象需要保存历史变化数据,而不是将数据库中所有对象的变化数据都保存下来,这样可以极大地减少空间需求。需要注意的是,闪回数据归档并不是记录数据库的所有变化,而只是记录了指定表的数据变化。所以,闪回数据归档是针对对象的保护,是闪回数据库的有力补充。闪回数据归档区是一个逻辑概念,是从一个或者多个表空间中拿出一定的空间,来保存表的修改历史,这样就摆脱了对Undo数据的依赖,不利用Undo就可以闪回到归档策略内的任何一个时间点上。
闪回数据归档并不是记录数据库的所有变化,而只是记录了指定表的数据变化。所以,闪回数据归档是针对对象的保护,是闪回数据库的有力补充。闪回数据归档区是一个逻辑概念,是从一个或者多个表空间中拿出一定的空间,来保存表的修改历史,这样就摆脱了对Undo数据的依赖,不利用Undo就可以闪回到归档策略内的任何一个时间点上。操作闪回恢复区需要有“FLASHBACK ARCHIVE ADMINISTER”的权限。操作闪回恢复区需要有“FLASHBACK ARCHIVE ADMINISTER”的权限。开启闪回数据归档常用操作如下所示:
1 2 3 4 | CREATE FLASHBACK ARCHIVE DEFAULT FLA_LHR TABLESPACE TBS1 QUOTA 10M RETENTION 5 YEAR; --创建闪回数据归档 ALTER FLASHBACK ARCHIVE FLA_LHR SET DEFAULT; --指定默认闪回数据归档 ALTER TABLE T_LHR FLASHBACK ARCHIVE; --启用闪回数据归档 SELECT PRODUCT_NUMBER ,PRODUCT_NAME ,COUNT FROM INVENTORY AS OF TIMESTAMP TO_TIMESTAMP ('2017-01-01 00:00:00' ,'YYYY-MM-DD HH24:MI:SS'); --查看闪回数据归档数据 |
清除闪回归档区中的数据常用操作如下所示:
1 2 3 4 5 | ALTER FLASHBACK ARCHIVE FLA_LHR PURGE ALL;--清除所有归档区的数据 ALTER FLASHBACK ARCHIVE FLA_LHR PURGE BEFORE TIMESTAMP (SYSTIMESTAMP - INTERVAL '1' DAY);--清除一天以前的数据 ALTER FLASHBACK ARCHIVE FLA_LHR PURGE BEFORE SCN 728969;--清除特定SCN之前的数据 ALTER TABLE T_LHR NO FLASHBACK ARCHIVE;--将指定的表不再设置数据归档 DROP FLASHBACK ARCHIVE data_test2;--删除数据归档区 |
关于闪回数据归档的一些比较有用的视图如下所示:
DBA_FLASHBACK_ARCHIVE:闪回归档区信息。
DBA_FLASHBACK_ARCHIVE_TS:闪回归档有关表空间的信息。
DBA_FLASHBACK_ARCHIVE_TABLES:对应表所对应的闪回归档信息。
闪回数据归档的后台进程是fbda,如下所示:
1 2 3 4 5 6 | [oracle@rhel6lhr ~]$ ps -ef|grep fbda oracle 34861 1 0 09:28 ? 00:00:01 ora_fbda_orclasm SYS@lhrdb> SELECT NAME,DESCRIPTION FROM V$BGPROCESS WHERE NAME='FBDA'; NAME DESCRIPTION ----- ---------------------------------------------------------------- FBDA Flashback Data Archiver Process |
如果对表指定了闪回数据归档区,那么不能对表进行如下操作:
删除,重命名,或者修改列。
进行分区或者子分区操作。
转换LONG到LOB类型。
ALTER TABLE操作。
DROP、RENAME、TRUNACTE表。
真题1、You enabled Flashback Data Archive on the INVENTORY table. Which DDL operation is supported on the table after enabling Flashback Data Archive?
A、Drop the table.
B、Partition the table
C、Truncate the table.
D、Add a column to the table.
E、Rename a column in the table.
答案:D。
题目的意思是启用INVENTORY表的闪回数据归档,启用闪回数据归档之后在表上支持哪一项DDL操作?A、B、C和E都不能操作,A的示例如下所示:
scott@11gR1> DROP TABLE TEST1;
DROP TABLE TEST1
*
ERROR at line 1:
ORA-55610: Invalid DDL statement on history-tracked table