[转]Oracle flashback家族成员

Undo 记录使用在如下情况:
(1) Roll back transactions whena ROLLBACK statement is issued
(2) Recover the database
(3) Provide read consistency
(4) Analyze data as of an earlierpoint in time by using Oracle Flashback Query
(5) Recover from logicalcorruptions using Oracle Flashback features

在oracle 9i中引入flashback查询,以便能在需要的时候查到过去某个时刻的一致性数据,依赖于undo表空间存储的信息来闪回查询以前的版本,当然这个受限于undo表空间的大小,以及保留策略。如果undo 被覆盖了就不能进行查询。
undo_retention确定undo表空间数据保留时间,超过规定的时间的undo数据会被标记expired。
如果undo表空间大小是固定的,undo_retention会被忽略,数据库会根据系统状态自动调整undo retention 值。
如果undo是自动扩展的,undo retention会生效,如果表空间不足时,并不会去覆盖未过期已经commit的数据undo数据,而是会去自动扩展表空间。当undo表空间扩展到maxsize之后,数据库才会覆盖那些未过期已commit的undo数据。
为了保证大事务和flashback操作,这个时候就需要甚至retention guarantee,强制保留undo数据。在undo retention内,即使undo空间不足也不会覆盖未过期的undo数据。如果没有设置retention guarantee,当undo不够时,数据库就会覆盖那么未过期的数据。
我们可以在创建数据库或者创建undo 表空间时指定retention guarantee 子句,也可以在创建完毕后修改undo 表空间的属性。命令如下:

SQL> Alter tablespace undotbs1 retention guarantee;

oracle10g中增强了闪回查询的功能,并且提供了将整个数据库回退到过去某个时刻的能力,这是通过引入一种新的flashback log实现的。flashback log有点类似redo log,只不过redo log将数据库往前滚,flashback log则将数据库往后滚。为了保存管理和备份恢复相关的文件,oracle10g提供了一个叫做闪回恢复区(Flashback recovery area),这个区域默认创建在oracle_base目录下。 可以将所有恢复相关的文件,比如flashback log,archive log,backup set等,放到这个区域集中管理。
在Oracle 10g中, Flash back家族分为以下成员: Flashback Database, Flashback Drop,Flashback Query(分Flashback Query,Flashback Version Query, Flashback Transaction Query 三种) 和Flashback Table。

在Oracle 11g里又出了一个新特性:Oracle Flashback Data Archive. FDA通过将变化数据另外存储到创建的闪回归档区(Flashback Archive)中,以和undo区别开来,这样就可以为闪回归档区单独设置存储策略,使之可以闪回到指定时间之前的旧数据而不影响undo策略。
db_flashback_retention_target :闪回恢复区数据保留时间
db_recovery_file_dest:闪回恢复区位置
db_recovery_file_dest_size:闪回恢复区空间大小

将db_recovery_file_dest参数设置为空,可以停用闪回恢复区。如果已经启用flashback database,则不能取消闪回恢复区。一般是这么做的:
SQL> alter database flashback off;
SQL> alter system set db_recovery_file_dest=”;
DB_RECOVERY_FILE_DEST_SIZE 只有在 DB_RECOVERY_FILE_DEST 清空之后才可以清空;
如果设置了DB_RECOVERY_FILE_DEST,那么log_archive_destlog_archive_dest_n将不可用。

flashback database

