Flashback 技术是以Undo segment中的内容为基础的, 因此受限于UNDO_RETENTON参数。要使用flashback 的特性,必须启用自动撤销管理表空间。
在Oracle 10g中, Flash back家族分为以下成员: Flashback Database, Flashback Drop,Flashback Query(分Flashback Query,Flashback Version Query, Flashback Transaction Query 三种) 和Flashback Table。
一. Flashback Database
Flashback Database 功能非常类似与RMAN的不完全恢复, 它可以把整个数据库回退到过去的某个时点的状态, 这个功能依赖于Flashback log 日志。 比RMAN更快速和高效。 因此Flashback Database 可以看作是不完全恢复的替代技术。 但它也有某些限制:
Flashback Database 架构
Flashback Database 整个架构包括一个进程Recover Writer(RVWR)后台进程,Flashback Database Log日志 和Flash Recovery Area。一旦数据库启用了Flashback Database, 则RVWR进程会启动,该进程会向Flash Recovery Area中写入Flashback Database Log, 这些日志包括的是数据块的 " 前镜像(before image)", 这也是Flashback Database 技术不完全恢复块的原因。
[oracle@dba ~]$ ps -ef|grep rvw
oracle 12620 12589 0 13:21 pts/1 00:00:00 grep rvw
启用Flashback Database
数据库的Flashback Database功能缺省是关闭的,要想启用这个功能,就需要做如下配置。
1. 配置Flash Recovery Area
要想使用Flashback Database, 必须使用Flash Recovery Area,因为Flashback Database Log只能保存在这里。 要配置的2个参数如下,一个是大小,一个是位置。如果数据库是RAC,flash recovery area 必须位于共享存储中。数据库必须处于archivelog 模式.
启用Flash Recovery Area:
禁用Flash Recovery Area:
对于Flash Recovery Area,Oracle 是这样建议的,flash recovery area 设置的越大,flashback database 的恢复能力就越强,因此建议flash recovery area 能够放的下所有的数据文件,增量备份,以及所有尚未备份的归档文件,当然还有它自己产生的flashback logs。
在数据库运行过程中,oracle 自动向该区域写入文件,当剩余空间不足15%的时候,它就会在alert 中增加警告,提示你空间不足。但此时不会影响数据库的正常运转,直到所有空间统统被用掉之后,oracle 首先尝试删除寻些过期的文件,冗余文件或备份过的文件,如果这些做完了,还是没有空闲空间的话,数据库就被hang 住了。
对于因Flash Recovery Area导致的数据库hang的处理,请参考:
http://blog.csdn.net/tianlesoftware/archive/2009/10/14/4668991.aspx
或者
http://user.qzone.qq.com/251097186/blog/1244650673
2. 启用数据库Flashback 功能
1). 数据库启动到mount状态
2). 检查Flashback 功能, 缺省时功能是关闭的。
3). 启动Flashback功能
数据库已更改。
4). 设置初始化参数:
该参数用来控制flashback log 数据保留的时间,或者说,你希望flashback database 能够恢复的最早的时间点。默认值是1440,单位是minute,即24 小时,需要注意的是该参数虽然未直接指定flash recovery area大小,但却受其制约,举个例子假如数据库每天有10%左右的数据变动的话,如果该初始化参数值设置为1440,则flash recovery area 的大小至少要是当前数据库实际容量的10%,如果该初始化参数设置为2880,则flash recovery area 的大小就至少是数据库所占容量的20%。
5). 启动数据库
SQL>alter database open;
Flashback Database操作示例
做操作前先备份数据库
1. 检查是否启动了flash recovery area:
2. 检查是否启用了归档
3. 检查是否启用了flashback database
4. 查询当前的scn
5. 查询当前的时间
6. 删除表A
7. Flashback Database 实际是对数据库的一个不完全恢复操作,因为需要关闭数据库重启到mount状态。
8. 执行恢复:分timestamp 或者SCN两种
9. 打开数据库:
在执行完flashback database 命令之后,oracle 提供了两种方式让你修复数据库:
1). 直接alter database open resetlogs 打开数据库,当然,指定scn 或者timestamp 时间点之后产生的数据统统丢失。
2). 先执行alter database open read only 命令以read-only 模式打开数据库,然后立刻通过逻辑导出的方式将误操作涉及表的数据导出,再执行recover database 命令以重新应用数据库产生的redo,将数据库修复到flashback database 操作前的状态,然后再通过逻辑导入的方式,将之前误操作的表重新导入,这样的话对现有数据的影响最小,不会有数据丢失。
这里演示,就以resetlogs方式打开:
SQL> alter database open resetlogs;
数据库已更改。
验证数据:
SQL> select * from A;
ID NAME
---------- ----------
1 tianle
2 dave
和Flashback Database 相关的2个视图:
Flashback DROP
Flashback Drop 是从Oracle 10g 开始出现的, 用于恢复用户误删除的对象(包括表,索引等), 这个技术依赖于Tablespace Recycle Bin(表空间回收站),这个功能和windows的回收站非常类似。
Flashback 不支持sys用户. system表空间下的对象,也不能从回收站里拿到。故使用SYS 或者SYSTEM用户登陆时, show recyclebin 为空。
1. Tablespace Recycle Bin
从Oracle 10g 开始, 每个表空间都会有一个叫作回收站的逻辑区域,当用户执行drop命令时, 被删除的表和表的关联对象( 包括索引, 约束,触发器,LOB段,LOB index 段) 不会被物理删除, 这些对象先转移到回收站中,这就给用户提供了一个恢复的可能。
初始化参数recyclebin 用于控制是否启用recyclebin功能,缺省是ON, 可以使用OFF关闭。
禁用该功能:
禁用后删除的对象将直接删除,不会写到Recycle中,当然在删除时,指定purge 参数,表也将直接删除,不会写到recyclebin中。
SQL> drop table name purge;
查看recyclebin中的对象列表:
SQL> select * from A;
ID
----------
1
2
3
SQL> drop table A;
表已删除。
SQL> show recyclebin
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ----------------------------- ------------ -------------------
A BIN$RWXQQcTPRde0ws4h9ewJcg==$0 TABLE 2009-10-15:12:44:33
查看recyclebin中对象:
SQL> select original_name,object_name from recyclebin;
ORIGINAL_NAME OBJECT_NAME
-------------------------------- ------------------------------
A BIN$RWXQQcTPRde0ws4h9ewJcg==$0
查看recyblebin对象里的内容:
SQL> select * from "BIN$RWXQQcTPRde0ws4h9ewJcg==$0";
ID
----------
1
2
3
表空间的Recycle Bin 区域只是一个逻辑区域,而不是从表空间上物理的划出一块区域固定用于回收站,因此Recycle Bin是和普通对象共用表空间的存储区域,或者说是Recycle Bin的对象要和普通对象抢夺存储空间。当发生空间不够时,Oracle会按照先入先出的顺序覆盖Recycle Bin中的对象。也可以手动的删除Recycle Bin占用的空间。
1). Purge tablespace tablespace_name : 用于清空表空间的Recycle Bin
2). Purge tablespace tablespace_name user user_name: 清空指定表空间的Recycle Bin中指定用户的对象
3). Purge recyclebin: 删除当前用户的Recycle Bin中的对象
4). Purge dba_recyclebin: 删除所有用户的Recycle Bin中的对象,该命令要sysdba权限
5). Drop table table_name purge: 删除对象并且不放在Recycle Bin中,即永久的删除,不能用Flashback恢复。
6). Purge index recycle_bin_object_name: 当想释放Recycle bin的空间,又想能恢复表时,可以通过释放该对象的index所占用的空间来缓解空间压力。 因为索引是可以重建的。
2. Flashback Drop 实例操作
SQL> select original_name,object_name from recyclebin;
ORIGINAL_NAME OBJECT_NAME
-------------------------------- ------------------------------
A BIN$RWXQQcTPRde0ws4h9ewJcg==$0
SQL> flashback table a to before drop;
闪回完成。
SQL> select * from a;
ID
----------
1
2
3
当我们删除表A后,在新建表A,这时在恢复的时候就会报错,此时我们在闪回时,对表重命名就可以了:
SQL> drop table a;
表已删除。
SQL> create table a
2 (id number(1));
表已创建。
SQL> flashback table a to before drop ;
flashback table a to before drop
*
第 1 行出现错误:
ORA-38312: 原始名称已被现有对象使用
SQL> flashback table a to before drop rename to B;
闪回完成。
SQL> select * from B;
ID
----------
1
2
3
当我们删除表A,在新建表A,在删除它,这是在Recycle Bin中就会有2个相同的表明,此时恢复我们就要指定object_name才行.
SQL> select * from B;
ID
----------
1
2
3
SQL> drop table B;
表已删除。
SQL> create table B(name varchar(20));
表已创建。
SQL> drop table B;
表已删除。
SQL> select original_name,object_name from recyclebin;
ORIGINAL_NAME OBJECT_NAME
-------------------------------- ------------------------------
B BIN$vYuv+g9fTi2exYP9X2048Q==$0
B BIN$geQ9+NekSjuRvzG+TqDVWw==$0
SQL> flashback table "BIN$vYuv+g9fTi2exYP9X2048Q==$0" to before drop;
闪回完成。
SQL> select * from B;
ID
----------
1
2
3
一旦完成闪回恢复,Recycle Bin中的对象就消失了. Flashback Drop 需要注意的地方:
1). 只能用于非系统表空间和本地管理的表空间
2). 对象的参考约束不会被恢复,指向该对象的外键约束需要重建。
3). 对象能否恢复成功,取决与对象空间是否被覆盖重用。
4). 当删除表时,信赖于该表的物化视图也会同时删除,但是由于物化视图并不会被放入recycle bin,因此当你执行flashback table to before drop 时,也不能恢复依赖其的物化视图,需要dba 手工介入重新创建。
5). 对于Recycle Bin中的对象,只支持查询.
Flashback Query
Flashback 是ORACLE 自9i 就开始提供的一项特性,在9i 中利用oracle 查询多版本一致的特点,实现从回滚段中读取表一定时间内操作过的数据,可用来进行数据比对,或者修正意外提交造成的错误数据,该项特性也被称为Flashback Query。
一、Flashback Query
正如前言中所提,Flashback Query 是利用多版本读一致性的特性从UNDO 表空间读取操作前的记录数据!
什么是多版本读一致性
Oracle 采用了一种非常优秀的设计,通过undo 数据来确保写不堵塞读,简单的讲,不同的事务在写数据时,会将数据的前映像写入undo 表空间,这样如果同时有其它事务查询该表数据,则可以通过undo 表空间中数据的前映像来构造所需的完整记录集,而不需要等待写入的事务提交或回滚。
flashback query 有多种方式构建查询记录集,记录集的选择范围可以基于时间或基于scn,甚至可以同时查询出记录在undo 表空间中不同事务时的前映象。用法与标准查询非常类似,要通过flashback query 查询undo 中的撤销数据,最简单的方式只需要在标准查询语句的表名后面跟上as of timestamp(基于时间)或as of scn(基于scn)即可。as of timestamp|scn 的语法是自9iR2 后才开始提供支持。
1、As of timestamp 的示例:
SQL> alter session set nls_date_format='YYYY-MM-DD hh24:mi:ss';
会话已更改。
SQL> select sysdate from dual;
SYSDATE
-------------------
2009-10-15 19:04:16
SQL> select * from A;
ID
----------
2
1
3
4
模拟用户误操作,删除数据
SQL> delete from A;
已删除4行。
SQL> commit;
提交完成。
SQL> select * from A;
未选定行
查看删除之前的状态:
假设当前距离删除数据已经有5 分钟左右的话:
SQL> select * from A as of timestamp sysdate-5/1440;
ID
----------
2
1
3
4
或者:
SQL>select * from A as of timestamp to_timestamp('2009-10-15 19:04:16','YYYY-MM-DD hh24:mi:ss');
ID
----------
2
1
3
4
用Flashback Query恢复之前的数据:
SQL>Insert into A select * from A as of timestamp to_timestamp('2009-10-15 19:04:16','YYYY-MM-DD hh24:mi:ss');
已创建4行。
SQL> COMMIT;
提交完成。
SQL> select * from A;
ID
----------
2
1
3
4
如上述示例中所表示的,as of timestamp 的确非常易用,但是在某些情况下,我们建议使用as of scn 的方式执行flashback query,比如需要对多个相互有主外键约束的表进行恢复时,如果使用as of timestamp 的方式,可能会由于时间点不统一的缘故造成数据选择或插入失败,通过scn 方式则能够确保记录的约束一致性。
2. As of scn 示例
查看SCN:
SELECT dbms_flashback.get_system_change_number FROM dual;
SELECT CURRENT_SCN FROM V$DATABASE;
SQL> SELECT CURRENT_SCN FROM V$DATABASE;
CURRENT_SCN
-----------
1095782
删除数据:
SQL> delete from A;
已删除4行。
SQL> commit;
提交完成。
查看删除之前的状态:
SQL> select * from A as of scn 1095782;
ID
----------
2
1
3
4
用Flashback Query恢复之前的数据:
SQL> insert into A select * from A as of scn 1095782;
已创建4行。
SQL> commit;
提交完成。
SQL> select * from A;
ID
----------
2
1
3
4
事实上,Oracle 在内部都是使用scn,即使你指定的是as of timestamp,oracle 也会将其转换成scn,系统时间标记与scn 之间存在一张表,即SYS 下的SMON_SCN_TIME
SQL> desc sys.smon_scn_time
名称 是否为空? 类型
----------------------------------------- -------- ---------------------------
THREAD NUMBER
TIME_MP NUMBER
TIME_DP DATE
SCN_WRP NUMBER
SCN_BAS NUMBER
NUM_MAPPINGS NUMBER
TIM_SCN_MAP RAW(1200)
SCN NUMBER
ORIG_THREAD NUMBER
每隔5 分钟,系统产生一次系统时间标记与scn 的匹配并存入sys.smon_scn_time 表,该表中记录了最近1440个系统时间标记与scn 的匹配记录,由于该表只维护了最近的1440 条记录,因此如果使用as of timestamp 的方式则只能flashback 最近5 天内的数据(假设系统是在持续不断运行并无中断或关机重启之类操作的话)。
注意理解系统时间标记与scn 的每5 分钟匹配一次这句话,举个例子,比如scn:339988,339989 分别匹配08-05-3013:52:00 和2008-13:57:00,则当你通过as of timestamp 查询08-05-30 13:52:00 或08-05-30 13:56:59 这段时间点
内的时间时,oracle 都会将其匹配为scn:339988 到undo 表空间中查找,也就说在这个时间内,不管你指定的时间点是什么,查询返回的都将是08-05-30 13:52:00 这个时刻的数据。
查看SCN 和 timestamp 之间的对应关系:
select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss')from sys.smon_scn_time;
Flashback version Query
相对于Flashback Query 只能看到某一点的对象状态, Oracle 10g引入的Flashback Version Query可以看到过去某个时间段内,记录是如何发生变化的。 根据这个历史,DBA就可以快速的判断数据是在什么时点发生了错误,进而恢复到之前的状态。
先看一个伪列 ORA_ROWSCN. 所谓的伪列,就是假的,不存在的数据列,用户创建表时虽然没有指定,但是Oracle为了维护而添加的一些内部字段,这些字段可以像普通文件那样的使用。
最熟悉的伪列就是 ROWID, 它相当于一个指针,指向记录在磁盘上的位置。ORA_ROWSCN 是Oracle 10g 新增的,暂且把它看作是记录最后一次被修改时的SCN。 Flashback Version Query 就是通过这个伪列来跟踪出记录的变化历史。
举个例子:
SQL> select * from A;
ID
----------
2
1
3
4
SQL> insert into A values(5);
已创建 1 行。
SQL> select * from A;
ID
----------
2
1
3
4
5
SQL> commit;
提交完成。
SQL> select ora_rowscn, id from A;
ORA_ROWSCN ID
---------- ----------
1098443 2
1098443 1
1098443 3
1098443 4
1098443 5
获取更多的历史信息
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;
或者
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);
VERSIONS_XID VERSIONS_STARTSCN VERSIONS_ENDSCN Operatio ID
---------------- ----------------- --------------- -------- ----------
05001A0054020000 1099482 Update 3
05001A0054020000 1099482 Delete 3
05001A0054020000 1099482 Delete 2
05001A0054020000 1099482 Delete 1
0400150005020000 1098443 Insert 5
下面我们来讲下伪列, Flashback Version Query 技术其实有很多伪列,但是ORA_ROWSCN是最重要。它记录的是最后一次被修改时的SCN, 注意是被提交的修改。如果没有提交,这个伪列不会发生变化。
ORA_ROWSCN 缺省是数据块级别的,也就是一个数据块内的所有记录都是一个ORA_ROWSCN,数据块内任意一条记录被修改,这个数据库块内的所有记录的ORA_ROWSCN都会同时改变。上例的查询结果以证明。
不过我们可以在建表时使用关键字 rowdependencies, 可以改变这种缺省行为,使用这个关键字后,每条记录都有自己的ORA_ROWSCN。
举例:
SQL> create table B (id number(2)) rowdependencies;
表已创建。
SQL> insert into B values(1);
已创建 1 行。
SQL> insert into B values(2);
已创建 1 行。
SQL> insert into B values(3);
已创建 1 行。
SQL> commit;
提交完成。
SQL> select ora_rowscn, id from B;
ORA_ROWSCN ID
---------- ----------
1100560 1
1100560 2
1100560 3
此处SCN一样,一定很奇怪,这正好说明是最后一次被修改时的SCN,如果没有提交,是不会变的,我们重做一下就清楚了。
SQL> analyze table B compute statistics;
表已分析。
SQL> select ora_rowscn, id from B;
ORA_ROWSCN ID
---------- ----------
1100560 1
1100560 2
1100560 3
SQL> delete from B;
已删除4行。
SQL> select ora_rowscn, id from B;
未选定行
SQL> insert into B values(1);
已创建 1 行。
SQL> commit;
提交完成。
SQL> insert into B values(2);
已创建 1 行。
SQL> commit;
提交完成。
SQL> select ora_rowscn, id from B;
ORA_ROWSCN ID
---------- ----------
1100723 1
1100729 2
Flashback Transaction Query
Flashback Transaction Query也是使用UNDO信息来实现。利用这个功能可以查看某个事务执行的所有变化,它需要访问flashback_transaction_query 视图,这个视图的XID列代表事务ID,利用这个ID可以区分特定事务发生的所有数据变化。
示例:
SQL> insert into B values(3);
已创建 1 行。
SQL> commit;
提交完成。
SQL> select * from B;
ID
----------
1
2
3
查看视图,每个事务都对应相同的XID
SQL>Select xid,operation,commit_scn,undo_sql from flashback_transaction_query where xid in (
Select versions_xid from B versions between scn minvalue and maxvalue);
或者
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);
XID OPERATION COMMIT_SCN
---------------- -------------------------------- ----------
UNDO_SQL
--------------------------------------------------------------------------------
03001C006A020000 DELETE 1100723
insert into "SYS"."B"("ID") values ('4');
03001C006A020000 DELETE 1100723
insert into "SYS"."B"("ID") values ('3');
03001C006A020000 DELETE 1100723
insert into "SYS"."B"("ID") values ('2');
Flashback Table
注意SYS用户不支持闪回,这点前面已经说明过。
Flashback Table也是使用UNDO tablespace的内容来实现对数据的回退。该命令相对简单,输入:flashback table table_name to scn(to timestamp) 即可。
注意:如果想要对表进行flashback,必须允许表的row movement.
Alter table table_name row movement;
要查看某表是否启用row movement,可以到user_tables 中查询(或all_tables,dba_tables),
例如:
SQL> select row_movement from user_tables where table_name='C';
ROW_MOVE
--------
ENABLED
要启用或禁止某表row movement,可以通过下列语句:
--启用
JSSWEB> ALTER TABLE table_name ENABLE ROW MOVEMENT;
表已更改。
--禁止
JSSWEB> ALTER TABLE table_name DISABLE ROW MOVEMENT;
表已更改。
举例:
SQL> create table C (id number(2));
表已创建。
SQL> insert into C values(1);
已创建 1 行。
SQL> insert into C values(2);
已创建 1 行。
SQL> commit;
提交完成。
SQL> select * from c;
ID
----------
1
2
SQL> alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss";
会话已更改。
SQL> select sysdate from dual;
SYSDATE
-------------------
2009-10-15 21:17:47
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
1103864
删除数据并恢复
SQL> delete from C;
已删除2行。
SQL> commit;
提交完成。
SQL> alter table c enable row movement;
表已更改。
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');
SQL> select * from c;
ID
----------
1
2
Flashback table 命令支持同时操作多个表,表名中间以逗号分隔即可,如果你执行一条flashback table命令时同时指定了多个表,要记住单个flashback table 是在同一个事务中,因此这些表的恢复操作要么都成功,要么都失败。
如:
flashback table a,b ,c to scn 1103864;
一些注意事项
1. 基于undo 的表恢复,需要注意DDL 操作的影响
第三个就是修改并提交过数据之后,对表做过DDL 操作,包括:
drop/modify 列, move 表, drop 分区(如果有的话), truncate table/partition,这些操作会另undo 表空间中的撤销数据失效,对于执行过这些操作的表应用flashback query 会触发ORA-01466 错误。另外一些表结构修改语句虽然并不会影响到undo 表空间中的撤销记录,但有可能因表结构修改导致undo 中重做记录无法应用的情况,比如对于增加了约束,而flashback query 查询出的undo 记录已经不符合新建的约束条件,这个时候直接恢复显然不可能成功,你要么暂时disable 约束,要么通过适当逻辑,对要恢复的数据进行处理之后,再执行恢复。
另外,flashback query 对v$tables,x$tables 等动态性能视图无效,不过对于dba_*,all_*,user_*等数据字典是有效的。同时该特性也完全支持访问远端数据库,比如select * from tbl@dblink as of scn 360;的形式。
2. 基于undo 的表恢复,flashback table 实际上做的也是dml 操作(会在被操作的表上加dml 锁),因此还需要注意triggers 对其的影响,默认情况下,flashback table to scn/timestamp 在执行时会自动disable 掉与其操作表相差的triggers,如果你希望在此期间trigger 能够继续发挥做用,可以在flashback table 后附加
ENABLE TRIGGERS 子句。
补充:
什么是Automatic Undo Management( 自动撤销管理表空间)
提到自动撤销管理表空间,就不得不提手动管理的回滚段。在9i 之前,回滚段的管理和监控是需要dba手工介入的,创建合适的回滚段是件非常耗费dba 精力的事情,你可能需要不断关注oracle 运行状况很长一阵子时间后,通过不断的调整才能基本确认一段时期内回滚段的大小,一旦回滚段创建的不合适,就极有可能引起性能问题甚至错误,比如ora-1555 就是典型的回滚段设置不合适触发的。
9i 之后呢(含9i),oracle 为了清晰它的整个概念,取消了回滚段这个说法(实际上并未取消回滚段),而完全以undo 来代替,这也它正好与redo 相对应,一个重做,一个撤销。回滚段可以不再由dba 手工介入,而是完全由它自己在运行时自动分配,这在一定程度上即解放了dba,也确实起到了提高性能的作用,比如采用自动管理表空间就可以最大程序的降低ora-1555发生的机率(注意是降低,不是避免,我们不可能创建一个无限大的回滚段,ora-1555 也并不完全是回滚段造成的,关于ora-1555 的问题这里就不深入讨论了,互联网上已经有太多文章描述和介绍该问题及解决方案)
是否起用自动管理的撤销表空间由二个初始化参数决定:
UNDO_MANAGEMENT:值为AUTO 表示使用了自动撤销管理表空间,MANUAL 则表示手动管理
UNDO_TABLESPACE:当UNDO_MANAGEMENT 值为AUTO 时,该参数用来指定当前的undo 表空间名称。
undo 表空间的大小,直接影响到flashback query 的查询能力,因为多版本查询所依赖的undo 数据都存储在undo 表空间中,该表空间越大,所能够存储的undo 数据自然也越多,如果该表空间可用空间非常小,别说flashback 了,恐怕正常查询都有可能触发ora-1555 吧。
初始化参数UNDO_RETENTION
该参数用来指定undo 记录保存的最长时间,以秒为单位,是个动态参数,完全可以在实例运行时随时修改通常默认是900 秒,也就是15 分钟。
一定要注意,undo_retention 只是指定undo 数据的过期时间,并不是说,undo 中的数据一定会在undo表空间中保存15 分钟,比如说刚一个新事务开始的时候,如果undo 表空间已经被写满,则新事务的数据会自动覆盖已提交事务的数据,而不管这些数据是否已过期,因此呢,这就又关联回了第一点,当你创建
一个自动管理的undo 表空间时,还要注意其空间大小,要尽可能保证undo 表空间有足够的存储空间。
同时还要注意,也并不是说,undo_retention 中指定的时间一过,已经提交事务中的数据就立刻无法访问,它只是失效,只要不被别的事务覆盖,它会仍然存在,并可随时被flashback 特性引用。如果你的undo表空间足够大,而数据库又不是那么繁忙,那么其实undo_retention 参数的值并不会影响到你,哪怕你设置成1,只要没有事务去覆盖undo 数据,它就会持续有效。因此呢,这里还是那句话,要注意undo 表空间的大小,保证其有足够的存储空间。
只有在一种情况下,undo 表空间能够确保undo 中的数据在undo_retention 指定时间过期前一定有效,就是为undo 表空间指定Retention Guarantee,指定之后,oracle 对于undo 表空间中未过期的undo 数据不会覆盖,
例如:
SQL> Alter tablespace undotbs1 retention guarantee;
如果想禁止undo 表空间retention guarantee,
例如:
SQL> Alter tablespace undotbs1 retention noguarantee;
在Oracle 10g中, Flash back家族分为以下成员: Flashback Database, Flashback Drop,Flashback Query(分Flashback Query,Flashback Version Query, Flashback Transaction Query 三种) 和Flashback Table。
一. Flashback Database
Flashback Database 功能非常类似与RMAN的不完全恢复, 它可以把整个数据库回退到过去的某个时点的状态, 这个功能依赖于Flashback log 日志。 比RMAN更快速和高效。 因此Flashback Database 可以看作是不完全恢复的替代技术。 但它也有某些限制:
1. Flashback Database 不能解决Media Failure, 这种错误RMAN恢复仍是唯一选择 2. 如果删除了数据文件或者利用Shrink技术缩小数据文件大小,这时不能用Flashback Database技术回退到改变之前的状态,这时候就必须先利用RMAN把删除之前或者缩小之前的文件备份restore 出来, 然后利用Flashback Database 执行剩下的Flashback Datbase。 3. 如果控制文件是从备份中恢复出来的,或者是重建的控制文件,也不能使用Flashback Database。 4. 使用Flashback Database锁能恢复到的最早的SCN, 取决与Flashback Log中记录的最早SCN。
Flashback Database 架构
Flashback Database 整个架构包括一个进程Recover Writer(RVWR)后台进程,Flashback Database Log日志 和Flash Recovery Area。一旦数据库启用了Flashback Database, 则RVWR进程会启动,该进程会向Flash Recovery Area中写入Flashback Database Log, 这些日志包括的是数据块的 " 前镜像(before image)", 这也是Flashback Database 技术不完全恢复块的原因。
[oracle@dba ~]$ ps -ef|grep rvw
oracle 12620 12589 0 13:21 pts/1 00:00:00 grep rvw
启用Flashback Database
数据库的Flashback Database功能缺省是关闭的,要想启用这个功能,就需要做如下配置。
1. 配置Flash Recovery Area
要想使用Flashback Database, 必须使用Flash Recovery Area,因为Flashback Database Log只能保存在这里。 要配置的2个参数如下,一个是大小,一个是位置。如果数据库是RAC,flash recovery area 必须位于共享存储中。数据库必须处于archivelog 模式.
启用Flash Recovery Area:
SQL>ALTER SYSTEM SET DB_RECOVERY_FILE_DEST_SIZE=20G SCOPE=BOTH; SQL>ALTER SYSTEM SET DB_RECOVERY_FILE_DEST='/DBA/FB' SCOPE=BOTH;
禁用Flash Recovery Area:
SQL>ALTER SYSTEM SET DB_RECOVERY_FILE_DEST='' ;[color=darkblue][/color]
对于Flash Recovery Area,Oracle 是这样建议的,flash recovery area 设置的越大,flashback database 的恢复能力就越强,因此建议flash recovery area 能够放的下所有的数据文件,增量备份,以及所有尚未备份的归档文件,当然还有它自己产生的flashback logs。
在数据库运行过程中,oracle 自动向该区域写入文件,当剩余空间不足15%的时候,它就会在alert 中增加警告,提示你空间不足。但此时不会影响数据库的正常运转,直到所有空间统统被用掉之后,oracle 首先尝试删除寻些过期的文件,冗余文件或备份过的文件,如果这些做完了,还是没有空闲空间的话,数据库就被hang 住了。
对于因Flash Recovery Area导致的数据库hang的处理,请参考:
http://blog.csdn.net/tianlesoftware/archive/2009/10/14/4668991.aspx
或者
http://user.qzone.qq.com/251097186/blog/1244650673
2. 启用数据库Flashback 功能
1). 数据库启动到mount状态
SQL> startup mount;
2). 检查Flashback 功能, 缺省时功能是关闭的。
SQL> select name, current_scn, flashback_on from v$database; NAME CURRENT_SCN FLASHBACK_ON -------- ----------- ------------------ DBA 945715 NO
3). 启动Flashback功能
SQL> alter database flashback on;
数据库已更改。
SQL> select name, current_scn, flashback_on from v$database; NAME CURRENT_SCN FLASHBACK_ON --------- ----------- ------------------ DBA 0 YES
4). 设置初始化参数:
DB_FLASHBACK_RETENTION_TARGET: SQL>alter system set db_flashback_retention_target=1440 scope=both;
该参数用来控制flashback log 数据保留的时间,或者说,你希望flashback database 能够恢复的最早的时间点。默认值是1440,单位是minute,即24 小时,需要注意的是该参数虽然未直接指定flash recovery area大小,但却受其制约,举个例子假如数据库每天有10%左右的数据变动的话,如果该初始化参数值设置为1440,则flash recovery area 的大小至少要是当前数据库实际容量的10%,如果该初始化参数设置为2880,则flash recovery area 的大小就至少是数据库所占容量的20%。
5). 启动数据库
SQL>alter database open;
Flashback Database操作示例
做操作前先备份数据库
RMAN> backup database;
1. 检查是否启动了flash recovery area:
SQL> show parameter db_recovery_file NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ db_recovery_file_dest tring D:\oracle/flash_recovery_area db_recovery_file_dest_size big integer 1G
2. 检查是否启用了归档
SQL> archive log list; 数据库日志模式 存档模式 自动存档 启用 存档终点 USE_DB_RECOVERY_FILE_DEST 最早的联机日志序列 9 下一个存档日志序列 11 当前日志序列 11
3. 检查是否启用了flashback database
SQL> select flashback_on from v$database; FLASHBACK_ON ------------------ YES
4. 查询当前的scn
SQL> SELECT CURRENT_SCN FROM V$DATABASE; CURRENT_SCN ----------- 947921
5. 查询当前的时间
SQL> select to_char(sysdate,'yy-mm-dd hh24:mi:ss') time from dual; TIME ----------------- 09-10-14 14:37:05
6. 删除表A
SQL> select * from A; ID NAME ---------- ---------- 1 tianle 2 dave SQL> drop table A; 表已删除。 SQL> commit;
7. Flashback Database 实际是对数据库的一个不完全恢复操作,因为需要关闭数据库重启到mount状态。
SQL> shutdown immediate 数据库已经关闭。 已经卸载数据库。 ORACLE 例程已经关闭。 SQL> startup mount ORACLE 例程已经启动。 Total System Global Area 209715200 bytes Fixed Size 1248116 bytes Variable Size 79692940 bytes Database Buffers 121634816 bytes Redo Buffers 7139328 bytes 数据库装载完毕。
8. 执行恢复:分timestamp 或者SCN两种
SQL> Flashback database to timestamp to_timestamp('09-10-14 14:37:05','yy-mm-dd hh24:mi:ss'); 闪回完成。 或者: SQL> Flashback database to scn 947921; 闪回完成。
9. 打开数据库:
在执行完flashback database 命令之后,oracle 提供了两种方式让你修复数据库:
1). 直接alter database open resetlogs 打开数据库,当然,指定scn 或者timestamp 时间点之后产生的数据统统丢失。
2). 先执行alter database open read only 命令以read-only 模式打开数据库,然后立刻通过逻辑导出的方式将误操作涉及表的数据导出,再执行recover database 命令以重新应用数据库产生的redo,将数据库修复到flashback database 操作前的状态,然后再通过逻辑导入的方式,将之前误操作的表重新导入,这样的话对现有数据的影响最小,不会有数据丢失。
这里演示,就以resetlogs方式打开:
SQL> alter database open resetlogs;
数据库已更改。
验证数据:
SQL> select * from A;
ID NAME
---------- ----------
1 tianle
2 dave
和Flashback Database 相关的2个视图:
1. V$database 这个视图可以查看是否启用了Flashback database功能 SQL> select flashback_on from v$database; FLASHBACK_ON ------------------ YES
2. V$flashback_database_log Flashback Database 所能回退到的最早时间,取决与保留的Flashback Database Log 的多少, 该视图就可以查看许多有用的信息。 Oldest_flashback_scn / Oldest_flashback_time : 这两列用来记录可以恢复到最早的时点 Flashback_size: 记录了当前使用的Flash Recovery Area 空间的大小 Retention_target: 系统定义的策略 Estimated_flashback_size: 根据策略对需要的空间大小的估计值 SQL> select oldest_flashback_scn os, to_char(oldest_flashback_time,'yy-mm-dd hh2 4:mi:ss') ot, retention_target rt,flashback_size fs, estimated_flashback_size es from v$flashback_database_log; OS OT RT FS ES ---------- ----------------- ---------- ---------- ---------- 946088 09-10-14 13:49:59 1440 16384000 350920704
3. V$flashback_database_stat 这个视图用来对Flashback log 空间情况进行更细粒度的记录和估计。 这个视图以小时为单位记录单位时间内数据库的活动量,Flashback_Data 代表Flashback log产生数量,DB_Date 代表数据改变数量,Redo_Date代表日志数量,通过这3个数量可以反映出数据的活动特点,更准确的预计Flash Recovery Area的空间需求 SQL> alter session set nls_date_format='hh24:mi:ss'; 会话已更改。 SQL> select *from v$flashback_database_stat; BEGIN_TI END_TIME FLASHBACK_DATA DB_DATA REDO_DATA ESTIMATED_FLASHBACK_SIZE -------- -------- -------------- ---------- ---------- ------------------------ 14:43:10 15:15:28 6455296 29310976 3898368 0
Flashback DROP
Flashback Drop 是从Oracle 10g 开始出现的, 用于恢复用户误删除的对象(包括表,索引等), 这个技术依赖于Tablespace Recycle Bin(表空间回收站),这个功能和windows的回收站非常类似。
Flashback 不支持sys用户. system表空间下的对象,也不能从回收站里拿到。故使用SYS 或者SYSTEM用户登陆时, show recyclebin 为空。
1. Tablespace Recycle Bin
从Oracle 10g 开始, 每个表空间都会有一个叫作回收站的逻辑区域,当用户执行drop命令时, 被删除的表和表的关联对象( 包括索引, 约束,触发器,LOB段,LOB index 段) 不会被物理删除, 这些对象先转移到回收站中,这就给用户提供了一个恢复的可能。
初始化参数recyclebin 用于控制是否启用recyclebin功能,缺省是ON, 可以使用OFF关闭。
SQL> show parameter recycle NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ buffer_pool_recycle string db_recycle_cache_size big integer 0 recyclebin string on
禁用该功能:
SQL> alter system set recyclebin=off; SQL> alter system set recyclebin=on; SQL> alter session set recyclebin=off; SQL> alter session set recyclebin=on;
禁用后删除的对象将直接删除,不会写到Recycle中,当然在删除时,指定purge 参数,表也将直接删除,不会写到recyclebin中。
SQL> drop table name purge;
查看recyclebin中的对象列表:
SQL> select * from A;
ID
----------
1
2
3
SQL> drop table A;
表已删除。
SQL> show recyclebin
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ----------------------------- ------------ -------------------
A BIN$RWXQQcTPRde0ws4h9ewJcg==$0 TABLE 2009-10-15:12:44:33
查看recyclebin中对象:
SQL> select original_name,object_name from recyclebin;
ORIGINAL_NAME OBJECT_NAME
-------------------------------- ------------------------------
A BIN$RWXQQcTPRde0ws4h9ewJcg==$0
查看recyblebin对象里的内容:
SQL> select * from "BIN$RWXQQcTPRde0ws4h9ewJcg==$0";
ID
----------
1
2
3
表空间的Recycle Bin 区域只是一个逻辑区域,而不是从表空间上物理的划出一块区域固定用于回收站,因此Recycle Bin是和普通对象共用表空间的存储区域,或者说是Recycle Bin的对象要和普通对象抢夺存储空间。当发生空间不够时,Oracle会按照先入先出的顺序覆盖Recycle Bin中的对象。也可以手动的删除Recycle Bin占用的空间。
1). Purge tablespace tablespace_name : 用于清空表空间的Recycle Bin
2). Purge tablespace tablespace_name user user_name: 清空指定表空间的Recycle Bin中指定用户的对象
3). Purge recyclebin: 删除当前用户的Recycle Bin中的对象
4). Purge dba_recyclebin: 删除所有用户的Recycle Bin中的对象,该命令要sysdba权限
5). Drop table table_name purge: 删除对象并且不放在Recycle Bin中,即永久的删除,不能用Flashback恢复。
6). Purge index recycle_bin_object_name: 当想释放Recycle bin的空间,又想能恢复表时,可以通过释放该对象的index所占用的空间来缓解空间压力。 因为索引是可以重建的。
2. Flashback Drop 实例操作
SQL> select original_name,object_name from recyclebin;
ORIGINAL_NAME OBJECT_NAME
-------------------------------- ------------------------------
A BIN$RWXQQcTPRde0ws4h9ewJcg==$0
SQL> flashback table a to before drop;
闪回完成。
SQL> select * from a;
ID
----------
1
2
3
当我们删除表A后,在新建表A,这时在恢复的时候就会报错,此时我们在闪回时,对表重命名就可以了:
SQL> drop table a;
表已删除。
SQL> create table a
2 (id number(1));
表已创建。
SQL> flashback table a to before drop ;
flashback table a to before drop
*
第 1 行出现错误:
ORA-38312: 原始名称已被现有对象使用
SQL> flashback table a to before drop rename to B;
闪回完成。
SQL> select * from B;
ID
----------
1
2
3
当我们删除表A,在新建表A,在删除它,这是在Recycle Bin中就会有2个相同的表明,此时恢复我们就要指定object_name才行.
SQL> select * from B;
ID
----------
1
2
3
SQL> drop table B;
表已删除。
SQL> create table B(name varchar(20));
表已创建。
SQL> drop table B;
表已删除。
SQL> select original_name,object_name from recyclebin;
ORIGINAL_NAME OBJECT_NAME
-------------------------------- ------------------------------
B BIN$vYuv+g9fTi2exYP9X2048Q==$0
B BIN$geQ9+NekSjuRvzG+TqDVWw==$0
SQL> flashback table "BIN$vYuv+g9fTi2exYP9X2048Q==$0" to before drop;
闪回完成。
SQL> select * from B;
ID
----------
1
2
3
一旦完成闪回恢复,Recycle Bin中的对象就消失了. Flashback Drop 需要注意的地方:
1). 只能用于非系统表空间和本地管理的表空间
2). 对象的参考约束不会被恢复,指向该对象的外键约束需要重建。
3). 对象能否恢复成功,取决与对象空间是否被覆盖重用。
4). 当删除表时,信赖于该表的物化视图也会同时删除,但是由于物化视图并不会被放入recycle bin,因此当你执行flashback table to before drop 时,也不能恢复依赖其的物化视图,需要dba 手工介入重新创建。
5). 对于Recycle Bin中的对象,只支持查询.
Flashback Query
Flashback 是ORACLE 自9i 就开始提供的一项特性,在9i 中利用oracle 查询多版本一致的特点,实现从回滚段中读取表一定时间内操作过的数据,可用来进行数据比对,或者修正意外提交造成的错误数据,该项特性也被称为Flashback Query。
一、Flashback Query
正如前言中所提,Flashback Query 是利用多版本读一致性的特性从UNDO 表空间读取操作前的记录数据!
什么是多版本读一致性
Oracle 采用了一种非常优秀的设计,通过undo 数据来确保写不堵塞读,简单的讲,不同的事务在写数据时,会将数据的前映像写入undo 表空间,这样如果同时有其它事务查询该表数据,则可以通过undo 表空间中数据的前映像来构造所需的完整记录集,而不需要等待写入的事务提交或回滚。
flashback query 有多种方式构建查询记录集,记录集的选择范围可以基于时间或基于scn,甚至可以同时查询出记录在undo 表空间中不同事务时的前映象。用法与标准查询非常类似,要通过flashback query 查询undo 中的撤销数据,最简单的方式只需要在标准查询语句的表名后面跟上as of timestamp(基于时间)或as of scn(基于scn)即可。as of timestamp|scn 的语法是自9iR2 后才开始提供支持。
1、As of timestamp 的示例:
SQL> alter session set nls_date_format='YYYY-MM-DD hh24:mi:ss';
会话已更改。
SQL> select sysdate from dual;
SYSDATE
-------------------
2009-10-15 19:04:16
SQL> select * from A;
ID
----------
2
1
3
4
模拟用户误操作,删除数据
SQL> delete from A;
已删除4行。
SQL> commit;
提交完成。
SQL> select * from A;
未选定行
查看删除之前的状态:
假设当前距离删除数据已经有5 分钟左右的话:
SQL> select * from A as of timestamp sysdate-5/1440;
ID
----------
2
1
3
4
或者:
SQL>select * from A as of timestamp to_timestamp('2009-10-15 19:04:16','YYYY-MM-DD hh24:mi:ss');
ID
----------
2
1
3
4
用Flashback Query恢复之前的数据:
SQL>Insert into A select * from A as of timestamp to_timestamp('2009-10-15 19:04:16','YYYY-MM-DD hh24:mi:ss');
已创建4行。
SQL> COMMIT;
提交完成。
SQL> select * from A;
ID
----------
2
1
3
4
如上述示例中所表示的,as of timestamp 的确非常易用,但是在某些情况下,我们建议使用as of scn 的方式执行flashback query,比如需要对多个相互有主外键约束的表进行恢复时,如果使用as of timestamp 的方式,可能会由于时间点不统一的缘故造成数据选择或插入失败,通过scn 方式则能够确保记录的约束一致性。
2. As of scn 示例
查看SCN:
SELECT dbms_flashback.get_system_change_number FROM dual;
SELECT CURRENT_SCN FROM V$DATABASE;
SQL> SELECT CURRENT_SCN FROM V$DATABASE;
CURRENT_SCN
-----------
1095782
删除数据:
SQL> delete from A;
已删除4行。
SQL> commit;
提交完成。
查看删除之前的状态:
SQL> select * from A as of scn 1095782;
ID
----------
2
1
3
4
用Flashback Query恢复之前的数据:
SQL> insert into A select * from A as of scn 1095782;
已创建4行。
SQL> commit;
提交完成。
SQL> select * from A;
ID
----------
2
1
3
4
事实上,Oracle 在内部都是使用scn,即使你指定的是as of timestamp,oracle 也会将其转换成scn,系统时间标记与scn 之间存在一张表,即SYS 下的SMON_SCN_TIME
SQL> desc sys.smon_scn_time
名称 是否为空? 类型
----------------------------------------- -------- ---------------------------
THREAD NUMBER
TIME_MP NUMBER
TIME_DP DATE
SCN_WRP NUMBER
SCN_BAS NUMBER
NUM_MAPPINGS NUMBER
TIM_SCN_MAP RAW(1200)
SCN NUMBER
ORIG_THREAD NUMBER
每隔5 分钟,系统产生一次系统时间标记与scn 的匹配并存入sys.smon_scn_time 表,该表中记录了最近1440个系统时间标记与scn 的匹配记录,由于该表只维护了最近的1440 条记录,因此如果使用as of timestamp 的方式则只能flashback 最近5 天内的数据(假设系统是在持续不断运行并无中断或关机重启之类操作的话)。
注意理解系统时间标记与scn 的每5 分钟匹配一次这句话,举个例子,比如scn:339988,339989 分别匹配08-05-3013:52:00 和2008-13:57:00,则当你通过as of timestamp 查询08-05-30 13:52:00 或08-05-30 13:56:59 这段时间点
内的时间时,oracle 都会将其匹配为scn:339988 到undo 表空间中查找,也就说在这个时间内,不管你指定的时间点是什么,查询返回的都将是08-05-30 13:52:00 这个时刻的数据。
查看SCN 和 timestamp 之间的对应关系:
select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss')from sys.smon_scn_time;
Flashback version Query
相对于Flashback Query 只能看到某一点的对象状态, Oracle 10g引入的Flashback Version Query可以看到过去某个时间段内,记录是如何发生变化的。 根据这个历史,DBA就可以快速的判断数据是在什么时点发生了错误,进而恢复到之前的状态。
先看一个伪列 ORA_ROWSCN. 所谓的伪列,就是假的,不存在的数据列,用户创建表时虽然没有指定,但是Oracle为了维护而添加的一些内部字段,这些字段可以像普通文件那样的使用。
最熟悉的伪列就是 ROWID, 它相当于一个指针,指向记录在磁盘上的位置。ORA_ROWSCN 是Oracle 10g 新增的,暂且把它看作是记录最后一次被修改时的SCN。 Flashback Version Query 就是通过这个伪列来跟踪出记录的变化历史。
举个例子:
SQL> select * from A;
ID
----------
2
1
3
4
SQL> insert into A values(5);
已创建 1 行。
SQL> select * from A;
ID
----------
2
1
3
4
5
SQL> commit;
提交完成。
SQL> select ora_rowscn, id from A;
ORA_ROWSCN ID
---------- ----------
1098443 2
1098443 1
1098443 3
1098443 4
1098443 5
获取更多的历史信息
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;
或者
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);
VERSIONS_XID VERSIONS_STARTSCN VERSIONS_ENDSCN Operatio ID
---------------- ----------------- --------------- -------- ----------
05001A0054020000 1099482 Update 3
05001A0054020000 1099482 Delete 3
05001A0054020000 1099482 Delete 2
05001A0054020000 1099482 Delete 1
0400150005020000 1098443 Insert 5
下面我们来讲下伪列, Flashback Version Query 技术其实有很多伪列,但是ORA_ROWSCN是最重要。它记录的是最后一次被修改时的SCN, 注意是被提交的修改。如果没有提交,这个伪列不会发生变化。
ORA_ROWSCN 缺省是数据块级别的,也就是一个数据块内的所有记录都是一个ORA_ROWSCN,数据块内任意一条记录被修改,这个数据库块内的所有记录的ORA_ROWSCN都会同时改变。上例的查询结果以证明。
不过我们可以在建表时使用关键字 rowdependencies, 可以改变这种缺省行为,使用这个关键字后,每条记录都有自己的ORA_ROWSCN。
举例:
SQL> create table B (id number(2)) rowdependencies;
表已创建。
SQL> insert into B values(1);
已创建 1 行。
SQL> insert into B values(2);
已创建 1 行。
SQL> insert into B values(3);
已创建 1 行。
SQL> commit;
提交完成。
SQL> select ora_rowscn, id from B;
ORA_ROWSCN ID
---------- ----------
1100560 1
1100560 2
1100560 3
此处SCN一样,一定很奇怪,这正好说明是最后一次被修改时的SCN,如果没有提交,是不会变的,我们重做一下就清楚了。
SQL> analyze table B compute statistics;
表已分析。
SQL> select ora_rowscn, id from B;
ORA_ROWSCN ID
---------- ----------
1100560 1
1100560 2
1100560 3
SQL> delete from B;
已删除4行。
SQL> select ora_rowscn, id from B;
未选定行
SQL> insert into B values(1);
已创建 1 行。
SQL> commit;
提交完成。
SQL> insert into B values(2);
已创建 1 行。
SQL> commit;
提交完成。
SQL> select ora_rowscn, id from B;
ORA_ROWSCN ID
---------- ----------
1100723 1
1100729 2
Flashback Transaction Query
Flashback Transaction Query也是使用UNDO信息来实现。利用这个功能可以查看某个事务执行的所有变化,它需要访问flashback_transaction_query 视图,这个视图的XID列代表事务ID,利用这个ID可以区分特定事务发生的所有数据变化。
示例:
SQL> insert into B values(3);
已创建 1 行。
SQL> commit;
提交完成。
SQL> select * from B;
ID
----------
1
2
3
查看视图,每个事务都对应相同的XID
SQL>Select xid,operation,commit_scn,undo_sql from flashback_transaction_query where xid in (
Select versions_xid from B versions between scn minvalue and maxvalue);
或者
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);
XID OPERATION COMMIT_SCN
---------------- -------------------------------- ----------
UNDO_SQL
--------------------------------------------------------------------------------
03001C006A020000 DELETE 1100723
insert into "SYS"."B"("ID") values ('4');
03001C006A020000 DELETE 1100723
insert into "SYS"."B"("ID") values ('3');
03001C006A020000 DELETE 1100723
insert into "SYS"."B"("ID") values ('2');
Flashback Table
注意SYS用户不支持闪回,这点前面已经说明过。
Flashback Table也是使用UNDO tablespace的内容来实现对数据的回退。该命令相对简单,输入:flashback table table_name to scn(to timestamp) 即可。
注意:如果想要对表进行flashback,必须允许表的row movement.
Alter table table_name row movement;
要查看某表是否启用row movement,可以到user_tables 中查询(或all_tables,dba_tables),
例如:
SQL> select row_movement from user_tables where table_name='C';
ROW_MOVE
--------
ENABLED
要启用或禁止某表row movement,可以通过下列语句:
--启用
JSSWEB> ALTER TABLE table_name ENABLE ROW MOVEMENT;
表已更改。
--禁止
JSSWEB> ALTER TABLE table_name DISABLE ROW MOVEMENT;
表已更改。
举例:
SQL> create table C (id number(2));
表已创建。
SQL> insert into C values(1);
已创建 1 行。
SQL> insert into C values(2);
已创建 1 行。
SQL> commit;
提交完成。
SQL> select * from c;
ID
----------
1
2
SQL> alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss";
会话已更改。
SQL> select sysdate from dual;
SYSDATE
-------------------
2009-10-15 21:17:47
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
1103864
删除数据并恢复
SQL> delete from C;
已删除2行。
SQL> commit;
提交完成。
SQL> alter table c enable row movement;
表已更改。
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');
SQL> select * from c;
ID
----------
1
2
Flashback table 命令支持同时操作多个表,表名中间以逗号分隔即可,如果你执行一条flashback table命令时同时指定了多个表,要记住单个flashback table 是在同一个事务中,因此这些表的恢复操作要么都成功,要么都失败。
如:
flashback table a,b ,c to scn 1103864;
一些注意事项
1. 基于undo 的表恢复,需要注意DDL 操作的影响
第三个就是修改并提交过数据之后,对表做过DDL 操作,包括:
drop/modify 列, move 表, drop 分区(如果有的话), truncate table/partition,这些操作会另undo 表空间中的撤销数据失效,对于执行过这些操作的表应用flashback query 会触发ORA-01466 错误。另外一些表结构修改语句虽然并不会影响到undo 表空间中的撤销记录,但有可能因表结构修改导致undo 中重做记录无法应用的情况,比如对于增加了约束,而flashback query 查询出的undo 记录已经不符合新建的约束条件,这个时候直接恢复显然不可能成功,你要么暂时disable 约束,要么通过适当逻辑,对要恢复的数据进行处理之后,再执行恢复。
另外,flashback query 对v$tables,x$tables 等动态性能视图无效,不过对于dba_*,all_*,user_*等数据字典是有效的。同时该特性也完全支持访问远端数据库,比如select * from tbl@dblink as of scn 360;的形式。
2. 基于undo 的表恢复,flashback table 实际上做的也是dml 操作(会在被操作的表上加dml 锁),因此还需要注意triggers 对其的影响,默认情况下,flashback table to scn/timestamp 在执行时会自动disable 掉与其操作表相差的triggers,如果你希望在此期间trigger 能够继续发挥做用,可以在flashback table 后附加
ENABLE TRIGGERS 子句。
补充:
什么是Automatic Undo Management( 自动撤销管理表空间)
提到自动撤销管理表空间,就不得不提手动管理的回滚段。在9i 之前,回滚段的管理和监控是需要dba手工介入的,创建合适的回滚段是件非常耗费dba 精力的事情,你可能需要不断关注oracle 运行状况很长一阵子时间后,通过不断的调整才能基本确认一段时期内回滚段的大小,一旦回滚段创建的不合适,就极有可能引起性能问题甚至错误,比如ora-1555 就是典型的回滚段设置不合适触发的。
9i 之后呢(含9i),oracle 为了清晰它的整个概念,取消了回滚段这个说法(实际上并未取消回滚段),而完全以undo 来代替,这也它正好与redo 相对应,一个重做,一个撤销。回滚段可以不再由dba 手工介入,而是完全由它自己在运行时自动分配,这在一定程度上即解放了dba,也确实起到了提高性能的作用,比如采用自动管理表空间就可以最大程序的降低ora-1555发生的机率(注意是降低,不是避免,我们不可能创建一个无限大的回滚段,ora-1555 也并不完全是回滚段造成的,关于ora-1555 的问题这里就不深入讨论了,互联网上已经有太多文章描述和介绍该问题及解决方案)
是否起用自动管理的撤销表空间由二个初始化参数决定:
UNDO_MANAGEMENT:值为AUTO 表示使用了自动撤销管理表空间,MANUAL 则表示手动管理
UNDO_TABLESPACE:当UNDO_MANAGEMENT 值为AUTO 时,该参数用来指定当前的undo 表空间名称。
undo 表空间的大小,直接影响到flashback query 的查询能力,因为多版本查询所依赖的undo 数据都存储在undo 表空间中,该表空间越大,所能够存储的undo 数据自然也越多,如果该表空间可用空间非常小,别说flashback 了,恐怕正常查询都有可能触发ora-1555 吧。
初始化参数UNDO_RETENTION
该参数用来指定undo 记录保存的最长时间,以秒为单位,是个动态参数,完全可以在实例运行时随时修改通常默认是900 秒,也就是15 分钟。
一定要注意,undo_retention 只是指定undo 数据的过期时间,并不是说,undo 中的数据一定会在undo表空间中保存15 分钟,比如说刚一个新事务开始的时候,如果undo 表空间已经被写满,则新事务的数据会自动覆盖已提交事务的数据,而不管这些数据是否已过期,因此呢,这就又关联回了第一点,当你创建
一个自动管理的undo 表空间时,还要注意其空间大小,要尽可能保证undo 表空间有足够的存储空间。
同时还要注意,也并不是说,undo_retention 中指定的时间一过,已经提交事务中的数据就立刻无法访问,它只是失效,只要不被别的事务覆盖,它会仍然存在,并可随时被flashback 特性引用。如果你的undo表空间足够大,而数据库又不是那么繁忙,那么其实undo_retention 参数的值并不会影响到你,哪怕你设置成1,只要没有事务去覆盖undo 数据,它就会持续有效。因此呢,这里还是那句话,要注意undo 表空间的大小,保证其有足够的存储空间。
只有在一种情况下,undo 表空间能够确保undo 中的数据在undo_retention 指定时间过期前一定有效,就是为undo 表空间指定Retention Guarantee,指定之后,oracle 对于undo 表空间中未过期的undo 数据不会覆盖,
例如:
SQL> Alter tablespace undotbs1 retention guarantee;
如果想禁止undo 表空间retention guarantee,
例如:
SQL> Alter tablespace undotbs1 retention noguarantee;
发表评论
-
Oracle关于时间/日期的操作
2012-04-09 23:12 8551.日期时间间隔操作 当前时间减去7分钟的时间 s ... -
oracle 数据库增量备份
2012-03-16 20:03 1164EXP和IMP是Oracle提供的一种逻辑备份工具。逻辑备份创 ... -
oracle start with connect by 用法
2012-02-19 23:58 1030oracle 提供了start with connect by ... -
Oracle数据导入导出imp/exp
2012-02-09 17:38 626Oracle数据导入导出imp/exp 功能:Oracle数 ... -
性能监控SQL语句
2011-12-23 13:51 831分析表 analyze table tablename co ... -
常用SQL语句
2011-12-23 13:50 984查找数据库中所有字段 以对应的表 select C.colu ... -
安装到最后的两个脚本作用
2011-12-06 18:32 1050在linux下安装Oralce的时候,最后会让你以root的身 ... -
ORACLE中一个字符占多少字节
2011-12-01 22:07 3875在oracle中一个字符特别是中文占几个字节是不同的。 比如 ... -
提高SQL效率
2011-12-01 00:13 1030下面就某些SQL 语句的 where 子句编写中需要注意 ... -
“exists”和“in”的效率问题
2011-11-30 23:49 1022有两个简单例子,以说明 “exists”和“in”的效率问题 ... -
Oracle建立全文索引详解
2011-11-30 20:42 14761.全文检索和普通检索的区别 不使用Oracle text功 ... -
全文检索CLOB
2011-11-30 12:00 997建议使用全文检索(FULL TEXT SEARCH) ... -
“Oracle”数据库的“周数计算”
2011-11-16 13:25 994——日期计算,算第n周的第一天及最后一天是几号。 by key ... -
Oracle中TO_DATE格式
2011-11-16 13:17 837TO_DATE格式(以时间:2007-11-02 13:4 ... -
Oracle 索引 详解
2011-11-15 13:00 26048Oracle 索引 详解 ... -
Oracle SQL中的IN 和 EXSITS区别总结
2011-11-15 11:06 1014IN 确定给定的值是否与子查询或列表中的值相匹配。 EX ... -
Oracle 字符集的查看和修改
2011-11-14 23:09 952一、什么是Oracle字符集 ... -
oracle日志归档模式改变
2011-11-14 00:15 1113在Oracle数据库中,主要 ... -
如何最大程度的 把表空间里面的数据给抢救出来
2011-11-03 16:18 1268今天一朋友问到一个比较有意识的问题: 如果一个表空间,其中一个 ... -
oracle 性能优化建议小结
2011-10-24 23:45 446原则一:注意WHERE子句 ...
相关推荐
在Oracle 10g及后续版本中,Flashback技术主要包括以下几个方面: 1. **Flashback Database** - **定义**:类似于RMAN的不完全恢复,能够将整个数据库恢复到过去某个时间点的状态。 - **实现方式**:依赖于...
Oracle Flashback技术是Oracle数据库提供的一种强大的数据恢复和历史数据查询功能,它允许用户恢复到数据库的某个历史状态,或者查询过去的某个时刻的数据。这项技术的核心是基于Undo Segment中的信息,Undo Segment...
Oracle Flashback技术是一种强大的工具,它允许用户恢复数据库、表或查询到过去的一个特定时间点。这项技术基于Undo段中的信息,因此其可用性受到UNDO_RETENTION参数的限制。在Oracle 10g中,Flashback技术包含了多...
Oracle的Flashback技术是数据库管理系统中的一个重要特性,它允许用户恢复到数据库的某个历史状态,无需依赖传统的备份和恢复过程。这项技术对于处理误操作、临时数据错误或进行时间点恢复非常有用。在本篇文章中,...
### Oracle Flashback 闪回技术详解 #### 一、引言 在Oracle数据库管理中,闪回技术(Flashback)是一种非常重要的数据恢复工具。它允许用户和管理员以一种简单而有效的方式,恢复误删、误改的数据。本文将详细介绍...
Oracle Flashback技术是Oracle数据库中的一个强大特性,旨在帮助用户恢复错误操作或进行历史数据分析。"Oracle Flashback 技术总结.doc"涵盖了Flashback Query(回溯查询)、Flashback Table(回溯表)、Flashback ...
Flashback技术是Oracle数据库中一项重要的数据恢复工具,它基于Undo Segment中的内容实现,并受到UNDO_RETENTION参数的影响。要使用这项特性,用户必须启用自动撤销管理表空间。在Oracle 10g版本中,Flashback技术...
Oracle 10g 引入了强大的 Flashback 技术,这是一系列旨在帮助管理员和开发者在出现数据丢失或损坏时能够快速恢复数据的功能集合。该技术从 Oracle 9i 开始引入,并在 10g 版本中得到了显著增强和完善。Flashback ...
### Oracle FlashBack 闪回技术详解 #### 一、引言 在Oracle数据库管理中,闪回技术(FlashBack)是一项极为重要的功能,它能够帮助数据库管理员恢复误操作或者数据丢失的情况,为数据的安全性和可靠性提供了强有力...
Oracle 10g引入了一系列回闪(Flashback)技术,旨在提供一种快速恢复数据库至特定时间点的能力,而无需传统的备份和恢复过程。这些技术允许数据库管理员轻松地撤消数据更改或恢复到特定的时间点,为误操作提供了...
Oracle Flashback技术是Oracle数据库10g及后续版本中的一项重要特性,它提供了一种快速、简单的方式来恢复数据,尤其适用于逻辑错误引起的数据库损坏场景。Flashback技术允许用户查看、查询和恢复数据至任意历史时间...
总结来说,Oracle闪回技术是一套强大的数据库恢复工具,它提供了灵活性和高效性,使得数据库管理员能够在不牺牲服务的情况下处理各种逻辑错误。了解和掌握这些技术对于优化数据库管理和维护至关重要。
总结来说,Oracle的闪回技术是数据库管理员的有力工具,它提供了灵活的数据恢复选项,可以帮助用户快速处理误操作或进行历史数据分析。通过闪回删除、闪回查询和闪回表数据,用户可以在不影响数据库正常运行的情况下...
在Oracle RAC(Real Application Clusters)环境下启用Flashback闪回功能是一项高级的数据库管理技术,它能够帮助数据库管理员在不丢失数据的情况下恢复到过去某一时间点的状态,这对于数据安全和灾难恢复至关重要。...
Oracle Flashback技术确实使用了undo信息来构造一致的数据视图。 - B. 正确。虽然PL/SQL游标可以在使用Flashback时不激活Flashback选项,但是此选项描述的是可以执行DML操作,这是正确的。 - C. 不正确。使用...
### Oracle Flashback技术详解 #### 一、概述 Oracle Flashback技术是一组强大的特性集合,旨在帮助用户在遇到数据丢失或损坏的情况下能够迅速地恢复数据。这些特性基于Oracle的Undo Segment,即撤销段中的内容,...
总结来说,Oracle的回闪技术是一套全面的数据恢复解决方案,涵盖了从数据库级到表级,甚至单个事务的恢复需求。正确配置和使用这些工具,能够极大地增强数据库的安全性和可恢复性,保护企业的数据资产免受意外损失。
Oracle Flashback 是一种能够帮助用户恢复数据库至某一特定时间点的技术。该技术在Oracle 10g中被广泛引入,为数据库管理员提供了一种简便的方式来恢复数据,而无需进行复杂的备份与恢复操作。 #### 二、启用...