☰
深入底层:Oracle闪回技术原理详解与实战边界
2026/10/1 11:34:17 网站建设 项目流程

凌晨两点半,一条没带WHERE条件的UPDATE,把生产库几百万行数据刷成了同一个值。这是数据库运维里最经典也最惊悚的剧本。Oracle环境下遇到这种场景,我的第一反应不是马上扛出RMAN备份做全库恢复,而是先看闪回能不能救。闪回技术(Flashback)在Oracle里已经存在了很多年,但多数人只把“AS OF TIMESTAMP”当查询小技巧用,根本没搞清楚它背后是怎么在几秒内把数据“变回去”的。这篇文章不谈概念堆砌,直接从底层把闪回家族过一遍:UNDO怎么存旧值、Flashback Log怎么记前像、回收站里藏了什么、闪回数据归档(FDA)又堵了哪个洞。适合DBA、运维、开发,以及准备Oracle面试、想真正理解闪回边界在哪里的人。

1. 闪回技术的全景图:先搞懂Oracle到底给了你哪几把“后悔药”

1.1 闪回并不是单点技术,而是一整套恢复工具链

很多人一听“闪回”,第一反应是Flashback Database整库回退。这其实是个大误区。Oracle从9i开始逐步构建的闪回体系,是一套分层的工具链,不同层面对应不同粒度的恢复场景:

  • Flashback Query(闪回查询):查某张表在某个时间点的历史数据,9i引入。
  • Flashback Version Query(闪回版本查询):看某一行在过去一段时间内的所有变更版本,10g引入。
  • Flashback Table(闪回表):把整张表恢复到指定时间点,10g引入。
  • Flashback Drop(闪回删除):误DROP的表,从回收站捞回来,10g引入。
  • Flashback Database(闪回数据库):整库回到过去,10g引入。
  • Flashback Transaction Query / Transaction Backout(闪回事务):定位某个事务做了什么,并生成补偿事务消除影响,10g-11g逐步完善。
  • Flashback Data Archive(闪回数据归档,FDA):把表的历史版本长期保存,突破UNDO保留期限制,11g以Total Recall形态出现,12c改名为FDA。

这套工具的意义在于:大部分“救命”场景,根本不需要走完整的备份恢复流程。误删一行、误改一片、跑错一个作业,如果你第一反应是restore database,往往意味着至少一小时的停机,而闪回在秒级到分钟级能解决的事,没必要动用RMAN。理解了这一点,你才能对下文各个分支的底层原理产生真正的兴趣——因为它们不是同一台发动机。

1.2 藏在背后的两条底层数据链路:UNDO与Flashback Log

整个闪回家族,底层其实只依赖两条数据链路。

第一条是UNDO。闪回查询、闪回版本查询、闪回表、闪回事务,全都建立在UNDO表空间之上。UNDO的本质是“修改前数据镜像”,当事务修改数据块时,Oracle会先把旧值写到UNDO段,再修改当前块。所以只要UNDO还在,你就可以把当前块沿着UNDO链“倒回去”。

第二条是Flashback Log。闪回数据库不走UNDO,它依赖的是一个叫RVWR的后台进程,在数据块第一次被修改之前,把块的前像记录到闪回日志里。这条链路能绕开“把所有事务反向重放一遍”的笨办法,直接拿块级别的前像做恢复拼接。

回收站(Recycle Bin)则是Flashback Drop的底层设施,它更像“改名搬家”而非“数据还原”。FDA则是把UNDO里行版本定期搬运到专用历史表,本质是“把临时保留变成永久归档”。把这四条线索理清后,再去看每条闪回命令,你就能判断它快在哪里、极限在哪里、会栽在哪里。

2. 闪回查询与闪回版本查询的底层原理:如何让数据“倒带”

2.1 关键前提:UNDO里存的到底是什么鬼东西

先来复习一下事务修改数据的路径。假设你要执行:

UPDATE emp SET salary = 20000 WHERE emp_id = 100;

事务刚开始时,Oracle会分配一个UNDO段,然后在UNDO段里写入一行UNDO记录,记录的内容是修改前的salary值(比如15000)。接着才去修改数据块里的salary为20000。与此同时,数据块的事务槽(ITL)会指向这条UNDO记录,UNDO记录里又通过UBA(Undo Block Address)指向前一条更早的UNDO记录,形成一条回滚指针链。

