oracle闪回技术

奋斗吧
奋斗吧
擅长邻域:未填写

标签: oracle闪回技术 Html/CSS博客 51CTO博客

2023-04-24 18:24:09 235浏览

oracle闪回技术,闪回技术(Flashback),是Oracle提供的能使数据库整体或局部回到“过去”的闪回功能的总称,主要用于对抗人为错误。在这些功能中,有的不会修改现有的数


闪回技术(Flashback),是Oracle提供的能使数据库整体或局部回到“过去”的闪回功能的总称,主要用于对抗人为错误。在这些功能中,有的不会修改现有的数据而只是展示以前的数据,即能够观察过去;有的可以将数据修改为以前的值,即真正地回到过去。

从11g开始,一共有7项闪回相关技术,分别为——闪回查询、闪回数据归档、闪回事务查询、闪回事务、闪回表、闪回删除和闪回数据库。

默认情况下,由于闪回日志没有启用,闪回数据库功能是关闭的;由于最小补充日志没有启用,闪回事务查询功能是关闭的;由于主键补充日志没有启用,闪回事务功能是关闭的,其他闪回功能默认便可使用。

oracle闪回技术_SQL

零、 可闪回时间窗口决定因素

1. 概述

根据闪回技术的不同,可闪回时间范围决定因素有所不同,但中心思想只有一个 —— 以空间换取过去的时间。闪回时间窗口可以有多大,最终取决于数据库能容忍多大的闪回数据保留量。

  • 闪回查询、闪回事务查询、闪回事务、闪回表:取决于undo数据保留时间(可以再细分为4种,参考后文)
  • 闪回数据归档:取决于历史表(存于普通表空间中)保留时间
  • 闪回删除:取决于回收站对象是否存在,当表空间存在空间压力时,Oracle自动清除回收站对象
  • 闪回数据库:取决于闪回及归档日志保留时间

2. undo数据保留时间取决因素

  • 初始化参数undo_retention的值

单位为秒(默认值为900s),该参数只是一个建议值,表示任何修改产生的undo数据应该在发起修改的事务提交之后再保留多长时间

show parameter undo_retention
  • UNDO表空间数据文件是否启用了自动增长

若能自动增长,则undo_retention参数的建议能够被最大限度地采纳。但必须注意,若能自动增长且undo_retention设置太高,UNDO表空间可能很大。

select autoextensible from dba_data_files where tablespace_name=(select value from v$parameter where name='undo_tablespace');
  • UNDO表空间是否为GUARANTEE

GARANTEE使原本为“建议”的undo_retention变为强制“规定”,默认为NOGARANTEE。

-- 查询UNDO表空间的RETENTION属性
select retention from dba_tablespaces where tablespace_name='UNDOTBS1';
-- 修改UNDO表空间的RETENTION属性
alter tablespace undotbs1 retention guarantee;

若UNDO表空间能自动增长,再配上过高undo_retention设置,现在再加上GUARANTEE设置,只能请DBA自重了,当事务量较大时,准备迎接巨无霸UNDO表空间吧。

  • 数据库中的事务量

显然事务量越大产生新的undo数据的速率就越高。面对庞大的事务量DBA在设置以上3要素时必须做出艰难的决定:想要确保UNDO表空间尽量小undo数据提交后肯定留不了多久,极端情况是接近900s;若要确保undo数据提交后再留得久一些,UNDO表空间必然变得很大,其中利弊只能由自己权衡了。

 下面我们正式来看7种闪回技术。

一、 闪回查询(Flashback Query)

以表为单位查询其过去的数据称为闪回查询,闪回查询能够在undo段内搜索“旧”数据,数据库能够保留多少undo数据决定了闪回查询的时间窗口的大小。

闪回查询分为两种:

  • 闪回时间点查询:在过去的一个时间点上的查询(as of子句与dbms_flashback包)
  • 闪回版本查询:在过去的一段时间范围内的查询(versions between子句)

1. 闪回时间点查询

通过下面几个例子很容易了解其使用方法与功能。

  • 查询hr.employees在2011-10-10 06:40:37时所有的行:
select * from hr.employees as of timestamp to_timestamp('2011-10-10 06:40:37','YYYY-MM-DD HH24:MI:SS');
  • 查询100号员工5分钟前的薪水:
