【Oracle】 Flashback(闪回)技术实操指南

一、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 以上支持,需额外
相关推荐
白山云北诗2 小时前
中小企业如何做好企业官网的网络安全
网络·数据库·web安全·ddos·cc·企业网络安全
lkbhua莱克瓦242 小时前
进阶-存储对象2-存储过程上
java·开发语言·数据库·sql·mysql
码农胖虎-java2 小时前
【AI】向量数据库选型实战:pgvector vs Milvus vs Qdrant
数据库·milvus·pg
Insist7532 小时前
KingbaseES 集群运维案例之 --- 集群架构拆分为单实例操作
网络·数据库·oracle
m0_598177232 小时前
MySQL项目开发 (2)
数据库·mysql
lkbhua莱克瓦243 小时前
进阶-存储对象1-视图
java·数据库·sql·mysql·视图
IvorySQL3 小时前
用 PostgreSQL 实践 Palantir 本体论
数据库·postgresql·开源
yangminlei3 小时前
Spring Boot 自动配置原理与自定义 Starter 开发实战
java·数据库·spring boot
萧曵 丶3 小时前
Redis 由浅到深面试题(分层次版)
数据库·redis·缓存