关于oracle:模拟Oracle11g下用Flashback-Data-Archive进行恢复的若干场景

120次阅读

共计 7099 个字符,预计需要花费 18 分钟才能阅读完成。

相干概念

Flashback Data Archive 是什么

Flashback data archiveoracle 11g 中引入的一个新个性。Flashback archive是一个新的数据库对象,用于存储一个或多表的历史数据。Flashback archive是一个逻辑对象,概念上相似于表空间。实际上 flashback archive 能够看作是存储一个或多个表的所有事务变动的逻辑空间。
Oracle 11gFlashback Data Archive 个性。将变动数据另外存储到创立的闪回归档区(Flashback Archive)中,以和 undo 区别开来,这样就能够为闪回归档区独自设置存储策略,使之能够闪回到指定工夫之前的旧数据而不影响 undo 策略。并且能够依据须要指定哪些数据库对象须要保留历史变动数据,而不是将数据库中所有对象的变动数据都保留下来,而只是记录了指定表的数据变动。所以,Flashback Data Archive 是针对对象的爱护,是 Flashback Database 的无力补充。

它和 Flashbak 的区别?

Oracle 中的 flashback 包含:flashback version queryflashback transaction queryflashback databaseflashback tableflashback drop等个性。

在这些闪回技术当中,除了 Flashback Database(依赖于闪回日志)之外,其余的闪回技术都是依赖于Undo 撤销数据,都与数据库初始化参数 UNDO_RETENTION 密切相关。

它们是从撤销数据中读取信息来结构旧数据的。这样就有一个限度,就是 undo 中的信息不能被笼罩。而 undo 段是循环应用的,只有事务提交,之前的 undo 信息就可能被笼罩,尽管能够通过 undo_retention等参数来缩短 undo 的存活期,但这个参数会影响所有的事务,设置过大,可能导致 undo tablespace 疾速收缩。

换句话说:个别的数据库内 undo_retention 只设置了 900 秒,如果事务量太大,在产生误操作后 undo 内的事务被其余顶掉或超过 900 秒,那么就无奈通过 flashbak 进行复原。而 Flashback Data Archiveundo无关,是独自创立一个闪回归档区,把表级的历史记录都存到归档区外面,能够随时查看表级对象的历史状况。

模仿用 Flashback Data Archive 复原

环境筹备

数据库版本:Oracle Database 11g Enterprise Edition Release 11.2.0.4.0
是否开启归档:否
是否为 RAC:否

建设测试表插入测试数据

建设一个测试表test_table_delete,插入数据如下图所示

查问 time_stamp 内的数据和执行打算

select * from test_table_delete as of timestamp to_timestamp('2020-09-17 13:55:09','yyyy-mm-dd hh24:mi:ss');


能够看到,此时的打算走的是 test_table_delete 这张表的全表扫描,先记着,前面有用。

创立一个用来存储闪回归档的表空间

能够应用现有表空间,但 Oracle 倡议最好应用专用表空间
对表空间的要求:
(1)Flashback data archive 只能在 ASSM 的 tablespace 上创立
(2)Flashback data archive 要求必须应用主动 undo 治理,即 undo_management 参数为 auto

create tablespace fa_data  datafile '/opt/ora_data/fa_01.dbf' size 1G;

查看咱们创立的 fa_data 表空间是否符合要求:

select dbt.TABLESPACE_NAME,dbt.SEGMENT_SPACE_MANAGEMENT  from dba_tablespaces dbt where dbt.TABLESPACE_NAME = 'FA_DATA';

SEGMENT_SPACE_MANAGEMENTAUTO 代表为 ASSM 形式段治理的表空间

数据库的 undo_management 参数也为AUTO

Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 
Connected as lijian@oraclevm

SQL> show parameter undo 
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS1

创立一个闪回归档区

语法:

create flashback archive fa_data tablespace fa_data quota 50M retention 1 year;

qutoa前面跟的是闪回归档区的大小,retention前面跟的是要保留多久的历史数据。
qutoa如果不设置,默认自增;当闪回归档区数据超过 retiontion 设置的值时 Oracle 会主动清理。

查看闪回归档、闪回归档和表空间的关系

