ITPub博客

首页 > 数据库 > Oracle > (f)--闪回恢复区---实践2---闪回表(闪回DML部分数据会用到闪回查询)

(f)--闪回恢复区---实践2---闪回表(闪回DML部分数据会用到闪回查询)

原创 Oracle 作者:maohaiqing0304 时间:2013-04-20 09:24:02 0 删除 编辑
 
Flashback table 闪表
     回收站功能---> 将表改名而已   alter table Z1 rename to ZZ1;
     回收站(recyclebin),是一个虚拟的容器,依旧在表的原表空间内,用于存放所有被删除的对象的数据字典
     特点:
          在线操作
          自动恢复相关属性,如索引、触发器等
          满足数据一致性,所有相关对象将自动一致
          新数据空间需求不足 系统自动清理回收站
     只能闪drop 不能闪truncate

闪回表有2中:
1、闪回整个删除的表   --基于undo表空间有数据库情况下  测试如果将undo表空间offline ,drop table T1, flashback table T1 to before drop;是成功的,后期查询是不行的,也就证明了“闪回查询是undo,而闪回表是回收站,闪回数据库则要依赖闪回区”  recover datafile 4,alter database datafile 'E:\APP\ADMINISTRATOR\ORADATA\ORACLE11G\USERS01.DBF'  online;  SELECT FILE#, STATUS,RECOVER, NAME,error FROM V$DATAFILE_HEADER;数据文件的状态
2、闪回部分的DML操作的表   --要基于undo表空间里的内容,只要undo内容足够就可以反复flashback ,恢复某个时间点和scn号

测试1:   --->整个表被删除的恢复,  数据文件空间(auto/nonauto)情况下,recyclebin变动情况
SCOTT@ora10g> drop table t4;
Table dropped.

SCOTT@ora10g> select * from tab;

TNAME                      TABTYPE     CLUSTERID
------------------------------ ------- ----------
DEPT                      TABLE
EMP                      TABLE
BONUS                      TABLE
SALGRADE                 TABLE
T5                      TABLE
T3                      TABLE
T2                      TABLE
BIN$mKoYM02QCojgQAB/AQAvyw==$0 TABLE

8 rows selected.

SCOTT@ora10g> 不放入回收站 直接删除
SCOTT@ora10g> drop table t3 purge;

Table dropped.

SCOTT@ora10g>


从回收站中恢复表
SCOTT@ora10g> show recycl
ORIGINAL NAME     RECYCLEBIN NAME          OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
T4          BIN$mKoYM02QCojgQAB/AQAvyw==$0 TABLE          2010-12-31:07:32:09


SCOTT@ora10g> flashback table t4 to before drop;

Flashback complete.

SCOTT@ora10g> select * from tab;

TNAME                      TABTYPE     CLUSTERID
------------------------------ ------- ----------
DEPT                      TABLE
EMP                      TABLE
BONUS                      TABLE
SALGRADE                 TABLE
T5                      TABLE
T4                      TABLE
T2                      TABLE

7 rows selected.

SCOTT@ora10g>

多次删除同一个表的恢复

SCOTT@ora10g> flashback table "BIN$mKoYM02RCojgQAB/AQAvyw==$0" to before drop;

Flashback complete.

SCOTT@ora10g>
SCOTT@ora10g> flashback table t4 to before drop rename to t7;

Flashback complete.

SCOTT@ora10g>
清空回收站
SCOTT@ora10g> sho recycle;
ORIGINAL NAME     RECYCLEBIN NAME          OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
T4          BIN$mKoYM02UCojgQAB/AQAvyw==$0 TABLE          2010-12-31:08:35:06
SCOTT@ora10g> purge table t4;

Table purged.

SCOTT@ora10g> sho recycle;
SCOTT@ora10g> purge recyclebin;


带索引的表的闪回时 索引名称不会还原 要手动改

SQL> SELECT INDEX_NAME,TABLE_NAME FROM DBA_INDEXES WHERE TABLE_NAME='T2';

INDEX_NAME                 TABLE_NAME
------------------------------ ------------------------------
IND_T2                      T2

SQL> drop table t2;

Table dropped.

SQL> select object_name,original_name,type from recyclebin;

OBJECT_NAME                 ORIGINAL_NAME               TYPE
------------------------------ -------------------------------- -------------------------
BIN$nTKLacW7QjzgQAoKCgoJog==$0 IND_T2                    INDEX
BIN$nTKLacW8QjzgQAoKCgoJog==$0 T2                    TABLE