flashback database跟raman非常类似,区别就是flashback database可以把数据库从当前时间点开始回退到flashback log记录的任何一个时间,而rman只能向前恢复。 但它也有某些限制:
(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 整个架构包括一个进程Recover Writer(RVWR)后台进程,Flashback Database Log日志 和Flash Recovery Area。一旦数据库启用了Flashback Database, 则RVWR进程会启动,该进程会向Flash Recovery Area中写入Flashback Database Log, 这些日志包括的是数据块的 ” 前镜像(before image)”, 这也是Flashback Database 技术不完全恢复块的原因。

SQL> archive log list;
Database log mode              Archive Mode
Automatic archival             Enabled
Archive destination            /home/oracle/app/oracle/product/11.2.0/dbhome_1/dbs/arch
Oldest online log sequence     12
Next log sequence to archive   14
Current log sequence           14
SQL> select flashback_on from v$database;

FLASHBACK_ON
------------------
YES

SQL> SQL> show parameter db_recovery

NAME                                 TYPE
------------------------------------ --------------------------------
VALUE
------------------------------
db_recovery_file_dest                string
$ORACLE_BASE/flash_recovery_ar
ea
db_recovery_file_dest_size           big integer
4G
SQL> show parameter flashback

NAME                                 TYPE
------------------------------------ --------------------------------
VALUE
------------------------------
db_flashback_retention_target        integer
1440
SQL> 

以上可以看到,数据库归档,flashback 都打开了,下面开始做测试:

select current_scn from v$database;
CURRENT_SCN
-----------
 1110160557

select to_char(sysdate,'yyyy-mm-dd hh24:MM:ss') from dual;
TO_CHAR(SYSDATE,'YYYY-MM-DDHH24:MM:SS')
---------------------------------------------------------------------------
2017-11-22 17:11:07
create table test1 (id int);

insert into test1(1);
insert into test1(2);

select current_scn from v$database;
CURRENT_SCN
-----------
 1110160660
drop table acs;

shutdown immediate;
startup mount

flashback database to scn  1110160660;
这里演示,就以resetlogs方式打开:
alter database open resetlogs;

SQL> select * from acs;

        ID
----------
         1
         2

几个相关视图:

SQL> desc v$flashback_database_log
 Name                                      
 ----------------------------------------- -------- ----------------------------
 OLDEST_FLASHBACK_SCN                     可以恢复最早的SCN
 OLDEST_FLASHBACK_TIME                           可以恢复最早的时间
 RETENTION_TARGET                                   保留时间
 FLASHBACK_SIZE                                        闪回恢复区大小
 ESTIMATED_FLASHBACK_SIZE                         预估闪回空间大小

SQL> select * from v$flashback_database_log;

OLDEST_FLASHBACK_SCN OLDEST_FL RETENTION_TARGET FLASHBACK_SIZE ESTIMATED_FLASHBACK_SIZE
-------------------- --------- ---------------- -------------- ------------------------
          1110141526 22-NOV-17             1440     1048576000                163209216
SQL> desc v$flashback_database_stat
 Name                                                  
 ----------------------------------------------------- -------- ------------------------------------
 BEGIN_TIME                                                  开始时间
 END_TIME                                                   结束时间
 FLASHBACK_DATA                                      产生的undo数据
 DB_DATA                                                       产生的改变数据
 REDO_DATA                                                      产生的redo数据
 ESTIMATED_FLASHBACK_SIZE                                    预估闪回空间大小

SQL> select * from v$flashback_database_stat;

BEGIN_TIM END_TIME  FLASHBACK_DATA    DB_DATA  REDO_DATA ESTIMATED_FLASHBACK_SIZE
--------- --------- -------------- ---------- ---------- ------------------------
22-NOV-17 22-NOV-17        1187840    2940928      97280                        0

flashback drop:

Flashback Drop 是从Oracle 10g 开始出现的,用于恢复用户误删除的对象(包括表,索引等), 这个技术依赖于Tablespace Recycle Bin(表空间回收站),这个功能和windows的回收站非常类似。
Flashback 不支持sys用户.及system表空间下的对象,也不能从回收站里拿到。
故使用SYS 或者SYSTEM用户登陆时, show recycle bin 为空。
Flashback Drop 是基于Tablespace RecycleBin 来实现恢复的。 它只支持闪回与table 相关连的对象,比如表,索引,约束,触发器等。 如果是函数或者存储过程等,就需要使用Flashback Query来实现。

Tablespace recycle bin
从Oracle 10g 开始, 每个表空间都会有一个叫作回收站的逻辑区域,当用户执行drop命令时, 被删除的表和表的关联对象( 包括索引, 约束,触发器,LOB段,LOB index 段) 不会被物理删除, 这些对象先转移到回收站中,这就给用户提供了一个恢复的可能。

When you drop a table, the database does not immediately remove the space associated with the table. The database renames the table and places it and any associated objects in a recycle bin, where, in case the table was dropped in error, it can be recovered at a later time. This feature is called Flashback Drop, and the FLASHBACK TABLE statement is used to restore the table. Before discussing the use of the FLASHBACK TABLE statement for this purpose, it is important to understand how the recycle bin works, and how you manage its contents.

            The recycle bin is actually a data dictionary table containing information about dropped objects. Dropped tables and any associated objects such as indexes, constraints, nested tables, and the likes are not removed and still occupy space. They continue to count against user space quotas, until specifically purged from the recycle bin or the unlikely situation where they must be purged by the database because of tablespace space constraints.

SQL> show parameter recyclebin

NAME TYPE VALUE


recyclebin string on

初始化参数recyclebin 用于控制是否启用recyclebin功能,缺省是ON, 可以使用OFF关闭。

禁用后删除的对象将直接删除,不会写到Recycle中,当然在删除时,指定purge 参数,表也将直接删除,不会写到recyclebin中。

SQL> select * from a;

        ID NAME
---------- ----------
         2 ??
         1 a
         3 b

SQL> drop table a;

Table dropped.

SQL> show recyclebin
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
A                BIN$XpEOc9xEbbjgU6ACJQrhrw==$0 TABLE        2017-11-22:18:48:14



SQL> select object_name,ORIGINAL_NAME,OPERATION from recyclebin;

OBJECT_NAME                    ORIGINAL_NAME                    OPERATION
------------------------------ -------------------------------- ---------
BIN$XpEOc9xEbbjgU6ACJQrhrw==$0 A                                DROP

既然是重命名对象,并迁移到recycle bin空间,那么就可以查询这个对象

SQL> select * from "BIN$XpEOc9xEbbjgU6ACJQrhrw==$0";

        ID NAME
---------- ----------
         2 ??
         1 a
         3 b


SQL> flashback table a to before drop;

Flashback complete.

SQL> select * from a;

        ID NAME
---------- ----------
         2 ??
         1 a
         3 b

SQL> show recyclebin;
SQL> select object_name,ORIGINAL_NAME,OPERATION from recyclebin;

no rows selected

注意事项:
1 . 当我们删除表A,在新建表A,在删除它,这是在Recycle Bin中就会有2个相同的表明,此时恢复我们就要指定object_name才行。

flashback table "BIN$vYuv+g9fTi2exYP9X2048Q==$0" to before drop;

2 . 当我们删除表A后,在新建表A,这时在恢复的时候就会报错,此时我们在闪回时,对表重命名就可以了。

flashback table a to before drop rename to B;

3 . 如果表上索引或者约束等信息,这些信息也会被恢复,但是这些对象会使用Oracle 自动的命名。 我们需要查看这些对象,然后对这些对象重新命名:

SQL>select index_name from user_indexes where table_name = 'test1';
INDEX_NAME
------------------------------
BIN$DBo9UChwZSbgQFeMiAdCcQ==$0
BIN$DBo9UChtZSbgQFeMiAdCcQ==$0
BIN$DBo9UChuZSbgQFeMiAdCcQ==$0
BIN$DBo9UChvZSbgQFeMiAdCcQ==$0

重命名:
SQL>alter index "bin$dbo9uchtzsbgqfemiadccq==$0" rename to jhist_job_ix;

4 . 只能用于非系统表空间和本地管理的表空间
5 . 对象的参考约束不会被恢复,指向该对象的外键约束需要重建。
6 . 对象能否恢复成功,取决与对象空间是否被覆盖重用。
7 . 当删除表时,信赖于该表的物化视图也会同时删除,但是由于物化视图并不会被放入recycle bin,因此当你执行flashback table to before drop 时,也不能恢复依赖其的物化视图,需要dba 手工介入重新创建。
8 . 对于Recycle Bin中的对象,只支持查询.

表空间的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所占用的空间来缓解空间压力。 因为索引是可以重建的。
那么recycle bin中的对象会保存多长?
用户无法再申请到扩展(extents )时,回收站空间将被逐个回收。
space pressure 两种情况:
1)表空间非自动扩展 已经达到限额
2)该用户有设置资源限制,达到限额

