千家信息网

Oracle的7大闪回技术讲解

发表于:2024-11-22 作者:千家信息网编辑
千家信息网最后更新 2024年11月22日,Oracle的闪回1 flashback 的功能:1)利用undo data回溯或撤销提交的数据,2)flashback log 使database 可以恢复到过去某个时间点,可以作为不完恢复的补充。
千家信息网最后更新 2024年11月22日Oracle的7大闪回技术讲解


Oracle的闪回












1 flashback 的功能:

1)利用undo data回溯或撤销提交的数据,

2)flashback log 使database 可以恢复到过去某个时间点,可以作为不完恢复的补充。


2 flashback分类

1)flashback drop

2)flashback query (新添flashback database archive)

3)flashback table

4)flashback version query

5)flashback transaction

6)flashback database



2.1 闪回drop 又名闪回删除

1)理解回收站(recyclebin)

从管理的角度为每个用户"分配"一个回收站,但这个回收站并不实际开辟空间(只是个逻辑容器),当drop table时(非purge),原来的表所使用的段中的数据并没有真正的删除。实际上是把table的段名以回收站方式重命名。该段所在表空间不足需要扩展时,回收站中的信息会被自动清除(考点)。


做个例子理解一下

SQL> show parameter recyclebin

//当初始化参数recyclebin为on时,每个用户都有了自己的回收站

//如果参数设为off 就取消了用户的回收站,那么当你drop table就相当于purge了。


SQL> create tablespace test1 datafile '/u01/app/oracle/oradata/hyyk/test01.dbf' size 1m;

SQL> create table scott.t1(id int) tablespace test1;

SQL> insert into scott.t1 values(1);

SQL> insert into scott.t1 values(1);

SQL> commit;

SQL> select segment_name from dba_segments where tablespace_name='TEST1';

//看test表空间下有了一个段

SQL> select sum(bytes) from dba_free_space where tablespace_name='TEST1';

//看这个段有多少空闲空间

继续插入数据,将表空间撑满

SQL> insert into scott.t1 values(1);

SQL> insert into scott.t1 select * from scott.t1;

/

/


查看数据有多少行

SQL> select count(*) from scott.t1;

SQL> select sum(bytes) from dba_free_space where tablespace_name='TEST1';

//显示没有空闲空间


删除表t1

SQL> drop table scott.t1;


查看表空间为TEST1的段名被修改了

SQL> select segment_name from dba_segments where tablespace_name='TEST1';


SQL> select sum(bytes) from dba_free_space where tablespace_name='TEST1';

请看,TEST表空间中的空闲空间又回来了,这说明如果test表空间不够时,这部分空闲空间是可以被重新利用的,实际上即使你设置了表空间autoextend特性,Oracle 会先使用recyclebin,若空间还不够,再考虑autoextend.


SQL> create table scott.emp2 tablespace test1 as select * from scott.emp; //挤占test表空间

SQL> select sum(bytes) from dba_free_space where tablespace_name='TEST1';

SQL> select segment_name from dba_segments where tablespace_name='TEST1';

//t1表的数据已经被冲掉了,使用闪回删除无法找回了(考点)。


2)关于回收站中的对象的闪回和清除


闪回和清除的顺序不同


闪回使用LIFO (后进先出)

清除使用FIFO (先进先出)


假设回收站里有两个t1表,看以下两条语句:


SQL> flashback table t1 to before drop; //闪回的是最新的那个t1表(考点)。

SQL> purge table t1; //清除的是最旧的那个t1表(考点)。


如果想避免混淆,可以直接点出回收站里的表名

SQL> flashback table " BIN$qrJLbL74ZgvgQKjA8Agb/A==$0" to befroe drop;

SQL> purge table "BIN$qrJLbL74ZgvgQKjA8Agb/A==$0";


SQL> purge recyclebin; //清空回收站


3)如何恢复同一个schema下准备闪回的表已有同名的对象存在,闪回drop需要重命名.

SQL> drop table emp1;

SQL> create table emp1 as select * from emp;

SQL> select * from tab;


SQL> show recycle;


SQL> flashback table emp1 to before drop rename to test_old;

//闪回drop语句中使用了重命名



4)system 表空间的对象没有回收站,所以在sys下缺省使用system表空间时,drop table会直接删除对象(考点)


5)如果一个表上面有索引和约束,drop后再闪回表,索引和约束还在吗?


