Oracle闪回技术详解

1. 概述

闪回技术是Oracle备份恢复机制的一部分,主要解决逻辑错误的恢复问题,无法解决物理损坏造成的故障。在实际工作中更多的用在开发及测试阶段,生产环境下要谨慎使用。

2. 闪回类型及原理

闪回类型原理
flashback drop 闪回删除RECYCLEBIN 回收站
flashback query 闪回查询UNDO 数据
flashback table 闪回表UNDO 数据
flashback version query 闪回版本查询UNDO 数据
flashback transaction 闪回事务UNDO 数据
flashback data archive 闪回归档Archive Log 归档
flashback database 闪回数据库Flashback Database Log 闪回日志

3. 闪回删除

3.1. 回收站

Oracle 从10g开始引入了回收站(RECYCLEBIN)的概念。它实际上是一个逻辑容器,没有固定的物理存储空间,与表空间中的对象公用物理存储空间。因此,当表被 DROP 后,如果表空间空间充足,且没有对回收站进行清理,那么被 DROP 掉的对象会一直保存在回收站中(有点类似于数据库使用中常用到的逻辑删除,只是打上了删除标记)。当表空间空间不足的时候,数据库会根据先进先出的顺序覆盖回收站中的对象,需要注意的是,这种覆盖是以对象为单位的,不存在部分对象的情况。

该功能由初始化参数 recyclebin 控制,当值为 on 时开启,值为 off 时关闭,默认值为 on

show parameter recyclebin

3.2. 回收站中对象的操作

对回收站中的对象可以进行闪回和清除操作,需要注意的是闪回和清除的顺序不同:

  • 闪回使用 LIFO (后进先出)
  • 清除使用 FIFO (先进先出)

3.3. 示例

闪回操作

-- 可以直接通过回收站中的名字进行查询,确认是否是需要的数据
select count(*) from "BIN$nBW14MjkYtzgUxUJqMBbHw==$0";
-- 确认是需要的数据的时候可以将回收站中的对象恢复
flashback table t1 to before drop;

在这里插入图片描述
清除操作

-- 清除后将无法再恢复
purge table t1;

在这里插入图片描述

3.4 相关操作及注意事项

如果想避免混淆,可以直接指定回收站中的表名:

flashback table "BIN$fNCNfmfYwQLgU8kKqMCzLA==$0" to before drop;
purge table "BIN$fNCNfmfYwQLgU8kKqMCzLA==$0";

清空回收站

purge recyclebin;

把闪回删除的对象重命名

flashback table "BIN$fNCNfmfYwQLgU8kKqMCzLA==$0" to before drop rename to t3;

system 表空间的对象没有回收站, sys 缺省使用 system 表空间,drop table 时会直接删除对象。

索引和约束在恢复后,名称会乱码,需要手动修改名称

select * from user_indexes;
select * from user_constraints;
alter index "BIN$yF3hbvIbioTgQAB/AQAJlg==$0" rename to t1_indx;
alter table t1 rename constraint "BIN$yF3hbvIbioTgQAB/AQAJlg==$0" to t1_pk;

4. 闪回查询

4.1. 作用

适用于 DML 误操作。利用 UNDO 里未被覆盖的数据,可以查询表的过去某个时间点的数据。通过设置 undo_retention 参数,可以控制前镜像的保留时间。

4.2. 语法

selectas of scn | timestamp;

4.3. 示例

-- 准备数据
create table t1 as select * from jobs;
-- 这是  t1 表开始时的数据,共19条数据
select * from t1;

在这里插入图片描述

-- 记录开始时刻(SCN 1)
select current_scn from v$database;
select to_char(sysdate,'YYYY-MM-DD HH24:MI:SS') n_time from dual;

在这里插入图片描述

-- 删除一些数据
delete t1 where job_id like 'AD%';
commit;

在这里插入图片描述

-- 记录了删除数据后的时刻,此时剩余16条数据(SCN 2)
select current_scn from v$database;
select to_char(sysdate,'YYYY-MM-DD HH24:MI:SS') n_time from dual;

在这里插入图片描述

-- 将 min_salary 列全部改为了 10000
update t1 set min_salary=10000;
commit;
-- 现在看到的是最终数据
select * from t1;

在这里插入图片描述

-- 查询到最开始时的数据(SCN 1)
select * from t1 as of scn 4496826;
select * from t1 as of timestamp to_timestamp('2020-01-14 16:17:26','YYYY-MM-DD HH24:MI:SS');

在这里插入图片描述

-- 查询到执行过删除,尚未进行更新时的数据(SCN 2)
select * from t1 as of scn 4496868;
select * from t1 as of timestamp to_timestamp('2020-01-14 16:18:36','YYYY-MM-DD HH24:MI:SS');

在这里插入图片描述

总结

通过该示例我们可以发现,只要 UNDO 数据不被覆盖,我们可以闪回查询到过去任意时刻的数据,这对于人为误操作的处理极为有用。