select salary from hr.employees as of timestamp (systimestamp - interval '5' minute) where employee_id=100;
  • 查询100号员工在SCN为1243223时的工种:
select job_id from hr.employees as of scn 1243223 where employee_id=100;
  • 将10分钟前的hr.employees表与1小时前的hr.departments表以department_id为条件进行关联:
select e.last_name, d.department_name
from hr.employees as of timestamp(systimestamp - interval '10' minute) e,hr.departments as of timestamp(systimestamp - interval '1' hour) d
where e.department_id = d.department_id
  • 将100号员工的EMAIL字段修改为15分钟前的值:
update hr.employees 
set email=(select email from hr.employees as of timestamp  (systimestamp - interval '15' minute) where employee_id=100) 
where employee_id=100
  • 闪回PACKAGE:
-- 首先查询对象的 obj#号是多少
SELECT obj# FROM obj$ AS OF TIMESTAMP TO_TIMESTAMP('2011-09-08 15:25:00', 'YYYY-MMDD HH24:MI:SS') WHERE NAME = 'TEST_PACKAGE';

OBJ#
----------------
76389
76390

-- 有两个值,一个是包头,一个是包体
-- 再用如下sql查询正确值时间点的数据,通过查询结果就可以恢复了
SELECT source FROM source$ AS OF TIMESTAMP TO_TIMESTAMP('2011-09-08 15:25:00', 'YYYYMM-DD HH24:MI:SS') where obj# = 76390;

SELECT source FROM source$ AS OF TIMESTAMP TO_TIMESTAMP('2011-09-08 15:25:00', 'YYYYMM-DD HH24:MI:SS') where obj# = 76389;

闪回时间点查询的另一种方法是进入闪回模式:用dbms_flashback包的enable_at_time或enable_at_scn存储过程锁定一个会话级别的闪回时间目标,随后的查询命令就可以省略“as of”,但也能达到使用“as of”的闪回效果,直到调用dbms_flashback. disable存储过程关闭闪回模式为止。

比如,将闪回模式会话定格在15分钟前:

SQL> exec dbms_flashback.enable_at_time(systimestamp - interval '15' minute);
PL/SQL procedure successfully completed.

-- 现在,虽然没有as of子句,但以下查询的含义就是查看15分钟前的hr.employees表
SQL> select * from hr.employees;

需要注意此时若访问SYSDATE、SYSTIMESTAMP等日期函数,它们的返回值还是正常的当前值,而不是静止在15分钟以前。另外,处于闪回会话模式时,执行dml和ddl将报错。还有,SYS用户不能调用enable_at_time和enable_at_scn。

SQL> exec dbms_flashback.enable_at_time(systimestamp - interval '15' minute); 

BEGIN dbms_flashback.enable_at_time(systimestamp - interval '15' minute); END; *
ERROR at line 1:
ORA-08185: Flashback not supported for user SYS
ORA-06512: at "SYS.DBMS_FLASHBACK", line 3
ORA-06512: at line 1

在回到过去对所有感兴趣的表查询一番后,再调用disable存储过程关闭闪回会话模式回到正常状态:

SQL> exec dbms_flashback.disable
PL/SQL procedure successfully completed.

2.  闪回版本查询

闪回版本查询用于查询一段时间范围内表的数据,只使用一条查询就能返回该时间窗口内的不同时间点上的数据,其语法是在表名之后加versions between子句。

比如,首先通过3个事务将200号员工的薪水进行修改。其值原先是4400,然后是700000和5000,最后为1。对200号员工执行闪回版本查询的结果将返回多个200号员工:

select employee_id,salary from hr.employees versions between timestamp (systimestamp - interval '10' minute) and maxvalue where employee_id=200;

EMPLOYEE_ID     SALARY
-----------     ----------
200             1
200             5000
200             700000
200             4400

为了能看清这些事务的先后顺序,可以在查询列表中使用闪回版本查询特有的伪字段:

SQL> select versions_xid,versions_startscn,versions_endscn,employee_id,salary
from hr.employees versions between timestamp (systimestamp - interval '15' minute) and maxvalue
where employee_id=200
order by 2 nulls first;

oracle闪回技术_SQL_02

其中VERSIONS_XID表示事务号,VERSIONS_STARTSCN和VERSIONS_ENDSCN分别是事务开始时的SCN和修改该行的下一个事务开始时的SCN,首尾衔接这两个字段的SCN号很容易得到真实的修改顺序:4400,700000,5000,最后变为1。