create table t (id int,name char(10));

alter table t add constraint pk_t primary key(id);

insert into t values (1,'sohu');

insert into t values (2,'sina');

commit;


SQL> select * from t;



-----看一眼约束和索引



SCOTT@hyyk> col segment_name for a20

SCOTT@hyyk> select segment_name,segment_type from user_segments;



SCOTT@hyyk> select constraint_name from user_constraints;


SQL> drop table t;






----表被drop到回收站,再看一眼约束和索引

SQL> select segment_name,segment_type from user_segments;

SQL> select constraint_name from user_constraints; //约束有,但乱码(除外键约束外)


SQL> flashback table t to before drop;


-----再看约束和索引


SQL> select segment_name,segment_type from user_segments;

//索引回来了,有效(考点),但乱码


SQL> select constraint_name from user_constraints; //约束也在,有效(考点),但乱码


-----分别重命名索引和约束


SQL> alter index "BIN$YIkba0zjgoDgUAEKCAFgVQ==$0" rename to pk_t;


SQL> alter table t rename constraint "BIN$YIkba0zigoDgUAEKCAFgVQ==$0" to pk_t;


-----再看约束和索引




2.2 闪回查询 flashback query:(用于DML 误操作)

1)要点:

利用在undo tablespace 里已经被提交的undo block(未被覆盖),可以通过查询的方式将表里面的记录回到过去某个时间点。通过设置undo_retention参数设置前镜像的保留时间。


查询的语法:

select … as of scn | timestamp


2)实验

sys用户:

create table scott.student (sno int,sname char(10),sage int);

insert into scott.student values(1,'Tom',21);

insert into scott.student values(2,'Kite',22);

insert into scott.student values(3,'Bob',23);

insert into scott.student values(4,'Mike',24);

commit;

/


查看数据

SQL> select * from scott.student;

取时间1和取scn1,用于后面闪回查询使用

select to_char(sysdate, 'yyyy-mm-dd hh34:mi:ss') from dual; //时间1

TO_CHAR(SYSDATE,'YY

-------------------

2017-12-17 20:28:49


select current_scn from v$database; //取scn1

CURRENT_SCN

-----------

1431343


删除表中1行数据,并提交

delete scott.student where sno=1;

commit;


验证是否删除成功

select * from scott.student;

这里我们在取时间2和scn2

select to_char(sysdate, 'yyyy-mm-dd hh34:mi:ss') from dual; //取时间2

TO_CHAR(SYSDATE,'YY

--------------------------

2017-12-17 20:30:41


select current_scn from v$database; //取scn 2

CURRENT_SCN

-----------

1431479


我们在更新一下表中的数据

update scott.student set sage=50;

commit;

select * from scott.student;





我们使用scott用户进行闪回查询:

闪回查询时间1时刻student表的数据,虽然数据库在时间1之后进行了删除和更新,但是可以可以没有覆盖的undo中读取到时间1时刻的状态

select * from student as of timestamp to_date('2017-12-17 20:30:41','yyyy-mm-dd hh34:mi:ss');

闪回查询scn2的状态

select * from student as of scn 1431343;

如果在scn2之后,由于操作事物导致一些数据丢失,就可以使用下面的方法恢复数据

1.通过闪回查询的数据建立一个student2表

create table student2 as select * from scott.student as of scn 1431343;


2.删除旧的的student

drop table student;


3.将student2表重命名成student

rename student2 to student;

select * from student;


*考点:可以查询以前某个时间点的数据库,但是永远不能对过去时间点得数据库做DML操作



2.3 闪回表

1)要点

闪回表通常是把表的状态回退到以前的某个时刻或者SCN上。(其实向前向后都能闪)。自动恢复相关的属性,包括索引、触发器等。

前提是对表启用行移动

为什么使用行移动:这里的flashback table 指的是从undo中闪回,试想这张表原来的存储位置被别的objects占用的话,他回不到原来的位置,所以要使用enable row movement


语法:

flashback table to timestamp | scn


2)实验

delete student;

commit;

alter table student enable row movement;

flashback table student to scn XXXXX


考点:

1)sys的表不能闪回。

2)必须使能行移动。

3)缺省下,闪回表的过程中有关的trigger都关闭。

4)闪回表有index是被维护的

5 ) 物化视图下不许闪回表操作


2.4 闪回数据归档 (FLASHBACK ARCHIVE) 11g新特性(TOTAL RECALL)