SQL> flashback table t2 to before drop;

Flashback complete.

SQL> SELECT INDEX_NAME,TABLE_NAME FROM DBA_INDEXES WHERE TABLE_NAME='T2';

INDEX_NAME                 TABLE_NAME
------------------------------ ------------------------------
BIN$nTKLacW7QjzgQAoKCgoJog==$0 T2

SQL> ALTER INDEX "BIN$nTKLacW7QjzgQAoKCgoJog==$0" RENAME TO "IND_T2";

Index altered.

SQL> SELECT INDEX_NAME,TABLE_NAME FROM DBA_INDEXES WHERE TABLE_NAME='T2';

INDEX_NAME                 TABLE_NAME
------------------------------ ------------------------------
IND_T2                      T2

SQL>


当新数据增长 表空间容量不足时 回收站的内容会自动被系统清理

SQL> create tablespace mytbs datafile '/u01/oracle/oradata/ora10g/mytbs01.dbf' size 2M;

Tablespace created.

SQL> create table t1 tablespace mytbs as select * from scott.emp;

Table created.

SQL> drop table t1;

Table dropped.

SQL> show recycle;
ORIGINAL NAME     RECYCLEBIN NAME          OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
T1          BIN$nTKLacW1QjzgQAoKCgoJog==$0 TABLE          2011-02-27:01:11:59
SQL> create table t1 tablespace mytbs as select * from scott.emp;

Table created.

SQL> show recycle;
ORIGINAL NAME     RECYCLEBIN NAME          OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
T1          BIN$nTKLacW1QjzgQAoKCgoJog==$0 TABLE          2011-02-27:01:11:59
SQL> insert into t1 select * from t1;

14 rows created.

SQL> /

...........

1792 rows created.

SQL> show recycle;
ORIGINAL NAME     RECYCLEBIN NAME          OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
T1          BIN$nTKLacW1QjzgQAoKCgoJog==$0 TABLE          2011-02-27:01:11:59
SQL> insert into t1 select * from t1;

3584 rows created.

SQL> /

7168 rows created.

SQL> /
insert into t1 select * from t1
*
ERROR at line 1:
ORA-01653: unable to extend table SYS.T1 by 128 in tablespace MYTBS


SQL> show recycle;
SQL>


即使数据文件可以拓展 也会清除回收站
SQL> alter database datafile '/u01/oracle/oradata/ora10g/mytbs01.dbf' autoextend on ;

Database altered.

SQL> drop table t1;

Table dropped.

SQL> show recyc;
ORIGINAL NAME     RECYCLEBIN NAME          OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
T1          BIN$nTKLacW2QjzgQAoKCgoJog==$0 TABLE          2011-02-27:01:21:27


SQL> create table t1 tablespace mytbs as select * from scott.emp;

Table created.

SQL> show recyc;
ORIGINAL NAME     RECYCLEBIN NAME          OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
T1          BIN$nTKLacW2QjzgQAoKCgoJog==$0 TABLE          2011-02-27:01:21:27
SQL> insert into t1 select * from t1;

14 rows created.

SQL> /
...................

3584 rows created.

SQL> show recyc;
ORIGINAL NAME     RECYCLEBIN NAME          OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
T1          BIN$nTKLacW2QjzgQAoKCgoJog==$0 TABLE          2011-02-27:01:21:27
SQL> /

7168 rows created.

SQL> show recyc;
ORIGINAL NAME     RECYCLEBIN NAME          OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
T1          BIN$nTKLacW2QjzgQAoKCgoJog==$0 TABLE          2011-02-27:01:21:27
SQL> /

14336 rows created.

SQL> show recyc;
SQL>


有些应用,会频繁地创建并删除表,如果这个时候打开这项功能,就会在回收站中产生很多的垃圾信息,如果需要,可以根据情况关闭这项功能。

[启用&关闭回收站]
     ALTER SESSION SET recyclebin = ON;
     ALTER SYSTEM SET recyclebin = ON;
     ALTER SESSION SET recyclebin = OFF;
     ALTER SYSTEM SET recyclebin = OFF;


测试2:   --->部分的DML操作恢复
update t1 set id=1;   默认15分钟内就可闪回show parameter undo_retention; 该参数保存了回滚段数据保存的秒时间
可以闪表到  undo_retention限制历史时间内:(10g开始正式支持)
alter table t1 enable row movement; 打开表的行移动(实现完之后再disable)
flashback table t1 to timestamp(sysdate-15/1440); 从回滚取出数据或者(to scn XX ) 
alter table t1 disable row movement; 
SQL> create table t1 as select OWNER,OBJECT_NAME  from all_objects where rownum<2;
SQL> select * from t1;

