一、Flashback Database(数据库级闪回)
1. 核心原理
类似 RMAN 不完全恢复,通过Flashback Log(闪回日志) 将整个数据库回退到过去某个时点,依赖 RVWR(Recover Writer)后台进程写入闪回日志到 Flash Recovery Area,比 RMAN 恢复更高效。
2. 核心限制
- 无法解决介质故障(Media Failure),此类场景仍需 RMAN 恢复;
- 若删除 / 缩小数据文件、恢复 / 重建控制文件,无法直接使用;
- 可恢复的最早 SCN 由 Flashback Log 中记录的最早 SCN 决定。
3. 启用步骤
sql
-- 1. 确认数据库处于归档模式
SQL> archive log list;
-- 2. 重启数据库到mount状态
SQL> shutdown immediate;
SQL> startup mount;
-- 3. 启用闪回数据库
SQL> alter database flashback on;
SQL> alter database open;
-- 4. 验证启用状态
SQL> select flashback_on from v$database; -- 结果为YES则启用成功
4. 实操示例(恢复误删表)
sql
-- 1. 记录操作前的SCN/时间
SQL> SELECT CURRENT_SCN FROM V$DATABASE; -- 例如:947921
SQL> select to_char(sysdate,'yy-mm-dd hh24:mi:ss') time from dual; -- 例如:09-10-14 14:37:05
-- 2. 模拟误删表
SQL> drop table A;
SQL> commit;
-- 3. 重启数据库到mount状态
SQL> shutdown immediate;
SQL> startup mount;
-- 4. 执行闪回(二选一)
SQL> Flashback database to timestamp to_timestamp('09-10-14 14:37:05','yy-mm-dd hh24:mi:ss');
-- 或基于SCN
SQL> Flashback database to scn 947921;
-- 5. 打开数据库(二选一)
-- 方式1:重置日志(后续数据丢失)
SQL> alter database open resetlogs;
-- 方式2:只读打开导出数据(无数据丢失)
SQL> alter database open read only;
-- 导出数据后恢复到原状态
SQL> recover database;
5. 关键视图
| 视图 | 作用 |
|---|---|
| V$database | 查看是否启用 Flashback Database |
| V$flashback_database_log | 查看最早恢复 SCN / 时间、闪回日志占用空间 |
| V$flashback_database_stat | 按小时统计闪回日志生成量,评估恢复区空间需求 |
6.使用场景
基于闪回日志的闪回(挽救步骤二:如果UNDO已被覆盖)
场景:如果错误在几天后才发现,UNDO早已被覆盖,闪回查询会报ORA-01555。
最后一招:使用闪回数据库(前提是已启用)。
SHUTDOWN IMMEDIATE;
STARTUP MOUNT EXCLUSIVE;
-- 闪回到误操作前的SCN(假设SCN是123456789)
FLASHBACK DATABASE TO SCN 123456789;
-- 以resetlogs方式打开,创建新化身
ALTER DATABASE OPEN RESETLOGS;
原理:Oracle定位到SCN 123456789之后生成的闪回日志,将这些日志中记录的旧数据块直接写回数据文件,从而"擦除"了所有在TRUNCATE操作之后发生的更改,将整个数据库回退到那个时间点。
二、Flashback Drop(闪回删除)
1. 核心原理
依赖Tablespace Recycle Bin(表空间回收站),删除表时对象不会物理删除,而是重命名存入回收站,类似 Windows 回收站;仅支持非 SYSTEM 表空间、本地管理表空间的表 / 索引 / 约束等对象,不支持 SYS 用户对象、函数 / 存储过程。
2. 核心配置
sql
-- 查看回收站启用状态
SQL> show parameter recyclebin; -- 默认ON
-- 禁用/启用回收站(会话级/系统级)
SQL> alter session set recyclebin=off;
SQL> alter system set recyclebin=off scope=both;
3. 实操示例
sql
-- 1. 查看回收站中的对象
SQL> show recyclebin;
SQL> select original_name,object_name from recyclebin; -- 例如:A → BIN$RWXQQcTPRde0ws4h9ewJcg==$0
-- 2. 恢复误删表(二选一)
-- 方式1:直接恢复
SQL> flashback table A to before drop;
-- 方式2:重命名恢复(原表名已被占用)
SQL> flashback table A to before drop rename to B;
-- 方式3:指定回收站对象名恢复(同名表多次删除)
SQL> flashback table "BIN$vYuv+g9fTi2exYP9X2048Q==$0" to before drop;
-- 3. 手动清理回收站
SQL> purge recyclebin; -- 清空当前用户回收站
SQL> purge dba_recyclebin; -- 清空所有用户(需SYSDBA)
SQL> drop table A purge; -- 永久删除,不进入回收站
4. 注意事项
- 回收站为逻辑区域,与普通对象共享表空间,空间不足时按 FIFO 覆盖旧对象;
- 恢复后索引 / 约束会保留但为系统自动命名,需手动重命名;
- 物化视图删除后不进入回收站,无法通过此方式恢复。
三、Flashback Query(闪回查询)
1. 核心原理
利用 UNDO 表空间的多版本读一致性,读取数据的前镜像,支持基于时间 / SCN 查询历史数据,可恢复误删 / 误改的数据;9iR2 后支持,对动态性能视图(v$tables)无效,对数据字典(dba_*)有效。
2. 实操示例
(1)基于 Timestamp 查询 / 恢复
sql
-- 1. 记录操作前时间
SQL> alter session set nls_date_format='YYYY-MM-DD hh24:mi:ss';
SQL> select sysdate from dual; -- 例如:2009-10-15 19:04:16
-- 2. 模拟误删数据
SQL> delete from A;
SQL> commit;
-- 3. 查询历史数据
SQL> select * from A as of timestamp to_timestamp('2009-10-15 19:04:16','YYYY-MM-DD hh24:mi:ss');
-- 4. 恢复数据
SQL> Insert into A select * from A as of timestamp to_timestamp('2009-10-15 19:04:16','YYYY-MM-DD hh24:mi:ss');
SQL> commit;
(2)基于 SCN 查询 / 恢复(推荐,保证约束一致性)
sql
-- 1. 记录操作前SCN
SQL> SELECT CURRENT_SCN FROM V$DATABASE; -- 例如:1095782
-- 2. 模拟误删数据
SQL> delete from A;
SQL> commit;
-- 3. 查询历史数据
SQL> select * from A as of scn 1095782;
-- 4. 恢复数据
SQL> insert into A select * from A as of scn 1095782;
SQL> commit;
3. 扩展:恢复函数 / 存储过程
sql
-- 基于Timestamp查询删除的函数代码
SQL> SELECT text
FROM dba_source
AS OF TIMESTAMP TO_TIMESTAMP ('2011-04-07 21:02:09', 'YYYY-MM-DD HH24:MI:SS')
WHERE owner = 'SYS' AND name = 'GETDATE'
ORDER BY line;
-- 重新执行查询结果中的代码即可恢复
4. SCN 与 Timestamp 映射
-
Oracle 内部用 SCN,Timestamp 会转换为 SCN;
-
系统每 5 分钟记录一次映射关系到
sys.smon_scn_time,仅保留最近 1440 条(约 5 天); -
查看映射关系: sql
SQL> select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss') from sys.smon_scn_time;
四、Flashback Version Query(闪回版本查询)
1. 核心原理
通过伪列ORA_ROWSCN(记录行最后一次修改的 SCN,默认数据块级,建表时指定rowdependencies可为行级),查看指定时间段内数据的所有版本变化(Insert/Update/Delete),定位数据修改轨迹。
2. 实操示例
sql
-- 查看表A的所有版本变化
SQL>Select versions_xid,versions_startscn,versions_endscn,
DECODE(versions_operation,'I','Insert','U','Update','D','Delete', 'Original') "Operation",
id from A versions between scn minvalue and maxvalue;
五、Flashback Transaction Query(闪回事务查询)
1. 核心原理
通过flashback_transaction_query视图,关联事务 ID(XID)查看单个事务的所有操作及对应的撤销 SQL,精准恢复误操作。
2. 实操示例
sql
-- 查看表B指定SCN范围内的事务及撤销SQL
SQL>select xid,commit_scn,commit_timestamp,operation,undo_sql
from flashback_transaction_query q
where q.xid in(select versions_xid from B versions between scn 413946 and 413959);
六、Flashback Table(闪回表)
1. 核心原理
基于 UNDO 表空间,将指定表回退到过去的 SCN / 时间;需启用表的row movement(行移动),支持多表同时恢复(同一事务)。
2. 实操示例
sql
-- 1. 启用行移动
SQL> ALTER TABLE C ENABLE ROW MOVEMENT;
-- 2. 记录操作前SCN/时间
SQL> select current_scn from v$database; -- 例如:1103864
-- 3. 模拟误删数据
SQL> delete from C;
SQL> commit;
-- 4. 闪回表(二选一)
SQL> flashback table C to scn 1103864;
SQL> flashback table C to timestamp to_timestamp('2009-10-15 21:17:47','yyyy-mm-dd hh24:mi:ss');
-- 5. 验证恢复结果
SQL> select * from C;
3. 注意事项
- DDL 操作(如 truncate、move 表、修改列)会导致 UNDO 数据失效,触发 ORA-01466 错误;
- 恢复时默认禁用触发器,需保留触发器可加
ENABLE TRIGGERS子句; - 多表恢复时要么全部成功,要么全部失败。
4.使用场景
场景: 下午2:00,开发人员误执行了TRUNCATE TABLE aa;。
基于UNDO的闪回(挽救步骤一:尝试闪回表)
发现错误:DBA在2:05发现错误。
确认时间点:DBA查询2:00前的数据是否可用:
SELECT COUNT(*) FROM important_data
AS OF TIMESTAMP TO_TIMESTAMP('2023-10-27 13:59:00', 'YYYY-MM-DD HH24:MI:SS');
-- 查询成功,说明UNDO数据还在
执行闪回表:
-- 启用行移动
ALTER TABLE important_data ENABLE ROW MOVEMENT;
-- 执行闪回
FLASHBACK TABLE important_data
TO TIMESTAMP TO_TIMESTAMP('2023-10-27 13:59:00', 'YYYY-MM-DD HH24:MI:SS');
原理:Oracle根据UNDO数据,为TRUNCATE操作后"丢失"的每一行数据生成并执行INSERT语句,将表恢复到之前的状态。
七、Flashback Data Archive(FDA,11g 新特性)
1. 核心原理
独立于 UNDO 表空间,将指定表的事务变化存储到闪回归档区(逻辑区域,由一个 / 多个表空间组成),支持长期保留数据(按策略),适用于审计 / 合规场景;依赖 FBDA 后台进程,要求表空间为 ASSM、UNDO 管理为自动(undo_management=auto)。
2. 核心操作
(1)创建闪回归档区
sql
-- 创建默认归档区(保留1年,配额10M)
SQL> create flashback archive default fla1 tablespace fda1 quota 10M retention 1 year;
-- 创建普通归档区(无配额限制,保留2年)
SQL> create flashback archive fla2 tablespace fda2 retention 2 year;
(2)修改归档区
sql
-- 设置默认归档区
SQL> alter flashback archive fla2 set default;
-- 修改保留时间
SQL> alter flashback archive fla1 modify retention 2 month;
-- 清理历史数据
SQL> alter flashback archive fla1 purge before timestamp (systimestamp - interval '1' day);
(3)表启用 / 禁用 FDA
sql
-- 创建表时启用
SQL> create table fa(id number) flashback archive fla1;
-- 已有表启用
SQL> alter table fa flashback archive fla1;
-- 禁用FDA(需SYSDBA或FLASHBACK ARCHIVE ADMINISTER权限)
SQL> alter table fa no flashback archive;
3. 关键视图
| 视图 | 作用 |
|---|---|
| DBA_FLASHBACK_ARCHIVE | 查看闪回归档区名称、状态、保留策略 |
| DBA_FLASHBACK_ARCHIVE_TABLES | 查看启用 FDA 的表及对应的归档表 |
八、开启建议
1. 建议开启的场景
如果你的数据库是 生产 / 测试环境,且有以下需求:
- 需要快速将整库回退到过去某个时点(比如误操作后快速恢复);
- 希望替代部分 RMAN 不完全恢复场景,提升恢复效率;
- 能提供 Flash Recovery Area(闪回恢复区) 的存储空间(需提前配置)。
2. 不建议开启的场景
如果是以下情况,可以暂时不开启:
- 数据库是 开发 / 临时环境,对恢复效率要求低;
- 服务器磁盘空间紧张(闪回日志会占用额外空间);
- 已依赖 RMAN 完成全量 / 增量备份,且不需要更快速的整库回退。
3. 开启的核心前提
开启前需满足:
- 数据库已处于 归档模式 (可通过
archive log list验证); - 已配置 Flash Recovery Area(指定存储闪回日志的路径和大小)。
总结
| 闪回类型 | 依赖对象 | 适用场景 | 核心限制 |
|---|---|---|---|
| Flashback Database | 闪回日志 | 整库回退到过去时点 | 无法解决介质故障,依赖控制文件 |
| Flashback Drop | 回收站 | 恢复误删表 / 索引 | 不支持 SYS 对象、函数 / 存储过程 |
| Flashback Query | UNDO 表空间 | 查询 / 恢复单表历史数据 | 受 UNDO_RETENTION 限制,最多保留 5 天 |
| Flashback Table | UNDO 表空间 + 行移动 | 单表 / 多表精准回退 | DDL 操作会导致 UNDO 失效 |
| Flashback Data Archive | 闪回归档区 | 长期保留 / 审计数据 | 11g 以上支持,需额外 |