暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 闪回表(Flashback table)的运用

原创 eygle 2019-12-05
7069

闪回表允许我们将数据表恢复到过去的某个时间点,而不必像以前一样采用基于时间点的恢复。
Oracle 10g的flashback table有如下特性:

  • 可以在线操作;
  • 恢复到指定时间点或者SCN的任何数据;
  • 自动恢复相关属性,如索引、触发器、约束等;
  • 满足分布式的一致性;
  • 满足数据一致性,所有相关对象将自动一致。

闪回表的常用语法为:

alter table table_name enable row movement;
flashback table table_name to timestamp|scn <timestamp|scn>;

注意:如果需要flashback一个数据表,需要具有flashback any table的系统权限或者是该表的flashback对象权限,同时还需要拥有该表的SELECT、INSERT、DELETE、ALTER权限,由于flashback table技术使用DML操作去恢复数据,不能保证Rowid不变,所以在闪回之前还需要启用表的row movement特性。

可以使用flashback table命令去闪回一个或多个表到过去的某个时间点或SCN,但是需要注意,flashback table不能将表恢复到改变表结构的DDL操作之前。

以下测试说明了闪回表的基本用法:

SQL> create table test as select * from dba_users;
表已创建。

SQL> select count(*) from test;
  COUNT(*)
----------
        32

SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
                 1030688

SQL> delete from test where rownum <13;
已删除12行。

SQL> commit;
提交完成。

SQL> select count(*) from test;
  COUNT(*)
----------
        20

SQL> alter table test enable row movement;
表已更改。

SQL> flashback table test to scn 1030688;
闪回完成。

SQL> select count(*) from test;
  COUNT(*)
----------
        32

实际上闪回表的功能是对闪回查询的增强,我们可以通过后台跟踪来研究一下闪回表的内部操作:

SQL> create table eygle as select * from dba_users;
表已创建。

SQL> select count(*) from eygle;
  COUNT(*)
----------
        32

SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
                 1031000

SQL> delete from eygle where rownum <13;
已删除12行。

SQL> commit;
提交完成。

SQL> select count(*) from eygle;
  COUNT(*)
----------
        20

SQL> alter session set events '10046 trace name context forever,level 12';
会话已更改。

SQL> alter table eygle enable row movement;
表已更改。

SQL> flashback table eygle to scn 1031000;
闪回完成。

SQL> select count(*) from eygle;
  COUNT(*)
----------
        32

获得跟踪文件,分析其中的主要内容,得到闪回表的主要操作步骤(以下测试在Oracle Database 11gR2中进行):

1.通过闪回查询在SYS_TEMP_FBT临时表记录闪回信息

以下查询通过as of SCN的闪回查询将指定对象、指定SCN的数据,包含ROWID插入到SYS_TEMP_FBT临时表中,注意这里面有一个重要的函数SYS_FBT_INSDEL,这个函数用于决定是通过INSERT操作还是DEL操作来还原数据:

PARSING IN CURSOR #1 len=159 dep=1 uid=86 oct=2 lid=86 tim=10946591929 hv=439595081 ad='2e25706c' sqlid='8qu8q54d37c29'
INSERT /*+ APPEND */ into SYS_TEMP_FBT SELECT /*+ FBTSCAN FULL(S) PARALLEL(S, DEFAULT) */ :1, :2, :3, rowid, SYS_FBT_INSDEL FROM "EYGLE"."EYGLE" as of SCN :4 S
END OF STMT
PARSE #1:c=0,e=48,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=1,plh=1028464186,tim=10946591927
BINDS #1:
 Bind#0
  oacdty=01 mxl=32(32) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=800000 frm=01 csi=852 siz=32 off=0
  kxsbbbfp=36167438  bln=32  avl=05  flg=09
  value="EYGLE"
 Bind#1
  oacdty=01 mxl=32(32) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=800000 frm=01 csi=852 siz=32 off=0
  kxsbbbfp=36167458  bln=32  avl=05  flg=09
  value="EYGLE"
 Bind#2
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=800000 frm=00 csi=00 siz=24 off=0
  kxsbbbfp=36167478  bln=22  avl=04  flg=09
  value=73442
 Bind#3
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=800000 frm=00 csi=00 siz=24 off=0
  kxsbbbfp=36167490  bln=22  avl=04  flg=09
  value=1031000

