在oracle进行闪回的时候分为了很多级别。有数据库级别的,表级别的,和事务处理级别的。
对于数据库级别来说,当truncate一个表的时候,误操作删除了一个表。由于是truncate操作,属于DDL操作,是没有任何办法进行回退的。这个时候就需要使用闪回技术了。就要靠闪回日志来闪回了。
如果误删除了一个表,只要用户开启了回收站功能,每当用户不小心删除一个表以后,这个表不会直接被删除掉,表会进入到对应的回收站里面。这个时候就要靠回收站来闪回了。
使用where错误的更新数据,就要使用还原数据来进行还原了。还原数据就是原来的数据,即修改之前的数据。它以逻辑结构被存放在还原表空间的还原段里面。还原段的使用是超时覆盖,意味着还原段在保留时间之内,是不会覆盖的。一旦超过时间就会被覆盖。这就意味着使用语句进行修改误操作了,第二天才发现误操作了,如果数据库比较繁忙,还原段超过保留时间的话,那么误操作的数据就未必可以找回来了。只要原来的数据在还原段当中就可以使用闪回查询来进行恢复。
闪回里面常用的,闪回表,闪回查询,闪回库。
SQL> create user hr identified by oracle;
User created.
SQL> grant dba to hr;
Grant succeeded.
SQL> conn hr/oracle;
Connected.
查看用户的回收站是不是开启的
SQL> show parameter recycle;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
buffer_pool_recycle string
db_recycle_cache_size big integer 0
recyclebin string on
可以看到hr用户的回收站是开启的。
创建一张测试表
SQL> create table emp (id number,name varchar(10));
Table created.
之后在表里面插入一些数据。
创建完表之后查看一下
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
EMP TABLE
可以看到用户有emp这张表。
之后将t1表删除。
SQL> drop table emp;
Table dropped.
再去查看一下数据字典
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
BIN$YXinqqnEC6bgVQAAAAAAAQ==$0 TABLE
可以看到和之前数据字典里面内容不一样了。BIN$YXinqqnEC6bgVQAAAAAAAQ==$0这个其实就是emp表,将emp表删除之后就放在回收站里面去了,这个就是回收站里面的emp表。
再去查看回收站里面的内容,显示的是当前用户回收站里面的内容,里面还有原始表的名称。
SQL> show recyclebin;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
EMP BIN$YXinqqnEC6bgVQAAAAAAAQ==$0 TABLE 2017-12-29:01:57:05
现在闪回表到删除之前
SQL> flashback table emp to before drop;
Flashback complete.
SQL> select * from emp;
ID NAME
---------- ----------
1 aaaa
2 b
3 cc
现在再去看看回收站里面的内容
SQL> show recyclebin;
里面的内容都没有了。
只要保证当前用户回收站的功能是开启的,那么删除的数据会自动的找回。
并不是任何删除表都会放在回收站里面,如果drop后面加上purge删除一张表drop table table_name purge,那么对于表的删除就不会放入回收站里面了。drop table table_name purge其实就是先将表放在回收站里面,热后再用清空回收站的命令(purge recyclebin)可以将回收站清空,其实drop table table_name purge是删除表之后将其放入回收站。在删除表的时候只要不加purge,在保证回收站开启的情况下,是可以从回收站找回的。
SQL> select * from emp;
ID NAME
---------- ----------
1 aaaa
2 b
3 cc
SQL> show user;
USER is "HR"
SQL> delete from emp where id=1;
1 row deleted.
SQL> commit;
Commit complete.
[root@localhost ~]# date 查看一下系统的删除之后的时间
Fri Dec 29 03:37:27 PST 2017
SQL> Select * from emp AS OF timestamp to_date('2017-12-29 03:20:27','yyyy-mm-dd hh24:mi:ss');
ID NAME
---------- ----------
1 aaaa
2 b
3 cc
可以看到将之前删除的数据也查询出来了,因为删除的数据以逻辑形式暂时存放在undo表空间里面。上面的查询就是在undo里面将相应的数据找回来了。要恢复数据可以通过。
(1)要恢复数据可以将查询出来的误删除的数据重新插入到表里面。
(2)SQL> alter table emp enable row movement;开启这个表的行迁移功能,就可以直接闪回表,闪回到需要的时间。
Flashback table emp to timestamp to_date('2017-12-29 03:20:27','yyyy-mm-dd hh24:mi:ss');
SQL> Flashback table emp to timestamp to_date('2017-12-29 03:20:27','yyyy-mm-dd hh24:mi:ss');
Flashback complete.
SQL> select * from emp;
ID NAME
---------- ----------
1 aaaa
2 b
3 cc
可以看到闪回查询将表恢复了。就是利用undo表空间里面旧的数据找回来。
如果要闪回一个数据库是要有前提的,要求当前数据库归档是开启的。
SQL> archive log list;
Database log mode Archive Mode
Automatic archival Enabled
Archive destination USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence 10
Next log sequence to archive 12
Current log sequence 12
同时还得设置数据库的闪回空间大小。因为闪回库的时候需要依赖闪回日志。而闪回日志是需要存放在某个闪回空间里面的,所以需要开启这个功能。
在mount状态下面
SQL> alter system set db_recovery_file_dest_size=10G;
SQL> alter system set db_recovery_file_dest='/u01/oracle/flash';
SQL> alter system set db_flashback_retention_target=2880 scope=both; 默认1440,一天
SQL> alter database flashback on; 闪回功能开启
SQL> alter database open;
使用truncated表是不会放进回收站的,是无法找回的。
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
1318941
SQL> truncate table emp;
Table truncated.
SQL> create table test (id number); 创建一张新的表做测试 看看闪回之后是否还在
Table created.
SQL> insert into test values(1);
1 row created.
SQL> conn / as sysdba
Connected.
SQL> startup force mount;
ORACLE instance started.
SQL> flashback database to scn 1318941 ;将整个数据库运行状态都进行回退
Flashback complete.
SQL> flashback database to scn 1318941 ;
Flashback complete.
SQL> alter database open resetlogs;
Database altered.
SQL> conn hr/oracle
Connected.
SQL> select * from emp;
ID NAME
---------- ----------
1 aaaa
2 b
3 cc
SQL> select * from test;
select * from test
*
ERROR at line 1:
ORA-00942: table or view does not exist
可以看到数据库回退了。即SCN 1318941之前的都有,之后的都没有了。
1、打开flashback:
关闭数据库
SQL>shutdown immediate;
启动到mount方式
SQL>startup mount;
如果归档没有打开,打开归档[因为flashback依赖Media recovery,所以在打开flashback之前必须先启用归档
SQL>alter database archivelog;
打开闪回
SQL> alter database flashback on;
2、关闭flashback:
关闭数据库:
SQL>shutdown immediate
启动到mount方式
SQL>startup mount;
关闭闪回
SQL> alter database flashback off;
关于Oracle闪回的打开和关闭,主要就是需要注意以下几点:
1、闪开打开的前提是数据库归档必须打开
2、闪回打开/关闭和归档打开/关闭一样,都是在mount模式下
3、如果要在打开闪回的数据库上关闭归档则必须先关闭依赖于归档的闪回功能
查看flashback是否开启:select name,flashback_on from v$database; 查看闪回恢复区及大小是否设置:show parameter db_recovery; 先设置闪回恢复区的大小:alter system set db_recovery_file_dest_size='2G'; 再设置闪回恢复区路径:alter system set db_recovery_file_dest='E:\oracle\product\10.2.0\db_recovery_file_dest'; 设置数据库回退的时间,默认1440分钟为一天时间:alter system set db_flashback_retention_target = 1440;