5. 闪回表

5.1. 作用

闪回表可以把表的状态闪回到某个时刻或者 SCN 上,既可以向前闪回,还可以向后闪回(闪回到的时刻早了)。该技术必须对表启用行移动。

5.2. 语法

-- 是能行移动
alter table tablename enable row movement;
flashback table tablename to scn | timestamp;

5.3. 示例

该示例数据接上一个 4.3 的示例

-- 将 t1 表的数据全部删除并使能行移动
delete t1;
commit;
alter table t1 enable row movement;

在这里插入图片描述

-- 闪回表到最初时刻
flashback table t1 to timestamp to_timestamp('2020-01-14 16:17:26','YYYY-MM-DD HH24:MI:SS');
select * from t1 ;

在这里插入图片描述

-- 将表 t1 闪回到 SCN2 的时刻,也就是删除过3行数据后的时刻
flashback table t1 to timestamp to_timestamp('2020-01-14 16:18:36','YYYY-MM-DD HH24:MI:SS');
select * from t1 ;

在这里插入图片描述

-- 将表 t1 闪回到删除前的时刻,也就是上一个示例最终的时刻
flashback table t1 to timestamp to_timestamp('2020-01-14 16:40:36','YYYY-MM-DD HH24:MI:SS');
select * from t1 ;

在这里插入图片描述

总结

把表闪回到过早的时刻后,还可以向后闪回。闪回表直接操作了表数据,生产环境谨慎使用

5.4. 注意事项

  • sys 的表不能闪回;
  • 必须使能行移动;
  • 缺省下,闪回表的过程中有关的 trigger 都关闭(可以使用 ENABLE TRIGGERS 关键字指定触发器有效);
  • 闪回表 index 是被维护的;
  • 表结构不能改变;
  • 物化视图、远程表、系统表、单个分区等特殊的表不能进行闪回;

6. 闪回版本查询

6.1. 作用

闪回版本查询可以对指定时间段内数据表的每行变化(不同版本)进行查询。如果想要获得 UNDO SQL(闪回事务查询),则需要开启附加日志

6.2. 语法

selectfrom … versions betweenand-- select 后面可以选择伪列,来获得事务的开始、结束时间,SCN 号、ID 号等。

6.3. 示例

-- 开启附加日志,为闪回事务查询做准备
alter database add supplemental log data;

-- 准备数据
create table t2 as select * from regions;
select * from t2;

在这里插入图片描述

-- 对数据进行一系列操作
delete t2 where region_id=1;
commit;
update t2 set region_name='CHINA' where region_id=3;
commit;
update t2 set region_id=region_id+100;
commit;

-- 闪回版本查询
select versions_startscn,versions_endscn,versions_xid,versions_operation,region_id,region_name from t2 versions between scn minvalue and maxvalue;

在这里插入图片描述
Oracle 闪回版本查询行数据伪列说明(官方文档)
在这里插入图片描述

7. 闪回事务查询

7.1. 作用

闪回事务查询可以提供撤销查询语句。从 flashback_transaction_query 这个视图里查询引起数据变化的事务,和撤销事务的 SQL 语句,也就是查询 operation 和 undo_sql 列。可以和闪回版本查询结合起来使用。

7.2. 示例

desc flashback_transaction_query;
 
SELECT undo_sql FROM flashback_transaction_query WHERE xid = HEXTORAW('0A001C00260F0000');

在这里插入图片描述执行上面的语句,原操作(update t3 set id=id+100;)就撤销了

7.3. 注意事项

  • 需要开启附加日志(alter database add supplemental log data;)
  • 查询 flashback_transaction_query 视图需要 select any transaction 权限

8. 闪回数据归档

8.1. 作用

闪回查询对 UNDO 的依赖注定了它们在大事务量的情况下闪回时间窗口将会很小,如果想要对重点表的数据进行长时间的闪回查询,就要用到闪回数据归档技术。闪回数据归档可以将表行的历史数据长期存储起来。它通过后台进程 FBDA ,捕捉必要的数据并将其保存在归档上,然后可以使用常规闪回查询命令( as of )查询需要的数据,可以看作是闪回查询的延伸。

8.2. 要点

  • 要有一个(或多个)表空间存放归档表,使用与原表同一表空间在技术上是可行的,但是 Oracle 建议他们与常规数据分开存放。
  • 建立一个归档名,作为一个数据库的对象,可以为它指定 default 属性,含义是把所以后要归档的表都建立在该缺省的归档名下。
  • 可以根据需要建立多个闪回归档名,这取决于你需要多少种不同的保留时间,一旦超过保留期限,后台进程 FDBA 将自动删除该表的历史记录,也可以在保留期内手动进行删除操作。
  • 闪回归档 enable 的前提条件,表空间要 ASSM 管理,undo_management=auto。

相关权限

权限名权限作用
flashback archive administer授予用户创建、修改和删除闪回归档名的权限
flashback archive授予用户对表进行归档的权限

