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小时
所有和恢复相关的文件都可以存放到闪回恢复区。 我们可以通过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
[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)配置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;
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 是从Oracle 10g 开始出现的,用于恢复用户误删除的对象(包括表,索引等),这个技术依赖于Tablespace Recycle Bin(表空间回收站),这个功能和windows的回收站非常类似。(每个表空间都有回收站)
Flashback 不支持sys用户。 system表空间下的对象,也不能从回收站里拿到。故使用SYS 或者SYSTEM用户登陆时, show recyclebin 为空。
Flashback Drop 是基于TablespaceRecycleBin 来实现恢复的。它只支持闪回与table相关连的对象,比如表,索引,约束,触发器等。 如果是函数或者存储过程等,就需要使用Flashback Query来实现。
禁用后删除的对象将直接删除,不会写到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;
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 是利用多版本读一致性的特性从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_*,all_*,user_*
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.
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也是使用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;
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
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