你可以把UNDO想象成账本的“红字冲销”栏。每一次改动,都在冲销栏里记了一笔“如果要撤销,应该改回什么”。如果某个数据块被连续修改了10次,那么这个块上就会挂着10条UNDO记录,从最新状态出发,沿着指针链可以依次看到第9、第8……直到第1次修改前的模样。

关键点在于:UNDO是循环使用的。UNDO表空间里的区,满了之后会被数据库自动覆盖。数据库用UNDO_RETENTION参数来设置“至少保留多久”,但它只是意愿,不是保证。只要UNDO空间不够用,即使还没到保留期,旧UNDO也可能被复用——除非你启用了UNDO_RETENTION GUARANTEE或者用保留保证。这一条后面排查ORA-01555时会反复用到。

2.2 一致性读与CR块:一个数据块的多个历史版本是怎么组装出来的

闪回查询的SQL写起来很简单:

SELECT * FROM emp AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '30' MINUTE) WHERE emp_id = 100;

真正执行时,Oracle内部动作远比你想的复杂。第一步,把TIMESTAMP翻译成SCN,用的是SCN_TO_TIMESTAMP和TIMESTAMP_TO_SCN函数,依赖的是SYS.SMON_SCN_TIME表里保存的SCN与时间映射关系。第二步,Oracle按SCN去构造这个块在那一刻的“一致性读版本”(CR块)。

CR块怎么构造?这是闪回查询最核心的原理。当Oracle发现当前数据块的版本已经晚于目标SCN,它不会去别处找旧数据,而是在Buffer Cache里拷一份当前块的副本,然后沿着刚才说的UNDO回滚指针链,把目标SCN之后发生的修改逐一“撤销”到这份副本上。于是这个副本就变成了目标SCN时刻的数据块内容,查询结果自然也就是历史数据。

这里有一个容易被忽略的性能特性:闪回查询可能需要遍历非常长的UNDO链。假设这张表在目标时间点到当前之间被UPDATE了几万次,每次UPDATE又产生了多条UNDO记录,那么构建一个CR块可能要把链上所有记录全部读一遍。所以闪回查询越往前追溯,耗时就越高,不是没有代价的。这也是很多人误以为“闪回查询就是快”之后,在生产环境一把梭查两小时前数据导致数据库IO飙升的原因。

2.3 从Flashback Query到Flashback Version/Transaction Query:一张表能看到的所有历史

Flashback Query只能看到“某个时间点的快照”,而Flashback Version Query能回答另一个问题:这一行在过去十分钟内到底被改了多少次、每次改成什么样、哪个事务改的。SQL长这样:

SELECT emp_id, salary, versions_starttime, versions_endtime, versions_operation FROM emp VERSIONS BETWEEN TIMESTAMP (SYSTIMESTAMP - INTERVAL '10' MINUTE) AND SYSTIMESTAMP WHERE emp_id = 100;

它的实现思想很巧妙:还是遍历UNDO链,但不再是在某个SCN处停止,而是把链上每一段版本变化都列出来。versions_starttime表示这个版本从什么时候开始生效,versions_endtime表示这个版本到什么时候失效,versions_operation可以告诉你这次变化是I(Insert)、U(Update)还是D(Delete)。这些信息本质上都保存了UNDO记录的事务头和事务槽里。

Flashback Transaction Query更进一步,它可以基于VERSIONS的信息找到具体的事务XID,然后通过DBMS_FLASHBACK.GET_TRANSACTION_INFO或者11g以后的FLASHBACK_TRANSACTION_QUERY视图,把事务里执行过的所有SQL语句和对应的UNDO反向SQL找出来。这意味着你可以知道“是谁在那个时刻改了什么”,而不只是“数据变成了什么”。

如果要用FLASHBACK TRANSACTION BACKOUT彻底撤销某个事务,Oracle会分析这个事务与其他事务的依赖关系,自动生成一组补偿SQL(不是简单反向执行,而是通过UNDO构造新的DML),保证逻辑等价消除影响。这个功能在生产运维里其实用得不多,因为依赖分析太严格,但面试聊起来,底层原理明确后会很加分。

3. 闪回表与闪回删除的实现机制:对象级恢复到底动了哪些手脚

3.1 闪回表的先决条件与执行链路

闪回表看着像“闪回查询+UPDATE全表”,但官方并不建议你手动这么干,而是提供了专有命令:

ALTER TABLE emp ENABLE ROW MOVEMENT; FLASHBACK TABLE emp TO TIMESTAMP (SYSTIMESTAMP - INTERVAL '20' MINUTE);

这里的先决条件非常关键:必须开启ROW MOVEMENT。为什么不开启就不能闪回?因为在闪回过程中,行数据要沿着UNDO链恢复成历史版本,它们的物理位置(ROWID)可能发生改变。普通表的行地址是被索引直接引用的,如果行悄悄换了块而Oracle不知道,索引就有破洞的风险。开启ROW MOVEMENT,等于明确告诉优化器“行可以移动”,闪回内部才能名正言顺地移动这些行并维护相关索引。

另一个容易被忽略的细节是:闪回表只恢复行数据,不恢复表结构。假设这张表在目标时间点之后执行过ADD COLUMN,那么闪回后,新列依然存在,但旧行在新列上的值为空;如果执行过DROP COLUMN,闪回后旧值也没办法回来。更麻烦的是,如果目标时间点之后做过TRUNCATE,闪回表通常无法恢复数据(TRUNCATE是DDL,不产生UNDO)。

所以我的习惯是:闪回表之前,一定先用Flashback Query验证目标时间点的数据形态,确认行数和关键值对得上,再执行闪回。闪回表本质上是在同一个表里原地做“数据块版本回滚”,比起CTAS备份再交换表,省时很多,但也正因如此,它无法帮你回退DDL、无法帮你找回被TRUNCATE掉的数据。边界要心里有数。

3.2 闪回删除背后的回收站机制

Flashback Drop的原理比闪回表更简单,也更容易被误解。执行:

DROP TABLE emp;

在默认参数(RECYCLEBIN=ON)下,Oracle并不是物理删除这个表,而是把这个段改名为一个系统内部名字,例如BIN$2fUuB8nwR+3gWgQAB/8f8Q==$0,然后把对象“挂”到回收站里。表的索引、触发器、约束等依赖对象也一并进入回收站。数据还在原来的表空间块里,只是从数据字典的可见视图里“抹掉”了。

恢复命令很直接:

FLASHBACK TABLE emp TO BEFORE DROP; -- 也可以指定新表名 FLASHBACK TABLE "BIN$2fUuB8nwR+3gWgQAB/8f8Q==$0" TO BEFORE DROP RENAME TO emp_restore;

但这里有几个实际生产里踩过的坑。

第一,回收站不是无限期的。当表空间压力上升,Oracle在需要空间分配新区时,会优先自动清理回收站里的对象,这叫做“空间压力清理”。所以DBA如果不看告警,误删的表可能过两天就被自动PURGE掉了,神仙也救不回来。

第二,同名对象冲突。回收站里如果已有同名表,直接FLASHBACK TO BEFORE DROP会报错,需要先RENAME或者DROP掉那个挡路的对象。

第三,PARTITION表、LOB段、IOT表的恢复逻辑各不相同,底层依赖对象会被带上系统生成名,恢复后需要手动改回业务名。不要指望一条命令把所有INDEX名字都还原得干干净净。

第四,FLASHBACK TABLE TO BEFORE DROP不依赖UNDO,它只是把回收站里的段重新挂回原命名空间。所以即使UNDO早就被覆盖,只要回收站里的段还在,就能恢复。

4. 闪回数据库的底层原理与配置:唯一能“时光倒流”整库的技术

4.1 RVWR与Flashback Log:在块被改写前先存一份“旧照片”

前面所有基于UNDO的闪回,都有一个硬伤:UNDO保留期太短,通常只够覆盖最近几十分钟到几小时。如果你整库逻辑损坏发生在两天前,闪回查询和闪回表几乎都无能为力。这时候才轮到闪回数据库登场。

闪回数据库的底层引擎是一个叫RVWR(Recovery Writer)的后台进程,配合的是Flashback Log(闪回日志)。当数据库开启闪回后,每个数据块在“保留窗口内第一次被修改”时,RVWR会把这个块的原始镜像拷贝到SGA里的Flashback Buffer,再异步写入FRA(快速恢复区)中的闪回日志。