相关视图

视图名视图说明
DBA_FLASHBACK_ARCHIVE描述配置的归档
DBA_FLASHBACK_ARCHIVE_TS列出使用的表空间
DBA_FLASHBACK_ARCHIVE_TABLES查看归档的表

语法格式

-- 需要首先创建归档表空间和归档,此处的归档名是指创建号的归档的名称
alter table 表名 flashback archive 归档名;

8.3. 示例

-- DBA 创建表空间,创建闪回归档并授权
create tablespace fda datafile '/oradata/ORA19C/pamsdb/fda01.dbf' size 50M;
create flashback archive fla1 tablespace fda retention 1 year;
grant flashback archive on fla1 to hr;

-- 用户为自己的表开启闪回归档,这样 T2 表上的闪回数据就会在表空间 fda 上保存一年的时间
alter table t2 flashback archive fla1;

在这里插入图片描述

-- 查看相关视图,通过查询以下视图,可以获得当前的闪回数据归档情况
select * from dba_flashback_archive;
 
select * from dba_flashback_archive_ts;
 
select * from dba_flashback_archive_tables;

在这里插入图片描述

-- 取消闪回数据归档。当不需要的时候可以取消闪回数据归档
alter table scott.emp no flashback archive;

总结

闪回数据归档是典型的以空间换容错的技术,如果某表数据特别重要,为了防止人为逻辑故障的发生,可以对该表进行闪回数据归档,但绝不建议对大多数表进行闪回数据归档,因为会产生大量的额外空间及性能开销。

9. 闪回数据库

9.1. 作用

闪回数据库可以将数据库整体回退到某个时间点(是不是跟 RMAN 做不完全恢复很像,但是不一样哦)。闪回数据库针对的是逻辑错误,如果数据库发生了物理损坏,闪回数据库将无能为力。
闪回数据库需要用到闪回日志,闪回日志存放在闪回恢复区。开启闪回日志后,某些块的映像会从 db buffer 中复制到闪回缓冲区,然后再由后台进程( Recover Write RVWR )将此闪回恢复区的内容刷新到磁盘的闪回日志。与重做日志不同的是闪回日志不是记录的数据库所有变化,而是记录完整块映像的记录。

9.2. 闪回恢复区

闪回恢复区( flash recovery area )是从 10g 版本引入的一个非常重要的概念,它不仅存放闪回日志,还有许多与恢复相关的文件。
例如可以存放与 RMAN 相关的三种自动管理的文件:

  • 归档日志
  • 控制文件自动备份
  • RMAN 备份片

当 flash recovery area 空间不够时,Oracle 还可以自动清除一些废弃( obsolete )文件。

相关参数

show parameter db_recovery_file_dest
show parameter db_flashback_retention_target

在这里插入图片描述

设置 db_recovery_file_dest 之前必须先设置 db_recovery_file_dest_size ;
db_flashback_retention_target 用来设置闪回日志的保留期,默认值 1440 ,单位是分钟。

9.3. 开闪回

-- 查看是否开启闪回数据库
select flashback_on from v$database;
 
-- 创建目录、赋予权限
$ mkdir /oradata/flash_recovery_area
$ ls -ld /oradata/flash_recovery_area

-- 修改初始化参数,生产环境一定要注意,db_recovery_file_dest_size 必须根据实际情况设置的足够大
alter system set db_recovery_file_dest_size=4G;
alter system set db_recovery_file_dest='/oradata/flash_recovery_area';
show parameter db_recovery_file_dest
show parameter db_flashback_retention_target

-- 开闪回。开闪回之前要开归档
archive log list
alter database flashback on;

select flashback_on from v$database;

9.4. 示例

-- 取当前 SCN,作为闪回目标
select current_scn from v$database;
select to_char(sysdate,'YYYY-MM-DD HH24:MI:SS') n_time from dual;
 
-- 也可以创建一个还原点
create restore point rp1;
 
-- 删除 hr 用户
drop user hr cascade;
 
-- 启动到 mount 下做闪回数据库
shut immediate
startup mount

-- 闪回到 rp1 闪回点
flashback database to restore point rp1;
-- 或者也可以用 SCN 或者 timestamp 闪回
flashback database to scn 2802872;
flashback database to timestamp to_timestamp('2020-01-14 17:16:16', 'YYYY-MM-DD HH24:MI:SS');

-- 只读方式打开,确认 hr 已经被闪回
alter database open read only;
select table_name from dba_tables where owner='HR';
select open_mode from v$database;
 
-- 确认无误后,以 resetlogs 方式打开数据库
shut immediate
startup mount
alter database open resetlogs;
select open_mode from v$database;
-- 一旦 resetlogs 打开,只能闪回到比当前更早的 SCN。
-- 所以闪回后,第一次最好以只读方式打开,检查是否恢复到你希望的那个时间点上。如果不是你希望的,还可以重新闪回(前闪/后闪都可以)。
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值