能在闪回版本查询中使用的伪字段有:VERSIONS_XID、VERSIONS_STARTSCN、VERSIONS_ENDSCN、VERSIONS_STARTTIME和VERSIONS_ENDTIME。

二、 闪回数据归档(Flashback Data Archive)

闪回查询对undo数据及参数undo_retention的依赖注定了它们在大事务量的情况下闪回时间窗口将会很小,想要查询数月之前的“旧”数据绝对不可能,但在闪回数据归档面前这并不是不可能的。

闪回数据归档的工作原理是将原本只能保存在UNDO表空间的undo数据额外的以历史表的形式保存在指定的普通表空间中,并且它可以只为特定的表服务,这样就可以长时间地保存感兴趣的“旧”数据了。

比如,在USERS表空间中创建一个能够将“旧”数据保存1年的数据归档,取名为“FDA1”,操作者必须拥有“flashback archive administer”系统权限:

SQL> create flashback archive fda1 tablespace users retention 1 year;
Flashback archive created.

或者创建一个默认的闪回数据归档,取名为“fda_default”,操作者必须拥有SYSDBA权限:

SQL> create flashback archive default fda_default tablespace users retention 1 year;
Flashback archive created.

有了归档,就可以使用“flashback archive”子句在特定的表上启用闪回数据归档功能了。

比如,让hr.employees使用fda1,从此该表的修改历史将保留1年:

SQL> alter table hr.employees flashback archive fda1;
Table altered.

若执行以上命令的是个普通账号,比如HR用户,那么其在执行命令前必须被授予“flashback archive”对象权限,比如:

SQL> grant flashback archive on fda1 to hr;
Grant succeeded.

若有默认的闪回数据归档,则启用时不必给出其名称。比如让hr.departments使用默认的FDA,从此该表的修改历史也将保留1年:

SQL> create table oe.inventory(id number,product_id number,supplier_id number) flashback archive fda1;
Table created.

使用no flashback archive子句可以关闭特定表上的闪回数据归档功能。执行该命令需要flashback archive administer权限:

SQL> alter table oe.inventory no flashback archive;
Table altered.

启用闪回数据归档之后大大扩展了闪回查询的时间窗口,比如在启用归档功能至少7个月之后再查看hr.employees表7个月前的内容:

SQL> select * from hr.employees as of timestamp (systimestamp - interval '7' month);

以hr.employees基表为例,使用以下查询能够一睹闪回归档的主要信息:

SQL> select a.flashback_archive_name fda_name,a.retention_in_days days,ts.tablespace_name ts,ts.quota_in_mb,t.archive_table_name
From dba_flashback_archive a,dba_flashback_archive_ts ts, dba_flashback_archive_tables t
Where a.flashback_archive_name = ts.flashback_archive_name and  a.flashback_archive_name = t.flashback_archive_name and  t.owner_name = 'HR' and t.table_name = 'EMPLOYEES';

oracle闪回技术_database_03

其中ARCHIVE_TABLE_NAME字段的值就是归档中历史表的名字——SYS_FBA_HIST_73953,该表不能直接查询,更不用提其他操作了。结果中还显示了配额的大小(QUOTA_IN_MB)为空,即没有配额限制。管理员在创建闪回归档时实际上可以为其设置能够占用的磁盘空间上限,即所谓的配额。

比如创建归档fda2时限制其空间限制为40GB:

SQL> create flashback archive fda2 tablespace users quota 40G retention 2 year;
Flashback archive created.

另外,闪回数据归档中的历史数据可以被手工清除。比如清除归档fda中一个月之前的数据:

SQL> alter flashback archive fda purge before timestamp (systimestamp - interval '1' month);
Flashback archive altered.

或全部清除:

SQL> alter flashback archive fda purge all;
Flashback archive altered.

启用了闪回数据归档功能的表依然支持绝大多数的ddl命令。但在执行少数ddl命令时会遭遇“ORA-55610: Invalid DDL statement on history-tracked table”错误,比如“alter table … shrink space”、“alter table … move”、“alter table … exchange partition”等。

三、 闪回事务查询

