ORACLE FLAHBACK 系列(包含版本9与版本10)
根据以往的经验,很多操作失误或者用户错误,将导致应用停顿甚至终止,但是,实际上,防止这种误操作的办法是非常用限的。如果没有良好的计划与高超的技术,一个很小的错误将可能导致一个很大的影响,如错误的删除(delete)数据或者是删除(drop)一个表。
那怎么样来防止这种“不小心的操作呢”,Oracle从版本9开始,就开始提供了flashback query(闪回查询)的功能,最初的功能也是很有限的,不仅完全依赖于自动Undo(AUM),对于drop,truncate等DDL操作是毫无办法,而且,由于受到Undo空间限制,能闪回的时间也是有限的。Oracle的版本10中,对falshback做了巨大的改进,不再仅仅是局限于AUM的闪回查询了,甚至可以闪回整个数据库,您将真正的回到操作之前的状态。
在以下的章节中,我们将了解到如下的内容
1、 从Oracle 9i开始的flashback query
2、 从Oracle 9i开始的flashback exp
3、
Oracle
4、
Oracle
5、
Oracle
6、
Oracle
7、
Oracle
在过去,如果用户错误操作数据后,除了不完全恢复外,没有好的解决办法,到了Oracle9i,这一个难堪局面有所改善。Oracle 9i中提供了一项新的技术手段——flashback query(闪回查询),这个功能的实现,由一个新的包DBMS_FLASH来实现。用户使用闪回查询可以及时取得误操作前的数据,并可以针对错误进行相应的恢复措施。
如果需要用到闪回查询,必须在init.ora或者是spfile.ora中设置以下参数UNDO_MANAGEMENT = AUTO ,在Oracle9i中,该参数默认就是Auto(AUM)。与此相关的其它参数还有:
SQL> show parameter undo
NAME TYPE
VALUE
--------------------------------
----------- -----------
undo_management
string AUTO
undo_retention integer
10800
undo_suppress_errors boolean
FALSE
undo_tablespace string
UNDOTBS
除了确保以上参数中的UNDO_MANAGEMENT =
AUTO外,还要注意另外一个参数undo_retention
= n(秒),它决定了能往前闪回的最大时间,从参数也可以看到,这个参数决定了Undo最多的保存时间,越大的值,就会需要更多的Undo空间的支持。我们可以通过如下的命令来修改该参数
SQL> ALTER SYSTEM SET undo_retention = 1200;
System altered.
以上的命令,告诉Oracle,Undo信息将保持1200秒(20分钟),这个将确保任何提交后的信息在Undo中将保持20分钟,除了可以一定程度的防止Ora-01555错误外,Falshback query将也直接的应用到其中的信息。
现在,我们用一个简单的例子来说明Oracle 9i的flashback query
1、创建FLASH用户
SQL> create
user flash identified by flash;
SQL> grant
connect, resource to flash;
SQL> grant
execute on dbms_flashback to flash;
SQL> connect
flash/flash
2、创建一个测试表
SQL> CREATE TABLE tst(t number(5));
Table created.
SQL> INSERT INTO tst VALUES(1);
1 row created.
SQL> INSERT INTO tst VALUES(2);
1 row created.
SQL> COMMIT;
Commit complete.
SQL> CREATE TABLE keep_date (date_scn_tracking date);
Table created.
SQL> SELECT * FROM tst;
T
----------
1
2
注意:在执行步骤3或者步骤4之前,等待5分钟。
3. 删除记录
SQL> execute dbms_flashback.disable;
PL/SQL procedure successfully completed.
SQL> INSERT INTO keep_date select sysdate from dual;
1 row created.
SQL> COMMIT;
Commit complete.
SQL> DELETE FROM tst WHERE t = 1;
1 row deleted.
SQL> COMMIT;
Commit complete.
SQL> SELECT * FROM tst;
T
----------
2
通过以上的操作,我们插入了两条记录,并删除了其中一条记录,现在的结果是,我们这里只有一条记录了。在以下的操作中,我们将通过flashback query找到删除的记录
4. 闪回查询
SQL> declare
2 restore_scn date;
3 begin
4 select date_scn_tracking into restore_scn from keep_date;
5 dbms_flashback.enable_at_time(restore_scn);
6 end;
7 /
PL/SQL procedure successfully completed.
SQL> SELECT * FROM tst;
T
----------
1
2
可以看到,虽然我们删除记录并提交了,但是通过特定操作,我们还能查询到删除前的两条记录,
这里需要特别注意的是,Oracle 9i是每五分钟记录一次SCN的,并将SCN和对应时间的映射做个纪录。如果原来插入的记录到做闪回的时间在5分钟之内,用基于时间的flashback可能并查询不到记录,因为如果是基于时间点的查询,也是转化为最近的一次SCN,然后从这个SCN开始进行恢复,因此,如果需要精确的查询,我们可以采用基于SCN的flashback,它将能精确的闪回到需要恢复的时间,关于获取SCN,我们可以通过DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER或者LOGMNR。如
DBMS_FLASHBACK.ENABLE_AT_SYSTEM_CHANGE_NUMBER(SCN_NUM);
来定位你的恢复时间点,下面是使用方法:
SQL> VARIABLE SCN_SAVE NUMBER;
SQL>EXECUTE :SCN_SAVE := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER;
PL/SQL procedure successfully completed.
SQL> print SCN_SAVE;
SCN_SAVE
----------
2.1202E+11
SQL>execute DBMS_FLASHBACK.ENABLE_AT_SYSTEM_CHANGE_NUMBER(:SCN_SAVE);
最后注意,Oracle 9i的Flashback有如下限制。
·采用时间点的恢复,不能精确到最近5分钟,如果需要更精确的查询,需要采用SCN。
·不能flashback5天以前的数据,这个并不是undo_retention所能决定的。
·闪回查询无法恢复到表结构改变之前,因为闪回查询使用的当前的数据字典。
·由于受到undo_retention的影响,对于undo_retention之前的时间,flashback不保证能成功
·对于drop,truncate等不记录回滚的操作,flashback是无能为力的。
Oracle 9i的flashback query在
如
SELECT * FROM TABLENAME AS OF TIMESTAMP
TO_TIMESTAMP('2003-04-04 09:30:00', 'YYYY-MM-DD HH:MI:SS')
WHERE ……;
或者
SELECT * FROM TABLENAME AS OF SCN
SCN_NUMBER
WHERE ……;
我们可以通过一个简单例子来说明这个问题
SQL> create table t1 as select * from dba_objects;
Table created
SQL> select count(*) from t1;
COUNT(*)
----------
43116
可见,现在记录是43116,我们获得现在的系统SCN
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
377688
然后,我们删除该表
SQL> delete from t1;
43116 rows deleted
SQL> commit;
Commit complete
通过如下检查的查询
SQL> SELECT count(*) FROM t1 AS OF SCN 377688;
COUNT(*)
----------
43116;
我们可以看到,查询到的记录数依然是删除前的记录数。
从9i开始,exp工具开始提供闪回导出,就是说,在现在时间,可以导出上一个时间点的数据,exp工具将提供两种闪回导出的方法,以下是9i以后版本exp新增的两个参数,默认情况下,它们都是”none”,如果被设置指定的值,将调用DBMS_FLASH包来获取时间点上的数据
·基于SCN的导出SCN (FLASHBACK_SCN),基于特定SCN的导出
·基于时间的导出time
(FLASHBACK_TIME),基于特定的时间,但是影射为最近的SCN
1. 参数FLASHBACK_SCN
这个参数指定了一个exp导出的特定的SCN,导出的所有数据将保持这个SCN的一致性。默认情况下是none,表示不 调用flashback query,如
exp system/manager file=exp.dmp
flashback_scn=2106860
2. 参数 FLASHBACK_TIME.
这个参数表示导出将基于"YYYY-MM-DD
HH24:MI:SS"的一个时间戳,exp将找到最近的一个SCN来代替这个时间戳来进行导出。 默认是none,表示不调用flashback query,格式如
exp system/manager file=exp.dmp
flashback_time='"2002-07-19 13:24:26"'
Oracle 9i的flashback exp如同oracle 9i的flashback query,它们有着同样的局限性(其实exp就是调用dbms_flash包),所以同样需要设定AUM与undo_retention,如果是时间方式,也不能精确到最近5分钟。除此之外,因为exp调用了dbms_flash包,所以普通用户如果想采用这种方式的导出,必须授权,如
sqlplus /nolog
SQL> connect / as sysdba
SQL> GRANT execute ON dbms_flashback TO test;
SQL> exit
这两个参数也不支持交互方式的导出,只能用命令行方式或者是参数文件。而且在表空间传输方式的时候,不能使用该方式。任何表结构的修改或者是Drop,truncate等DDL语句也影响这种导出方式,因为这些操作将引起undo无法正常会到以前的数据。
下面将举例说明该问题
首先,我们设置相关环境变量
如果在win下面
C:\> SET NLS_DATE_FORMAT=YYYY-MM-DD HH24:MI:SS
--如果是C SHELL
-- $ setenv NLS_DATE_FORMAT 'YYYY-MM-DD HH24:MI:SS'
-- KORN-shell:
-- $ export NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'
-- VMS:
-- DEFINE/NOLOG NLS_DATE_FORMAT "YYYY-MM-DD HH24:MI:SS"
SQL>conn / as sysdba
SQL>GRANT EXECUTE ON dbms_flashback to test;
-- 我们用SCOTT用户登录并创建测试表
SQL>conn test/test
SQL>CREATE TABLE flash AS SELECT * FROM USER_OBJECTS;
SQL>SELECT
COUNT(*) FROM flash;
COUNT(*)
----------
14;
SQL>
SELECT SYSDATE, dbms_flashback.get_system_change_number FROM DUAL;
SYSDATE GET_SYSTEM_CHANGE_NUMBER
----------------------- ------------------------
2004-4-13
13:15:21 386524
如果是版本9,为了防止ORA-1466 "table definition has changed"错误,需要等待5分钟后操作,现在,假定等待了5分钟,我们开始删除表。
SQL> DELETE FROM flash;
SQL>COMMIT;
SQL>SELECT
COUNT(*) FROM flash;
COUNT(*)
----------
0
可以看到,记录已经被清除了,现在,我们运行导出命令,可以看到,有14行从flash表中导出
HOST exp test/test file=exp_flash.dmp
log=exp_flash.log tables=flash
flashback_scn=386524
当然,10g也支持flashback exp,而且如同其它flashback的改进一样,在10g中,你可以精确的利用时间点来导出了。
Oracle
l Oracle Flashback Database
这个特性允许你通过SQL语句FLASHBACK DATABSE语句,让数据库前滚到当前的前一个时间点或者SCN,而不需要做时间点的恢复。
l Oracle Flashback Table
这个特性允许你利用SQL语句FLASHBACK TABLE语句,确保回滚到表的前一个时间点。
l Oracle Flashback Drop
Oracle
l Oracle Flashback Version Query
利用保存的回滚信息,你可以看到特定的表在时间段内的任何修改,如电影的回放一样,你将了解表在该期间的任何变化
l Oracle Flashback Transaction Query
这个特性将确保您检查数据库的任何改变在一个事务级别。你可以利用它来诊断问题,性能分析和审计事务
闪回数据库可以迅速的时数据库回到误操作或人为错误的前一个时间点,如实际中的“撤消”操作,将可以不利用备份就快速的实现时间点的恢复(有后悔药可以吃了)。实际上,Oracle为了实现这一个功能,创建了另外一组日志,就是Flashback Logs(前滚日志),记录数据库的前滚操作。如果希望能闪回数据库,需要设置如下参数:
·DB_RECOVER_FILE_DEST
·DB_RECOVER_FILE_DEST_SIZE
这两个参数来确定Flashback日志的存放地点与该恢复区的大小。在创建数据库的时候,Oracle将自动创建恢复区(需要注意,该恢复区可不仅仅是为了flashback log,还可以用来归档,备份与恢复),但是默认是关闭Flashback database功能。如果想要利用这一功能,DBA就必须正确的配置该日志区的大小,如一个数据库的数据库,每天有10%的块发生改变,那么一天(24小时)的Flash Recovery
Area就是1/10个数据库大小。DBA也可以动态的改变其大小以满足不同的需求。
另外一个参数DB_FLASHBACK_RETENTION_TARGET参数允许您设定闪回数据的保存时间,单位是分。默认是一天(24*60)
如果想启动FLASHBACK DATABASE的功能,您必须在MOUNT模式下,执行alter database flashback on命令。或者是alter tablespace tsname flashback on,数据库将采集falshback log,如果需要关系该功能,则修改On为OFF。
如果想执行flashback database命令,你可以在两种方式下执行:RMAN与SQLPLUS,如
SQL >flashback database to time to_date(xxx);
SQL >flashback database to time TO_TIMESTAMP (xxx);
SQL >flashback database to scn xxx
SQL >flashback database to sequence xxx thread 1
SQL>flashback database to timestamp(sysdate-1/24)
我们下面看看具体的例子说明
SQL> startup mount
ORACLE instance started.
Total System Global Area 113246208 bytes
Fixed Size 787708 bytes
Variable Size 87030532 bytes
Database Buffers 25165824 bytes
Redo Buffers 262144 bytes
Database mounted.
SQL> alter database flashback on;
alter database flashback on
*
ERROR at line 1:
ORA-38706: Cannot turn on FLASHBACK DATABASE logging.
ORA-38707: Media recovery is not enabled.
可以看到,flashback还必须要归档的保证
SQL> alter database archivelog;
Database altered.
SQL> alter database flashback on;
Database altered.
SQL> alter database open;
Database altered.
SQL> archive log list
Database log mode Archive Mode
Automatic archival Enabled
Archive destination USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence 13
Next log sequence to archive 15
Current log sequence 15
经过以上步骤,我们确保了flashback database的功能,我们还可以发现,10g的自动归档是不需要手工干预的,只要开启了归档,就是自动归档了,归档区也在DB_RECOVERY_FILE_DEST参数指定的地点。
通过如下的查询
SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
Session altered.
SQL> SELECT OLDEST_FLASHBACK_SCN, OLDEST_FLASHBACK_TIME
2 FROM V$FLASHBACK_DATABASE_LOG;
OLDEST_FLASHBACK_SCN OLDEST_FLASHBACK_TI
-------------------- -------------------
1135440 2004-04-06 15:20:57
我们可以知道,可以前滚恢复到的最早的SCN与时间点是多少,如果没有确保flashback database,该视图将没有查询结果。
我们创建三个一样的表
SQL> create table t1 as select * from dba_objects;
Table created.
SQL> create table t2 as select * from t1;
Table created.
SQL> create table t3 as select * from t1;
Table created.
SQL> set time on;
SQL> select sysdate from dual;
SYSDATE
-------------------
2004-04-06 15:29:33
我们确定了一个时间点
现在,我们分别truncate一个表与drop一个表,模拟误操作。
15:30:10 SQL> truncate table t2;
Table truncated.
15:30:43 SQL> drop table t3;
Table dropped.
没有备份,我们利用flashback来恢复数据库到2004-04-06 15:29:33时间点。
15:39:02 SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
15:39:31 SQL> startup mount exclusive
ORACLE instance started.
15:41:19 SQL> FLASHBACK DATABASE TO timestamp(to_date('2004-04-06 15:29:33','yyyy-mm-dd hh24:mi:ss'));
Flashback complete.
之后,我们可以用ALTER DATABASE OPEN READ ONLY来检查结果是否正确,如果满足结果,则可以用resetlog来正式启动数据库,注意,一旦resetlogs之后,将不能再flashback的resetlogs之前的时间点。
15:41:32 SQL> alter database open resetlogs;
Database altered.
我们现在查询那三个表
15:42:10 SQL> select count(*) from t1;
COUNT(*)
----------
47708
15:42:47 SQL> select count(*) from t2;
COUNT(*)
----------
47708
15:42:50 SQL> select count(*) from t3;
COUNT(*)
----------
47708
发现truncate的记录或者是drop的表都存在,现在数据库已经前滚到前一个时间点了。
15:44:56 SQL> SELECT OLDEST_FLASHBACK_SCN, OLDEST_FLASHBACK_TIME
15:45:05 2 FROM V$FLASHBACK_DATABASE_LOG;
OLDEST_FLASHBACK_SCN OLDEST_FLASHBACK_TI
-------------------- -------------------
1136169 2004-04-06 15:41:50
同时发现数据库的最早的flashback的时间与scn都回到resetlog的时间点了。
flashback table与9i的flashback query相似,利用undo信息来恢复一个或者一些表到现在以前的一个时间点(一个快照)。Undo相关参数如下,需要确保AUM与足够的retention值。
SQL> show parameter undo
NAME TYPE VALUE
------------------------------------ ----------- -----------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
首先要说明的是,flashback table不等于flashback query,所谓query,仅仅是查询以前的一个快照点而已,并不改变当前表的状态,而flashback table不一样,将改变当前表及附属对象一起回到以前的时间点。
·在线操作
·恢复到指定时间点或者SCN的任何数据.
·自动恢复相关属性,如索引,触发器等
·满足分布式的一致性
·满足数据一致性,所有相关对象将自动一致
语法为:
FLASHBACK TABLE tablename TO TIMESTAMP (
FLASHBACK TABLE employee TO SCN 123456;
FLASHBACK TABLE t1 TO TIMESTAMP '2003-03-03 12:05:00' ENABLE
TRIGGERS;
其中ENABLE TRIGGERS表示触发器恢复之后为enable状态,而默认为disable状态。
注意:如果需要flashback一个表,需要保证
·需要有flashback any table的系统权限或者是该表的flashback对象权限。
·需要有该表的SELECT, INSERT, DELETE, ALTER权限
·必须保证该表ROW MOVEMENT
下面,我们用一个详细的例子来说明这个过程:
16:16:51 SQL> create user flash identified by flash;
User created.
16:17:04 SQL> grant connect,resource to flash;
Grant succeeded.
16:17:19 SQL> connect flash/flash;
Connected.
16:26:35 SQL> create table t1 as select * from
all_objects;
Table created.
16:37:24 SQL> create table t2 as select * from t1;
Table created.
16:37:35 SQL> select count(*) from t1;
COUNT(*)
----------
38949
16:37:43 SQL> select count(*) from t2;
COUNT(*)
----------
38949
16:38:06 SQL> create index inx_test1 on T1 (object_name);
Index created.
16:39:55 SQL> create index inx_test2 on T1 (object_id);
Index created.
16:40:47 SQL> select to_char(sysdate,'yyyy-mm-dd
hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'YY
-------------------
2004-04-06 16:41:18
以上获得一个时间戳,假定我们要恢复该表到这个时间,那么以下对该表的操作都将被前滚。
16:41:18 SQL> drop index inx_test1;
Index dropped.
16:41:33 SQL> delete from t1;
38949 rows deleted.
16:41:46 SQL> commit;
Commit complete.
16:41:49 SQL> truncate table t2;
Table truncated.
在以上的操作中,我们delete一个表,然后truncate一个表,下面,我们将来看看flashback
table的效果,能恢复到什么程度
16:37:55 SQL> ALTER TABLE t1 ENABLE ROW MOVEMENT;
Table altered.
16:38:03 SQL> ALTER TABLE t2 ENABLE ROW MOVEMENT;
Table altered.
16:43:10 SQL> flashback table t1 TO TIMESTAMP
to_timestamp('2004-04-06 16:41:18','yyyy-mm-dd hh24:mi:ss');
Flashback complete.
16:43:49 SQL> flashback table t2 TO TIMESTAMP
to_timestamp('2004-04-06 16:41:18','yyyy-mm-dd hh24:mi:ss');
flashback table t2 TO TIMESTAMP to_timestamp('2004-04-06
16:41:18','yyyy-mm-dd hh24:mi:ss')
*
ERROR at line 1:
ORA-01466: unable to read data - table definition has
changed
我们可以发现,执行delete操作的表是可以恢复的,而执行truncate操作的表是不可以恢复的,这正好也说明了flashback
table利用undo的结论。
看看我们的结果:
SQL> select count(*) from t1;
COUNT(*)
----------
38949
SQL> select count(*) from t2;
COUNT(*)
----------
0
SQL> select t.index_name from user_indexes t where
t.table_name='T1';
INDEX_NAME
------------------------------
INX_TEST2
还可以看到,对于drop的索引,也是没有办法恢复的,因为drop并不记录undo,所以所谓索引的恢复,仅仅是相关索引树的改变而不能找回删除掉的索引。
意外的drop对象时有发生,当用户或者甚至是DBA认识到这个错误的时候,很多时候都太晚了,在以前的版本中,除了不完全恢复,几乎是没有一个好的解决办法,Oracle
10g的flashback drop功能,允许你恢复一个被删除(drop)了的对象,oracle将自动将该对象放入回收站(但是注意,对于truncate的表,除了flashback
database之外,其它的flashback功能可能帮不了你)。
所谓的回收站,是一个虚拟的容器,用于存放所有被删除的对象。在回收站中,被删除的对象将占用创建时的同样的空间,对于一个对象的删除,其实仅仅就是简单的重令名操作。你甚至还可以对已经删除的表查询,也可以利用flashback功能来恢复它, 这个就是flashback
drop功能。
关于回收站内的相关信息可以从recyclebin/USER_recyclebin/DBA_recyclebin等视图中获取,或者通过SQL*Plus的show recyclebin
命令查看
回收站的对象在如下情况下将被清除:
·由于添加新的对象引起表空间的空间不够或者用户的空间配额不够
·表空间需要扩展新区间来增长空间
·手工发purge命令或flashback命令
现在我们做一个简单的测试
SQL> create user test identified by test;
User created.
SQL> grant connect,resource to test;
Grant succeeded.
SQL> connect test/test;
Connected.
SQL> show recyclebin;
可以看到,回收站中是没有任何结果的,表示没有任何表在回收站中。
现在,我们创建一个表,并drop它
SQL> create table t1 as select * from all_objects;
Table created.
SQL> drop table t1;
Table dropped.
SQL> select table_name from user_tables;
TABLE_NAME
------------------------------
BIN$nwjcjTOtQUirZW4H1wlFVA==$0
SQL> show recyclebin
ORIGINAL NAME
RECYCLEBIN NAME
OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------
-------------------
T1
BIN$nwjcjTOtQUirZW4H1wlFVA==$0 TABLE
Show
recyclebin的信息同样可以从recyclebin/user_recyclebin/dba_resyclebin等视图中获得中获得,而且回收站中的表依然可以在user_tables/dba_tables中查询到。
通过以上查询可以看到,该表被放入了回收站,而且名称也变了,当一个表被删除并移动到"回收站"中,它的名字要进行一些转换.这样的目的显而易见是为了避免同类对象名称的重复,转换后的名字格式如下:
BIN$$globalUID$version
其中的globalUID是一个全局唯一的,24个字符长的标示对象,没有任何实际意义,也不可能从这里看到对象未删除前实际的名称。
$
version is是数据库分配的版本号
回收站中的名称为30个字符
通过如下的语句
SQL> select count(*) from
"BIN$nwjcjTOtQUirZW4H1wlFVA==$0";
COUNT(*)
----------
38947
可以看到,实际上,该表在回收站中还是可以被访问的,但是不能在上面发布任何DDL/DML语句。
我们通过FLASHBACK TABLE TABLENAME TO BEFORE DROP;
可以将表恢复到删除之前。如
SQL> FLASHBACK TABLE t1 TO BEFORE DROP;
或者
SQL> FLASHBACK TABLE BIN$nwjcjTOtQUirZW4H1wlFVA==$0 TO
BEFORE DROP;
Flashback complete.
SQL> show recyclebin
SQL> select table_name from user_tables;
TABLE_NAME
------------------------------
T1
可以看到,表T1已经被恢复了,需要注意的是,flashback命令中的表名可以是原来的名字或者是回收站中的名称,都无所谓。如果原来的名称在回收站中存在同名,那么将恢复最后drop的表。
如,我先删除原来的表t1,就是刚才创建的表
SQL> drop table t1;
Table dropped.
在创建一个同样的表(但是内容不一样)
SQL> create table t1 as select * from dual;
Table created.
SQL> drop table t1;
Table dropped.
SQL> show recyclebin;
ORIGINAL NAME
RECYCLEBIN NAME
OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------
-------------------
T1
BIN$FXe9sgDgQM69yX5gNR+qtA==$0 TABLE
T1 BIN$pj80dtOaSwawSKb/rd3Vhg==$0 TABLE
可以看到,在回收站中现在存在两个表T1,但是drop的时间不一样。
SQL> FLASHBACK TABLE t1 TO BEFORE DROP RENAME TO t1_1;
Flashback complete.
SQL> select count(*) from t1_1;
COUNT(*)
----------
1
可以看到恢复的是从dual创建的T1,而不是从all_objects创建的t1,也就是后来创建并drop的表,如果想恢复先删除的表怎么办呢?其实只要在flashback命令后用回收站中的名称恢复就可以了。
怎么管理回收站的信息呢,我们可以用purge
table清除单个表或者是purge recyclebin清除整个回收站。
SQL> drop table t1_1;
Table dropped.
SQL> create table t1 as select * from dual;
Table created.
SQL> drop table t1;
Table dropped.
SQL> show recyclebin
ORIGINAL NAME RECYCLEBIN
NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------
-------------------
T1 BIN$f0UqwWsqQAaQDo5FYyTM
T1 BIN$pj80dtOaSwawSKb/rd3Vhg==$0 TABLE
T1_1 BIN$MVdYcZOzR/KxaX0HGogz9Q==$0 TABLE
可以看到,现在有三个对象在回收站中
SQL> purge table t1;
Table purged.
SQL> show recyclebin
ORIGINAL NAME
RECYCLEBIN NAME
OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------
-------------------
T1 BIN$f0UqwWsqQAaQDo5FYyTM
T1_1 BIN$MVdYcZOzR/KxaX0HGogz9Q==$0 TABLE
可以看到,同样道理,purge
tbale t1并不是清除两个已经删除的表t1,而是仅仅是清除随后被删除的表
SQL> purge recyclebin;
Recyclebin purged.
SQL> show recyclebin
之后,可以看到,回收站中已经没有任何信息
同理我们可以通过purge user_recyclebin或者是purge dba_recyclebin来清除不同的回收站对象。也可以通过PURGE TABLESPACE TSNAME,PURGE TABLESPACE TSNAME USER USERNAME命令来选择清除回收站。
如果删除一个表,而不想放到回收站中,可以利用purge选项在drop语句中,如
drop table tablename purge
另外,还有一些需要注意的地方
·drop
tablespace tsname including contents时,表空间内的所有对象包括回收站内的对象都将被清除。
·如果仅仅是drop
tablespace时,如果有永久对象将不能执行,如果仅仅是有回收站内的对象,将先清除回收站,然后删除表空间
·如果drop
user username cascade时,所有对象将被删除,而且不放入回收站
flashback
version query提供了一个审计行改变的功能,它能找到所有已经提交了的行的记录,比如说,时间1,我插入一条记录,时间2我删除了这条记录,对于时间3,当然查询不到这条记录,但是flashback
version query能够把时间1、时间2的操作给记录下来,并详细的查询出来。
flashback
version query一样依赖于AUM,所以,这里就不再多说AUM的配置。flashback
version query采用VERSIONS BETWEEN语句来进行查询,常用的有
·VERSIONS_SCN
– 系统改变号
·VERSIONS_TIMESTAMP
– 时间
Flashback version query是一个功能强大的工具,可以分析到什么时间执行了什么操作的问题。也可以用于记录的审计,而没有必要去开启细粒度审计功能或者是使用LOGMNR了。
下面将展示这个具有电影功能的flashback
version query
SQL> connect test/test
Connected.
SQL> create table test(a int,b varchar2(10));
Table created.
我们执行一系列如下的操作
16:33:17 SQL> insert into test values(1,'16:33:17');
1 row created.
16:33:31 SQL> commit;
Commit complete.
16:33:34 SQL> update test set a=2,b='16:33:34';
1 row updated.
16:33:53 SQL> commit;
Commit complete.
16:33:57 SQL> update test set a=3;
1 row updated.
16:34:04 SQL> commit;
Commit complete.
16:34:06 SQL> delete test;
1 row deleted.
16:34:11 SQL> commit;