Flashback Query:

Flashback 是ORACLE 自9i 就开始提供的一项特性,在9i 中利用oracle 查询多版本一致的特点,实现从回滚段中读取表一定时间内操作过的数据,可用来进行数据比对,或者修正意外提交造成的错误数据,该项特性也被称为Flashback Query。
Flashback Query分Flashback Query,Flashback Version Query, Flashback Transaction Query 三种。
Flashback Query 是利用多版本读一致性的特性从UNDO 表空间读取操作前的记录数据。
flashback query 对v$tables,x$tables 等动态性能视图无效,不过对于dba_*,all_*,user_*等数据字典是有效的。
该特性也完全支持访问远端数据库,比如select * from tbl@dblink as of scn 3600;的形式。

多版本读一致性:
不同的事务在写数据时,会将数据的前映像写入undo 表空间,这样如果同时有其它事务查询该表数据,则可以通过undo 表空间中数据的前映像来构造所需的完整记录集,而不需要等待写入的事务提交或回滚。
Flashback query 有多种方式构建查询记录集,记录集的选择范围可以基于时间或基于scn,甚至可以同时查询出记录在undo 表空间中不同事务时的前映象。
用法与标准查询非常类似,要通过flashback query 查询undo 中的撤销数据,最简单的方式只需要在标准查询语句的表名后面跟上as of timestamp(基于时间)或as of scn(基于scn)即可。
“as of timestamp|scn ”的语法是自9iR2 后才开始提供支持。

SQL>  alter session set nls_date_format='YYYY-MM-DD hh24:mi:ss';
会话已更改。
SQL> select sysdate from dual;

SYSDATE
-------------------
2017-11-22 19:18:29

SQL> select current_scn from v$databases;

CURRENT_SCN
-----------
 1110164814

SQL> delete from a where id=4;

1 row deleted.

SQL> commit;

SQL> select * from a as of scn 1110164814;

        ID NAME
---------- ----------
         2 ??
         1 a
         3 b
         4 4
select * from a as of timestamp to_timestamp('2017-11-22 19:18:29','YYYY-MM-DD hh24:mi:ss');

        ID NAME
---------- ----------
         2 ??
         1 a
         3 b
         4 4

SCN 与 timestamp 关系:
Oracle 在内部都是使用scn,即使你指定的是as of timestamp,oracle 也会将其转换成scn,系统时间标记与scn 之间存在一张表,即SYS 下的SMON_SCN_TIME


 select time_dp,scn from sys.smon_scn_time;
 TIME_DP                    SCN
------------------- ----------
2017-11-23 00:10:17 1110201991
2017-11-23 00:15:20 1110202107
2017-11-23 00:20:17 1110202211
2017-11-23 00:25:23 1110202333
2017-11-23 00:30:15 1110202447 

每隔5 分钟,系统产生一次系统时间标记与scn 的匹配并存入sys.smon_scn_time 表,该表中记录了最近1486个系统时间标记与scn 的匹配记录,由于该表只维护了最近的1486 条记录,因此如果使用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 ,timestamp 08-05-30 13:52:00 到undo 表空间中查找,也就说在这个时间内,不管你指定的时间点是什么,查询返回的都将是08-05-30 13:52:00 这个时刻的数据。
上面我们提到过,flashback query只能闪回表及表相关的对象,如果是其他对象如 function,procedure,trigger等,就需要使用all_source表来进行闪回。
先看联机文档对该表的说明:
ALL_SOURCE describes the text source of the stored objects accessible to the current user.

Related Views
DBA_SOURCE describes the text source of all stored objects in the database.
USER_SOURCE describes the text source of the stored objects owned by the current user. This view does not display the OWNER column.