1. 概念

无限期的存储表行数据,通过后台进程FBDA,捕捉必要的数据并将其保存在归档上,然后可以使用常规闪回查询命令(as of)查询需要的数据,但闪回可以回朔到多年以前。闪回归档可以看成是闪回查询时间的延伸。


2. 有几个要点


  1. 首先要有一个(或多个)表空间存放归档表,可以加上配额,使用与原表同一表空间在技术上是可行的,但Oracle建议它们与常规的数据分开存放更好。


  2. 先要建立一个归档名(方案),作为一个数据库的对象,可以为它指定default属性,含义是把所有要归档的表都建立在该缺省的归档名下。


3) 可以根据需要建立多个闪回归档名(方案),这取决于你需要多少种不同的保留时间。可以调整保留时间,一旦超过了保留期限,后台进程FDBA将自动删除该表历史记录,也可以在保留期内手动进行删除操作。


4) 关于两个权限:

flashback archive administer //授予用户创建,修改或删除闪回归档名(方案)

flashback archive //授予用户对表进行归档。


5) 启用表的闪回归档需要使用alter table 表名 flashback archive 归档名


6) 闪回归档enable也有个前提条件,表空间要ASSM管理和以及undo_management=on, 否则修改表时报ORA_55614错误


7) 关于闪回归档的视图:

DBA_FLASHBACK_ARCHIVE //描述配置的归档

DBA_FLASHBACK_ARCHIVE_TS //列出使用的表空间

DBA_FLASHBACK_ARCHIVE_TABLES //查看归档的表



3. 实验

例1:DBA建一个表空间用于闪回归档,然后将闪回归档作为一个对象创建并授权。

sys:

create tablespace fda datafile '/u01/app/oracle/oradata/hyyk/fda01.dbf' size 5m;

create flashback archive fla1 tablespace fda quota 2m retention 1 year;

grant flashback archive on fla1 to scott;


用户将自己的表定义为闪回归档

scott:

alter table emp1 flashback archive fla1;


可以做些DML操作在使用闪回查询(as of)验证。

11gR1上尝试做一些DDL操作会报错(11gR2上已改进了,PPT-II-291):

scott:

alter table emp1 drop column comm;

truncate table emp1;

ORA-55610: 针对历史记录跟踪表的 DDL 语句无效。(修改列删除列,清空记录可以 但是不能删除)


drop table emp1;(11gR2上也不行)


下面演示取消归档保护

sys:

查看有哪些归档名

SQL> select owner_name,flashback_archive_name from dba_flashback_archive;

SQL> select * from dba_flashback_archive_ts; //查看归档使用表空间的信息


SQL> select * from dba_flashback_archive_tables; //查看表emp1和归档名的关系。

sys:

SQL> alter table scott.emp1 no flashback archive; //将表scott.emp1从闪回归档中取消


例2:通过一道考题我们来实验一下,什么是default归档:

题目:

Note the output of the following query;

SQL> SELECT flashback_archive_name, status FROM dba_flashback_archive;


FLASHBACK_ARCHIEVE_NAME STATUS

FLA1 (无default 需要指定)


You executed the following command to enable Flashback Data Archive on the

EXCHANGB_PATE table:

ALTER TABLE exchange_rate FLASHBACK ARCHIEVE; on。。。。。

What is the outcome of this command?

A.The table uses the default Flashback Data Archive.

B.The Flashback Data Archive Is created In the SYSAUX tablespace.

C.The Flashback Data Archive is created in the same tablespace where the tables are stored.

D.The command generates an error because no flashback Data Archive name is specified and there is no default Flashback Data Achieve.


答案:d


SQL> conn / as sysdba。

SQL> alter flashback archive fla1 set default;

SQL> select FLASHBACK_ARCHIVE_NAME,STATUS from dba_flashback_archive;


SQL> alter table scott.emp1 flashback archive; //不用指定归档名,emp1绑定了FLA1(DEFAULT)。


SQL> select * from dba_flashback_archive_tables;


删除闪回归档(方案)

SQL> drop flashback archive fla1;



考点:设置闪回数据归档有两个先决条件:

1)使能automatic undo managent

2)tablespace要ASSM的。




2.5 闪回版本查询(PPT-II-260)


1)要点

闪回查询仅仅能够得到过去某个时间点上的数据,但是无法反映出一段时间内数据表中数据变化的细节,10g的闪回版本查询可以对时间段内数据表的每行变化(不同版本)进行查询。


