一、什么是Flashback?
Flashback 技术是oracle 9i中引入的一种技术,通过闪回,我们可以查到过去某个时刻的一致性数据。
这里的一致性,是通过我们UNDO 表空间的前镜像来实现的。 因为闪回与UNDO 表空间密切相关。
比如UNDO 表空间的大小,保留策略。如果undo 被覆盖了就不能进行闪回查询。
?
undo_management参数:
[oracle@testrac1 ~]$ orz param undo
NAME??????????????????????????ISDEFAULT? SESMOD???? SYSMOD????VALUE
------------------------------ ---------- ---------- ------------------------------------------------------------
undo_management??????????????? FALSE????? FALSE?????FALSE????? AUTO
undo_tablespace???????????????FALSE????? FALSE????? IMMEDIATE?UNDOTBS1
undo_retention????????????????FALSE????? FALSE????? IMMEDIATE?1800
——undo_retention控制undo的保留时间,单位:秒,一般建议设为3600,即1小时
?
二、闪回恢复区(flash recovery area)
1. 如何查看闪回恢复区里包含的内容
所有和恢复相关的文件都可以存放到闪回恢复区。 我们可以通过v$flash_recovery_area_usage视图来查看。
?
SQL> select file_type fromv$flash_recovery_area_usage;
FILE_TYPE
------------------------------------
CONTROLFILE
ONLINELOG
ARCHIVELOG
BACKUPPIECE
IMAGECOPY
FLASHBACKLOG
?
6 rows selected.
?
上面视图中查询的结果列出的所有类型的文件,都可以利用闪回恢复区来存放、管理。
?
[oracle@testrac1 ~]$ orz desc v$controlfilesys
?Name?????????????????????????????????????Null???? Type
?------------------------------------------------- ----------------------------
?STATUS????????????????????????????????????????????VARCHAR2(7)
?NAME??????????????????????????????????????????????VARCHAR2(513)
?IS_RECOVERY_DEST_FILE????????????????????????? VARCHAR2(3)? --可看出控制文件可以闪回
?BLOCK_SIZE??????????????????????????????????????? ?NUMBER
?FILE_SIZE_BLKS???????????????????????????????????? NUMBER
2.设置FRA 参数
[oracle@dave ~]$ orz param db_recover
NAME?????????????????????????????????? ISDEFAULT ? SESMO ? SYSMOD ???????? VALUE
---------------------------- --------- ----- ---------------------------------------------
db_recovery_file_dest ??? ??FALSE ???????? FALSE??? IMMEDIATE ?/u01/app/oracle/fast_recovery_area
db_recovery_file_dest_size FALSE ????????????????? FALSE??? IMMEDIATE ?1018937856
这2个参数就是控制闪回恢复区的。在我们创建实例的时候,就配置的选项。
?
创建数据库的时候,归档路径默认为FRA,若之后开启归档,并没有修改FRA大小,有一天数据库会因为FRA满了而导致数据库hang住。
所以建议修改归档路径。
?
解决FRA因撑满导致数据库hang住:
1、进rman删除文件
(1). delete obsolete;
(2). crosscheck backupset;
delete expired backupset;
RMAN> delete archivelog;
?
2、增加FRA空间,修改db_recovery_file_dest_size
SQL> ALTER SYSTEM SETdb_recovery_file_dest_size=3g SCOPE=BOTH;
System altered.
SQL> ALTER SYSTEM SETdb_recovery_file_dest='/u01/flashback' SCOPE=BOTH;
System altered.
?
问题1:这里我们修改这2个参数,需不需要重启实例?
不需要重新启动实例
?
问题2:能否停止闪回恢复区?
可以,将db_recovery_file_dest改为空即可.
SQL>alter system set db_recovery_file_dest='';
?
三、Flashback Database
1.如何启用和禁用Flashback Database
数据库的Flashback Database功能缺省是关闭的,要想启用这个功能,就需要做如下配置。
(1)配置Flash Recovery Area
(2)启动flashback database
默认情况数据库的flashback database是关闭,可以在mount exclusive状态下打开。在设置了闪回恢复区后,可以启动闪回数据库功能。
?
开启flashbackdatabase
--数据库必须已经处于归档模式:
SQL> archive log list;
SQL> shutdown immediate;
SQL> startup mount;
SQL> alter database archivelog;
SQL> alter database flashback on;
SQL> alter database open;
SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------
YES
?
关闭flashback database步骤同开启
SQL> alter database flashback off;
?
2. 使用Flashback Database 实现对数据库进行不完全恢复的示例
SQL> Flashback database to timestamp to_timestamp('09-10-1414:37:05','yy-mm-dd hh24:mi:ss');
闪回完成。
或者:
SQL> Flashback database to scn 947921;
闪回完成。
【实验过程】建立测试表,并闪回到相应时间点
SQL> SELECT CURRENT_SCN FROM V$DATABASE;
CURRENT_SCN
-----------
???? 947921
?
SQL> Create table dave as select * fromdba_objects;
SQL> Select count(*) from dave;
COUNT(*)
----------
???? 49747
?
--启动到mount状态
SQL> shutdown immediate
SQL> startup mount
Flashback Database 实际是对数据库的一个不完全恢复操作,
?
SQL> Flashback database to timestampto_timestamp('09-10-14 14:37:05','yy-mm-dd hh24:mi:ss');
--或者:
SQL> Flashback database to scn 947921;
?
SQL> alter database open resetlogs;
?
--验证
SQL> SELECT count(*) from dave;
SELECT count(*) from dave
???????????????? *
ERROR at line 1:
ORA-00942: table or view does not exist
?
?
在执行完flashback database 命令之后,oracle 提供了两种方式让你修复数据库:
1). 直接alter database openresetlogs?打开数据库,当然,指定scn 或者timestamp 时间点之后产生的数据统统丢失。
2). 先执行alter databaSEOpen read only?命令,以read-only 模式打开数据库,然后立刻通过逻辑导出的方式将误操作涉及表的数据导出,再执行recover database 命令以重新应用数据库产生的redo,将数据库修复到flashback database 操作前的状态,然后再通过逻辑导入的方式,将之前误操作的表重新导入,这样的话对现有数据的影响最小,不会有数据丢失。
SQL> alter database open resetlogs;
SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-01589: must use RESETLOGS orNORESETLOGS option for database open
?
?
四、Flashback Drop
Flashback Drop 是从Oracle 10g 开始出现的,用于恢复用户误删除的对象(包括表,索引等),这个技术依赖于Tablespace Recycle Bin(表空间回收站),这个功能和windows的回收站非常类似。(每个表空间都有回收站)
Flashback?不支持sys用户。 system表空间下的对象,也不能从回收站里拿到。故使用SYS 或者SYSTEM用户登陆时, show recyclebin 为空。
Flashback Drop 是基于TablespaceRecycleBin 来实现恢复的。它只支持闪回与table相关连的对象,比如表,索引,约束,触发器等。 如果是函数或者存储过程等,就需要使用Flashback Query来实现。
1.查看回收站内容
禁用后删除的对象将直接删除,不会写到Recycle中,当然在删除时,指定purge参数,表也将直接删除,不会写到recyclebin中。
?
SQL> show recyclebin
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ----------------------------- ------------
A BIN$RWXQQcTPRde0ws4h9ewJcg==$0 TABLE 2009-10-15:12:44:33
--只要表空间空间够drop的表就会存在在回收站中。
?
--注意recyclebin需要打开
[oracle@testrac1 ~]$ orz param recycle
NAME??????????????????????????ISDEFAULT? SESMOD???? SYSMOD????VALUE
------------------------------ ---------- ---------- ------------------------------------------------------------
db_recycle_cache_size?????????TRUE?????? FALSE????? IMMEDIATE?0
buffer_pool_recycle???????????TRUE?????? FALSE????? FALSE
recyclebin???????????????????? FALSE????? TRUE??????IMMEDIATE? ON
?
--查看recyclebin中对象:
SQL> select original_name,object_name from recyclebin;
ORIGINAL_NAME OBJECT_NAME
-------------------------------- ------------------------------
A BIN$RWXQQcTPRde0ws4h9ewJcg==$0
?
--查看recyblebin对象里的内容:
SQL> select * from "BIN$RWXQQcTPRde0ws4h9ewJcg==$0";
?
--查看当前用户所drop的对象(里面有对象之前的名字和drop之后的名字)
select * from user_recyclebin;
select * from recyclebin;
?
--查看所有用户drop掉的对象:
select * from dba_recyclebin;
?
【实验】Flashback Drop 实例操作(在非sys用户下操作):
SQL> create table dba as select * fromall_users;
Table created.
?
SQL> drop table dba;
Table dropped.
?
SQL> show recyclebin
ORIGINAL NAME??? RECYCLEBINNAME??????????????? OBJECT TYPE? DROP TIME
---------------- ------------------------------ -------------------------------
DBA?????????????BIN$5GK6ipOINnHgQwc4qMBi6g==$0 TABLE??????? 2013-08-20:22:18:19
?
--查看recyblebin对象里的内容:
SQL> select * from"BIN$5GK6ipOINnHgQwc4qMBi6g==$0";
USERNAME?????????????????????????USER_ID CREATED
------------------------------ ---------- ---------
RMAN??????????????????????????????????91 04-JUL-13
BI????????????????????????????????????89 03-JUL-13
PM????????????????????????????????????88 03-JUL-13
SH????????????????????????????????????87 03-JUL-13
IX????????????????????????????????????86 03-JUL-13
OE????????????????????????????????????85 03-JUL-13
HR????????????????????????????????????84 03-JUL-13
SCOTT?????????????????????????????????83 17-SEP-11
OWBSYS????????????????????????????????78 17-SEP-11
APEX_030200???????????????????????????77 17-SEP-11
APEX_PUBLIC_USER??????????????????????75 17-SEP-11
……….
?
37 rows selected.
?
SQL> flashback table dba to before drop;?????? 非sys用户
Flashback complete.
?
SQL> select count(*) from dba;
? COUNT(*)
----------
??????? 37
?
将dba drop后再建,再drop
Drop table dba;
Create table dba as select * from all_objects;
SQL> select count(*) from dba;
?
? COUNT(*)
----------
?????? 103
Drop table dba;
SQL> show recyclebin
ORIGINAL NAME??? RECYCLEBINNAME??????????????? OBJECT TYPE? DROP TIME
---------------- ------------------------------ -------------------------------
DBA?????????????BIN$5GK6ipOTNnHgQwc4qMBi6g==$0 TABLE??????? 2013-08-20:22:22:19
DBA?????????????BIN$5GK6ipOQNnHgQwc4qMBi6g==$0 TABLE??????? 2013-08-20:22:21:29
DBA?????????????BIN$5GK6ipOMNnHgQwc4qMBi6g==$0 TABLE??????? 2013-08-20:22:20:59
SQL> flashback table dba to before drop;
?
Flashback complete.
?
SQL> show recyclebin
ORIGINAL NAME??? RECYCLEBINNAME??????????????? OBJECT TYPE? DROP TIME
---------------- ------------------------------ -------------------------------
DBA?????????????BIN$5GK6ipOQNnHgQwc4qMBi6g==$0 TABLE??????? 2013-08-20:22:21:29
DBA?????????????BIN$5GK6ipOMNnHgQwc4qMBi6g==$0 TABLE??????? 2013-08-20:22:20:59
SQL> select count(*) from dba;
?
? COUNT(*)
----------
?????? 103
?
SQL> flashback table dba to before drop;
flashback table dba to before drop
*
ERROR at line 1:
ORA-38312: original name is used by an existing object
?
?
SQL> drop table dba purge;
?
Table dropped.
?
SQL> show recyclebin
ORIGINAL NAME??? RECYCLEBINNAME??????????????? OBJECT TYPE? DROP TIME
---------------- ------------------------------ -------------------------------
DBA?????????????BIN$5GK6ipOQNnHgQwc4qMBi6g==$0 TABLE??????? 2013-08-20:22:21:29
DBA?????????????BIN$5GK6ipOMNnHgQwc4qMBi6g==$0 TABLE??????? 2013-08-20:22:20:59
SQL> flashback table dba to before drop;
?
Flashback complete.
?
SQL> select count(*) from dba;
?
? COUNT(*)
----------
??????? 37
?
?
SQL> create table a as select * from all_users;
Table created.
?
SQL> select count(*) from a;
?
? COUNT(*)
----------
??????? 37
?
SQL> drop table a;
?
Table dropped.
?
SQL> show recyclebin
ORIGINAL NAME??? RECYCLEBINNAME??????????????? OBJECT TYPE? DROP TIME
---------------- ------------------------------ -------------------------------
A????????????????BIN$5GNKYhWvP8HgQwc4qMCkUQ==$0 TABLE???????2013-08-20:22:58:32
DBA??????????????BIN$5GK6ipOMNnHgQwc4qMBi6g==$0 TABLE???????2013-08-20:22:20:59
?
回收站名称:BIN$unique_id$version?? e.g.BIN$5GK6ipOMNnHgQwc4qMBi6g==$0
其中BIN代表RecycleBin,unique_id是数据库中该对象的唯一标志,26个字符长度,version表示该对象的版本号.
?
回收站会自动清空
手工清空:
1). Purge tablespace tablespace_name : 用于清空表空间的RecycleBin
2). Purge tablespace tablespace_name useruser_name: 清空指定表空间的Recycle Bin中指定用户的对象
3). Purge recyclebin: 删除当前用户的RecycleBin中的对象
4). Purge dba_recyclebin: 删除所有用户的RecycleBin中的对象该命令要sysdba权限
?
--system级别:
10g:
alter system set recyclebin=off;
alter system set recyclebin=on;
11g:
alter system set recyclebin=off deferred;
alter system set recyclebin=on deferred;
?
执行10g的语句会报错
SQL> alter system set recyclebin=off;
alter system set recyclebin=off
????????????????????????????? *
ERROR at line 1:
ORA-02096: specified initialization parameter is not modifiable with this
Option
?
SQL> select distinctISSYS_MODIFIABLE? from? v$parameter;
?
ISSYS_MOD
---------
IMMEDIATE????????????? --立即生效
FALSE?????????????????????????? --false:表示是静态参数,只要当instance重新启动时才会生效;
DEFERRED???????????????? --延时。表示修改后要等下一个session才能生效,修改时已经连接的session是不会生效的.
?
五、Flashback Query
Flashback Query 是利用多版本读一致性的特性从UNDO?表空间读取操作前的记录数据。
flashback query对v$tables,x$tables等动态性能视图无效,但对于dba_*,all_*,user_*等数据字典是有效的。
该特性也完全支持访问远端数据库,比如select* from tbl@dblink as of scn 3600;的形式。
不同的事务在写数据时,会将数据的前映像写入undo表空间,这样如果同时有其它事务查询该表数据,则可以通过undo 表空间中数据的前映像来构造所需的完整记录集,而不需要等待写入的事务提交或回滚。
通过flashback query 查询undo 中的撤销数据,最简单的方式只需要在标准查询语句的表名后面跟上as of timestamp(基于时间)或as of scn(基于scn)即可。
as oftimestamp|scn 的语法是自9iR2 后才开始提供支持。
?
闪回查询是基于undo的,很重要,必须会!
1. 对业务表没有问题
2. dba_*,user_*
?
1.用来恢复表对象
SQL> conn scott/scott
Connected.
?
SQL> create table fra as select * fromdba_objects;
Table created.
?
SQL> alter session setnls_date_format='yyyy-mm-dd hh24:mi:ss';
Session altered.
?
SQL> select sysdate from dual;
SYSDATE
-------------------
2013-08-20 23:35:16
?
SQL> select count(*) from fra;
? COUNT(*)
----------
???? 75470
?
SQL> delete fra;
75470 rows deleted.
?
SQL> commit;
Commit complete.
?
--闪回查询
SQL> select count(*) from fra as oftimestamp to_timestamp('2013-08-20 23:35:16','YYYY-MM-DD hh24:mi:ss');
? COUNT(*)
----------
???? 75470
?
--插入原表
SQL> insert into fra select * from fra as oftimestamp to_timestamp('2013-08-20 23:35:16','YYYY-MM-DD hh24:mi:ss');
75470 rows created.
?
2.Flashback Query 函数,存储过程,包,触发器等对象
Flashback Drop 可以闪回与表相关联的对象, 如果是其他的对象,比如function,procedure,trigger等。 这时候,就需要使用到ALL_SOURCE?表来进行FlashbackQuery。
?
可以使用Flashback Query的类型:
SQL> select distinct TYPE from dba_source;
TYPE
--------------------
PROCEDURE
PACKAGE
PACKAGE BODY
TYPE BODY
TRIGGER
FUNCTION
TYPE
?
基于timestamp恢复的语句
SQL> SELECT?text
FROM?dba_source
AS?OF?TIMESTAMP?TO_TIMESTAMP?('XXXXX',?'YYYY-MM-DD?HH24:MI:SS')
WHERE?owner?=?'XXXX'?AND?name?=?'你删除的对象名'
ORDER?BY?line;
?
Flashback Query:
1. 用来恢复表对象
2. dba_source 里的类型
?
六、Flashback Table
Flashback Table也是使用UNDO tablespace的内容来实现对数据的回退。该命令相对简单,输入:flashback table table_name to scn(to timestamp)即可。
?
注意:如果想要对表进行flashback,必须允许表的row movement.
SQL>Alter table table_name enable row movement;
?
要查看某表是否启用row movement,可以到user_tables 中查询(或all_tables,dba_tables).
例如:
SQL> select row_movement from user_tableswhere table_name='C';
ROW_MOVE
--------
ENABLED
?
要启用或禁止某表row movement,可以通过下列语句:
--启用
SQL> ALTER TABLE table_name?ENABLE?ROWMOVEMENT;
--禁止
SQL> ALTER TABLE table_name?DISABLE?ROW MOVEMENT;
?
1.Flashback 单个 table
SQL> alter table c enable row movement;
表已更改。
SQL> flashback table c?to scn1103864;
闪回完成。
或者
SQL> flashback table c?to timestampto_timestamp('2012-10-15 21:17:47','yyyy-mm-dd hh24:mi:ss');
?
【实验】
SQL> create table sharon as select * fromall_users;
Table created.
?
SQL> select row_movement from user_tableswhere table_name='SHARON';
ROW_MOVE
--------
DISABLED
?
SQL> alter table sharon enable row movement;
Table altered.
?
SQL> select row_movement from user_tableswhere table_name='SHARON';
ROW_MOVE
--------
ENABLED
?
SQL> alter session setnls_date_format='yyyy-mm-dd hh24:mi:ss';
Session altered.
?
SQL> select sysdate from dual;
SYSDATE
-------------------
2013-08-22 10:47:58
?
SQL> delete from sharon;
92 rows deleted.
?
SQL> commit;
Commit complete.
?
SQL> select count(*) from sharon;
? COUNT(*)
----------
???????? 0
?
SQL> flashback table sharon to timestampto_timestamp('2013-08-22 10:47:58','yyyy-mm-dd hh24:mi:ss');
Flashback complete.
?
SQL> select count(*) from sharon;
? COUNT(*)
----------
??????? 92
2.Flashback 多个table
Flashback table 命令支持同时操作多个表,表名中间以逗号分隔即可,如果你执行一条flashback table命令时同时指定了多个表,要记住单个flashback table 是在同一个事务中,因此这些表的恢复操作要么都成功,要么都失败。
如:
SQL> flashback table a,b,c to scn1103864;
?
SQL> create table a as select * fromall_users;
Table created.
SQL> create table b as select * fromall_users;
Table created.
?
SQL> select row_movement,table_name fromuser_tables;
ROW_MOVE TABLE_NAME
-------- ------------------------------
DISABLED A
ENABLED? SHARON
DISABLED B
DISABLED SYS_TEMP_FBT
?
SQL> alter table a enable rowmovement;??
Table altered.
SQL> alter table b enable row movement;
Table altered.
?
SQL> select row_movement,table_name fromuser_tables;
ROW_MOVE TABLE_NAME
-------- ------------------------------
ENABLED? A
ENABLED? SHARON
ENABLED? B
DISABLED SYS_TEMP_FBT
?
SQL> select to_char(current_scn) fromv$database;
TO_CHAR(CURRENT_SCN)
----------------------------------------
10341953120
?
SQL> delete from a;
92 rows deleted.
SQL> delete from b;
92 rows deleted.
?
SQL> select * from a;
no rows selected
SQL> select * from b;
no rows selected
?
SQL> flashback table a,b to scn10341953120;???????????????????????????????
Flashback complete.
?
SQL> select count(*) from a;
? COUNT(*)
----------
??????? 92
SQL> select count(*) from b;
?
? COUNT(*)
----------
??????? 92