Oracle闪回技术[未完]

Posted 满格

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle闪回技术[未完]相关的知识,希望对你有一定的参考价值。

(一)闪回技术概要

闪回技术是数据库备份与恢复的重要补充手段,主要包括以下7种特性:

特性 原理 数据库支持
闪回查询
(Flashback Query)
利用undo表空间中的回退信息,查询过去某个时刻或SCN时表中数据的快照 Undo表空间配置
闪回版本查询
(Flashback Version Query)
利用undo表空间中的回退信息,查询过去某个时间段或某个SCN段内数据的变化情况 Undo表空间配置
闪回事务查询
(Flashback Transaction Query)
利用undo表空间中的回退信息,查询过去某个事务或所有事务在过去一段时间内对数据库所做的修改 Undo表空间配置
闪回表
(Flashback Table)
利用undo表空间中的信息,将表中的数据恢复到过去某个时间点或SCN时的状态 Undo表空间支持
闪回删除
(Flashback Drop)
利用“回收站功能”,将表及关联对象恢复到删除以前的状态 回收站
闪回数据库
(Flashback Database)
利用存储在快速恢复区(Flashback Recovery Area)的闪回日志(Flashback log),将数据库恢复到过去某个时刻或某个SCN 快速恢复区
闪回数据归档
(Flashback Data Archive)
利用保存在一个或多个表空间中的数据变化信息,查询过去某个时刻或SCN值时数据库表中数据的快照。 一个或多个闪回数据归档区

接下来一一学习。

 

(二)闪回查询

(1)主要功能

返回已经丢失或被误操作删除的数据在操作之前的快照。

(2)Undo表空间设置

与undo表空间相关的参数主要是下面三个:

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS1

①   undo_management:设置undo表空间的管理模式,有自动和手动管理两种方式,默认自动管理undo表空间;

②   undo_retention:设置保留时间,我们可以对其修改:

SQL > ALTER SYSTEM SET UNDO_RETENTION = 86400;  --修改为24小时

值得注意的是,undo_retention是一个“软设置”,数据库会尽量给你保留24小时,但是假如undo表空间不够用,数据是不会保留24小时的。

如果必须要保留24小时,可以启用Undo表空间的retention guarantee,保证过期的数据才能被删除,设置如下:

SQL > ALTER TABLESPACE undotbs1 RETENTION GUARANTEE;

③   undo_tablespace:指明所使用的undo表空间

(3)闪回查询语法:

闪回查询是通过AS OF关键字实现的,具体如下:

SELECT column_name FROM table_name
AS OF SCN|TIMESTAMP expression
[WHERE condition];

其中,scn与timestamp是一一对应的,可以通过函数TIMESTAMP_TO_SCN(timestamp)和SCN_TO_TIMESTAMP(scn)来转换。

(4)例子1、通过timestamp来闪回查询用户所做操作。

16:59:48 SQL> create table test01
           2  (
           3      id        number(5),
           4      name      varchar(20),
           5      salary    number(5)
           6  );