注意细节:不是每次修改都记录,而是一个块在一个保留期内只记录一次前像。如果同一个块被改了100次,闪回日志里通常只有第一次修改前的版本。为什么要这样设计?因为闪回的目标不是回放所有事务,而是快速把块的版本回退到较早时间点,然后用REDO补足到精确目标。如果块在保留期内至少被记录过一次,数据库就知道它在任意时刻的起点版本。

4.2 闪回数据库的恢复流程:Flashback Log加Redo的组合拳

闪回数据库的执行流程可以这样理解:

SHUTDOWN IMMEDIATE; STARTUP MOUNT; FLASHBACK DATABASE TO TIMESTAMP TO_TIMESTAMP('2024-06-15 03:00:00','YYYY-MM-DD HH24:MI:SS'); ALTER DATABASE OPEN RESETLOGS;

数据库在MOUNT状态下,先扫描闪回日志,找到早于目标时间点的、可用的块前像集合,把这些块整体恢复到较早状态;然后再应用归档REDO日志,把数据前滚到目标时间点。本质上是一个“闪回日志倒带 + REDO微调”的组合恢复。

这个方案比RMAN全库恢复快在哪?RMAN恢复要restore所有数据文件,而闪回数据库只处理那些在窗口内被修改过的块。生产库动辄几百G,一次全库restore可能要两小时,闪回数据库可能十分钟就完成。但它的前提很苛刻:目标时间点必须落在Flashback Log覆盖范围内,且FRA空间必须够。

还有一个非常重要的限制:传统版本里,闪回数据库不能跨越OPEN RESETLOGS边界。也就是说,如果你上一次用RESETLOGS方式打开过数据库,那么你不能闪回到那次RESETLOGS之前的时间点。新版Oracle对这个限制有所放宽,但生产环境里我仍然坚持把RESETLOGS当作不可跨越的边界。

4.3 生产环境快速上手:开启、使用与限制

开启闪回数据库的步骤不算复杂:

-- 1. 检查是否归档模式 ARCHIVE LOG LIST; -- 2. 如果非归档,需要重启到MOUNT状态开启 SHUTDOWN IMMEDIATE; STARTUP MOUNT; ALTER DATABASE ARCHIVELOG; -- 3. 设置闪回保留目标为2小时(单位:分钟) ALTER SYSTEM SET DB_FLASHBACK_RETENTION_TARGET=120 SCOPE=BOTH; -- 4. 开启闪回 ALTER DATABASE FLASHBACK ON; ALTER DATABASE OPEN;

开启后用这两个视图监控状态和数据量:

SELECT * FROM V$FLASHBACK_DATABASE_LOG; SELECT * FROM V$FLASHBACK_DATABASE_STAT;

有几个实操体会想重点说一下。

一是DB_FLASHBACK_RETENTION_TARGET只是“目标”,不是“保证”。闪回日志空间如果不够,数据库会丢弃最老的闪回日志,保留窗口自动缩短。因此FRA空间规划很关键,闪回日志的合理大小需要结合业务写入量测算。V$FLASHBACK_DATABASE_LOG里的ESTIMATED_FLASHBACK_SIZE可以给一个估算参考。

二是打开RESETLOGS之后,建议立刻在最近的正常时间点创建一个RESTORE POINT,作为新的闪回基准。这样万一RESETLOGS之后又发现更早的逻辑问题,你还有个明确坐标。

三是闪回数据库需要SYSDBA权限,且数据库必须处于MOUNT状态,意味着整个库要停机。它对“逻辑灾难快速回退”非常高效,但不适合单表误删,别拿它当闪回表的替代品。

四是如果启用了表空间加密或者特殊文件配置,闪回日志本身也会加密,实际可用保留窗口可能比预估短,做方案时要把这部分损耗算进去。

5. 闪回数据归档(FDA):打破UNDO保留期天花板

5.1 FDA是怎么把历史版本搬进“仓库”的

闪回查询最大的软肋是UNDO保留期。生产库UNDO_RETENTION通常设置15分钟到几小时,超过这个范围,历史数据就拿不到了。如果你有审计需求、报表回溯需求、或者只是想让“七天前某个时刻的数据”随时可查,就得靠闪回数据归档(FDA)。

FDA的底层结构并不神秘。启用闪回归档后,Oracle会为每个启用FDA的表创建配套的内部历史表,名字形如SYS_FBA_HIST_xxx。后台进程(Flashback Data Archiver,fbda)会定期扫描UNDO,把目标表的行变更版本“搬运”进历史表,并按时间做分区。查询时,如果目标时间点已经在当前UNDO保留窗口之外,优化器会自动改走历史表,把对应分区的行版本读出来。