select * from dba_flashback_archive;
select * from dba_flashback_archive_ts;


把测试表调配到闪回归档区

alter table test_table_delete flashback archive fa_data;

查问 DBA_FLASHBACK_ARCHIVE_TABLES 视图能够取得曾经归档的表

select * from dba_flashback_archive_tables;

模仿 delete 操作(更新不频繁的表)

因为测试库没有那么大量的事务,所以 undo 会保留很长时间
这里为了模仿,所以采纳的看执行打算的形式来判断是否走了 Flashback Data Archive
并且上面所有的操作,都没有用 flashbak 操作命令,为的就是区别这两种做法

操作过程:删掉一条数据
复原指标:复原到表里之前 5 条数据的状况

delete from test_table_delete where cityid =1002;
commit;
SQL> select * from test_table_delete;
CITYID                                             CITYNAME
-------------------------------------------------- --------------------------------------------------
1001                                               吉林
1003                                               武汉
1004                                               成都
1005                                               四川

再来看一下之前 SQL 的执行打算

发现打算里曾经走了 DBA_FLASHBACK_ARCHIVE_TABLES 里的表,阐明曾经调用到闪回归档的信息,当初查问进去的数据就是走的 Flashback Data Archive,不走undo

进行复原

SQL> select  to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'YYYY-MM-DDHH2
------------------------------
2020-09-17 14:47:09   -- 获取当初的工夫

-- 这里的 2020-09-17 14:25:54 能够始终往前找,delete 后理论表里存在 4 条数据
-- 咱们须要找到一个工夫点,外面有 5 条数据的。SQL> select * from test_table_delete as of timestamp to_timestamp('2020-09-17 14:25:54','yyyy-mm-dd hh24:mi:ss');
CITYID                                             CITYNAME
-------------------------------------------------- --------------------------------------------------
1002                                               长春
1001                                               吉林
1003                                               武汉
1004                                               成都
1005                                               四川

-- 这里咱们间接用 insert into 语句,where 条件后跟 cityid=1002,因为咱们晓得删的数据是哪条。SQL> insert into test_table_delete (select * from test_table_delete as of timestamp to_timestamp('2020-09-17 14:25:54','yyyy-mm-dd hh24:mi:ss') where cityid = 1002);
1 row inserted

SQL> commit;
Commit complete

-- 能够看到,id=1002,cityname= 长春的数据被咱们复原回来了。-- 无论是删除 1 条还是多条,还是删除后表里又新增数据,只有晓得过后删除的条件,都能够找回来。SQL> select * from test_table_delete;
CITYID                                             CITYNAME
-------------------------------------------------- --------------------------------------------------
1002                                               长春
1001                                               吉林
1003                                               武汉
1004                                               成都
1005                                               四川

模仿 truncate 操作

truncate 表操作,用 flashbak 命令是无奈进行闪回的
Flashback Data Archive将不可能变成了可能。

复原指标:

  1. truncate 后复原到新增 3 条数据之前的 5 条记录

    1. truncate 后复原到 8 条记录
-- 我又新增了 3 条数据进去
SQL> select * from test_table_delete;
CITYID                                             CITYNAME
-------------------------------------------------- --------------------------------------------------
1002                                               长春
1006                                               甘肃
1007                                               上海
1008                                               北京
1001                                               吉林
1003                                               武汉
1004                                               成都
1005                                               四川
8 rows selected
Commit complete

SQL> truncate table test_table_delete;
Table truncated

SQL> select * from test_table_delete;
CITYID                                             CITYNAME
-------------------------------------------------- --------------------------------------------------

-- 用之前 5 条记录的工夫点来看,是否还能查出来数据
SQL> select * from test_table_delete as of timestamp to_timestamp('2020-09-17 14:25:54','yyyy-mm-dd hh24:mi:ss');
CITYID                                             CITYNAME
-------------------------------------------------- --------------------------------------------------
1002                                               长春
1005                                               四川
1003                                               武汉
1004                                               成都
1001                                               吉林

-- 咱们能够将这个 sql 的后果 insert 到 test_table_delete 表里来实现 truncate 后的复原
SQL> insert into test_table_delete (select * from test_table_delete as of timestamp to_timestamp('2020-09-17 14:25:54','yyyy-mm-dd hh24:mi:ss'));
5 rows inserted