闪回事务查询有别于闪回查询的特点有以下3个:

  • 不但需要利用undo数据,还需要事先启用最小补充日志。
  • 返回的结果不是以前的“旧”数据,而是能够将当前数据修改为以前的样子的撤销SQL语句(Undo SQL)。
  • 都在flashback_transaction_query表上查询,而不是在各个表上通过“as of”或“versions between”子句查询。

首先打开最小补充日志

SQL> alter database add supplemental log data;

此后,只要在闪回查询的查询窗口内,管理员就可以通过flashback_transaction_query表获得相关事务的撤销SQL。

下面列举一个典型的闪回事务查询的使用方法。

场景:用户在一个事务中分别使用insert和update命令修改了hr.departments和hr.employees表:

SQL> insert into hr.departments(department_id,department_name,manager_id,location_id) values (999,'SETI',100,1700);
SQL> update hr.employees set department_id=999 where employee_id=200;
SQL> commit;

该事务创建了一个新的999号部门,并且将200号员工指派入该新部门。可惜这个事务是人为错误,如何利用闪回事务查询恢复原始状态?

首先通过闪回版本查询获得该事务的XID,比如从错误的999号部门入手:

SQL> select versions_xid,versions_startscn,department_id,department_name
from hr.departments versions between timestamp minvalue and maxvalue
where department_id=999
order by 2 nulls first;

然后使用结果中的事务号090010002B030000查询flashback_transaction_query表以获得撤销SQL:

SQL> select undo_sql from flashback_transaction_query where xid='090010002B030000';

UNDO_SQL
--------------------------------------------------
update "HR"."EMPLOYEES" set "DEPARTMENT_ID" = '10' where ROWID = 'AAAR5pAAFAAAADLAAC';
delete from "HR"."DEPARTMENTS" where ROWID = 'AAAR5kAAFAAAACtAAA';
2 rows selected.

结果得到了两句dml命令,不难发现撤销SQL试图将hr.employees表中200号员工的部门从999修改为10

oracle闪回技术_database_04

并且试图删除999号部门

oracle闪回技术_oracle_05

闪回事务查询可以将同一事务的所有撤销SQL列出,这是闪回查询做不到的,如有必要,管理员还能够执行对应一个事务的部分撤销SQL恢复一部分数据,如此行事正确与否完全取决于应用的逻辑。

最后,因为ddl命令的撤销SQL包括对数据字典表的DML操作,人为修改数据字典表是非常危险的,况且某些DDL操作不仅仅是对数据字典的DML操作,它们还涉及撤销SQL无法影响到的领域,所以不要指望通过直接执行撤销SQL恢复错误的ddl命令造成的影响。

四、 闪回事务(Flashback Transaction)

1. 简介

到目前为止,介绍的所有功能均不会直接将数据恢复为“以前”的样子。闪回查询只是查看,闪回数据归档只是延伸了闪回查询的时间窗口,闪回事务查询虽然提供了撤销SQL,但是否执行及如何执行还需要管理员进一步手动操作。

若是管理员决定撤销某个或某些事务,Oracle提供一个专门用来撤销事务的工具——闪回事务。

闪回事务又名撤销事务(Backout Transaction),能够撤销一个或多个事务的修改,其功能由一个名为DBMS_FLASHBACK.TRANSACTION_BACKOUT的存储过程实现。该存储过程的工作原理是自动分析重做日志,挖掘出变更前的值用以构建撤销SQL(Undo SQL),然后执行撤销SQL最后达到撤销事务的目的。

为使用该功能,至少需要事先启用主键补充日志。另外,为了能够跟踪外键依赖还需要启用外键补充日志。

2. 事务的依赖性

在继续讨论此功能前,首先应了解一个概念:事务的依赖性。比如,两个事务TX1和TX2,符合以下3个条件的任意一个就可以认为TX2依赖TX1:

  • WAW依赖(Write After Write):在TX1修改了表的某行之后,TX2又修改了同一行。
  • 主键依赖:在一张拥有主键的表中TX1首先删除了一行,之后TX2又插入了具有相同主键值的另一行。
  • 外建依赖:由于TX1的修改(insert或update)而产生了新的可被外键参考的字段值,之后TX2修改(insert或update)外键字段时利用了TX1所产生的字段值。

了解事务依赖性有助于解决在撤销事务时遇到的矛盾,以主键依赖为例,试想若直接将事务TX1撤销并且不理会事务TX2,岂不是会出现主键值重复的行?

