--=====================================
-- Oracle 闪回特性 (FLASHBACK DATABASE)
--=====================================
闪回技术通常用于快速简单恢复数据库中出现的认为误操作等逻辑错误,从闪回的方式可以分为基于数据库级别闪回、表级别闪回、事务
级别闪回,根据闪回对数据的影响程度又可以分为闪回恢复,闪回查询。闪回恢复将修改数据,闪回点之后的数据将全部丢失。而闪回查询则可
以查询数据被 DML 的不同版本,也可以在此基础之上确定是否进行恢复等。本文主要描述 flashback database 的使用。
一、 flashback database 特性
flashback data1base 闪回到过去的某一时刻
闪回点之后的工作全部丢失
使用 resetlogs 创建新的场景并打开数据库 ( 一旦 resetlogs 之后,将不能再 flashback 至 resetlogs 之前的时间点 )
常用的场景 :truncate table 、多表发生意外错误等
使用闪回日志来实现数据库闪回,闪回点之后的数据将丢失
二、 flashback database 的组成
闪回缓冲区 : 当启用 flashback database, 则 sga 中会开辟一块新区域作为闪回缓冲区 , 大小由系统分配
启用新的 rvwr 进程 :rvwr 进程将闪回缓冲区的内容写入到闪回日志中,注意闪回日志不同于联机重做日志,闪回日志在联机重做日志基础之
上生成,是完整数据块映像的日志。联机日志则是变化的日志。闪回日志不能复用,也不能归档。闪回日志使用循环写方式。
三、 flashback database 的配置
flashback database 要求数据库必须处于归档模式,且闪回之后必须使用 resetlogs 打开数据库
a . 查看数据库的归档模式及闪回是否启用
SQL > select log_mode , open_mode , flashback_on from v$database ;
LOG_MODE OPEN_MODE FLASHBACK_ON
------------ ---------- ------------------
ARCHIVELOG READ WRITE NO --FLASHBACK_ON 为 NO ,则表示闪回特性尚未启用
b . 查看及设置闪回目录、闪回目录空间大小等
-- 下面查看恢复目录及恢复目路分配的大小
-- 可以使用 alter system set db_recovery_file_dest 来设置新路径
-- 可以使用 alter system set db_recovery_file_dest_size 来设定新的大小
SQL > show parameter db_recovery
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest string / u01 / app / oracle / flash_recovery
_area
db_recovery_file_dest_size big integer 2G
c . 设置闪回保留目标生存期
SQL > show parameter db_flashback -- 缺省为分钟,即小时
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_flashback_retention_target integer 1440
SQL > alter system set db_flashback_retention_target = 30 ; -- 设定保留时间为半小时
d . 在 mount 状态下来启用 flashback ,如在 open 状态下则出现下列错误提示
SQL > alter database flashback on ;
alter database flashback on
*
ERROR at line 1 :
ORA - 38759 : Database must be mounted by only one instance and not open .
-- 一致性关闭数据库后,在 mount 状态下设置 flashback
SQL > startup mount exclusive ;
SQL > select status from v$instance ;
STATUS
------------
MOUNTED
SQL > alter database flashback on ; -- 开启闪回数据库功能
SQL > ho ps - ef | grep rvw -- 可以看到新增了后台进程 rvwr
oracle 3563 1 0 12 : 12 ? 00 : 00 : 00 ora_rvwr_orcl
-- 下面查看闪回区分配的大小为大约 M ,闪回分钟以内的数据则需要 M 左右的空间
-- 注意列 oldest_flashback_time 说明了允许返回的最早的时间点
SQL > select oldest_flashback_scn old_flhbck_scn , oldest_flashback_time old_flhbck_tim ,
2 retention_target rete_trgt , flashback_size / 1024 / 1024 flhbck_siz ,
3 estimated_flashback_size / 1024 / 1024 est_flhbck_size
4 from v$flashback_database_log ;
OLD_FLHBCK_SCN OLD_FLHBC RETE_TRGT FLHBCK_SIZ EST_FLHBCK_SIZE
-------------- --------- ---------- ---------- ---------------
915137 24 - OCT - 10 30 7.8125 11.2519531
SQL > select * from v$flashback_database_stat ; -- 查看闪回
BEGIN_TIM END_TIME FLASHBACK_DATA DB_DATA REDO_DATA ESTIMATED_FLASHBACK_SIZE
--------- --------- -------------- ---------- ---------- ------------------------
24 - OCT - 10 24 - OCT - 10 7905280 86802432 96329728 0
SQL > select * from v$sgastat where name like 'flashback%' ; -- 查看 sga 中分配的闪回空间大小
POOL NAME BYTES
------------ -------------------------- ----------
shared pool flashback generation buff 3981204
shared pool flashback_marker_cache_si 9196
SQL > ho ls - hlt $ORACLE_BASE / flash_recovery_area / ORCL / flashback -- 查看生成的闪回日志
total 7.9M
- rw - r ----- 1 oracle oinstall 7.9M Oct 24 12:37 o1_mf_6d7dkogw_.flb
四、使用 flashback database 闪回数据库
步骤 ( 前提归档日志可用 )
关闭数据库
启动数据库到 mount 状态 (exclusive 模式 )
闪回至某个时间点, SCN 或 log sequence number
使用 resetlogs 打开数据库
1. 使用 sqlplus 实现闪回
可以接受一个时间标记或一个系统改变号实参
sqlplus 几种常用的闪回数据库方法
FLASHBACK [STANDBY] DATABASE [<database_name>] TO [BEFORE] SCN <system_change_number> -- 基于 SCN 闪回
FLASHBACK [STANDBY] DATABASE [<database_name>] TO [BEFORE] TIMESTMP <system_timestamp_value> -- 基于时间戳闪回
FLASHBACK [STANDBY] DATABASE [<database_name>] TO [BEFORE] RESTORE POINT <restore_point_name> -- 基于时点闪回
如下面的示例:
SQL > flashback database to timestamp ( '2010-10-24 13:04:30' , 'yyyy-mm-dd hh24:mi:ss' );
SQL > flashback database to scn 918987 ;
SQL > flashback database ro restore point b1_load ;
a . 基于时间戳闪回
SQL > select count ( 1 ) from usr1 . tb1 ; -- 查询用户 usr1 下表 tb1 中的记录数
COUNT ( 1 )
----------
404944
SQL > select to_char ( sysdate , 'yyyy-mm-dd hh24:mi:ss' ) tm from dual ; -- 获得系统当前的时间
TM
-------------------
2010 - 10 - 24 13 : 04 : 30
SQL > drop user usr1 cascade ; -- 删除帐户 usr1 ,同时帐户 usr1 下的所有对象将被删除
SQL > conn scott / tiger ; -- 使用 scott 帐户登陆
SQL > create table tb_emp as select * from emp ; -- 新创建表 tb_emp
SQL > shutdown immediate ; -- 关系系统
SQL > startup mount ; -- 重新到 mount 状态
SQL > flashback database to timestamp -- 实施闪回
2 to_timestamp ( '2010-10-24 13:04:30' , 'yyyy-mm-dd hh24:mi:ss' ) ;
SQL > alter database open resetlogs ;
SQL > select count ( 1 ) from usr1 . tb1 ; -- 帐户 usr1 及其对象 tb1 被成功闪回
COUNT ( 1 )
----------
404944
SQL > select count ( 1 ) from scott . tb_emp ; -- 闪回成功后,在闪回点之后修改的数据全部丢失
select count ( 1 ) from scott . tb_emp
*
ERROR at line 1 :
ORA - 00942 : table or view does not exist
b . 基于 SCN 号闪回
SQL > select current_scn from v$database ; -- 获得当前的 SCN 号
CURRENT_SCN
-----------
918987
SQL > drop table usr1 . tb1 ; -- 删除用户 usr1 下的表 tb1
SQL > alter system checkpoint ; -- 手动执行检查点
SQL > select file# , checkpoint_change# from v$datafile ;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
5 921478
SQL > shutdown abort ;
SQL > startup mount ;
SQL > flashback database to scn 918987 ;
SQL > select count ( 1 ) from usr1 . tb1 ;
COUNT ( 1 )
----------
404944
c . 基于时点闪回
SQL > create table t ( id int , col varchar2 ( 20 )); -- 创建表 t
SQL > insert into t values ( 1 , 'ABC' );
SQL > insert into t values ( 2 , 'DEF' );
SQL > commit ;
SQL > create restore point bef_damage ; -- 创建闪回点
SQL > insert into t values ( 3 , 'GHI' );
SQL > select ora_rowscn , id , col from t ; -- 查看表 t 的记录
ORA_ROWSCN ID COL
---------- ---------- --------------------
1874406 1 ABC
1874406 2 DEF
1874406 3 GHI
SQL > shutdown immediate ;
SQL > startup mount exclusive ;
SQL > flashback database to restore point bef_damage ; -- 实施时点闪回
SQL > alter database open resetlogs ;
SQL > select * from t ; -- 闪回成功后,闪回点之后的数据丢失
ID COL
---------- --------------------
1 ABC
2 DEF
2. 使用 RMAN 进行 flashback database
使用 RMAN 进行闪回数据库的几种常用办法
RMAN > flashback database to scn = 918987 ;
RMAN > flashback database to sequence = 85 thread = 1 ;
SQL > create table scott . tb_emp as select * from scott . emp ;
SQL > select count ( 1 ) from scott . tb_emp ;
COUNT ( 1 )
----------
14
SQL > select to_char ( sysdate , 'yyyy-mm-dd hh24:mi:ss' ) tm from dual ;
TM
-------------------
2010 - 10 - 24 13 : 59 : 38
SQL > drop table scott . tb_emp ;
SQL > shutdown abort ;
SQL > startup mount ;
RMAN > flashback database
2 > to time = "to_date('2010-10-24 13:59:00','yyyy-mm-dd hh24:mi:ss')" ;
SQL > select count ( 1 ) from scott . tb_emp ;
COUNT ( 1 )
----------
14
查询视图: v$recovery_file_dest 将显示闪回区的使用情况
SQL > select name , space_limit / 1024 / 1024 sp_limt
2 , space_used / 1024 / 1024 sp_usd , space_reclaimable / 1024 / 1024 sp_recl ,
3 number_of_files num_fils from v$recovery_file_dest ;
NAME SP_LIMT SP_USD SP_RECL NUM_FILS
--------------------------------------------- ---------- ---------- ---------- ----------
/ u01 / app / oracle / flash_recovery_area 2048 472.070313 380.671875 18
可以将某些表空间排除在闪回之外
SQL > alter tablespace users flashback off ;
SQL > select name , flashback_on from v$tablespace where ts# = 4 ;
NAME FLA
--------------- ---
USERS NO
如果需要对上述表空间启用闪回功能,则需要在 mount 模式下对该表空间进行开启该功能。
五、总结
闪回策略是针对 Oracle 撤销功能的增强,为快速恢复数据库提供了更多的便利。数据库的闪回恢复的速度要快于 RMAN 以及基于用户管理的备份与恢复,其主要原因是因为数据库闪回使用的是闪回日志,而闪回日志中保存的是数据块的完整镜像。其次闪回能够恢复的程度取决于闪回空间的大小以及闪回的保留策略,闪回空间大小会被循环使用,而闪回的保留策略则决定了闪回日志保留的时间长度。总之,合理的平衡恢复速度与可用空间依赖于具体服务要求。
六、 更多参考
有关基于用户管理的备份和备份恢复的概念请参考:
Oracle 基于用户管理恢复的处理 ( 详细描述了介质恢复及其处理 )
有关 RMAN 的恢复与管理请参考:
有关 Oracle 体系结构请参考:
Oracle 实例和Oracle 数据库(Oracle 体系结构)
Oracle 联机重做日志文件(ONLINE LOG FILE)