OWNER                          OBJECT_NAME
------------------------------ ------------------------------
SYS                            ICOL$

SQL> create index i_objectidon on t1  (owner);
SQL>  select a.table_owner,a.table_name,a.index_name,a.status from user_indexes a where a.table_name='T1';

TABLE_ TABLE_N INDEX_NAME                     STATUS
------ ------- ------------------------------ --------
TEST1  T1      I_OBJECTIDON                   VALID
TEST1  T1      PK_T1                               VALID

SQL> select current_scn from v$database;                    ---->--DML 操作前scn

CURRENT_SCN
-----------
6213312590
SQL> select to_char(sysdate,'yyyy-mm-dd HH24:MI:SS') from dual;   ---DML 操作前时间

SYSDATE
-------------------
2013-04-11 17.34.47

SQL> insert into t1 values('A','B');

已创建 1 行。

SQL> commit;

提交完成。

SQL> select * from t1 as of timestamp sysdate;

OWNER                          OBJECT_NAME
------------------------------ ------------------------------
A                              B
SYS                            ICOL$

SQL> select * from t1 as of timestamp sysdate-10/1440 ;

OWNER                          OBJECT_NAME
------------------------------ ------------------------------
SYS                            ICOL$

SQL> select * from t1 as of scn 6213312590;     ---DML 操作前scn

OWNER                          OBJECT_NAME
------------------------------ ------------------------------
SYS                            ICOL$


SQL> select current_scn from v$database;    ---DML 操作后scn

CURRENT_SCN
-----------
6213312684

SQL> select * from t1 as of scn  6213312684;  ---DML 操作后scn的数据

OWNER                          OBJECT_NAME
------------------------------ ------------------------------
A                                B
SYS                            ICOL$


都用起来很方便 但as of timestamp缺点是时间精缺度不足
     比如问题发生后,你每次执行闪查都是以当前时间为基线做运算
     当前时间又在不断流逝 所以说精确度不足
     所以建议采用 as of scn
     SCN历史的数字是固定的.这使我们查询就更容易定点了
获取当前系统SCN的方法
 9I; 
SQL> select dbms_flashback.get_system_change_number from dual;

  GET_SYSTEM_CHANGE_NUMBER
             ------------------------
             6213312926

 10G:
SQL> select current_scn from v$database;

               CURRENT_SCN
               -----------
               6213312924  


查看SCN和时间对应关系
     SQL> select SCN,TIME_DP from smon_scn_time;  --只有sys用户可以查询
     这个表中存储 每间隔5分钟存储一次
     每隔5分钟,系统产生一次系统时间标记与scn的匹配并存入sys.smon_scn_time表,
     该表中记录了最近1440个系统时间标记与scn的匹配记录,由于该表只维护了最近的1440条记录,
     因此如果使用as of timestamp的方式则只能flashback最近5天内的数据
     (假设系统是在持续不断运行并无中断或关机重启之类操作的话)。
     所以在Oracle9iR2中,表属性修改时间和flashback时间差至少应为5分钟。否则就会出现ORA-01466错误。
     到了10G后虽然这个表记录的还是间隔5分,但多了TIM_SCN_MAP字段记录
     系统每3-6秒钟左右更新一次SCN与时间的对应 这个时间对人类操作可以忽略了
时间和scn互换函数
     SQL>SQL> select scn_to_timestamp((select current_scn from v$database)) from dual;

          SCN_TO_TIMESTAMP((SELECTCURRENT_SCNFROMV$DATABASE))
          ---------------------------------------------------------------------------
          11-4月 -13 05.51.17.000000000 下午

     SQL>    select timestamp_to_scn((select scn_to_timestamp((select current_scn from v$database)) from dual)) SCN,(select current_scn from v$database) 当前SCN from dual;
                 SCN    当前SCN
          ---------- ----------
          6213313313 6213313319

恢复;  闪回DML数据是使用回滚段进行恢复
SQL> flashback table  t1 to scn 6213312590;
                 *
第 1 行出现错误:
ORA-08189: 因为未启用行移动功能, 不能闪回表

SQL> alter table t enable row movement; ----> rowmove就是个允许Oracle修改rowid开关,插入数据时会为该条数据分配唯一rowid并且不变,要启用闪回功能必须开启可修改rowid功能打开之后如果行移动了,就会有影响,如果行没移动,就没有影响