可以使用冒号来定义对齐方式:

ColumnDescription
OWNEROwner of the object
NAMEName of the object
TYPEType of object: FUNCTION, JAVA SOURCE, PACKAGE, PACKAGE BODY, PROCEDURE, TRIGGER, TYPE, TYPE BODY
LINELine number of this line of source
TEXTText source of the stored object

如果我们误删除了某些对象,如procedure,就可以使用all_source 表进行恢复。
实例:

SQL> create or replace function getdate return date
  2  as 
  3  v_date date;
  4  begin 
  5  select sysdate into v_date from dual;
  6  return v_date;
  7  end;
  8  /

Function created.
SQL> select getdate() from dual;

GETDATE()
-------------------
2017-11-23 10:41:18

SQL> drop function getdate;

Function dropped.
SQL> select text from all_source where name='GETDATE';

no rows selected
SQL> select text from sys.all_source as of timestamp to_timestamp('2017-11-23 10:41:18','yyyy-mm-dd hh24:mi:ss') where name='GETDATE';

TEXT
----------------------------------------------------------------------------------------------------
function getdate return date
as
v_date date;
begin
select sysdate into v_date from dual;
return v_date;
end;

7 rows selected.

通过flashback query 查询物化视图对象:

select mview_name, query from dba_mviews as of timestamp to_timestamp('2013-04-21 15:00:00','yyyy-mm-dd hh24:mi:ss') where mview_name='V1_AREA_CENTER_SUMMARY'

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 ora_rowscn,id,name from a;

ORA_ROWSCN         ID NAME
---------- ---------- ----------
 355490272          2 ??
 355490272          1 a
 355490272          3 b

这里SCN都一样,这也正好说明了记录了最后一个提交的SCN。如果没有提交SCN是不会变的。
下面我们来讲下伪列, Flashback Version Query 技术其实有很多伪列,但是ORA_ROWSCN是最重要。它记录的是最后一次被修改时的SCN, 注意是被提交的修改。如果没有提交,这个伪列不会发生变化。

        ORA_ROWSCN 缺省是数据块级别的,也就是一个数据块内的所有记录都是一个ORA_ROWSCN,数据块内任意一条记录被修改,这个数据库块内的所有记录的ORA_ROWSCN都会同时改变。上例的查询结果以证明。

        不过我们可以在建表时使用关键字 rowdependencies, 可以改变这种缺省行为,使用这个关键字后,每条记录都有自己的ORA_ROWSCN。
SQL> select versions_xid,versions_startscn,versions_endscn,versions_operation,id from a versions between scn minvalue and maxvalue;

VERSIONS_XID     VERSIONS_STARTSCN VERSIONS_ENDSCN V         ID
---------------- ----------------- --------------- - ----------
                                                              2
                                                              1
                                                              3
0A001B0000BA1A00        1110164825                 D          4
01001B00F87D0100        1110164790      1110164825 I          4


SQL> select * from a versions between scn minvalue and maxvalue;

        ID NAME
---------- ----------
         2 ??
         1 a
         3 b
         4 4
         4 4

Flashback Transaction Query

Flashback Transaction Query也是使用UNDO信息来实现。利用这个功能可以查看某个事务执行的所有变化,它需要访问flashback_transaction_query 视图,这个视图的XID列代表事务ID,利用这个ID可以区分特定事务发生的所有数据变化。

FLASHBACK_TRANSACTION_QUERY displays information about all flashback transaction queries in the database。

ColumnDescription
XIDTransaction identifier
START_SCNTransaction start system change number (SCN)
START_TIMESTAMPTransaction start timestamp
COMMIT_SCNTransaction commit system change number (null for active transactions)
COMMIT_TIMESTAMPTransaction commit timestamp (null for active transactions)
LOGON_USERLogon user for the transaction
UNDO_CHANGE#Undo system change number (1 or higher)
OPERATIONForward-going DML operation performed by the transaction: D -delete,I-insert,U-update,B,unknown
TABLE_NAMEName of the table to which the DML applies
TABLE_OWNEROwner of the table to which the DML applies
ROW_IDRowid of the row that was modified by the DML
UNDO_SQLSQL to undo the DML indicated by OPERATION

查看视图,每个事务都对应相同的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);

XID              OPERATION                        COMMIT_SCN
---------------- -------------------------------- ----------
UNDO_SQL
----------------------------------------------------------------------------------------------------
0A001B0000BA1A00 DELETE                           1110164825
insert into "BOBO"."A"("ID","NAME") values ('4','4');

0A001B0000BA1A00 BEGIN                            1110164825


01001B00F87D0100 INSERT                           1110164790
delete from "BOBO"."A" where ROWID = 'AAAwNVAAEAAAA2nAAA';


XID              OPERATION                        COMMIT_SCN
---------------- -------------------------------- ----------
UNDO_SQL
----------------------------------------------------------------------------------------------------
01001B00F87D0100 BEGIN                            1110164790




Execution Plan
----------------------------------------------------------
Plan hash value: 1947788431