在SYS_TEMP_FBT这个临时表中记录了闪回表的数据操作,表中共有52条记录,先是DELETE 20条记录,然后是INSERT 32条记录,删除的是表中当前记录共20条,INSERT的是闪回目标点的32条记录:

SQL> select * from sys_temp_fbt;
SCHEMA     OBJECT_NAM    OBJECT# RID                  A
---------- ---------- ---------- -------------------- -
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAM   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAN   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAO   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAP   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAQ   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAR   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAS   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAT   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAU   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAV   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAW   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAX   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAY   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAZ   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAa   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAb   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAc   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAd   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAe   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAf   D
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAA   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAB   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAC   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAD   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAE   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAF   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAG   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAH   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAI   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAJ   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAK   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAL   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAM   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAN   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAO   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAP   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAQ   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAR   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAS   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAT   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAU   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAV   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAW   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAX   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAY   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAZ   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAa   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAb   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAc   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAd   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAe   I
EYGLE      EYGLE           73442 AAAR7iAAEAAAACrAAf   I

已选择52行。

第二个步骤在数据表中删除那些需要删除的记录:

PARSING IN CURSOR #1 len=237 dep=1 uid=86 oct=7 lid=86 tim=10946767645 hv=2296038091 ad='2e2566dc' sqlid='46df7uk4dphqb'
/* Flashback Table */ DELETE /*+ BYPASS_UJVC */ FROM (SELECT /*+ ORDERED USE_NL(S) PARALLEL(S,DEFAULT) PARALLEL(T,DEFAULT) */ S.rowid FROM SYS_TEMP_FBT T, "EYGLE"."EYGLE" S WHERE T.rid = S.rowid and T.action = 'D' and T.object#  = : 1) V
END OF STMT
PARSE #1:c=0,e=66,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=1,plh=4211461806,tim=10946767643
WAIT #1: nam='cursor: pin S' ela= 4 idn=2296038091 value=1 where=327680 obj#=-1 tim=10946773047
BINDS #1:
 Bind#0
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=800000 frm=00 csi=00 siz=24 off=0
  kxsbbbfp=361676c8  bln=22  avl=04  flg=09
  value=73442

第三个步骤是执行INSERT操作,还原期望SCN点上的32条记录:

PARSING IN CURSOR #1 len=290 dep=1 uid=86 oct=2 lid=86 tim=10946853708 hv=3158191884 ad='2e25d5ec' sqlid='f8k47dfy3wbsc'
/* Flashback Table */ INSERT /*+ PARALLEL(S, DEFAULT) PARALLEL(T, DEFAULT) */ INTO "EYGLE"."EYGLE" SELECT /*+ USE_NL(S) ORDERED PARALLEL(S, DEFAULT) PARALLEL(T, DEFAULT) */ S.* FROM SYS_TEMP_FBT T , "EYGLE"."EYGLE" as of SCN :1 S WHERE T.rid = S.rowid and T.action = 'I' and T.object# = :2 
END OF STMT
PARSE #1:c=0,e=62,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=1,plh=890006386,tim=10946853705
BINDS #1:
 Bind#0
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=800000 frm=00 csi=00 siz=24 off=0
  kxsbbbfp=36167628  bln=22  avl=04  flg=09
  value=1031000
 Bind#1
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=800000 frm=00 csi=00 siz=24 off=0
  kxsbbbfp=36167640  bln=22  avl=04  flg=09
  value=73442

这就是闪回表的内部实现机制。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论