SQL> commit;
Commit complete

-- 5 条数据被复原回来
SQL> select * from test_table_delete;
CITYID                                             CITYNAME
-------------------------------------------------- --------------------------------------------------
1002                                               长春
1005                                               四川
1003                                               武汉
1004                                               成都
1001                                               吉林

-- 再执行一遍 truncate,这次要复原 8 条数据
SQL> truncate table test_table_delete;
Table truncated
-- 找到存在 8 条记录的工夫
SQL> select * from test_table_delete as of timestamp to_timestamp('2020-09-17 15:00:00','yyyy-mm-dd hh24:mi:ss');
CITYID                                             CITYNAME
-------------------------------------------------- --------------------------------------------------
1002                                               长春
1006                                               甘肃
1007                                               上海
1008                                               北京
1005                                               四川
1003                                               武汉
1004                                               成都
1001                                               吉林
8 rows selected
-- 用 Insert 语句进行复原
SQL> insert into test_table_delete (select * from test_table_delete as of timestamp to_timestamp('2020-09-17 15:00:00','yyyy-mm-dd hh24:mi:ss'));
8 rows inserted

SQL> commit;
Commit complete

SQL> select * from test_table_delete;
CITYID                                             CITYNAME
-------------------------------------------------- --------------------------------------------------
1002                                               长春
1006                                               甘肃
1007                                               上海
1008                                               北京
1005                                               四川
1003                                               武汉
1004                                               成都
1001                                               吉林
8 rows selected
SQL> 

对于 Drop table 的操作

对于退出了归档空间的 table,进行删除的时候会产生一个报错,强制不让你 drop 这个表
从另一种角度来说,也是存在肯定的平安因素。
如果非要删除,那么须要用 dbms_flashback_archive 包来解除关联关系,咱们来试验一下。

SQL> drop table test_table_delete;
drop table test_table_delete
ORA-55610: 针对历史记录跟踪表的 DDL 语句有效

SQL> EXEC DBMS_FLASHBACK_ARCHIVE.DISASSOCIATE_FBA('LIJIAN','TEST_TABLE_DELETE');
PL/SQL procedure successfully completed

SQL> drop table test_table_delete;
drop table test_table_delete
ORA-55610: 针对历史记录跟踪表的 DDL 语句有效

SQL> exec dbms_flashback_archive.reassociate_fba('LIJIAN','test_table_delete');
PL/SQL procedure successfully completed

发现执行了 dbms_flashback_archive 包来解除关联关系,咱们也无奈 drop table
网上的材料说是 Oracle 的一个 bug,也有材料说是在 11.2 版本修复的,然而我是 11.2.0.4 试过了也不行

既然 drop 不行,那么测试下 rename 和一些增加、批改字段的操作,具体的测试步骤不写了,大略是这样:

  1. 在原表减少一个字段,不必波及到 dbms_flashback_archive 包的相干操作,间接新增就能够,在主表减少实现后闪回归档空间的对象表主动减少一个列,如图所示:

2. 如果主表中删除一个列,也不须要波及到 dbms_flashback_archive 包的相干操作,间接删除就能够。然而删除后在闪回归档空间的对象表里存在一列记录,如图所示:

3. 要还原删除列后的表,须要先在主表上减少字段后从对应工夫点内复原

  1. 如果不须要在闪回归档空间的对象表里保留曾经删除列的信息,则须要用 dbms_flashback_archive 包进行解除关系,之后删除回归档空间的对象表里的列。
  2. 如果真要强行drop table,那么只能解除表和闪回归档空间的关系,带来的结果是无奈再复原之前的历史记录。
alter table test_delete no flashback archive;

总结

通过 Flashback Data Archive,咱们能够更好的治理表级别的复原,然而应用Flashback Data Archive 也有一些限度。
比方咱们应该布局数据库中哪些表是十分重要的,将它们退出到闪回归档区里。
另外还须要独自为空间进行布局,这须要肯定的存储用来保留你冀望的历史数据。
对于频繁批改的表,可能不太实用。
以上。

正文完
 0