语法:select … from … versions between

其中,select后面可以选择伪列,来获得事务的开始、结束时间、SCN号、ID号等。


2)举例:

scott:

create table t3 (id int, name char(10));

insert into t3 values(1,'tim');

insert into t3 values(2,'mike');

insert into t3 values(3,'brain');

insert into t3 values(4,'cade');

commit;


update t3 set name='nelson' where id=4;

commit;

delete t3 where id=2;

commit;

update t3 set id=id+100;

commit;


看看t3表经历的时间变化

SQL> select versions_startscn, versions_endscn, versions_xid, versions_operation,id,name from scott.t3 versions between scn minvalue and maxvalue;







SQL>select versions_xid, versions_operation,id, name from t3 versions between scn minvalue and maxvalue;

考点:

  1. 闪回版本查询不能用于外部表、临时表或V$视图。原因是这些对象都不生成撤销数据。(临时表的撤销是基于session的)。

2)闪回版本中的内容不包括未提交的DML语句。


2.6 闪回事务查询(PPT-II-270)

1)要点:

闪回事务查询可以提供撤销查询语句。从flashback_transaction_query 这个视图里查询引起数据变化的事务,和撤销事务的SQL语句也就是查询operation 和 undo_sql列。可以和闪回版本查询结合起来使用。

sys:

SQL>desc flashback_transaction_query;

SQL>select undo_sql from flashback_transaction_query where xid=hextoraw('事务号');


接上例:

SQL> select undo_sql from flashback_transaction_query where xid=hextoraw('02000E0024040000');

//执行上面语句,原操作(update t3 set id=id+100;)就撤销了


SQL> update "SYS"."T3" set "ID" = '4' where ROWID = 'AAANByAABAAAO/yAAD';

SQL> update "SYS"."T3" set "ID" = '3' where ROWID = 'AAANByAABAAAO/yAAC';

SQL> update "SYS"."T3" set "ID" = '1' where ROWID = 'AAANByAABAAAO/yAAA';

SQL> commit;


grant execute on dbms_flashback to scott;


闪回事务查询考点

  1. Enable Supplemental Logging(补充日志) 并且数据库版本10.0 compatibility
  2. SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;

3) 查询flashback_transaction_query视图需要SELECT ANY TRANSACTION权限。



2.7 闪回数据库(先闪回日志)

1)概念:

闪回数据库相当于不完全恢复,它通过闪回日志将数据库整体回退到某个时间点。

闪回数据库针对的是逻辑错误,如果数据库发生了物理损坏或介质丢失,闪回数据库将无能为力,闪回数据库不能完全代替传统不完全恢复(考点)

使用闪回数据库,需要开启闪回日志,闪回日志存放在闪回恢复区里。


一旦启用了闪回数据库,某些块的映像会从db buffer 复制到 SGA的一个新的存储区域中,即闪回缓冲区,然后再由后台进程(Recover Write RVWR)将此闪回恢复区的内容刷新到磁盘和闪回日志。这一切并没有改变LGWR的常规作用。与重做日志不同的是 RVWR不是记录数据库变化的日志,而是记录完整块影像的记录。(PPT-311)

*考点:不同于重做日志,闪回日志不能被多路复用和归档。它们是自动创建和管理的。


2)闪回日志放在闪回恢复区里

闪回恢复区(flash recovery area)是一个非常重要的概念, 它不仅存放闪回日志,还有许多与恢复有关的文件,比如,可以存放与RMAN相关的三种自动管理的文件,1.归档日志、2.控制文件自动备份 3.RMAN备份片。当flash recovery area空间不够用,Oracle还可以自动清除一些废弃(obsolete)文件。(PPT-II-49-55)


SQL> show parameter recovery_file


SQL> show parameter flash


*考点:1.设置db_recovery_file_dest之前必须先设置db_recovery_file_dest_size 。2.闪回日志存放的保留期,缺省值1440,单位是分钟。(先设置大小,再设置路径)


3)配置闪回数据库的基本步骤:


3.1) 数据库闪回要在mount状态下

SQL> STARTUP MOUNT EXCLUSIVE;


alter database archivelog;必须先开启归档,因为flashback依赖media recovery

alter database flashback on;


3.2) 配置成归档方式

SQL> ALTER DATABASE ARCHIVELOG;

