ITPub博客

首页 > 数据库 > Oracle > 闪回数据库(flashback database)知识分享

闪回数据库(flashback database)知识分享

Oracle 作者:hd_system 时间:2016-11-10 14:20:23 0 删除 编辑
闪回数据库(flashback database)——依赖的是闪回日志:
1.  一旦启用了闪回数据库,修改的块的前映像会不时地从数据库缓冲区的缓存中复制到SGA内的一个新的存储区域中,即闪回缓冲区。通过一个新的后台进程——恢复写入器(RVWR)把此闪回缓冲区刷新到磁盘和闪回日志。这没有改变向日志缓冲区写入更改的常规程序,LGWR(日志写入器)然后将日志缓冲区刷新到磁盘;闪回日志记录是此操作的附属物。不同于重做日志,不能多路复用和归档闪回日志,闪回日志是自动创建和管理的。
闪回日志在哪里?
SQL> show parameter recovery
NAME                  TYPE   VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest             string /orcldata/fast_recovery_area
db_recovery_file_dest_size        big integer 4182M
recovery_parallelism          integer    0
SQL> !
[william@orcl ~]$ cd /orcldata/fast_recovery_area/
ORCL
[william@orcl fast_recovery_area]$ cd ORCL/flashback/
[william@orcl flashback]$ pwd
/orcldata/fast_recovery_area/ORCL/flashback  #这里就是闪回日志所在的位置
[william@orcl flashback]$ ls
o1_mf_b1htdog9_.flb  o1_mf_b1htdt8x_.flb
恢复写入器是哪个?
[william@orcl ~]$ ps -ef|grep "william"
william   3128     1  0 09:11 ?        00:00:00 /opt/app/william/product/11.2.0/dbhome_1/bin/tnslsnr LISTENER -inherit
william   3221     1  0 09:11 ?        00:00:00 ora_pmon_orcl
william   3223     1  0 09:11 ?        00:00:00 ora_psp0_orcl
william   3225     1  0 09:11 ?        00:00:08 ora_vktm_orcl
william   3229     1  0 09:11 ?        00:00:00 ora_gen0_orcl
william   3231     1  0 09:11 ?        00:00:00 ora_diag_orcl
william   3233     1  0 09:11 ?        00:00:00 ora_dbrm_orcl
william   3235     1  0 09:11 ?        00:00:01 ora_dia0_orcl
william   3237     1  0 09:11 ?        00:00:00 ora_mman_orcl
william   3239     1  0 09:11 ?        00:00:00 ora_dbw0_orcl
william   3241     1  0 09:11 ?        00:00:00 ora_lgwr_orcl
william   3243     1  0 09:11 ?        00:00:00 ora_ckpt_orcl
william   3245     1  0 09:11 ?        00:00:00 ora_smon_orcl
william   3247     1  0 09:11 ?        00:00:00 ora_reco_orcl
william   3249     1  0 09:11 ?        00:00:01 ora_mmon_orcl
william   3251     1  0 09:11 ?        00:00:00 ora_mmnl_orcl
william   3253     1  0 09:11 ?        00:00:00 ora_d000_orcl
william   3255     1  0 09:11 ?        00:00:00 ora_s000_orcl
william   3262     1  0 09:11 ?        00:00:00 ora_rvwr_orcl  #这个就是恢复写入器
william   3265     1  0 09:11 ?        00:00:00 ora_arc0_orcl
william   3267     1  0 09:11 ?        00:00:00 ora_arc1_orcl
william   3269     1  0 09:11 ?        00:00:00 ora_arc2_orcl
william   3271     1  0 09:11 ?        00:00:00 ora_arc3_orcl
william   3273     1  0 09:11 ?        00:00:00 ora_fbda_orcl
william   3275     1  0 09:11 ?        00:00:00 ora_qmnc_orcl
william   3289     1  0 09:11 ?        00:00:00 ora_cjq0_orcl
william   3435     1  0 09:11 ?        00:00:00 ora_q000_orcl
william   3437     1  0 09:11 ?        00:00:00 ora_q001_orcl
william   3500     1  0 09:16 ?        00:00:00 ora_smco_orcl
william   4285     1  0 10:36 ?        00:00:00 oracleorcl (LOCAL=NO)
william   4287     1  0 10:36 ?        00:00:00 oracleorcl (LOCAL=NO)
root      4292  2817  0 10:38 ?        00:00:00 sshd: william [priv]
william   4294  4292  0 10:38 ?        00:00:00 sshd: william@pts/0
william   4295  4294  0 10:38 pts/0    00:00:00 -bash
william   4377     1  0 10:46 ?        00:00:00 ora_w000_orcl
william   4460  4295  0 10:56 pts/0    00:00:00 ps -ef
william   4461  4295  0 10:56 pts/0    00:00:00 grep william
2.  与闪回数据库有关的初始化参数:
undo_management              string AUTO                      #只有在自动回滚段管理的情况下才能使用闪回数据库?
undo_tablespace                  string UNDOTBS1                  #默认的回滚表空间
db_recovery_file_dest            string /orcldata/fast_recovery_area   #指定闪回日志存储位置
db_recovery_file_dest_size       big integer 4182M                    #指定db_recovery_file_dest的上限,与db_flashback_retention_target组合作用
db_flashback_retention_target   integer    1440                       #指定闪回日志支持的回滚时间的上限(单位min),与db_recovery_file_dest_size组合作用
3.  预定义的条件:
u  启用归档模式。
因为Oracle并不是把所有变化都复制到闪回缓冲区,只是这些变化的一个子集。如果把全部块的所有变化复制到缓冲区,就内存使用和把缓冲区刷新到磁盘所需的额外I/O压力来说,这些开销会削弱数据库性能。Oracle内部算法限制把哪些块的哪些版本复制到闪回缓冲区,以便限制闪回缓冲区以及写入磁盘的大小和频率。这些算法的初衷是在启用闪回数据库时确保不会对性能造成负面影响,保证即使很繁忙的块的记录频率也很低。
当执行数据库闪回时,Oracle会读取闪回日志以提取每个改变的数据库块的版本,并将这些版本复制回数据文件。因为这些变化是按照逆时间的顺序应用到当前数据库的,这样做的效果是通过反转DBWn进程执行的写入操作及时回退数据库。
由于不是把每个变化的块的所有版本都复制到闪回缓冲区和随后的闪回日志中,因此不可能闪回到某个精确的时间点。闪回操作将尽可能接近期望的时间(不晚于该时间)回退每个更改的块。因此闪回数据库构造一个恰好在希望的时间点之前的数据库文件版本。数据文件的这种版本可能完全不一致。要完成闪回过程,Oracle需要使用重做日志,把所有的块严格恢复到请求的时间,因而把所有数据文件同步到相同的SCN上。最后一个阶段是回滚在那个时间点还未提交的任何事务——与不完整恢复的最后一个阶段所做的操作相同。
因此,闪回数据库实际上是多个进程和数据结构的组合。首先,必须在SGA中分配一些内存(自动的,无法控制闪回缓冲区的大小)并在磁盘上分配一些空间来存储闪回数据,同时启动RVWR进程来支持闪回日志记录。当执行闪回时,Oracle会使用闪回日志将数据库及时回退到期望的时间之前的某个时间点,然后按照不完整恢复中的常规方式应用重做日志(归档或联机的重做日志),以便将数据文件前滚到希望的确切时间。然后可以按照与普通的不完整恢复采用的相同方式,open resetlogs打开数据库。
4.  配置闪回数据库
SQL> archive log list;
Database log mode          Archive Mode
Automatic archival         Enabled
Archive destination        /orcldata/archivelog
Oldest online log sequence     3
Next log sequence to archive   5
Current log sequence          5
SQL> alter system set db_recovery_file_dest='/orcldata/fast_recovery_area';
System altered.
SQL> alter system set db_recovery_file_dest_size=4182M;
System altered.
SQL> alter system set db_flashback_retention_target=1440;
System altered.
SQL> show parameter undo_management
        NAME                     TYPE   VALUE
