一、了解闪回
1.1 什么是闪回
通常我们对数据库进行了误操作时, 需要把数据库Rollback到之前的版本。
一个常用的方法就是使用日志来进行数据库恢复。
这个方法虽然强大有效, 但是花费时间等成本高。
例如当我们只是误提交了1个delete语句, 丢失了删除行的数据时, 如果我们执行数据库恢复的话, 就需要断开当前所有server processes, 甚至需要关闭数据库,相当于暂停了所有的生产活动。
而且使用日志恢复的话, 还往往需要相当长的时间(取决于备份文件的复制时间和日志的应用时间)。
闪回技术是Oracle强大数据库备份恢复机制的一部分,在数据库发生逻辑错误的时候,闪回技术能提供快速且最小损失的恢复(多数闪回功能都能在数据库联机状态下完成)。需要注意的是,闪回技术旨在快速恢复逻辑错误,对于物理损坏或是介质丢失的错误,闪回技术就回天乏术了,还是得借助于Oracle一些高级的备份恢复工具如RAMN去完成(这才是Oracle强大备份恢复机制的精髓所在啊)
1.1.1 技术原理
Oracle会将数据库数据的每1个改动记录在日志文件中,所以理论上依靠日志文件,是能将数据库回滚到任何一个时间点的。
而Flashback的机制有点类似与回收站,会把数据库改动前的镜像放到undo表空间中。
如果用户要rollback1个数据库对象,只需要找到undo表空间中对应的Undo数据即可。
1.1.2 优点
Flashback并不依赖于日志文件, 只需Undo表空间中undo数据即可发挥作用.
所以Flashback可以满足用户逻辑错误的快速恢复.
所以优点如下:
-
快速
-
在线恢复, 无需关闭数据库
-
操作简单便捷
1.1.3 缺点
-
只适用于用户逻辑错误, 所谓逻辑错误就是用户对数据的唔操作, 例如误删除一些数据行等等。
而对于数据文件的损坏则无能为力(只能通过日志恢复). -
undo表空间的容量有限, 旧的undo数据有可能会被新的数据覆盖, 所以Flashback一般只适用于短时间内的恢复, 对于一段相当时间前的误操作, 很可能因为undo数据被覆盖而恢复失败。
1.2 闪回的历史
Oracle 9i 开始支持闪回,Oracle10g开始全面支持闪回功能,Oracle11g有所完善,为大家快速的恢复数据,查询历史数据提供了很大的便捷方法。
| 闪回级别 | 闪回场景 | 闪回技术 | 对象依赖 | 影响数据 |
|---|---|---|---|---|
| 数据库 | 表截断、逻辑错误、其他多表意外事件 | 闪回DATABASE | 闪回日志、undo | 是 |
| DROP | 删除表 | 闪回DROP | 回收站(recyclebin) | 是 |
| 表 | 更新、删除、插入记录 | 闪回TABLE | 还原数据,undo | 是 |
| 查询 | 当前数据和历史数据对比 | 闪回QUERY | 还原数据,undo | 否 |
| 版本查询 | 比较行版本 | 闪回Version Query | 还原数据,undo | 否 |
| 事务查询 | 比较 | 闪回Transaction Query | 还原数据,undo | 否 |
| 归档 | DDL、DML | 闪回Archive | 归档日志 | 是 |
1.3 有哪些闪回技术
Oracle提供了四种可供使用的闪回技术(闪回查询,闪回删除,闪回归档,闪回数据库),每种都有不同的底层体系结构支撑,但其实这四种不同的闪回技术部分功能是有重叠的,使用时也需要根据实际场景合理选择最合适的闪回功能。
1.3.1 闪回查询(Flashback Query)
1.3.1.1 基本闪回查询
功能描述:可以查询过去某个时间段的数据库状态。
工作原理:Oracle 会提取所需要的撤销数据(前提是撤销是可用的,即撤销数据还没被覆盖)进行回滚,但这种回滚是临时的,仅针对当前session可见。
select * from dept as of timestamp to_timestamp('2021-12-10 11:00:00','yyyy-mm-dd hh24:mi:ss');
1.3.1.2 闪回表
功能描述:可将某个表回退到过去某个时间点
工作原理:同样,Oracle会先去查询撤销段,提取过去某个时间点之后的所有变更,构造反转这些变更的SQL语句进行回退,闪回操作是一个单独的事务,所以若由于撤销数据过期之类的原因导致无法闪回,整个操作会回滚,不会存在不一致的状态。
步骤:
- 启用表闪回首先要在表上支持行移动(在数据字典中设置标识来标识该操作可能会改变行ID,即同一条数据闪回成功后主键都一样,但行ID其实已经发生变化了)
alter table emp enable row movement;
- 闪回表操作
flashback table dept to timestamp to_timestamp('2016-09-10 11:00:00','yyyy-mm-dd hh24:mi:ss');
闪回表可能会失败,有可能有以下几种情况:
-
违反了数据库约束,比如用户不小心删除了子表中的数据,现在想利用闪回表技术进行回退,恰好在这中间,父表中与该数据对应的那条记录也被删除了,在这种情况下,由于违反了外键约束,导致闪回表操作失败了;
-
撤销数据失效,比如用于支撑闪回操作的撤销数据被覆盖了,这种情况闪回表操作自然会失败;
-
闪回不能跨越DDL,即在闪回点和当前点之间,表结构有过变更,这种情况闪回操作也会失败。
注意:上述闪回功能都是基于撤销数据的,而撤销数据是会被重写的(Expired会被重写,Active不会被重写),所以,在需要使用这几种闪回功能去恢复数据的时候(确切地说,是需要使用基于撤销数据的闪回功能时),最短时间发现错误,第一时间执行闪回操作,才能最大程度地保证闪回功能的成功。
1.3.2 闪回删除(Flashback Drop)
功能描述:闪回删除可以轻松将一个已经被Drop的表还原回来。相应的索引,数据库约束也会被还原(除了外键约束)
原理描述:Drop命令其实是Rename命令,早期的Oracle版本(10g之前),闪回删除意味着从数据字典中删除了该表的所有引用,虽然表中数据可能还存在,但已成了孤魂野鬼,没法进行恢复了,10g版本之后,Drop命令则仅仅是一个Rename操作,所以恢复就很容易了。
闪回删除操作执行命令很简单
flashback table emp to before;
如果要还原的表名在当前系统中已经被占用,也可以在闪回删除的时候对表重命名
flashback table emp to before drop rename to emp_new;
也可以通过回收站查看当前用户那些表被删除了,每个用户都有一个回收站,这个回收站是个逻辑结构,它不是一块独立的存储空间,它存在在当前表空间内,所以如果有别的操作需要空间,比如现在需要创建一张表,没有足够空间可用,回收站中的数据就会被清理,这也是导致闪回删除失败的原因。
SHOW RECYCLEBIN;
彻底删除表,闪回删除也无能为力
DROP TABLE EMP PURGE;
清空回收站
PURGE RECYCLEBIN;
注意:闪回删除只针对Drop命令,注意区分truncate操作和drop操作,truncate称为表截断,会清空表中数据(调节Oracle高水位线实现),表结构不受影响,速度很快,弊端是此过程不会产生任何撤销数据或是重做日志,如果误删,恢复异常麻烦,要慎重使用。而Drop则会删除数据+表结构,闪回删除仅针对Drop操作。
1.3.3 闪回数据归档(Flashback Data Archive )
功能描述:闪回数据归档可使表具有回退到过去任何时间点的能力,前面提到的闪回查询,闪回表都会受限于撤销数据是否失效,如果撤销数据被覆盖重写了,闪回操作自然会失败,闪回删除则受限于表空间是否有足够可用空间,而闪回数据归档,则没有这些限制。
创建闪回归档
1. 创建一个用户闪回数据归档的表空间,当然,也可以使用已经存在的表空间。
create tablespace test_tb datafile 'test.dbf' size 20m;
2. 创建一个保留时间为2年的闪回归档
create flashback archive test_fa tablespace test_tb retention 2 year;
为scott用户下的emp表启用闪回归档
- 赋予用户归档的权限
grant flashback archive on test_fa to scott;
- 连接用户
conn scott/tiger;
- 为emp表启用闪回归档
alter table emp flashback archive test_fa;
至此,emp表就拥有了可以查询或回退到过去2年任意时间点的能力。
1.3.4 闪回数据库(Flashback Database)
功能描述:闪回数据库可将整个数据库回退到过去某个时间点,闪回表是某张表的时空穿梭,闪回数据库则是整个数据库的时空穿梭。当然,闪回点之后的所有工作就丢失了,其实就相当于数据库的不完整恢复,所以只能以resetlogs模式打开数据库。闪回数据库会造成停机时间,当然相比于传统备份恢复机制,恢复过程会快很多。
工作原理:闪回数据库不使用撤销数据,使用另外一种机制来保留回退所需要的恢复数据,当启用闪回数据库,发生变化的数据块会不断从数据库缓冲区缓存中复制到闪回缓冲区,然后,称为恢复写入器(Recovery Writer)的后台进程会将这些数据刷新到磁盘中的闪回日志文件中。闪回的过程,则是一个 提取闪回日志–>将块映像复制回数据文件 的过程。
配置闪回数据库(闪回数据库要求数据库为归档模式)
- 指定闪回恢复区,也就是存放闪回日志的位置,但闪回恢复区不仅仅是为了存放闪回日志,Oracle的很多备份恢复技术都用到这个区域,比如控制文件的自动备份等都会存放到此区域。
alter system set db_recovery_file_dest ='/flash_recovery_area';
- 指定恢复区大小
alter system set db_recovery_file_dest_size=4G;
- 指定闪回日志保留时间为2小时,即通过闪回操作,可以将数据库回退到前两小时内的任意时间点
alter system set db_flashback_retention_target=120;
- 有序关闭数据库–mount模式下启用闪回数据库–打开数据库
shutdown immediate;
startup mount;
alter database flashback on;
alter database open;
至此,闪回数据库配置完成!
使用闪回数据库功能
shutdown immediate;
startup mount;
flashback database to timestamp sysdate-60/1440;
alter database open resetlogs;
1.3.5 总结
本文列举了四类闪回技术,其中,闪回查询,包括基本闪回查询,闪回表等技术都依赖于撤销数据(还有一类闪回技术为闪回事务,可以对指定事务进行闪回操作,原理类似,借助于撤销数据来构建用于反转事务的SQL语句),依赖于撤销数据,则自然受限于撤销数据的保留时间,可能会由于撤销数据被覆写而导致闪回失败。闪回删除,则是由于10g版本后对表的删除仅表现为一个rename操作,引入回收站的概念,但此回收站仅是当前表空间的一块逻辑划分,所以会受限于当前表空间的可用空间的限制;闪回归档可提供查询或回退到过去任意时间点的功能,闪回数据库则是一中更极端的数据库恢复功能,相当于不完整恢复,依赖于闪回日志。