TRANSACTION_BACKOUT存储过程的OPTIONS参数就是为了解决事务依赖性问题而存在的。假设被撤销的事务是TX1,若其具有依赖事务,则称为TX2。OPTIONS参数有4种可选值:

  • NOCASCADE:TX1不可以被任何其他事务依赖(即TX2必须不存在),否则撤销操作报错。
  • CASCADE:将TX1和TX2一起撤销。
  • NOCASCADE_FORCE:忽略TX2,只将TX1撤销,如果没有约束上的冲突操作将成功,否则约束报错导致撤销失败。
  • NONCONFILICT_ONLY:在不影响TX2的前提下,撤销TX1的修改。会首先过滤一下TX1的撤销SQL,确保它们不会作用在TX2修改的行上。

3. 简单用法

  • 查询待撤销事务的xid和commit_scn
select distinct xid,commit_scn
from flashback_transaction_query
where table_owner='HR' and table_name='EMPLOYEES' and commit_timestamp > systimestamp - interval '15' minute
order by commit_scn;

XID              COMMIT_SCN
---------------- ----------
0A00160094020000    1277129
0900070068030000    1277301
  • 将待撤销事务的xid载入对应VARRAY集合变量,并以NOCASCADE方式调用BACKOUT_TRANSACTION。

如果报错,再从另外3种方式中选择一个调用BACKOUT_TRANSACTION。

declare
xids sys.xid_array;
begin
xids := sys.xid_array('0A00160094020000');
dbms_flashback.transaction_backout(1,xids,options=>dbms_flashback.nocascade);
end;
/

dbms_flashback.transaction_backout存储过程参数含义如下:

  1. 第一个参数表示VARRAY内事务号的数量,本例中只有一个事务需要撤销,所以等于1。
  2. 第二个参数是一个容纳事务号的VARRAY集合变量
  3. 第三个参数是上面提过的OPTIONS选项
  • 查看闪回事务操作的报告

oracle闪回技术_数据库_06

  • 最后决定提交或回滚

五、 闪回表(Flashback Table)

闪回表flashback table命令能够以表为单位将数据恢复为“以前”的样子(而不像闪回事务以事务为单位)。

闪回表也是利用UNDO表空间的undo数据,所以能将表闪回到多久之前同样受到前面所说的因素影响

1. 注意事项

  • 被闪回的表必须启用行移动功能
alter table hr.employees enable row movement;
Table altered.
  • 闪回表命令执行者必须有FLASHBACK ANY TABLE权限或者在被闪回的表上有FLASHBACK对象权限
  • FLASHBACK TABLE属于ddl命令,自动提交
  • SYS用户的表无法使用此功能

2. 简单用法

  • 将hr.employees闪回到10分钟之前:
flashback table hr.employees to timestamp (systimestamp - interval '10' minute);
Flashback complete.
  • 将hr.employees闪回到SCN为1080381的时候:
flashback table hr.employees to scn 1080381;
Flashback complete.
  • 将hr.employees和hr.departments两张表同时闪回到SCN为1080381的时候(有外键关系的表可能需要一起闪回):
flashback table hr.employees,hr.departments to scn 1080381;
Flashback complete.

六、 闪回删除(Flashback Drop)

闪回删除指的是撤销“DROP TABLE”的效果,需要启用回收站。语法为“FLASHBACK TABLE … TO BEFORE DROP”。

1. 简单例子

-- 创建一张带数据的新表EMP:
SQL> create table emp tablespace users as select * from hr.employees;
Table created.

-- 删除EMP:
SQL> drop table emp;
Table dropped.

-- 找回EMP:
SQL> flashback table emp to before drop;
Flashback complete.

SQL> select count(*) from emp;

COUNT(*)
----------
107

2. 工作原理

执行drop table时,表和索引并没有被真正删除,其所占空间(称为段)只是分配给了回收站对象,并且这种分配没有使数据和数据块发生任何移动,还是待在原来的数据文件及表空间中。

回收站对象的信息可以通过dba_recyclebin视图获得,普通用户可以使用show recyclebin命令查看自己的回收站:

oracle闪回技术_SQL_07

回收站对象本身也可以被查询

select count(*) from "BIN$r4C+sJfzPq7gQAsLDAsoBQ==$0";