表已更改。

SQL> flashback table  t1 to scn 6213312590;   ----->恢复到增加前的scn

闪回完成。

SQL> select * from t1 ;

OWNER                          OBJECT_NAME
------------------------------ ------------------------------
SYS                            ICOL$

SQL> flashback table  t1 to scn 6213312684;   ----->取消刚刚的恢复  恢复到增加后的scn

闪回完成。

SQL> select * from t1 ;

OWNER                          OBJECT_NAME
------------------------------ ------------------------------
A                              B
SYS                            ICOL$

SQL> flashback table  t1 to timestamp(sysdate-1/10); ----->恢复到增加前的时间段

闪回完成。

SQL> select * from t1 ;

OWNER                          OBJECT_NAME
------------------------------ ------------------------------
SYS                            ICOL$


SQL> flashback table  t1 to timestamp(sysdate-10/1400);  ---->取消刚刚的恢复  恢复到增加后的scn

闪回完成。

SQL> select * from t1 ;

OWNER                          OBJECT_NAME
------------------------------ ------------------------------
A                                    B
SYS                              ICOL$

结论得出:只要undo内容足够就可以反复flashback ,恢复某个时间点和scn号

测试:rowmove就是个开关,打开之后如果行移动了,就会有影响,如果行没移动,就没有影响
SQL> select t.*, t.rowid from T1 t ;

OWNER                          OBJECT_NAME                    ROWID
------------------------------ ------------------------------ ------------------
SYS                            ICOL$                          AAAY/wAAEAAABkzAAC

SQL> delete from t1;

已删除 1 行。

SQL> commit;

提交完成。
SQL> flashback table  t1 to timestamp(sysdate-1/10);

闪回完成。

SQL> select t.*, t.rowid from T1 t;

OWNER                          OBJECT_NAME                    ROWID
------------------------------ ------------------------------ ------------------
SYS                            ICOL$                          AAAY/wAAEAAABkzAAA

SQL> 
结论:enable row movement  可能导致索引失效,触发器一定会失效(网上说的还未测试),行移动就会有影响,如果没移动,就没影响



疑问:
恢复区没有flashback_on   为什么可以恢复表和恢复DML表?
答:只有 flashback database操作依赖于flashback log (存储在flashback area中,需要数据库 flashback_on)
其它的 flashback操作(比如flashback query )(flashback tables/DML tables)都依赖于 undo数据,与数据库flashback on还是 off无关。

V$FLASHBACK_DATABASE_LOG显示闪回数据的信息,用来评估当前负载下需要的闪回空间
Name                                                  Description
----------------------------------            --------------------------------------------------
OLDEST_FLASHBACK_SCN            Lowest system change number (SCN) in the flashback data, for any incarnation 闪回数据最小的 scn
OLDEST_FLASHBACK_TIME                 Time of the lowest SCN in the flashback data, for any incarnation闪回数据最小的时间
RETENTION_TARGET                             Target retention time (in minutes)                                 闪回保留时间
FLASHBACK_SIZE                                    Current size (in bytes) of the flashback data             闪回数据大小
ESTIMATED_FLASHBACK_SIZE           Estimated size of flashback data needed for the current target retention 评估满足当前闪回保留时间,需要的闪回空间的大小
                                                                                                                                            
V$FLASHBACK_DATABASE_STAT   显示数据库收集到的闪回信息
Name                                           Description
----------------------------------            --------------------------------------------------
BEGIN_TIME                                 Beginning of the time interval                           一段时间间隔的起始时间     
END_TIME                                     End of the time interval                                       一段时间间隔的结束时间                              
FLASHBACK_DATA                         Number of bytes of flashback data written during the interval  一段时间内闪回数据的大小 (bytes)  
DB_DATA                                           Number of bytes of database data read and written during the interval一段时间内数据库读写大小 (bytes) 
REDO_DATA                                     Number of bytes of redo data written during the interval            一段时间内 redo 数据的大小(bytes)
ESTIMATED_FLASHBACK_SIZE     Value of ESTIMATED_FLASHBACK_SIZE in V$FLASHBACK_DATABASE_LOG at the end of the time interval 一段时间间隔的结束时,评估需要闪回空间的大小
未开闪回,drop table T1; flashback table t1 to before drop;  √;flashback database to timestamp(sysdate-1/1465);  X
本文博客

http://blog.sina.com.cn/s/blog_bba8a5b40101bdhu.html

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

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

注册时间:2013-03-13

  • 博文量
    117
  • 访问量
    2626246