------------------------------------ ----------- ------------------------------
undo_management              string AUTO
SQL> alter database flashback on;
Database altered.
5.  监视闪回数据库
闪回保留时间只是一个目标时间——实际上并不保证能闪回到其内的某个时间。相反,甚至可能闪回到该目标时间之外。可获得的闪回期限是每秒钟生成的闪回日志信息量和在使用更新的数据重写它们之前可供存储这些信息的空间量的一个函数。
最基本的层次是确认确实启用了闪回数据库:
SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------
YES
在Unix/Linux上可以看到RVWR进程是一个操作系统进程;在Windows上它将是ORACLE.EXE内的另一个线程。
为了监视当前的闪回能力并估计为满足目标时间闪回日志所需的空间,可以查询V$FLASHBACK_DATABASE_LOG视图。V$FLASHBACK_DATABSE_STAT提供了一个有关数据文件、联机重做日志文件盒闪回日志文件所占磁盘I/O比例的历史视图。
SQL> select retention_target,flashback_size,to_char(oldest_flashback_time,'yyyy-mm-dd hh24:mi:ss') from v$flashback_database_log;
RETENTION_TARGET FLASHBACK_SIZE TO_CHAR(OLDEST_FLAS
---------------- -------------- -------------------
1440      209715200 2014-09-17 11:29:10
RETENTION_TARGET:闪回日志保留目标时间(1440min)
FLASHBACK_SIZE:闪回日志文件占用的实际空间(209715200字节)
oldest_flashback_time:可以把数据库回退到的确切时间(2014-09-17 11:29:10)
SQL> select to_char(end_time,'yyyy-mm-dd hh24:mi:ss') end_time,flashback_data,db_data,redo_data from v$flashback_database_stat;
END_TIME        FLASHBACK_DATA    DB_DATA  REDO_DATA
------------------- -------------- ---------- ----------
2014-09-17 12:52:49     278528     188416     112128
2014-09-17 12:44:35    4767744    7028736   2294784
显示为了启用闪回数据库而付出的代价,计量单位是每小时必需的I/O字节数。首行总是显示到当前时间为止。
Flashback_data:每小时产生的闪回日志大小
Db_data:每小时产生的数据文件大小
Redo_data:每小时产生的重做日志大小
SQL> select * from v$sgastat where name='flashback generation buff';
POOL         NAME                BYTES
------------ -------------------------- ----------
shared pool  flashback generation buff    15937344   #≈15M
闪回缓冲区的大小不受DBA控制,但是要查看其当前大小,查询V$SGASTAT视图。
6.  使用闪回数据库
SQL> conn hr/hr
Connected.
SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'YY
-------------------
2014-09-17 11:32:19
SQL> desc employees
Name                      Null?    Type
----------------------------------------- -------- ----------------------------
EMPLOYEE_ID                   NOT NULL NUMBER(6)
FIRST_NAME                     VARCHAR2(20)
LAST_NAME                 NOT NULL VARCHAR2(25)
EMAIL                     NOT NULL VARCHAR2(25)
PHONE_NUMBER                       VARCHAR2(20)
HIRE_DATE                 NOT NULL DATE
JOB_ID                    NOT NULL VARCHAR2(10)
SALARY                         NUMBER(8,2)
COMMISSION_PCT                     NUMBER(2,2)
MANAGER_ID                     NUMBER(6)
DEPARTMENT_ID                      NUMBER(4)
SQL> update employees set last_name='WENG' where employee_id=199;
1 row updated.
SQL> commit;
Commit complete.
SQL> conn / as sysdba
Connected.
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.
Total System Global Area 1653518336 bytes
Fixed Size          2253784 bytes
Variable Size       1023413288 bytes
Database Buffers      620756992 bytes
Redo Buffers            7094272 bytes
Database mounted.
SQL> flashback database to timestamp to_timestamp('2014-09-17 11:32:19','yyyy-mm-dd hh24:mi:ss');
Flashback complete.
SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open
SQL> alter database open resetlogs;
Database altered.
SQL> conn hr/hr
Connected.
SQL> select * from employees where employee_id=199;
EMPLOYEE_ID FIRST_NAME      LAST_NAME         EMAIL             PHONE_NUMBER     HIRE_DATE    JOB_ID          SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
----------- -------------------- ------------------------- ------------------------- -------------------- ------------ ---------- ---------- -------------- ---------- -------------
    199 Douglas     Grant             DGRANT            650.507.9844     13-JAN-08    SH_CLERK     2600               124        50
7.  限制生成的闪回数据量
启用闪回数据库可能对联机性能造成影响。Oracle用来限制写到闪回日志中的数据量的算法是精心设计的,以便尽量减小对性能的影响,但是(尤其是在有I/O限制的系统上)可能希望进一步降低其影响。在一些环境中,还可能发现满足目标时间生成的闪回数据量过大,可以在闪回日志中不记录表空间,但是这样恢复过程稍微复杂些。
默认情况下,如果启用了闪回数据库,那么会记录所有表空间的闪回数据。使用如下命令关闭表空间闪回属性:
alter tablespace flashback off;
可以在任何时候执行上面或在数据库处于mounted模式时执行下面的命令:
alter tablespace flashback on;
V$TABLESPACE视图提供了flashback_on列标记是否为表空间启用闪回:
SQL> select name, flashback_on from v$tablespace;
NAME                   FLA
------------------------------ ---
SYSTEM                 YES
SYSAUX                 YES
UNDOTBS1               YES
USERS                  YES
TEMP                   YES
EXAMPLE                YES
FBDA                   YES
对于那些与数据库的其余部分相比可以容忍较长停机时间的表空间、只要愿意可以随时删除的表空间或可以快速还原和恢复的表空间来说,可以考虑不执行闪回操作。
如果一个或多个表空间不生成闪回数据,那么在执行闪回操作之前必须使构成表空间的文件脱机。然后闪回(包括隐式的恢复)可以正常进行。要记住RECOVER将忽略脱机数据文件——这与FLASHBACK是相同的。
在删除了构成脱机表空间的数据文件或将他们还原和恢复到与闪回相同的时间点之前,不能打开数据库(使用或不使用REDETLOGS)。删除它们是极端的做法 ,但是,如果它是一个能够适时删除和重新创建的表空间,并且可以重新实例化表空间内的对象,那么这样做可以最小化停机时间。否则在闪回操作后使构成表空间的数据文件联机。然后,还原它们并执行不完整恢复,一直到闪回的时间点。这样做将同步所有数据文件,并且随后可以使用RESETLOGS打开它们。
闪回数据归档——依赖归档的闪回数据
1.  闪回数据库、闪回删除和各种形式的闪回查询很有用,但是它们的闪回能力都有限。可以配置闪回数据归档保证将表闪回到过去任何时间——可能是多年之前的某个时间。闪回数据归档还能保证数据过期时予以删除。
2.  从体系结构上看,闪回数据归档要求一个或多个表空间、用于每个受保护的表的各种段以及一个新的后台进程:FBDA进程,DBA必须创建表空间和其内部的归档,为每个归档指定保留期限并指定由归档保护的表。将会自动创建必需的段并且会根据要求启动FBDA。就DML来说,用户和应用不会意识到任何变化。一些DDL命令(eg.DROP和TRUCNCATE)不适用于受保护的表,因为它们将从数据字典中删除解释归档中的信息所必需的一些信息。可以在保护表的归档指定的时间段内,对表的各种版本成功执行闪回查询命令(如有AS OF子句的SELECT命令)。
3.  为了使用闪回数据归档实现的Total Recall功能,首先创建一个表空间。然后创建归档、指定表空间、保留时间和一个可选的配额。例如:
create flashback archive default hrarch tablespace fbda quota 10g retention 5 year;
该命令包括default关键字,意味着除非另行说明,它将用作所有表的归档。另外,也可以稍后设置默认的归档:
alter flashback archive hrarch set default;
quota子句显示归档在表空间中占用的空间。如果归档失败,就可以在原有的表空间或另一个表空间添加更多的空间。例如,下面的命令将归档扩展到另一个表空间中:
alter flashback archive hrarch add tablespace fbda2 quota 10g;
也可以调整保留时间:
alter flashback archive hrarch modify retention 7 year;
一旦数据超过了指定的保留期限,将有FBDA后台进程自动从归档中删除。但是在数据过期之前也可以手工删除,例如:
alter flashback archive hrarch purge before timestamp to_timestamp('01-01-2009','dd-mm-yyy');
由于管理归档的权力往往牵涉到法律问题,因此通过设定权限来保护它。FLASHBACK ARCHIVE ADMINISTER系统权限能够创建、修改或删除归档以及控制归档的保留和清除。因此,必须授予用户归档的FLASHBACK ARCHIVE权限以便能够对表进行归档:
grant flashback archive administer to fbdaadmin;
grant flashback archive on hrarch to hr;
最后,为了启用表的归档保护,使用如下命令:
alter table hr.employees flashback archive hrarch;
4.  有三个数据字典视图来记录闪回数据归档配置:
DBA_FLASHBACK_ARCHIVE描述配置的归档。
DBA_FLASHBACK_ARCHIVE_TS显示每个表空间的每个归档分配的配额。
DBA_FLASHBACK_ARCHIVE_TABLES列出了启用了归档的表。
5.  使用闪回数据归档:
(1) 创建一个供闪回数据归档使用的表空间:
create tablespace fbda datafile 'fbda01.dbf’ size 2g;
(2) 在上述表空间创建一个保留时间20天的闪回数据归档:
create flashback archive fbdaarch tablespace fbda retention 20 day;
(3) 创建用于练习的模式,并授予它DBA角色:
grant dba to fbdauser identified by fbdauser;
(4) 授予用户操作归档的必要权限:
grant flashback archive on fbdaarch to fbdauser;
(5) 作为fbdauser连接。创建一个表并为此表启用闪回数据归档:
connect fbdauser/fbdauser
create table t1 as select * from all_users;
alter table t1 flashback archive fbdaarch;
(6) 运行下列查询确定归档创建的对象。可能必须等待几分钟,因为对象不是立即创建的。
select object_name,object_type from user_objects;
select segment_name,segment_type from dba_segments where tablespace_name='FBDA';
(7) 对保护的表执行一些DML:
delete from t1;
commit;
(8) 使用标准的闪回查询语法对保护的表执行闪回查询,然后查询归档中的历史表。历史表的名称将显示在步骤6中。
Select * from t1 as of timestamp(sysdate – 20/1440);
(9) 尝试对保护的表执行一些DDL命令:
alter table t1 drop column created;
truncate table t1;
drop table t1;
作为SYSDBA连接,并尝试执行如下命令:
drop user fbdauser cascade;
drop tablespace fbda including contents and datafiles;
注意,这些命令将会生成与归档和保护的表的存在有关的错误。
(10) 删除表的归档保护:
alter table fbdauser.t1 no flashback archive;
(11) 删除闪回数据归档:
drop flashback archive fbdaarch;
(12) 重新运行步骤(9)中的所有命令。
闪回删除——flashback dop,针对drop掉的段,依赖于回收站recyclebin(回收站实际上仍旧是表空间的一部分存储空间,需要重用时,要释放出来)
1.  闪回删除允许将之前删除的表(非截断)恢复到刚好删除它之前的状态,同时还会恢复所有索引以及任何触发器和权限。唯一的主键和非空约束也会被恢复——但不包括外键约束。
flashback drop命令仅适用于表,但是也会恢复所有相关的对象——外键约束除外。
2.  闪回删除的实现:
直到(包括)9i版本的Oracle数据库为止,删除一个表时,到该表的所有引用都会从数据字典中删除。过去的DROP TABLE命令的源代码实际上是在定义了表及其空间占用的SYS模式中的一系列针对各种表的DELETE命令,后面跟着一个COMMIT命令。实际上并没有将数据从磁盘上清除,但是删除的表占用的空间被标记为未使用,因而空间可以重用。尽管表的数据块仍存在,但是无法找到它们,因为数据字典没有记录哪些块属于删除的表。恢复删除的标的唯一方法是执行时间点恢复,还原在删除表之前数据字典仍了解该表状态时的一个数据库版本。
从10g版本开始,DROP TABLE命令的实现方法完全不一样了。在这些版本的数据库中根本没有删除表,而只是重命名它们。已经在内部将DROP TABLE命令映射到RENAME命令,它将作用于表及其所有相关的索引、触发器和约束,但不包括外键约束(它将被删除)。必须物理地删除外键约束,如果要维护它们,即使采用不同的名称,未删除的父表上的DML将会受删除的表的内容约束,这将很荒诞。
表的授权没有名称,因此无法重命名它们。当授予一个对象权限时,通过名称指定对象并且底层存储的授权通过它的对象号来引用该对象。由于RENAME操作并没有改变对象号,因此授权仍然是有效的。
就常规的SELECT和DML语句而言,删除的表肯定是被删除了。对于任何其他命令来说也是一样,并且所有软件都假定删除的表确实是消失了。但既然DROP实际上是RENAME,就有可能撤销删除——通过将表重命名回它原先的名称。但是,并不能保证这样做总能成功。因为删除的表占用的空间有可能被重用,并且还会出现更复杂的情况,比如在此期间创建了另一个表,并且重用了与删除的表相同的名称。
通过查看回收站获取它们的新名称可以查询删除的对象。这里列出了已删除的所有对象,并将原始的表和索引名称映射到删除对象的系统生成的名称。每个用户都有一个回收站,可以在USER_RECYCLEBIN数据字典视图中看到它,若要了解全局视图,可以查询DBA_RECYCLEBIN。当表空间的空间不足时,可以自动重用回收对象占用的空间(此后不能恢复对象),或者可以手动强制Oracle使用PURGE命令真正删除对象。
使用flashback drop不能保证成功执行,但是很可能会生效。越早执行该命令,成功的可能性就越大。
3.  使用闪回删除
Drop命令将表重命名为系统生成的名称,闪回删除可以恢复它。
①   真正删除表
drop table <table_name> purge;
purge关键字指示Oracle数据库恢复DROP的原始含义:删除到该表的所有引用并且永远无法恢复。
②   闪回表并重新命名(有时重新命名时必须的,以防在删除和闪回期间创建了另一个与删除的表具有相同名称的表)
flashback table <table_name> to before drop rename to <new_name>;
注意,尽管在闪回期间可以对表重命名,但不能更改模式:所有闪回操作出现在对象所属的模式内。和表一同闪回的索引、触发器和约束都保持它们的回收站名称。如果希望恢复它们原先的名称,则可以在闪回操作后手动重命名。必须要强调两点。第一,flashback drop只能恢复drop命令,而不能恢复truncate命令。第二,如果删除了一个用户,使用闪回无法恢复任何该用户的表。删除模式意味着Oracle根本无法维护对象(即使在回收站内),因为没有可供对象连接的用户。
4.  SQL*Plus命令show recyclebin将显示删除的对象,连同它们原始的名称和回收站名称。DBA_RECYCLEBIN视图提供了相同(甚至更多)的信息。
如果删除了表,然后创建了具有相同名称的另一个表,并且随后也删除了它,那么在回收站中将有两个表。它们具有不同的回收站名称,但是原始名称相同。默认情况下,flashback drop命令总是恢复最新版本的表,但是,如果这不是您想要的版本,则可以指定您希望恢复的版本的回收站名称,而不是原先的名称。例如:
SCOTT@orcl>drop table bonus;
Table dropped.
SCOTT@orcl>show recyclebin
ORIGINAL NAME   RECYCLEBIN NAME        OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
BONUS       BIN$A6Kgm8gMEePgUwEAAH++3A==$0 TABLE        2014-09-22:14:37:16
SCOTT@orcl>flashback table "BIN$A6Kgm8gMEePgUwEAAH++3A==$0" to before drop;
Flashback complete.
SCOTT@orcl>desc bonus
Name                      Null?    Type
----------------------------------------- -------- ----------------------------
ENAME                          VARCHAR2(10)
JOB                            VARCHAR2(9)
SAL                            NUMBER
COMM                           NUMBER
5.  管理回收站
回收站是表示删除的对象使用的存储空间的一个术语。可以完全忽略回收站——它的管理是自动的,无论是在删除对象时将它们转移到回收站,还是在活动对象的表空间需要空间时,都将它们永久清除。但是有些情况下需要了解回收站的内容以及它们占用的空间大小。
可以使用实例参数RECYCLEBIN禁用回收站,默认值是ON,意味着所有模式都有一个回收站。该参数是动态的,可以为某个会话或整个系统将其设置为OFF。
查询回收站
SCOTT@orcl>show recyclebin
ORIGINAL NAME    RECYCLEBIN NAME        OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
BONUS        BIN$A6Kgm8gMEePgUwEAAH++3A==$0 TABLE        2014-09-22:14:37:16
若要了解更详细的信息,查询数据字典视图USER_RECYCLEBIN或DBA_RECYCLEBIN:
select owner,original_name,type,droptime,can_undrop,space from dba_recyclebin;
关键的列是can_undrop。Oracle并不负责保存删除的表或索引:flashback drop完全是Oracle提供的一个便利功能,并不属于关系数据库标准。如果Oracle需要删除的对象占用的空间以便为活动对象分配更多的空间,它可以重用该空间——但是从那以后使用flashback drop将无法恢复删除的对象,并且将从视图中清除它。Space列(单位是数据文件块)显示删除的对象占用的空间量。
6.  回收回收站的空间
删除的对象占用的空间处于不明确的状态:虽然将它分配给对象,但是Oracle可以任意重写它。有关空间使用的正常诊断程序会忽略回收站占用的空间,这意味着在活动对象占用的空间达到警告和临界空间使用级别之前,不会触发“表空间比例已满”的警报。此外,如果启用了数据文件的autoextend特性,Oracle实际上不会自动扩展数据文件,直到重新分配了删除的对象占用的所有空间:它将优先重写回收站以增加数据文件大小。
如果一个新数据段的表空间需要空间,那么可以占用它——但是此后将无法在保留删除的表。如果在回收站中有许多删除的对象,Oracle将会首先重写在回收站中留存时间最长的对象。这种先进先出算法假定最近删除的对象最有可能充当闪回的候选对象。
可以使用各种形式的PURGE命令永久性地清除删掉的对象:
dop table <table_name> purge;_除表并且不将它转移到回收站。
prge table <table_name>;——从回收站中清除表。
如果存在多个具有相同原始名称的对象,那么将清除时间最久的对象。也可以通过指定回收站名称来避免混淆。
purge index <index_name>;——从回收站中清除索引,同样可以指定原始名称或回收站名称。
purge tablespace <tablespace_name>;——从表空间中清除所有删除的对象。
purge tablespace <tablespace_name> user <user_name>;——从表空间中清除属于一个用户的所有删除的对象。
purge user_recyclebin;——清除删除的所有对象。
purge dba_recyclebin;——清除数据库上被删除的所有对象,需要DBA权限。
***********************************************************************************************
闪回查询——依赖的是回滚段
自从Oracle9i发布以来就提供了基本形式的闪回查询:可以查询过去某个时间的数据库状况。工作原理是将查询制定的时间映射到一个系统变更号和SCN,每当查询找到自该SCN以来更改的一个快,它将转到撤销段以提取回滚此更改所需的撤销数据。严格上说这种回滚是临时性的,并且仅对运行闪回查询的会话可见。显然,为了成功执行闪回查询,撤销数据必须是可用的。

在后续版本的数据库中,大大增强了闪回查询功能,现在它可以用来检索一个行的所有版本,反转各个事务,或反转某个时间以来对表做出的所有更改。当然,也可以保证闪回成功执行——但是做到这一点要付出代价:它可能会引起事务失败。

所有形式的闪回查询依赖撤销数据来重构它在过去某个时间点的数据。

1.  基本的闪回查询

任何select语句可以针对以前某个版本的表。

select * from regions as of timestamp to_timestamp('2014-09-22 15:27:31', 'yyyy-mm-dd hh24:mi:ss');

尽管针对过去某个时间点的数据执行查询是有用的,但有时也希望完成一系列选择。通过使用DBMS_FLASHBACK程序包可以将整个回话回退到过去某个时间:

execute dbms_flashback.enable_at time( to_timestamp('2014-09-22 15:36:37', 'yyyy-mm-dd hh24:mi:ss'));

从此以后,所有的查询将看到数据库在指定的时间的状态。其他所有会话将看到实时数据——但是在取消闪回之前这个会话将看到一个冻结版本的数据库。

execute dbms_flashback.disable;

处于闪回模式时,无法执行DML命令。如果这样做会抛出错误,只能执行SELECT语句。

闪回查询(通过一个查询或使用dbms_flashback)可以回退到多久以前取决于撤销段的内容。如果构造过时的结果集所需的撤销数据不可用,那么查询将会失败并给出一个ORA-08180错误消息"No snapshot found based on specified time"。

启用闪回查询的语法接收时间戳或SCN。如果使用SCN,那么闪回转到的时间点是精确的,如果指定某个时间,那么它将映射到一个SCN上并且精度是3秒。

可以查询以前某个时间点的数据库,但是永远不能对过去版本的数据执行DML。

2.  闪回表查询

从概念上来说,表闪回很简单。Oracle将会查询撤销段以提取已更改的所有行,然后构造并执行将会取消更改的语句。闪回操作是一个单独的事务,如果可能,它就会抵消以前所有事务的效果。数据库仍然保持联机并且正常的运行不受影响,除非行锁定成为一个问题。这不是回滚提交的工作,而是一个新事务用来取消已提交工作的影响。维护所有的索引并强制执行约束:表闪回只是另一种事务,通常的规则仍适用。不同于正常处理的唯一之处是,表上的触发器对闪回操作默认是禁用的。

表闪回经常涉及一个存在外键关系的表。这种情况下,几乎不可避免的是闪回操作会因为违反约束而失败。为了避免此问题,语法支持用一条命令闪回多个表,这将作为单位事务来执行,并且在最后检查约束。

启用表闪回的第一步是在表上支持行移动。这在数据字典中是设置标志来通知Oracle可能改变了行ID。行ID实际上永远不会改变——但是闪回操作可能使它看起来好像改变了。举例来说,在删除了一行的情况下闪回操作会将它重新插入到表中:它将具有相同的主键值,但是不同的行ID。

在下面的示例中有两个表:EMP和DEPT。这两个表存在外键关系,就是说EMP表中的每个员工必定是DEPT表中某个部门的一个成员。

首先,插入一个新的部门并在该部门中插入一个员工,同时记录时间:

insert into dept values(50, 'SUPPORT', 'LONDON');

insert into emp values (8000, 'WASTON', 'ANALYST',7566, '27-DEC-08',3000,null,50);

commit;

select sysdate from dual;

接下来删除该部门和员工,要注意首先删除员工以避免违反约束:

delete from emp where empno=8000;

delete from dept where deptno=50;

commit;

现在尝试将表闪回到该部门和员工存在的时刻:

flashback table emp to timestamp ti_timestamp('27-12-08 18:30:11', 'dd-mm-yy hh24:mi:ss');

该操作会失败,因为默认情况下没有为任何表启用行移动(作为表闪回的前提条件)——因此要为这两个表启用它:

alter table emp enable row movement;

alter table dept enable row movement;

现在重新尝试闪回:

flashback table emp to timestamp to_timestamp('27-12-08 18:30:11', 'dd-mm-yy hh24:mi:ss');

这一次造成闪回失败的原因更加微妙。闪回试图通过插入此员工来取消对员工8000的删除——但是员工8000属于部门50,该部门已被删除而不存在。因此,违反了外键约束。解决方法是一起闪回这两个表:

flashback table emp,dept to timestamp to_timestamp('27-12-08 18:30:11', 'dd-mm-yy hh24:mi:ss');

这样闪回会成功,因为在一个事务中同时闪回了两个表,并且仅在该事务的结尾检查约束——到那个时候数据在逻辑上是一致的。

闪回也可能由于其他原因而失败:

如果在删除和闪回之间重用了键值,就会违反主键约束。

如果没有足够的撤销信息返回到请求的时间,就会引起一个错误ORA-08180,"No Snapshot found based on specified time"。

如果其他用户锁定闪回作用的任何行,则闪回会失败并给出一条消息ORA-00054: "Resource busy and acquire with NOWAIT specified"。

表定义在考察期间内不能改变——闪回不能跨越DDL。试图这样做会产生错误ORA-01466: "Unable to read data——table definition has changed"。

闪回不适用于处于SYS模式下的表,试着想象一下闪回部分数据字典的效果。

如果闪回由于任何原因而失败,就会取消闪回操作:将回滚成功执行的任何一部分操作,并且表将处于闪回命令发出之前的状态。

语法的变形允许闪回到一个系统变更号并在操作期间激活DML触发器:

flashback table emp,dept to scn 6539425 enable triggers;

3.  闪回版本查询

一个行在它的生命周期内可能改变多次。闪回版本查询(flashback version query)允许查看一个行所有提交的版本(而不能查看任何未提交的版本),包括创建和约束每个版本的时间戳。另外,还可以查看创建了任何特定版本的行的事务的事务标识符,然后可以将它用于闪回事务查询。此信息可以通过每个表可用的许多伪列来提供。与闪回相关的伪列包括:

versions_startscn:通过insert或update创建此版本的行的SCN

versions_starttime:创建此版本的行的时间戳

versions_endscn:由于delete或update使此版本的行失效的SCN

versions_endtime:此版本的行失效的时间戳

versions_xid:创建此版本的行的事务的唯一标识符(这个xid可以用于闪回事务)

versions_operation:创建此版本的行的事务执行的操作,可以是insert、update或delete

为了查看伪列,必须在查询中包括versions between关键字。下面的查询显示了员工8000的行的所有版本:

select empno,ename,sal,versions_xid,versions_startscn,versions_endscn,versions_operation from emp versions between scn minvalue and maxvalue where empno=8000;

版本是按照存在时间的降序存储的:必须自下而上读取它们。

versions between子句使用两个常量来表示SCN。minvalue指示Oracle检索撤销段中最早的信息;maxvalue将作为当前的SCN。

查询的语法也接受使用连个时间戳指定的时间范围:

select empno,ename,sal,versions_xid,versions_startscn,versions_endscn,versions_operation from emp versions between timestamp (systimestamp-1/24) and systimestamp where empno=8000;

选在在最近一个小时内存在的员工编号为8000的行的所有版本。

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

4.  闪回事务查询

闪回表和闪回版本查询使用对象的撤销数据。闪回事务查询从一个不同的尺度来分析撤销数据:它会检索一个事务的所有撤销数据,而不考虑它影响多少对象。关键的视图是flashback_transaction_query。由于该视图的数据比较敏感,通过设定权限来保护它:在能够查询它之前必须授权select any transaction。在该视图中撤销数据仍保存在撤销段内的每个事务将对应一行或多行,并且每一行都会引用受该事务影响的一行。

一行SQL语句可能在flashback_transaction_query中生成许多行,这是因为SQL是一种集合型语言:一条语句可以影响多行。但是每个受影响的行在视图中都有它自己的行,视图会显示提交的事务以及进行中的事务。对于活动事务来说,commit_scn和commit_timestamp列都是NULL,并且不显示回滚的事务。

select operation,undo_sql from flashback_transaction_query where xid=hextoraw('06002600B0010000');

视图flashback_transaction_query将构造撤销语句来取消事务,但是对于大型事务而言,单个地执行它们是一项繁重的任务。这种情况下,可以使用dbms_flashback包:它含有取消事务的过程,但必须授予flashback any table权限。

execute dbms_flashback.transaction_backout(numtxns=>2,xids=>sys,xid_array('0900010059100000', '02000700920F0000'),options=>dbms_flashback.cascade);

5.  闪回和撤销数据

闪回查询的各种形式完全取决于撤销数据。查询是否成功依赖于撤销数据是否仍可用。

为了保证在给定的时间段闪回查询总能成功,设置撤销表空间的RETENTION GUARANTEE属性以及UNDO_RETENTION实例参数。这将确保总能闪回指定的秒数——但付出的代价是,如果对于事务工作负荷来说撤销表空间的大小设置的不够大,那么在执行DML时可能挂起数据库。必须监视V$UNDOSTAT视图来计算必需的撤销表空间大小。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29209863/viewspace-2128254/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2016-10-12

  • 博文量
    149
  • 访问量
    99044