----------------------------------------------------------------------------------------------
| Id  | Operation                | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |                   |     3 |  6135 |     7  (15)| 00:00:01 |
|   1 |  NESTED LOOPS            |                   |     3 |  6135 |     7  (15)| 00:00:01 |
|   2 |   VIEW                   | VW_NSO_1          |     3 |    18 |     7  (15)| 00:00:01 |
|   3 |    HASH UNIQUE           |                   |     3 |       |     7  (15)| 00:00:01 |
|   4 |     TABLE ACCESS FULL    | A                 |     3 |       |     6   (0)| 00:00:01 |
|*  5 |   FIXED TABLE FIXED INDEX| X$KTUQQRY (ind:1) |     1 |  2039 |     0   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   5 - filter("XID"="VERSIONS_XID")


Statistics
----------------------------------------------------------
    1640551  recursive calls
        116  db block gets
    5464062  consistent gets
      59621  physical reads
          0  redo size
        981  bytes sent via SQL*Net to client
        524  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
       1411  sorts (memory)
          0  sorts (disk)
          4  rows processed

Flashback table

注意SYS用户不支持闪回,这点前面已经说明过。
Flashback Table也是使用UNDO tablespace的内容来实现对数据的回退。该命令相对简单,输入:flashback table table_name to scn(to timestamp) 即可。
注意:如果想要对表进行flashback,必须允许表的row movement.
SQL>Alter table table_name row movement;

        要查看某表是否启用row movement,可以到user_tables 中查询(或all_tables,dba_tables).
SQL> alter table a enable row movement;


SQL> alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss";

Session altered.

SQL> select sysdate from dual;

SYSDATE
-------------------
2017-11-23 13:38:20

SQL> select current_scn from v$database;

CURRENT_SCN
-----------
 1110211029

SQL> delete from a;

SQL>  flashback table a to scn 1110211029;

Flashback complete.

SQL> select * from a;

        ID NAME
---------- ----------
         4 4
         2 ??
         1 a
         3 b

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 约束,要么通过适当逻辑,对要恢复的数据进行处理之后,再执行恢复。
(2)基于undo 的表恢复,flashback table 实际上做的也是dml 操作(会在被操作的表上加dml 锁),因此还需要注意triggers 对其的影响,默认情况下,flashback table to scn/timestamp 在执行时会自动disable 掉与其操作表相差的triggers,如果你希望在此期间trigger 能够继续发挥做用,可以在flashback table 后附加 ENABLE TRIGGERS 子句。

Flashback data archive

在Oracle 11g里又出了一个新特性:Oracle Flashback Data Archive. 在11g的官方文档里搜到了相关内容说明,参考:
Using Oracle Flashback Technology
–Using Flashback Data Archive (Oracle Total Recall)
http://download.oracle.com/docs/cd/E11882_01/appdev.112/e17125/adfns_flashback.htm#BJFIEJGG

官网的定义如下:
A Flashback Data Archive provides the ability to track and store transactional changes to a table over its lifetime. A Flashback Data Archive is useful for compliance with record stage policies and audit reports.
–Flashback Data Archive 在它的有效期内将保存事务改变的信息。
A Flashback Data Archive consists of one or more tablespaces or parts thereof. You can have multiple Flashback Data Archives. If you are logged on as SYSDBA, you can specify a default Flashback Data Archive for the system. A Flashback Data Archive is configured with retention time. Data archived in the Flashback Data Archive is retained for the retention time.
– FDA 包含一个或者多个表空间,我们可以创建多个FDA。 当以sysdba 登陆时,可以指定default FDA。
By default, flashback archiving is off for any table. You can enable flashback archiving for a table if all of these conditions are true:
– 默认情况下,FDA 是关闭的,当具备一下条件时,我们可以启用FDA。
(1). You have the FLASHBACK ARCHIVE object privilege on the Flashback Data Archive to use for that table.
(2). The table is either nested, clustered, temporary, remote, or external.
(3). The table contains neither LONG nor nested columns.

After flashback archiving is enabled for a table, you can disable it only if you either have the FLASHBACK ARCHIVE ADMINISTER system privilege or you are logged on as SYSDBA.
–当FDA 启动以后,只有具有FLASHBACK ARCHIVE ADMINISTER 权限的用户或者用SYSDBA登陆的用户才可以禁用FDA。

When choosing a Flashback Data Archive for a specific table, consider the data retention requirements for the table and the retention times of the Flashback Data Archives on which you have the FLASHBACK ARCHIVE object privilege.

给用户赋:
SQL> create user boboidentified by ‘ckf77856’default tablespace users temporary tablespace temp;
User created.

SQL> grant resource,connect to bobo;
Grant succeeded.

SQL> grant flashback archive administer to bobo;
Grant succeeded.

SQL> grant flashback archive administer to bobo;

在Oracle 10g中的lashback 包括: flashback version query、flashback transaction query、flashback database、flashback table和flashback drop等特性。
在这些闪回技术当中,除了Flashback Database(依赖于闪回日志)之外,其他的闪回技术都是依赖于Undo撤销数据,都与数据库初始化参数UNDO_RETENTION密切相关。
它们是从撤销数据中读取信息来构造旧数据的。这样就有一个限制,就是undo中的信息不能被覆盖。而undo段是循环使用的,只要事务提交,之前的undo信息就可能被覆盖,虽然可以通过 undo_retention等参数来延长undo的存活期,但这个参数会影响所有的事务,设置过大,可能导致undo tablespace快速膨胀。