所以FDA本质上不是把UNDO变大了,而是把“临时的行版本链”转化成了“持久化的历史表”。这也是为什么它能突破UNDO_RETENTION的限制——只要分区保留期没到,数据就在。

5.2 关键配置与使用效果

配置一个FDA环境,核心是三步:

-- 1. 建闪回归档 CREATE FLASHBACK ARCHIVE DEFAULT fda1 TABLESPACE tbs_fda RETENTION 1 YEAR; -- 2. 对表启用 ALTER TABLE emp FLASHBACK ARCHIVE fda1; -- 3. 查询时直接按目标时间走 SELECT * FROM emp AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '180' DAY) WHERE emp_id = 100;

看到没,查询语法和Flashback Query一模一样。区别只在于,超过一年时间点的数据,Oracle会自动从历史表里取,而不是依赖UNDO。

使用FDA有几个代价必须讲清楚。

第一,空间开销很大。每个被修改的行都会在历史表里留下版本,审计类表如果每天全量更新一次,历史表可能是业务表的几十倍上百倍。分区策略做得不好,FRA或数据表空间会爆。

第二,DML路径上会有额外开销。fbda进程要读取UNDO、写历史表,相当于每次UPDATE都多了一笔写操作。写入敏感的大表上FDA,性能影响不能忽略。

第三,启用FDA的表在某些DDL场景下会受限,比如TRUNCATE。至少我在实操中碰到的结论是:FDA表不能随意TRUNCATE,如果业务上确实需要截断,必须先禁用FDA,截断完再启用。具体哪些DDL被限制,各版本略有差异,上生产前一定要先在测试环境验证,别拿核心表直接试。

6. 常见问题与排查技巧实录

6.1 ORA-01555快照过旧:最典型的闪回失败

所有用UNDO的闪回功能,最经典也最恼人的错误就是ORA-01555: snapshot too old。原因很单纯:数据库构造CR块时,需要的UNDO记录已经被覆盖了。可能因为UNDO表空间太小,也可能因为查询目标是太久之前的时间点,还可能因为UNDO_RETENTION被设置得太保守。

排查路径一般是这样的:

-- 1. 看UNDO使用率和保留情况 SELECT tablespace_name, status, SUM(bytes)/1024/1024 mb FROM dba_undo_extents GROUP BY tablespace_name, status; -- 2. 看UNDO统计信息 SELECT TO_CHAR(begin_time,'HH24:MI') begin_time, undoblks, txncount, maxquerylen, maxquerysid FROM v$undostat ORDER BY begin_time;

V$UNDOSTAT里的MAXQUERYLEN表示最长的查询时长(秒)。如果这个值接近UNDO_RETENTION,说明长查询已经在挑战保留极限。解决思路无非三选一:加大UNDO_RETENTION、扩大UNDO表空间、或者换FDA方案保存长期历史。

还有个细节:闪回查询的目标时间点越久远,构造CR块需要遍历的UNDO链越长,执行速度也越慢。如果慢到超过UNDO保留期的一半,即使没报ORA-01555,结果也可能不如预期。所以生产上闪回查询的合理窗口,一般控制在UNDO_RETENTION的一半以内比较稳妥。

6.2 闪回表失败:ROW MOVEMENT与依赖对象

闪回表最常碰到的错误是ORA-08189,提示需要开启ROW MOVEMENT。这个前面讲过了,直接执行:

ALTER TABLE emp ENABLE ROW MOVEMENT;

但还一类错误很隐蔽:表上有外键约束、物化视图日志、或者依赖该表的存储过程,闪回时Oracle会因为依赖对象不一致而拒绝执行。例如ORA-00942或ORA-01466出现在恢复途中,通常是表在目标时间点之后做了DDL,导致UNDO里的行版本与当前结构对不上。

我的处理套路是:先查DBA_DEPENDENCIES和DBA_CONSTRAINTS,把外键临时DISABLE,闪回完再恢复;如果是有物化视图,先考虑重建;如果是结构DDL导致的版本错位,老实说闪回表已经不适合了,建议走“基于时间点恢复表空间”或者从逻辑备份中捞数据。硬着头皮执行,只会让数据库处于更尴尬的半恢复状态。