闪回数据库必须配备成归档方式,是因为闪回日志里只记录了快照,这些快照可以使数据库回退到某个SCN点,而回退快照的SCN仅比你指定的SCN提前一点,然后会运用归档日志或当前日志前滚一小段,当到达指定的san时停住。然后在此SCN前resetlogs打开数据库。


3.3) 指定闪回恢复区

设置参数db_recovery_file_dest='u01/flash_recovery_area'


3.4) 配置闪回保留时间

设置参数db_flashback_retention_target=1440

注意单位是分钟,缺省1440 相当于24小时


3.5) 使能闪回数据库

SQL> alter database flashback on;

//其结果在/u01/app/oracle/flash_recovery_area/HYYK/flashback目录下创建了一个.flb的闪回日志文件。


SQL> select flashback_on from v$database; //查看闪回数据库启用或关闭

只是检查RVWR进程和闪回日志是否有了,如果alter database flashback off;闪回日志自动清除(考点)。


3.6)打开数据库

alter database open;


4) 例: 恢复被删除的用户。


首先进入mount下,配置相关参数,开启闪回数据库日志,然后打开数据库,接下来:


4.1)取当前SCN

SQL> select current_scn from v$database;

(方法二,SQL> create restore point abc [gurantee flashback database];

//"gurantee flashback database"选项可保证abc点(SCN)以来的闪回日志一直存在,不受retention影响)


CURRENT_SCN

-----------

1472195


4.2)删除scott用户

SQL> drop user scott cascade;


4.3)准备到mount下做闪回数据库

SQL> shutdown immediate;

SQL> startup mount exclusive //mount要附加exclusive(独占),意思是其他sysdba不能打开数据库,这是一个考点。


SQL> flashback database to scn 1472195;

(方法二,SQL> flashback database to restore point abc;)


4.4)只读方式打开,确认scott已经被闪回

SQL> alter database open read only;

SQL> select * from scott.emp;


4.5)确认无误后,重新以resetlogs 方式打开数据库(属于不完全恢复)


startup force;

alter database open resetlogs;

//一旦resetlogs打开,若想再一次做闪回,只能闪回比当前更早的scn(见PPT-315page)。



提醒:要在mount下闪回数据库

flashback database to timestamp to_date('2012-03-02 19:11:11','yyyy-mm-dd hh34:mi:ss');

flashback database to scn 1264788;


闪回后,打开数据库,第一次最好用只读方式, 看看是否恢复到你希望的那个时间点上去了,如果不是你希望的,还可以重新闪回(前闪/后闪都可以,因为只读方式scn是不会增长的)。


5)那些操作适合或不适合闪回数据库


适合:

drop table xxx purge

drop user xxx cascade

在某个用户操作影响到整个数据库时错误的truncate表


不适合:

控制文件,数据文件,修改数据不能用闪回数据库

使用了备份的控制文件或trace文件

drop表空间的操作

段重组后的表,收缩后的数据文件。


6) 使用保存点闪回数据库

SQL> create restore point gold; //保存点gold相当一个标记,记录了当前的SCN

...

SQL> startup mount

SQL> flashback database to restore point gold;


7)限制生成闪回数据量

默认情况下,如果启用了闪回数据库,那么会记录所有表空间的闪回数据,使用下面命令可以关闭个别表空间的属性,自然就不会生成该表空间的闪回数据。


SQL> alter tablespace flashback off; //可以在open下设置

SQL> alter tablespace flashback on; //可以在mount下设置

SQL> select * from v$tablespace //有个字段FLA可显示状态


flashback off的表空间在闪回数据库之前要offline(不参与闪回),所有数据文件scn不一致前不能打开数据库。

联机前要对offline的数据文件做部分还原和不完全恢复。


8)关于闪回数据库有两个视图:


v$flashback_database_log显示所能回退到的最早时间,取决与保留的Flashback Database Log 的多少。

v$flashback_database_stat以一个时间段为一行(大约1小时), 记录单位时间内数据库的活动量。


SQL> select * from v$flashback_database_log;

考点:OLDEST_FLASHBACK_SCN表示能够让你闪回到最早的那个scn点。


SQL>select * from v$flashback_database_stat;

相比来看,v$flashback_database_log信息对于flash database更有帮助。


*考点:闪回数据库要求归档日志模式,并使用alter database open resetlogs来创建数据库日志的一个新的化身。

0