17:02:52 SQL> insert into test01 values(1,\'lijiaman\',1000);
17:02:52 SQL> insert into test01 values(2,\'liudedong\',2000);
17:03:52 SQL> update test01 set salary = 1200 where id = 1;
17:04:59 SQL> update test01 set salary = 1400 where id = 1;
17:06:06 SQL> update test01 set salary = 1600 where id = 1;
17:07:04 SQL> delete from test01 where id = 2;

对于整个过程,我们可以使用下图来表示:

接下来,我们使用闪回查询技术查看数据:

-- 查看表中目前数据,只有一行
17:21:46 SQL> select * from test01;         
    ID NAME                 SALARY
------ -------------------- ------
     1 lijiaman               1600
     
-- 查看17:07:00的数据,此时还未删除数据,有2行,且id=1的salary是1600        
17:46:26 SQL> select * from test01 as of timestamp to_timestamp(\'2017-10-07 17:07:00\',\'yyyy-mm-dd hh24:mi:ss\');
    ID NAME                 SALARY
------ -------------------- ------
     1 lijiaman               1600
     2 liudedong              2000

-- 查看17:06:00的数据,此时id=1的salary还是1400 
17:54:28 SQL> select * from test01 as of timestamp to_timestamp(\'2017-10-07 17:06:00\',\'yyyy-mm-dd hh24:mi:ss\');
    ID NAME                 SALARY
------ -------------------- ------
     1 lijiaman               1400
     2 liudedong              2000

-- 查看17:04:00的数据,此时id=1的salary还是1200 
17:54:57 SQL> select * from test01 as of timestamp to_timestamp(\'2017-10-07 17:04:00\',\'yyyy-mm-dd hh24:mi:ss\');
    ID NAME                 SALARY
------ -------------------- ------
     1 lijiaman               1200
     2 liudedong              2000

-- 查看17:03:00的数据,此时id=1的salary还是1000 
17:55:14 SQL> select * from test01 as of timestamp to_timestamp(\'2017-10-07 17:03:00\',\'yyyy-mm-dd hh24:mi:ss\');
    ID NAME                 SALARY
------ -------------------- ------
     1 lijiaman               1000
     2 liudedong              2000 

-- 查看17:02:00的数据,此时还未向数据库插入数据 
17:55:20 SQL> select * from test01 as of timestamp to_timestamp(\'2017-10-07 17:02:00\',\'yyyy-mm-dd hh24:mi:ss\');
    ID NAME                 SALARY
------ -------------------- ------

 

(三)闪回版本查询

(1)主要功能

闪回版本提供了审计行数据变化的功能,可以跟踪一条记录在一段时间内的变化情况,即一条记录的多个提交版本信息(一个事物对一条记录的操作结果视为该记录的一个版本),从而为行级数据的追踪提供了可能。

(2)闪回版本查询语法
SELECT column_name[,…] FROM table_name 
VERSIONS BETWEEN SCN|TIMESTAMP MINVALUE|expression AND 
MAXVALUE|expression
[AS OF SCN | TIMESTAMP expression]
WHERE condition

参数说明:

--VERSIONS BETWEEN:用于指定闪回查询所要求的时间段或SCN段;

--AS OF:用于指定闪回查询时查询的目标时刻或目标SCN值;

 

在闪回查询的目标列中,可以使用以下伪列来返回行的版本信息:

--VERSIONS_STARTTIME:基于时间的版本有效范围的下界,可以理解为某个版本的开始时间,下亦相同;

--VERSIONS_ENDTIME:基于时间的版本有效范围的上界;

--VERSIONS_STARTSCN:基于SCN的版本有效范围的下界;

--VERSIONS_ENDSCN:基于SCN的版本有效范围的上界;

--VERSIONS_XID:操作的事物ID;

--VERSIONS_OPERATION:执行操作的类型,I:insert,D:delete,U:update

(3)例子2、版本闪回查询测试
20:06:51 SQL> create table test02
           2  (
           3      id        number(5),
           4      name      varchar(20),
           5      salary    number(5)
           6  );

20:09:23 SQL> insert into test02 values(1,\'lijiaman\',1000);           --事物1:第一次数据插入
20:09:23 SQL> insert into test02 values(2,\'liudedong\',2000);
20:09:23 SQL> commit;
20:10:09 SQL> update test02 set salary = 1100 where id = 1;
20:10:09 SQL> update test02 set salary = 1200 where id = 1;           --事物2:这里对同一行数据在同一个事物中更新了2次
20:10:09 SQL> commit;
20:11:10 SQL> update test02 set salary = 1400 where id = 1;           --事物3:再次数据更新
20:11:10 SQL> commit;
20:12:11 SQL> update test02 set salary = 1600 where id = 1;           --事物4:再次数据更新 
20:12:11 SQL> commit;
20:13:09 SQL> delete from test02 where id = 2;
20:13:09 SQL> commit;

接下来,我们通过闪回事物查询来看一下id=1的事物记录

20:15:27 SQL> select
           2    versions_xid,
           3    versions_starttime,
           4    versions_endtime,
           5    versions_operation,
           6    salary
           7  from
           8    test02
           9  versions between timestamp minvalue and maxvalue
          10  where
          11    id = 1;
 
VERSIONS_XID     VERSIONS_STARTTIME        VERSIONS_ENDTIME          VERSIONS_OPERATION SALARY
---------------- ------------------------  ------------------------- ------------------ ------
0300080046030000 07-10月-17 08.12.09 下午                                  U                  1600             --事物4:再次数据更新
07001A006D020000 07-10月-17 08.11.09 下午  07-10月-17 08.12.09 下午     U                  1400             --事物3:再次数据更新
070019006C020000 07-10月-17 08.10.03 下午  07-10月-17 08.11.09 下午     U                  1200             --事物2:这里执行了2次更新,很明显,第一次更新未记录
0400090080020000 07-10月-17 08.09.27 下午  07-10月-17 08.10.03 下午     I                  1000             --事物1:第一次数据插入

 

(四)闪回事物查询

(1)主要功能

闪回事务查询可以返回在一个特定事务中行的历史数据及与事务相关的元数据,或返回一个时间段内所有事务的操作结果及事务的元数据。

(2)日志追加功能

在Oracle 11g中,为了记录事务操作的详细信息,需要启动数据库的日志追加功能。

查看是否开启补充日志功能:

SQL> select supplemental_log_data_min from v$database;

SUPPLEMENTAL_LOG_DATA_MIN
-------------------------
NO

执行以下语句,开启数据库的日志追加功能:

SQL > ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;

如果要禁用日志追加功能,可以使用下面的命令:

SQL > ALTER DATABASE DROP SUPPLEMENTAL LOG DATA;

(3)执行闪回事务查询

执行闪回事务查询要查询静态数据字典FLASHBACK_TRANSACTION_QUERY,该视图结构如下:

SQL> desc flashback_transaction_query;

Name             Type            Comments                                 
---------------- --------------  -----------------------------------------
XID              RAW(8)          事务ID
START_SCN        NUMBER          事务开始的SCN
START_TIMESTAMP  DATE            事务开始的时间戳
COMMIT_SCN       NUMBER          事务提交的SCN
COMMIT_TIMESTAMP DATE            事务提交的时间戳
LOGON_USER       VARCHAR2(30)    执行事物的数据库用户
UNDO_CHANGE#     NUMBER          撤销的SCN
OPERATION        VARCHAR2(32)    执行的操作类型
TABLE_NAME       VARCHAR2(256)   表名
TABLE_OWNER      VARCHAR2(32)    表的属主
ROW_ID           VARCHAR2(19)    行的ROWID
UNDO_SQL         VARCHAR2(4000)  撤销该事物的SQL

(4)例子3、执行闪回事物查询

--第一步:开启追加日志
SQL> select supplemental_log_data_min from v$database;
SUPPLEME
--------
NO

SQL> alter database add supplemental log data;

--第二步:创建测试表test06
--21:19:34
create table test06
(
    id        number(5),
    name      varchar(20),
    salary    number(5)
);

--21:20:27
insert into test06 values(1,\'lijiaman\',1000);               --事物1:第一次数据插入20:09:23 SQL> insert into test02 values(2,\'liudedong\',2000);
commit;

--21:21:23 
update test06 set salary = 1100 where id = 1;
update test06 set salary = 1200 where id = 1;           --事物2:这里对同一行数据在同一个事物中更新了2次
commit;

--21:22:12 
update test06 set salary = 1400 where id = 1;           --事物3:再次数据更新
commit;


--第三步:执行闪回事物查询
--闪回事物查询通常与闪回版本查询一起使用

--先看闪回版本查询结果
select 
  versions_xid,
  versions_starttime,
  versions_endtime,
  versions_operation,
  id,
  name,
  salary
from
  test06
versions between timestamp minvalue and maxvalue
where 
  id = 1;

VERSIONS_XID     VERSIONS_STARTTIME     VERSIONS_ENDTIME       VERSIONS_OPERATION     ID NAME                 SALARY
---------------- ---------------------- ---------------------- ------------------ ------ -------------------- ------
060014002A040000 10-OCT-17 09.22.15 PM                         U                       1 lijiaman               1400
05001C00F7040000 10-OCT-17 09.21.30 PM  10-OCT-17 09.22.15 PM  U                       1 lijiaman               1200
0800140031040000 10-OCT-17 09.20.38 PM  10-OCT-17 09.21.30 PM  I                       1 lijiaman               1000

--第四步:根据闪回版本查询结果,执行闪回事物查询
SQL> select xid,start_timestamp,operation,table_name,undo_sql from flashback_transaction_query where xid = hextoraw(\'0800140031040000\');                  --与上面事物1对应的版本查询
 
XID              START_TIMESTAMP OPERATION TABLE_NAME  UNDO_SQL
---------------- --------------- --------- ----------- ---------------------------------------------------------------
0800140031040000 2017/10/10 21:2 INSERT    TEST06      delete from "SYS"."TEST06" where ROWID = \'AAATteAABAAAU4ZAAA\';
0800140031040000 2017/10/10 21:2 BEGIN                 
  
  
SQL> select xid,start_timestamp,operation,table_name,undo_sql from flashback_transaction_query where xid = hextoraw(\'05001C00F7040000\');                --与上面事物2对应的版本查询
 
XID              START_TIMESTAMP OPERATION TABLE_NAME UNDO_SQL
---------------- --------------- --------- ---------- --------------------------------------------------------------------------------
05001C00F7040000 2017/10/10 21:2 UPDATE    TEST06     update "SYS"."TEST06" set "SALARY" = \'1100\' where ROWID = \'AAATteAABAAAU4ZAAA\';
05001C00F7040000 2017/10/10 21:2 UPDATE    TEST06     update "SYS"."TEST06" set "SALARY" = \'1000\' where ROWID = \'AAATteAABAAAU4ZAAA\';
05001C00F7040000 2017/10/10 21:2 BEGIN

 

(五)闪回表

(1)主要功能

闪回表是将表恢复到过去的某个状态,闪回表与闪回查询不同,闪回查询只是得到过去某个时刻的快照,并不改变表的当前状态,而闪回表则是将表及附属对象一起恢复到以前的某个时刻的状态。

(2)相关设置

(2.1)权限设置

为了使用FLASHBACK TABLE语句,用户需具有下列权限:

--需要具有FLASHBACK ANY TABLE系统权限,或者具有相应对象的FLASHBACK对象权限;

--用户对相应表需具有INSERT、SELECT、DELETE、ALTER的对象权限;

--如果要执行FLASHBACK TABLE … RESTORE POINT语句,需具有SELECT ANY DICTIONARY或FLASHBACK ANY TABLE系统权限,或具有SELECT_CATALOG_ROLE角色。

(2.2)表结构

当前表结构与要恢复到的时间点的表结构必需相同。例如表的升级(UPGRADE)、结构重组(MOVE)、数据的删减(TRUNCATE)、添加约束、修改列、删除列等操作都改变了表的结构,不能进行闪回操作。

(2.3)行移动

执行FLASHBACK TABLE之前,需要启用表的ROW MOVEMENT特性,闪回操作后,行的ROWID将会发生变化。

ALTER TABLE table_name ENABLE ROW MOVEMENT;

(3)语法

FLASHBACK TABLE [SCHEMA.]table_name TO SCN|TIMESTAMP expression
[ENABLE|DISABLE TRIGGERS]

参数解释:

--ENABLE|DISABLE TRIGGERS:在闪回表的过程中,表上的触发器是启用还是禁用。默认在闪回表的过程中禁用触发器,闪回完成后启用触发器

(4)例子4、闪回表操作

--创建测试样例

--17:08:12
create table test04
(
  id         number(2),
  name       varchar(20),
  salary     varchar(30)
);

--17:18:05
create index idx_test04_id on test04(id); 

--Oracle闪回技术详解

Oracle闪回技术详解

Oracle-闪回技术

Oracle闪回技术--更新ing

Oracle 闪回 找回数据的实现方法

Oracle闪回技术