COUNT(*)
----------
107

将回收站对象取出并重命名

flashback table emp to before drop rename to empold;
Flashback complete.

如果表名重复,在闪回时遵循后入先出原则,留意“show recyclebin”命令显示的“DROP TIME”字段或者在闪回时指明被恢复的回收站对象:

flashback table "BIN$r4D3SgQXjj7gQAsLDAsxdw==$0" to before drop;
Flashback complete.

回收站对象毕竟是一种弱存在,Oracle没有义务永远保留被删除的表的数据,表空间在自动增长的压力下会按照先入先出的规则将回收站对象的区(数据块的集合)分配给需要空间的段,在将回收站对象耗尽之前数据文件是不会自动增长的,反之,若数据文件自动增长了,说明其内的所有回收站对象已经全部失效了。

以下查询可以确认有哪些回收站对象已经不能回到被DROP之前了:

select owner,object_name,original_name from dba_recyclebin where can_undrop='NO';
no rows selected

3. 回收站手动清理

  • drop时跳过回收站(删除EMP表并且不产生回收站对象)
drop table emp purge;
Table dropped.
  • 删除特定回收站对象
purge table "BIN$r4D3SgQmjj7gQAsLDAsxdw==$0";
Table purged.
  • 删除当前用户回收站中的所有对象:
purge user_recyclebin;
Recyclebin purged.
  • 删除数据库中所有的回收站中的所有对象:
purge dba_recyclebin;
DBA Recyclebin purged.

4. 禁用回收站功能

将静态参数recyclebin改为off后重启实例

SQL> alter system set recyclebin='off' scope=spfile;
System altered.

SQL> shutdown immediate;
SQL> startup;

七、 闪回数据库

闪回数据库的命令是“flashback database ”,可以是SCN、时间或还原点,顾名思义,就是将整个数据库回退到指定的一个时间点,实际上是数据库不完全恢复的另一种方式。真正的不完全恢复需要消耗的时间与数据库的大小有密切联系,数据库越庞大,需要的时间就越多,对于大型数据库来说,哪怕是只为了回到30秒之前,消耗的时间也是惊人的。

闪回数据库技术改变了这个窘境,其处理问题方式着重于如何将相对较短的时间内发生的变更去除,而不是如何还原足够旧的备份(这已经很花时间了),再利用归档日志前滚至指定时间。闪回的“闪”字用在这里显得十分贴切。

1. 闪回数据库与日志

闪回数据库需要使用两种日志:闪回日志和归档日志。归档日志已为大家所知,而闪回日志就像是归档日志的反作用力,闪回日志的记载正好与归档日志的记载相反。比如,逻辑上归档日志记录insert命令的重做记录,闪回日志就记录delete命令的重做记录(当然实际上没那么简单)。在发起闪回操作时,只要根据写入闪回日志的相反顺序,即后写先读的顺序,将闪回记录从闪回日志读出并执行其记录的变更就能够将数据库在时间轴上倒推。

闪回日志的保存路径一定是fra的子目录,保存的期限则由参数db_flashback_retention_target控制(分钟),超出保存期限的闪回日志将会在fra空间紧张的时候被自动删除。

指定数据库保留两天的闪回日志

SQL> alter system set db_flashback_retention_target=2880;
System altered.

查看闪回日志是否已启用

SQL> select flashback_on from v$database; FLASHBACK_ON
------------------
NO

启用闪回日志,即闪回数据库功能:

SQL> alter database flashback on;
Database altered.

启用后在fra的flashback子目录下将会出现扩展名为.flb的文件,它们就是闪回日志。

2. 闪回数据库用法

  • 检查最远可以闪回到哪里
select oldest_flashback_scn,to_char(oldest_flashback_time,'YYYY-MM-DD HH24:MI:SS') from v$flashback_database_log;