6.3 闪回数据库时间点不准与RESETLOGS边界

闪回数据库失败或结果不对,排查方向比闪回表更粗一些。常见情况是目标时间点早于Flashback Log覆盖窗口,数据库报ORA-38706或类似错误。这时先看V$FLASHBACK_DATABASE_LOG里的OLDEST_FLASHBACK_SCN和时间,确认窗口。

另一个问题是TIMESTAMP转SCN的映射误差。V$SCN_TIME表只有大约5天的映射记录,而且映射不是精确一一对应的。如果你指定的是“某天3点整”,数据库实际恢复到的可能是3点00分到3点05分之间的任意SCN对应的状态。排查方法:先查归档日志找到目标时间点最近的SCN,再执行:

SELECT TIMESTAMP_TO_SCN(TO_TIMESTAMP('2024-06-15 03:00:00','YYYY-MM-DD HH24:MI:SS')) FROM dual;

如果业务上要求分钟级精确,宁可多往前恢复几分钟,也别往后——往前可以再用REDO补,往后就回不去了。

至于RESETLOGS边界,遇到“cannot flashback database to before resetlogs”这类错误,只能接受现实。这也是为什么我坚持在每次OPEN RESETLOGS之后马上做一个RESTORE POINT,保证后续有一个新的、可闪回坐标。

6.4 闪回日志空间暴涨与性能抖动

闪回日志的写入量和你想象中不一样:它不跟事务量成正比,而跟“被修改数据块的数量”成正比。一张全表UPDATE,会把表空间里几乎每个块都标记为“第一次修改”,RVWR就得把每个块的前像倒腾出去,FRA里的闪回日志瞬间猛涨。

监控视图是V$FLASHBACK_DATABASE_STAT,里面记录了每小时的闪回数据量。如果发现某段时间暴涨,去看对应时间的业务作业,八成是全表刷新或者大批量UPDATE。这时候可以考虑把这类作业错峰执行,或者临时关闭闪回(ALTER DATABASE FLASHBACK OFF),作业完成后再重新打开。注意关闭再打开会重置保留窗口,等于前面记录的闪回日志全部作废,所以要评估代价。

6.5 常见问题速查表

场景典型报错根因首选排查/处理
闪回查询超时或失败ORA-01555UNDO被覆盖查V$UNDOSTAT,调大UNDO_RETENTION或扩容UNDO表空间
闪回查询报无法读取版本ORA-01466目标时间点太早或UNDO损坏换SCN重试,确认目标在保留窗口内
闪回表拒绝执行ORA-08189未开启ROW MOVEMENTALTER TABLE ... ENABLE ROW MOVEMENT
闪回表中途结构错位ORA-01466/ORA-00904目标后做过DDL确认结构变更,改用恢复备份/逻辑导出
闪回删除后表名带BIN$无报错,命名异常回收站对象依赖未完全还原查询DBA_RECYCLEBIN,手动RENAME相应对象
闪回数据库窗口不足ORA-38706FRA空间不够或RETENTION设置过短查看V$FLASHBACK_DATABASE_LOG,调整FRA空间
闪回数据库跨RESETLOGS失败ORA-38726不能闪回到RESETLOGS之前基于RESTORE POINT重新规划恢复点
FDA历史表空间失控空间告警历史版本增长快检查SYS_FBA_HIST_*分区,优化分区和清理策略

结尾的个人体会

我在实际维护Oracle的过程中,最深的体会是:闪回技术的价值不在于“炫”,而在于它把数据库恢复的粒度从“小时级停机”压缩到了“分钟级止血”。但越快的工具,越要求你理解它的原理和边界。面试时如果只背命令,问到“为什么Flashback Database不用UNDO”就露馅了;生产上如果不明白闪回查询受UNDO保留期限制,关键时刻一条ORA-01555就让你彻底凉凉。

最后分享一个我在多个生产库上验证过的小习惯:每周维护窗口里,固定打一个RESTORE POINT,同时把DB_FLASHBACK_RETENTION_TARGET设到120分钟以上。日常误操作靠闪回表或闪回查询,逻辑灾难靠闪回数据库,彻底恢复才动用RMAN。这套组合打下来,绝大多数事故都能在十几分钟内控制住。希望你永远用不上这些命令,但脑子里要一直存着这张底牌。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询