Oracle 11g中flashback增加了:Flashback Data Archive 特性。该技术与之前的Flashback的实现机制不同,通过将变化数据另外存储到创建的闪回归档区(Flashback Archive)中,以和undo区别开来,这样就可以为闪回归档区单独设置存储策略,使之可以闪回到指定时间之前的旧数据而不影响undo策略。并且可以根据需要指定哪些数据库对象需要保存历史变化数据,而不是将数据库中所有对象的变化数据都保存下来,这样可以极大地减少空间需求。
Flashback Data Archive并不是记录数据库的所有变化,而只是记录了指定表的数据变化。所以,Flashback Data Archive是针对对象的保护,是Flashback Database的有力补充。

  通过Flashback Data Archive,可以查询指定对象的任何时间点(只要满足保护策略)的数据,而且不需要用到undo,这在有审计需要的环境,或者是安全性特别重要的高可用数据库中,是一个非常好的特性。缺点就是如果该表变化很频繁,对空间的要求可能很高。

闪回数据归档区
闪回数据归档区是闪回数据归档的历史数据存储区域,在一个系统中,可以有一个默认的闪回数据归档区,也可以创建其他许多的闪回数据归档区域。
每一个闪回数据归档区都可以有一个唯一的名称。同时,每一个闪回数据归档区都对应了一定的数据保留策略。
例如可以配置归档区FLASHBACK_DATA_ARCHIVE_1中的数据保留期为1年,而归档区FLASHBACK_DATA_ARCHIVE_2的数据保留期为2天或者更短。 以后如果将表放到对应的闪回数据归档区,则就按照该归档区的保留策略来保存历史数据。
闪回数据归档区是一个逻辑概念,是从一个或者多个表空间中拿出一定的空间,来保存表的修改历史,这样就摆脱了对Undo撤销数据的依赖,不利用undo就可以闪回到归档策略内的任何一个时间点上。

Flashback archive相关数据字典

ColumnDescription
*_FLASHBACK_ARCHIVEDisplays information about Flashback Data Archive files.
*_FLASHBACK_ARCHIVE_TSDisplays tablespaces of Flashback Data Archive files.
*_FLASHBACK_ARCHIVE_TABLESDisplays information about tables that are enabled for Data Flashback Archive files.

* 代表DBA 或者User。

Flashback archive的后台进程
Oracle11g为Flashback data archive特性专门引入了一个新的后台进程FBDA,用于将追踪表(traced table,也就是将指定使用flashback data archive的table)的历史变化数据转存到闪回归档区。

Flashback archive 的限制条件
(1)Flashback data archive只能在ASSM(auto segment space manager)的tablespace上创建
(2)Flashback data archive要求必须使用自动undo管理,
即 undo_management 参数为auto

Creating a Flashback Data Archive:

Create a Flashback Data Archive with the CREATE FLASHBACK ARCHIVE statement, specifying:
(1)Name of the Flashback Data Archive
(2)Name of the first tablespace of the Flashback Data Archive
(3)(Optional) Maximum amount of space that the Flashback Data Archive can use in the first tablespace。The default is unlimited. Unless your space quota on the first tablespace is also unlimited, you must specify this value; otherwise, error ORA-55621 occurs.
(4)Retention time (number of days that Flashback Data Archive data for the table is guaranteed to be stored)

– 创建FDA 时,可以指定以上4个参数,没有没有执行Flashback Archive 的配额,默认为 unlimited。 这里的配额,指的是用户对表空间的配额。

If you are logged on as SYSDBA, you can also specify that this is the default Flashback Data Archive for the system. If you comit this option, you can still make this Flashback Data Archive the default later .
– 如果以SYSDBA 登陆,还可以指定default Flashback Data Archive。 如果没有指定,也可以通过alter flashback archive 命令来指定。

测试:
(1).创建测试表空间


SQL> create tablespace fda1 datafile '/home/oracle/app/oracle/product/oradata/fda1.dbf' size 5m autoextend on next 1m maxsize 50m extent management local ;

Tablespace created.

SQL> create tablespace fda2 datafile '/home/oracle/app/oracle/product/oradata/fda2.dbf' size 5m autoextend on next 1m maxsize 50m extent management local ;

Tablespace created.

SQL> create tablespace fda3 datafile '/home/oracle/app/oracle/product/oradata/fda3.dbf' size 5m autoextend on next 1m maxsize 50m extent management local ;

Tablespace created.

(2). 创建一个默认的Flashback Archive, 配额为10M,数据保留期为1月

SQL> create flashback archive default fla1 tablespace fda1 quota 10m retention 1 month;

Flashback archive created.

默认的Flashback Archive 只能有一个,但是我们可以通过alter flashback archive 来修改。

SQL> alter flashback archive fla2 set default;

SQL> select flashback_archive_name name, status  from dba_flashback_archive;

NAME       STATUS
---------- -------
FLA1
FLA2       DEFAULT

创建非默认flashback archive ,使用默认配额unlimited。

SQL> create flashback archive fla2 tablespace fda2  retention 2 month;

Flashback archive created.

根据官网的说法,这种情况下,用户对该表空间的配额也必须为ulimited。 否则就会报错ORA-55621。

测试一下:

SQL> grant unlimited tablespace to dvd;
Grant succeeded.

SQL> conn dvd/dvd;
Connected.

SQL> create flashback archive fla5 tablespace fda4 retention 1 day;
Flashback archive created.