OLDEST_FLASHBACK_SCN TO_CHAR(OLDEST_FLAS
-------------------- -------------------
1041426              2011-10-17 02:57:34
  • 进入MOUNT状态发起闪回操作

可以反复地以任何顺序执行:“flashback database to …”、“recover database”和“alter database open read only”。

-- 进入数据库的MOUNT状态:
SQL> startup force mount;

-- 回到SCN号1041440:
SQL> flashback database to scn 1041440;
Flashback complete.

-- 以只读形式打开数据库,查看SCN在1041440时所有数据,以便判断闪回操作是否达到目的
SQL> alter database open read only;
Database altered.

-- 如此循环,直到获得满意的结果为止。
  • 获得满意结果后,如果是主库,最后以resetlogs方式打开数据库,效果和不完全恢复一模一样
SQL> startup force mount;
SQL> alter database open resetlogs;
Database altered.
  • 如果是从库,通过dblink或dump将需要数据取出,然后恢复主从同步

若有足够的归档,可以直接开启日志应用

alter database recover managed standby database using current logfile disconnect from session parallel 4;

若归档不够,可以尝试闪回到最近有归档保留的时候再开启日志应用,或者从主库拷贝归档过来再进行注册(比较麻烦)

详情参考 Oracle 闪回(flashback)数据库到指定时间点_Hehuyi_In的博客

3. 闪回数据库原理

一次闪回数据库操作可能由两种方式进行。

比如,令当前时间点为TC,数据库闪回的目标时间点为T1(TC大于T1),会自动选择以下两种方式之一进行闪回操作。

方式一:

  • 第一阶段:利用闪回日志将数据库从TC“倒推”至较T1更旧的某一时刻T2。
  • 第二阶段:利用归档日志将数据库从T2“前滚”至T1。

方式二:

  • 第一阶段:确定一个比T1更旧的某一时刻T2。对于闪回日志无法恢复的对象或数据(执行了truncate,drop等),设此类对象创建时间为T3,首先利用T3到T2的归档日志将其重新产生并恢复。
  • 第二阶段:利用闪回日志将数据库从TC“倒推”至T2。
  • 第三阶段:利用归档日志将数据库从T2“前滚”至T1(途中经过T2)。

究竟采用哪种方式执行取决于目标时间点T1与当前时间点TC之间执行过什么命令,如果是在闪回日志中有对应反向操作的命令(如insert、update、delete)就采用方式一;如果在闪回日志中找不到对应反向操作的命令(比如:truncate命令)则采用方式二。方式二较方式一可能会索要更多的归档日志才可以完成闪回。

若有发生过truncate table操作,那么方式二中的T3就是被截断的表当初创建的时刻,这意味着整个闪回操作需要从T3至T1的所有的归档日志,否则闪回数据库不可能成功。这样,可能会发生这样的问题:即使只是在10秒前错误地截断了一张表,需要回到10秒之前,但是闪回数据库时向管理员索要一年前的归档日志!

悲观情绪不必过度蔓延,如果T1和TC之间只是发生过类似update那样的DML,若是想回到10秒前,那么会采用方式一,差不多只是需要10秒的闪回日志和归档日志,闪回会很快,这也是闪回的真谛。

4. 常见问题

无论哪种方式,都可能遇到归档日志不充分的问题,报错信息类似:

SQL> flashback database to scn 1036988; flashback database to scn 1036988;

ERROR at line 1:
ORA-38754: FLASHBACK DATABASE not started; required redo log is not available 
ORA-38762: redo logs needed for SCN 1036814 to SCN 1036988
ORA-38761: redo log sequence 19 in thread 1, incarnation 2 could not be accessed

也可能遇到闪回日志不够的问题,报错信息如下所示:

SQL> flashback database to scn 1036988; flashback database to scn 1036988;

ERROR at line 1:
ORA-38729: Not enough flashback database log data to do FLASHBACK.

八、 常见报错小结

  • 若闪回查询需要的撤销数据已经不存在,select将报告“ORA-01555: snapshot too old”错误。
  • 若闪回表需要的撤销数据已经不存在,flashback将报告“ORA-08180: no snapshot found based on specified time”错误。
  • 闪回查询、闪回事务查询、闪回表均依赖ROWID定位“过去”和“现在”的行,如果执行过导致行移动的命令(如“alter table … move”、“alter table … shrink space”),再执行闪回操作将会导致“ORA-01466: unable to read data - table definition has changed”错误。
  • 闪回事务依赖重做日志和撤销数据,如果调用dbms_flashback.transaction_backout时所需的日志不存在,将报告类似“ORA-00308: cannot open archived log”的错误;若是撤销数据已不存在,将报告“ORA-01555: snapshot too old”错误。

参考:《临危不惧Oracle11g数据库恢复技术》

好博客就要一起分享哦!分享海报

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695