概述:
Flashback Database 功能非常类似与RMAN 的不完全恢复, 它可以把整个数据库回
退到过去的某个时点的状态, 这个功能依赖于Flashback log 日志。比RMAN 更快速和高效。因此Flashback Database 可以看作是不完全恢复的替代技术。
sys dba删除的东西无法闪回, 其他用户的可以
1.配置Flash Recovery Area
mount下先开归档 再开闪回
要想使用Flashback Database, 必须使用Flash Recovery Area,因为Flashback
Database Log 只能保存在这里。要配置的2 个参数如下,一个是大小,一个是位置。如果
数据库是RAC,flash recovery area 必须位于共享存储中。数据库必须处于archivelog 模
式。
1) 更改闪回区大小:
SQL>ALTER SYSTEM SET DB_RECOVERY_FILE_DEST_SIZE=2G
SCOPE=BOTH;
2) 更改闪回区路径:
SQL> ALTER SYSTEM SET DB_RECOVERY_FILE_DEST=
' /arch/flashback/' SCOPE=BOTH;
SQL> alter database flashback on;
alter database flashback on
*
ERROR at line 1:
ORA-38706: Cannot turn on FLASHBACK DATABASE logging.
ORA-38714: Instance recovery required.
这是没有设置闪回区路径和大小
SQL> alter database flashback on;
Database altered.
SQL>
SQL> select FLASHBACK_ON from v$database;
FLASHBACK_ON
------------------
YES
flashback database 的恢复能力就越强,因此建议flash recovery area 能够放的下所有的
数据文件,增量备份,以及所有尚未备份的归档文件,当然还有它自己产生的flashback logs。
在数据库运行过程中,oracle 自动向该区域写入文件,当剩余空间不足15%的时候,
它就会在alert 中增加警告,提示你空间不足。但此时不会影响数据库的正常运转,直到所
有空间统统被用掉之后,oracle 首先尝试删除寻些过期的文件,冗余文件或备份过的文件,
如果这些做完了,还是没有空闲空间的话,数据库就被hang 住了。
2.启用数据库Flashback 功能
1). 数据库启动到mount 状态
SQL> startup mount;
2). 检查Flashback 功能, 缺省时功能是关闭的。
SQL> select name, current_scn, flashback_on from v$database;
NAME CURRENT_SCN FLASHBACK_ON
-------- ----------- ------------------
DBA 945715 NO
3). 启动Flashback 功能
SQL> alter database flashback on;
数据库已更改。
4). 设置初始化参数:DB_FLASHBACK_RETENTION_TARGET:
SQL>alter system set db_flashback_retention_target=1440 scope=both;
Tips:该参数用来控制flashback log 数据保留的时间,或者说,你希望flashback
database 能够恢复的最早的时间点。默认值是1440,单位是minute,即24 小时,需要
注意的是该参数虽然未直接指定flash recovery area 大小,但却受其制约,举个例子假如数
据库每天有10%左右的数据变动的话,如果该初始化参数值设置为1440,则flash recovery
area 的大小至少要是当前数据库实际容量的10%,如果该初始化参数设置为2880,则flash
recovery area 的大小就至少是数据库所占容量的20%。
5). 启动数据库
SQL>alter database open;
一、闪回版本(Flashback Query)
1.As of timestamp
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
nls_date_format string
SQL> alter session set nls_date_format='YYYY-MM-DD hh24:mi:ss';
Session altered.
SQL> select sysdate from dual;
SYSDATE
-------------------
2015-11-22 15:05:05
SQL>
SQL> conn scott/tiger 不要用sys
Connected.
SQL> select sysdate from dual;
SYSDATE
---------
22-NOV-15
SQL> alter session set nls_date_format='YYYY-MM-DD hh24:mi:ss';
Session altered.
SQL> select sysdate from dual;
SYSDATE
-------------------
2015-11-22 15:06:36
SQL>
SQL> create table f1 (id int, sdate date);
Table created.
SQL> insert into f1 select 1, sysdate from dual;
1 row created.
SQL> insert into f1 select 2, sysdate from dual;
1 row created.
SQL> insert into f1 select 3, sysdate from dual;
1 row created.
SQL> insert into f1 select 4, sysdate from dual;
1 row created.
SQL> insert into f1 select 5, sysdate from dual;
1 row created.
SQL>
SQL> create table f2 as select * from f1;
Table created.
SQL>
insert into f1 select 6, sysdate from dual;
insert into f1 select 7, sysdate from dual;
insert into f1 select 8, sysdate from dual;
insert into f1 select 9, sysdate from dual;
insert into f1 select 10, sysdate from dual;
insert into f2 select 6, sysdate from dual;
insert into f2 select 7, sysdate from dual;
insert into f2 select 8, sysdate from dual;
insert into f2 select 9, sysdate from dual;
insert into f2 select 10, sysdate from dual;
SQL> commit;
Commit complete.
SQL>
SQL> delete from f1;
10 rows deleted.
SQL> select * from f1;
no rows selected
SQL> commit;
Commit complete.
SQL>
no rows selected
SQL> select * from f1 as of timestamp sysdate-4/1440;
ID SDATE
---------- -------------------
1 2015-11-22 15:08:45
2 2015-11-22 15:08:57
3 2015-11-22 15:09:07
4 2015-11-22 15:09:20
5 2015-11-22 15:09:34
6 2015-11-22 15:11:16
7 2015-11-22 15:11:16
8 2015-11-22 15:11:16
9 2015-11-22 15:11:16
10 2015-11-22 15:11:17
10 rows selected.
SQL>
或者:
SQL>select * from f1 as of timestamp to_timestamp('2015-11-22
15:15:16','YYYY-MM-DD hh24:mi:ss');
ID SDATE
---------- -------------------
1 2015-11-22 15:08:45
2 2015-11-22 15:08:57
3 2015-11-22 15:09:07
4 2015-11-22 15:09:20
5 2015-11-22 15:09:34
6 2015-11-22 15:11:16
7 2015-11-22 15:11:16
8 2015-11-22 15:11:16
9 2015-11-22 15:11:16
10 2015-11-22 15:11:17
10 rows selected.
SQL>
用Flashback Query 恢复之前的数据:
SQL> Insert into f1 select * from f1 as of timestamp to_timestamp('2015-11-22
15:15:16','YYYY-MM-DD hh24:mi:ss'); 2
10 rows created.
SQL>
SQL> commit;
Commit complete.
SQL>
如上述示例中所表示的,as of timestamp 的确非常易用,但是在某些情况下,我们建
议使用as of scn 的方式执行flashback query,比如需要对多个相互有主外键约束的表进行
恢复时,如果使用as of timestamp 的方式,可能会由于时间点不统一的缘故造成数据选择
或插入失败,通过scn 方式则能够确保记录的约束一致性。
2.As of scn
查看SCN:这个要在sys下查
SELECT dbms_flashback.get_system_change_number FROM dual;这个发生SCN改变
SELECT CURRENT_SCN FROM V$DATABASE;
SQL> SELECT dbms_flashback.get_system_change_number FROM dual;
SELECT CURRENT_SCN FROM V$DATABASE;
GET_SYSTEM_CHANGE_NUMBER
------------------------
1813662
SQL>
CURRENT_SCN
-----------
1813663
SQL>
SQL> SELECT CURRENT_SCN FROM V$DATABASE;
SELECT dbms_flashback.get_system_change_number FROM dual;
CURRENT_SCN
-----------
1813652
SQL>
GET_SYSTEM_CHANGE_NUMBER
------------------------
1813652
SQL> SQL>
SQL>
删除数据:
SQL> delete from f1;
10 rows deleted.
SQL> commit;
Commit complete.
SQL> select * from f1;
no rows selected
SQL>
查看删除之前的状态:
SQL> select * from f1 as of scn 1813652;
用Flashback Query 恢复之前的数据:
SQL> insert into f1 select * from f1 as of scn 1813652;
10 rows created.
SQL>
SQL> commit;
Commit complete.
SQL> select * from f1;
ID SDATE
---------- -------------------
1 2015-11-22 15:08:45
2 2015-11-22 15:08:57
3 2015-11-22 15:09:07
4 2015-11-22 15:09:20
5 2015-11-22 15:09:34
6 2015-11-22 15:11:16
7 2015-11-22 15:11:16
8 2015-11-22 15:11:16
9 2015-11-22 15:11:16
10 2015-11-22 15:11:17
10 rows selected.
SQL>
事实上,Oracle 在内部都是使用scn,即使你指定的是as of timestamp,oracle 也会
将其转换成scn,系统时间标记与scn 之间存在一张表,即SYS 下的SMON_SCN_TIME
SQL> desc sys.smon_scn_time sys下
SQL> desc sys.smon_scn_time
Name Null? Type
----------------------------------------- -------- ----------------------------
THREAD NUMBER
TIME_MP NUMBER
TIME_DP DATE
SCN_WRP NUMBER
SCN_BAS NUMBER
NUM_MAPPINGS NUMBER
TIM_SCN_MAP RAW(1200)
SCN NUMBER
ORIG_THREAD NUMBER
SQL>
每隔5 分钟,系统产生一次系统时间标记与scn 的匹配并存入sys.smon_scn_time
表,该表中记录了最近1440 个系统时间标记与scn 的匹配记录,由于该表只维护了最近的
1440 条记录,因此如果使用as of timestamp 的方式则只能flashback 最近5 天内的数据
(假设系统是在持续不断运行并无中断或关机重启之类操作的话)。
注意理解系统时间标记与scn 的每5 分钟匹配一次这句话,举个例子,比如
scn:339988,339989 分别匹配08-05-3013:52:00 和2008-13:57:00,则当你通过as of
timestamp 查询08-05-30 13:52:00 或08-05-30 13:56:59 这段时间点内的时间时,oracle
都会将其匹配为scn:339988 到undo 表空间中查找,也就说在这个时间内,不管你指定的
时间点是什么,查询返回的都将是08-05-30 13:52:00 这个时刻的数据。
查看SCN 和timestamp 之间的对应关系:
select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss')from sys.smon_scn_time;
SCN TO_CHAR(TIME_DP,'YY
---------- -------------------
1381299 2015-10-12 13:35:56
1381904 2015-10-12 13:55:55
1382288 2015-10-12 14:05:57
1382765 2015-10-12 14:15:57
1383057 2015-10-12 14:25:55
1384934 2015-10-12 15:15:58
1385215 2015-10-12 15:25:58
1385349 2015-10-12 15:30:58
1385677 2015-10-12 15:40:58
1386322 2015-10-12 16:00:59
1627 rows selected.
SQL> l
1* select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss')from sys.smon_scn_time
SQL>
1814619 2015-11-22 16:11:19
1814754 2015-11-22 16:15:55
1814925 2015-11-22 16:21:10
1815105 2015-11-22 16:25:55
SCN TO_CHAR(TIME_DP,'YY
---------- -------------------
1815297 2015-11-22 16:31:19
1629 rows selected.
SQL> l
1* select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss')from sys.smon_scn_time order by scn
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
1815353
SQL>
SQL> select * from (select time_dp, scn, rownum rn from sys.smon_scn_time order by scn desc) where rownum<5;
TIME_DP SCN
RN
--------- ---------- ----------
22-NOV-15 1814229 856
22-NOV-15 1813997 838
22-NOV-15 1813854 855
22-NOV-15 1813722 836
SQL>
3.伪列ORA_ROWSCN
所谓的伪列,就是假的,不存在的数据列,用户创建表时虽然没有指定,但是Oracle
为了维护而添加的一些内部字段,这些字段可以像普通文件那样的使用。
最熟悉的伪列就是ROWID, 它相当于一个指针,指向记录在磁盘上的位置。
ORA_ROWSCN 是Oracle 10g 新增的,暂且把它看作是记录最后一次被修改时的SCN。
Flashback Version Query 就是通过这个伪列来跟踪出记录的变化历史。
举个例子:
SQL> select ora_rowscn, id from f1;
SQL> select ora_rowscn, id from f1;
ORA_ROWSCN ID
---------- ----------
1814158 1
1814158 2
1814158 3
1814158 4
1814158 5
1814158 6
1814158 7
1814158 8
1814158 9
1814158 10
10 rows selected.
SQL>
二、闪回事物(Flashback Transaction Query)
Oracle11g 闪回事务查询就是对过去某段时间内所完成的事务的查询和撤销,通过闪回事
物分析,可以识别在一个特定的时间段内所发生的所有变化,也可以对数据库表进行事物级
恢复。前面提到可以审计一个事务到底做了什么,现在可以获得事务的历史操作进行撤销。
SQL> drop table f2;
Table dropped.
SQL> show recyclebin;
ORIGINAL NAME RECYCLEBIN NAMEOBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
F2 BIN$JR2tyNI8WgfgUAB/AQARUA==$0 TABLE 2015-11-22:16:13:08
SQL>
select id,name,versions_operation,versions_xid,versions_starttime from f2
versions between timestamp minvalue and maxvalue order by id;
三、闪回丢弃(Flashback Drop )
在DROP 表前索引已经被删除从Oracle 10g 开始, 每个表空间都会有一个叫作回收
站的逻辑区域,当用户执行drop 命令时, 被删除的表和表的关联对象( 包括索引, 约束,
触发器,LOB 段,LOB index 段) 不会被物理删除, 这些对象先转移到回收站中,这就给
用户提供了一个恢复的可能。
闪回丢弃是指将被丢弃的数据库对象及其相依对象的拷贝保存在回收站中,以便在必要
时能够及时恢复这些对象。在回收站被清空以前,被丢弃的对象并没有从数据库中删除,这
就使得数据库能够恢复被意外或误操作而删除的表。
回收站:是所有丢弃表及其相依对象的逻辑存储容器。Oracle 回收站将用户所做的
DROP 语句操作记录在一个系统表里,即将被删除的对象写到一个数据字典中,当不再需
要被删除对象时,可以使用PURGE 命令对回收站空间进行清除。
举例说明:
SQL>drop table f2;
查询user_recyclebin 回收站
SQL> select object_name,original_name from user_recyclebin;
OBJECT_NAME ORIGINAL_NAME
------------------------------ --------------------------------
BIN$JR2tyNI8WgfgUAB/AQARUA==$0 F2
SQL>
利用回收站中的记录,使用flashback 恢复表f2
SQL> flashback table f2 to before drop;
Flashback complete.
SQL>
回收站空间清除:
可以使用PURGE 命令清除回收站对象从而释放空间,有以下几种方式:
1、使用PURGE TABLE original_table_name; 这里的original_table_name 表示未drop 以
前的名称
2、使用PURGE TABLE recyclebin_object_name; 这里的recyclebin_object_name 表示回
收站中的对象名称
3、使用PURGE TABLESPACE tablespace_name 从指定的表空间中清除所有的丢弃对象
4、使用PURGE TABLESPACE tablespace_name USER user_name 从回收站中清除属
于某个特定用户的所有丢弃对象。
5、DROP USER user_name cascade 直接删除指定用户及其所属的全部对象,也就是说,
DROP USER 命令会绕过回收站进行直接删除。
6、使用PURGE RECYCLEBIN 命令清除用户自己的回收站
7、PURGE DBA_RECYCLEBIN 从所有用户的回收站清除所有对象
局限性:
闪回丢弃对于如下表不生效:
存放在SYSTEM 表空间上的表;
使用精细审计或虚拟私有数据库
建在字典管理表空间上的表
已经被手工清除或自动清除的表(即表被DROP 后使用了PURGE 操作)
如下依赖对象不受保护:
位图索引
物化视图日志
外键一致性约束
初始化参数recyclebin 用于控制是否启用recyclebin 功能,缺省是ON,可以使用OFF
关闭。
SQL> show parameter recycle
sys用户
NAME TYPEVALUE
------------------------------------ ----------- ------------------------------
buffer_pool_recycle string
db_recycle_cache_size big integer 0
recyclebin
stringon
SQL>
禁用该功能:如果回收站被禁用那么闪回失效 drop的没有了
SQL> alter system set recyclebin=off;
SQL> alter session set recyclebin=off;
SQL> alter session set recyclebin=off;
Session altered.
SQL> drop table f2;
Table dropped.
SQL> flashback table f2 to before drop;
flashback table f2 to before drop
*
ERROR at line 1:
ORA-38305: object not in RECYCLE BIN
SQL>
delete的是有的
禁用后删除的对象将直接删除,不会写到Recycle 中,当然在删除时,指定purge 参数,
表也将直接删除,不会写到recyclebin 中。
SQL> drop table name purge;
查看recyclebin 中的对象列表:
SQL> select * from A;
SQL> drop table A;
表已删除。
SQL> show recyclebin
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ----------------------------- ------------ -------------------
A BIN$RWXQQcTPRde0ws4h9ewJcg==$0 TABLE 2009-10-15:12:44:33
查看recyclebin 中对象:
SQL> select original_name,object_name from recyclebin;
ORIGINAL_NAME OBJECT_NAME
-------------------------------- ------------------------------
A BIN$RWXQQcTPRde0ws4h9ewJcg==$0
查看recyblebin 对象里的内容:
SQL> select * from "BIN$RWXQQcTPRde0ws4h9ewJcg==$0";
表空间的Recycle Bin 区域只是一个逻辑区域,而不是从表空间上物理的划出一块区域
固定用于回收站,因此Recycle Bin 是和普通对象共用表空间的存储区域,或者说是Recycle
Bin 的对象要和普通对象抢夺存储空间。当发生空间不够时,Oracle 会按照先入先出的顺序
覆盖Recycle Bin 中的对象。也可以手动的删除Recycle Bin 占用的空间。
SQL> select original_name,object_name from recyclebin;
ORIGINAL_NAME OBJECT_NAME
-------------------------------- ------------------------------
A BIN$RWXQQcTPRde0ws4h9ewJcg==$0
SQL> flashback table a to before drop;
闪回完成。
SQL> select * from a;
当我们删除表A 后,在新建表A,这时在恢复的时候就会报错,此时我们在闪回时,对表
重命名就可以了:
SQL> drop table a;
表已删除。
SQL> create table a (id number(1));
表已创建。
SQL> flashback table a to before drop ;
flashback table a to before drop
*
第1 行出现错误:
ORA-38312: 原始名称已被现有对象使用
SQL> flashback table a to before drop rename to B;
闪回完成。
SQL> select * from B;
当我们删除表A,在新建表A,在删除它,这是在Recycle Bin 中就会有2 个相同的表明,
此时恢复我们就要指定object_name 才行.
SQL> select * from B;
SQL> drop table B;
表已删除。
SQL> create table B(name varchar(20));
表已创建。
SQL> drop table B;
表已删除。
SQL> select original_name,object_name from recyclebin;
ORIGINAL_NAME OBJECT_NAME
-------------------------------- ------------------------------
B BIN$vYuv+g9fTi2exYP9X2048Q==$0
B BIN$geQ9+NekSjuRvzG+TqDVWw==$0
SQL> flashback table "BIN$vYuv+g9fTi2exYP9X2048Q==$0" to before drop;
闪回完成。
SQL> select * from B;
一旦完成闪回恢复,Recycle Bin 中的对象就消失了. Flashback Drop 需要注意的地方:
1). 只能用于非系统表空间和本地管理的表空间
2). 对象的参考约束不会被恢复,指向该对象的外键约束需要重建。
3). 对象能否恢复成功,取决与对象空间是否被覆盖重用。
4). 当删除表时,信赖于该表的物化视图也会同时删除,但是由于物化视图并不会被放入
recycle bin,因此当你执行flashback table to before drop 时,也不能恢复依赖其的物化视
图,需要dba 手工介入重新创建。
5). 对于Recycle Bin 中的对象,只支持查询.