With the ALTER FLASHBACK ARCHIVE statement, you can:
– 使用alter flashback archive 可以修改如下内容:
(1)Change the retention time of a Flashback Data Archive
(2)Purge some or all of its data
(3)Add, modify, and remove tablespaces

Note:
Removing all tablespaces of a Flashback Data Archive causes an error.
If you are logged on as SYSDBA, you can also use the ALTER FLASHBACK ARCHIVE statement to make a specific file the default Flashback Data Archive for the system.
– 不能移除Flashback Data Archive里的所有表空间。 否则报错。 如果用sysdba 登陆,可以修改默认的Flashback archive。

–给flashback archive fla1 增加表空间

SQL> alter flashback archive fla1 add tablespace fda3;

Flashback archive altered.

SQL> alter flashback archive fla1 remove tablespace fda1;
alter flashback archive fla1 remove tablespace fda1
*
ERROR at line 1:
ORA-55626: Cannot remove the Flashback Archive’s primary tablespace

–给flashback archive fla1 移除表空间

SQL> alter flashback archive fla1 remove tablespace fda3;

Flashback archive altered.

–修改flashback archive fla1 配额

SQL>  alter flashback archive fla1 modify tablespace fda1 quota 30m;

Flashback archive altered.

–修改flashback archive fla1 保留时间

SQL> alter flashback archive fla1 modify retention 5 day;

Flashback archive altered

–移除flashback archive fla1所有信息

SQL> alter flashback archive fla1 purge all;

Flashback archive altered.

–清除1天之前的数据

SQL> alter flashback archive fla1 purge before timestamp(sysdate-1);

Flashback archive altered.

–清空Flashback Archive 中指定SCN 之前的所有历史数据

SQL> select current_scn from v$database;
CURRENT_SCN
-----------
 1315755078

SQL> alter flashback archive fla1 purge before scn  1315755078;
Flashback archive altered.
Dropping a Flashback Data Archive:
        Drop a Flashback Data Archive with the DROP FLASHBACK ARCHIVE statement. Dropping a Flashback Data Archive deletes its historical data, but does not drop its tablespaces.

– 删除Flashback Archive 不会删除相应的表空间,只是删除了对应的数据字典。当然也可以通过flashback database 恢复操作。

示例:
SQL> DROP FLASHBACK ARCHIVE fla2;
Flashback archive dropped.

SQL>  select flashback_archive_name name, status  from dba_flashback_archive;
NAME       STATUS
---------- -------
FLA1

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.

Total System Global Area  451006464 bytes
Fixed Size                  2254024 bytes
Variable Size             390073144 bytes
Database Buffers           50331648 bytes
Redo Buffers                8347648 bytes
Database mounted.
SQL>  flashback database to scn 1110269584;

Flashback complete.

SQL> alter database open resetlogs;

Database altered.

SQL> select flashback_archive_name name, status  from dba_flashback_archive;

NAME       STATUS
---------- -------
FLA1
FLA2       DEFAULT
Enabling and Disabling Flashback Data Archive
By default, flashback archiving is disabled for any table. You can enable flashback archiving for a table if you have the FLASHBACK ARCHIVE object privilege on the Flashback Data Archive to use for that table.

To enable flashback archiving for a table, include the FLASHBACK ARCHIVE clause in either the CREATE TABLE or ALTER TABLE statement.

In the FLASHBACK ARCHIVE clause, you can specify the Flashback Data Archive where the historical data for the table are stored. The default is the default Flashback Data Archive for the system. If you specify a nonexistent Flashback Data Archive, an error occurs.

If you enable flashback archiving for a table, but AUM(automatic undo managed) is disabled, error ORA-55614 occurs when you try to modify the table.

If a table has flashback archiving enabled, and you try to enable it again with a different Flashback Data Archive, an error occurs

 After flashback archiving is enabled for a table, you can disable it only if you either have the FLASHBACK ARCHIVE ADMINISTER system privilege or you are logged on as SYSDBA.

 To disable flashback archiving for a table, specify NO FLASHBACK ARCHIVE in the ALTER TABLE statement. (It is unnecessary to specify NO FLASHBACK ARCHIVE in the CREATE TABLE statement, because that is the default.)
SQL> create table test2(id int) flashback archive;

Table created.

SQL> create table test3(id int) flashback archive fla2;

Table created.

SQL> alter table test flashback archive  ;

Table altered.

SQL> alter table test flashback archive fla1 ;

Table altered.

SQL> alter table test no flashback archive;

Table altered.
DDL Statements on Tables Enabled for Flashback Data Archive:

Flashback Data Archive supports many DDL statements, including some that alter the table definition or move data. For example:
–启动Flashback Data Archive的表支持以下的DDL 操作
(1)ALTER TABLE statement that does any of the following:
1)Adds, drops, renames, or modifies a column
2)Adds, drops, or renames a constraint
3)Drops or truncates a partition or subpartition operation
(2)TRUNCATE TABLE statement
(3)RENAME statement that renames a table

Some DDL statements cause error ORA-55610 when used on a table enabled for Flashback Data Archive. For example:
        -- 启动Flashback Data Archive的表上的一些DDL 操作可能触发ORA-55610的错误,这些DDL 如下:

(1)ALTER TABLE statement that includes an UPGRADE TABLE clause, with or without an INCLUDING DATA clause
(3)ALTER TABLE statement that moves or exchanges a partition or subpartition operation
(3)DROP TABLE statement

  If you must use unsupported DDL statements on a table enabled for Flashback Data Archive, use the DBMS_FLASHBACK_ARCHIVE.DISASSOCIATE_FBA procedure to disassociate the base table from its Flashback Data Archive.

        To reassociate the Flashback Data Archive with the base table afterward, use the DBMS_FLASHBACK_ARCHIVE.REASSOCIATE_FBA procedure.

– 如果必须在已经启用Flashback Archive的表上执行这些不支持的DDL 操作,可以用DBMS_FLASHBACK_ARCHIVE 包将表从Flashback Data Archive 分离出来,待操作结束后在添加进去。

        The DBMS_FLASHBACK_ARCHIVE package contains two simple procedures for disassociation and reassociation of a Flashback Data Archive (FDA) enabled table from/with its underlying FDA respectively.

        在Flashback Area中,会有一张历史表记录着我们启动FA表的所有操作。 我们可以通过如下SQL 来查看他们之间的映射关系。
SQL> select table_name,archive_table_name,status from dba_flashback_archive_tables;

TABLE_NAME                     ARCHIVE_TABLE_NAME                                    STATUS
------------------------------ ----------------------------------------------------- -------------
TEST2                          SYS_FBA_HIST_212285                                   ENABLED
TEST3                          SYS_FBA_HIST_212286                                   ENABLED

我们要执行那些不支持的DDL,就需要用dbms_flashback_archive禁用他们之间的映射关系,在操作,操作完在用该包启用他们。

关于dbms_flashback_archive包的使用,参考官网:
DBMS_FLASHBACK_ARCHIVE
http://download.oracle.com/docs/cd/E11882_01/appdev.112/e16760/d_flashb_archive.htm#ARPLS72464

如:

SQL> drop table test2;
drop table test2
           *
ERROR at line 1:
ORA-55610: Invalid DDL statement on history-tracked table

这个表使我们之前创建的,并启用了Flashback Archive.
所以我们先要把test2分离开,

SQL> exec dbms_flashback_archive.disassociate_fba('sys','test2');

PL/SQL procedure successfully completed.

操作完那些不支持的ddl,然后在重新分配:

SQL> exec dbms_flashback_archive.reassociate_fba('sys','test2');
PL/SQL procedure successfully completed.
Flashback Data Archive 恢复数据的测试

查询当前用户启用flashback archive的表

SQL> select table_name,FLASHBACK_ARCHIVE_NAME,ARCHIVE_TABLE_NAME,STATUS from dba_flashback_archive_tables;

TABLE_NAME  FLASHBACK_ARCHIVE_NA   ARCHIVE_TABLE_NAME           STATUS                          
----------  -------------------- -----------------------  ---------------------- 
TEST2           FLA2               SYS_FBA_HIST_212285        ENABLED                             
TEST3           FLA2               SYS_FBA_HIST_212286        ENABLED                             
SQL> declare 
  2  i number;
  3  begin 
  4  for i in 1..100 loop
  5  insert into test2 values(i);
  6  end loop;
  7  end;
  8  /

PL/SQL procedure successfully completed.

select * from test2 as of scn 1110272538;
select * from test2 as of timestamp to_timestamp(sysdate-1);

SQL> select table_name,FLASHBACK_ARCHIVE_NAME,ARCHIVE_TABLE_NAME,STATUS from dba_flashback_archive_tables;

TABLE_NAME                     FLASHBACK_ARCHIVE_NA ARCHIVE_TABLE_NAME                                    STATUS
------------------------------ -------------------- ----------------------------------------------------- -------------
TEST2                          FLA2                 SYS_FBA_HIST_212285                                   ENABLED
TEST3                          FLA2                 SYS_FBA_HIST_212286                                   ENABLED

从这个结果,可以看出,在Flashback archive对应的FA表的历史表是SYS_FBA_HIST_212285。


SQL> select flashback_archive_name,status from dba_flashback_archive;

FLASHBACK_ARCHIVE_NA STATUS
-------------------- -------
FLA1
FLA2                 DEFAULT

查看表 test2的flashback archive的历史数据:(有时候会查询不到数据,需要重新分离–>分配下,有可能是我环境问题)
注意一点:我们不能对这些历史表做任何修改操作,只能查询。

SQL> desc SYS_FBA_HIST_212285
 Name                                      Null?    Type
 ----------------------------------------- -------- ---------------
 RID                                                VARCHAR2(4000)
 STARTSCN                                           NUMBER
 ENDSCN                                             NUMBER
 XID                                                RAW(8)
 OPERATION                                          VARCHAR2(1)
 ID                                                 NUMBER

 select * from SYS_FBA_HIST_212285

如果想对这些历史表进行相关的修改操作,和之前的操作一样:使用dbms_flashback_archive分离2个表之间的关系。

SQL> alter table SYS_FBA_HIST_212285 flashback archive fla1;
alter table SYS_FBA_HIST_212285 flashback archive fla1
*
ERROR at line 1:
ORA-55622: DML, ALTER and CREATE UNIQUE INDEX operations are not allowed on table "SYS"."SYS_FBA_HIST_212285"

操作失误,报了个错误,这里我们也可以知道对一个表启用FDA,会在这个基表上创建索引。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值