Oracle FlashBack(闪回)

概述

FLASHBACK是在10g中推出的一个技术簇,其中主要包括:

  • Flashback Database
  • Flashback Drop
  • Flashback Table
  • Flashback Query
  • Flashback Version Query
  • Flashback Transaction Query
  • 11g的Total-Recall

该技术提供了更加快捷,粒度更小,简单地数据恢复方案。还可用于安全审计、数据变更版本跟踪、应用测试、容灾环境等场景

FLASHBACK DATABASE

使用FLASHBACK DATABASE语句可以将数据库闪回到过去的时间和SCN,该语句提供了不完整数据库恢复的快速替代方法。执行FLASHBACK DATABASE之后必须以resetlog方式打开数据库。

先决条件

您必须拥有SYSDBA系统特权。必须为数据库准备快速恢复区域。除非将数据库刷新到保证还原点[1],否则必须将数据库置于语句的FLASHBACK模式中ALTER DATABASE FLASHBACK ON。数据库必须处于MOUNT状态不能打开。此外:

  • 数据库必须以ARCHIVELOG模式运行。
  • 数据库必须以当前控制文件装入,但不能打开。控制文件不能是备份或重新创建。当数据库控制文件从备份恢复或重新创建时,所有现有的闪回日志信息都将被丢弃。
  • 数据库必须不包含利用SQL语句ALTER TABLESPACE… FLASHBACK OFF禁用闪回功能的在线表空间。

flashback database

当执行FLASHBACK DATABASE语句时,Oracle数据库首先会验证是否有可用的所有必需的归档和联机重做日志。如果它们可用,则它将数据库中的所有当前在线数据文件还原为此语句中指定的SCN或时间点。

  • 保留在数据库中的闪回数据量由DB_FLASHBACK_RETENTION_TARGET初始化参数和快速恢复区域的大小控制。您可以通过查询V$FLASHBACK_DATABASE_LOG视图来确定您可以回退多远。
  • 如果数据库中的数据不足以执行闪回,则可以使用标准恢复过程将数据库恢复到过去的时间点。
  • 如果一组数据文件的数据不足,则数据库返回一个错误。在这种情况下,您可以使这些数据文件脱机并重新发出该语句以恢复数据库的其余部分。然后,您可以尝试使用标准恢复过程来恢复脱机数据文件。

技术原理

Oracle为实现FLASHBACK DATABASE功能,新设计了Flashback Buffer缓存区,同过新的后台进程PVWR将变更的前镜像定期写入Flashback Database Log中,执行闪回时Oracle将按时间倒序方向读取Flashback Database Log进行恢复。

示例

回退到指定的时间点

1
2
flashback database to timestamp(to_date(‘2018.04.02 20:03:00′,’YYYY.MM.DD HH24:MI:SS’));
flashback database to timestamp(sysdate – 1/24);

回退到指定SCN

1
flashback database to scn 3775124;

回退到指定的Log sequence

1
flashback database to sequence=223 thread=1;

FLASHBACK DROP

通过Flashback drop可以快速恢复DROP删除的表,在执行DROP TABLE后数据库并不会立即删除表占用的空间,而是将表重命名并与关联的对象一起放置在回收站中,系统生成的回收站对象名称是唯一的。

  • 该表必须位于SYSTEM表空间以外的本地管理表空间中
  • 如果恢复时指定删除前的表名,并且回收站中有多个该表的对象。则按照后进先出的原则恢复最近记录到回收站的对象
  • 如果表空间空间不足Oracle按照先入先出的原则将回收站中部分表彻底清除,为新表分配空间 Flashback Drop不能恢复表相关位图索引或域索引、物化视图日志和参照约束

RecycleBin

回收站实际上是一个数据字典表,其中包含有关被删除对象的信息。删除的表和任何关联的对象(如索引,约束,嵌套表等)不会被删除并仍占用空间。

回收站对象命名规则:unique_id 是此对象的26个字符的全局唯一标识符,这使得回收站名称在所有数据库中都是唯一的;version 是由数据库分配的版本号

1
BIN$unique_id$version

禁用回收站

1
2
3
4
##会话参数设置
ALTER SESSION SET recyclebin = OFF; 
##spfile参数设置,需重启
ALTER SYSTEM SET recyclebin = OFF SCOPE = SPFILE;

启用回收站

1
2
3
4
##会话参数设置
ALTER SESSION SET recyclebin = ON; 
##spfile参数设置,需重启 
ALTER SYSTEM SET recyclebin = ON SCOPE = SPFILE;

清空回收站对象

1
2
3
4
5
PURGE TABLE table_name;
PURGE TABLESPACE tablespace_name;
PURGE TABLESPACE tablespace_name USER username;
PURGE RECYCLEBIN;
PURGE DBA_RECYCLEBIN;

闪回

1
FLASHBACK TABLE table_name TO BEFORE DROP [RENAME TO new_table_name];

FLASHBACK TABLE

FLASHBACK TABLE在发生认为或应用程序错误时,可以用来恢复表到较早的状态。闪回取决于UNDO回滚段的数据。且无法恢复任何DDL操作。FLASHBACK TABLE的操作是无法回滚的,但是可以发起另外一个FLASHBACK TABLE操作恢复到之前的状态,因此建议在执行该操作时先记录当前数据库SCN。

  • 在Oracle闪回表操作期间,Oracle数据库在闪回列表中指定的所有表上获取独占DML锁。这些锁可以防止表在恢复到以前的状态时进行任何操作。
  • 无论闪回列表中指定的表的数量是多少,闪回表操作都在单个事务中执行。要么所有的表格都恢复到以前的状态,要么都没有。如果闪回表操作在任何表上失败,则整个语句失败。
  • 在闪回表操作完成时,数据输入表与先前时间一致。但是,FLASHBACK TABLE TO SCN或者TIMESTAMP不保留rowid,并且FLASHBACK TABLE TO BEFORE DROP不会恢复参照约束。
  • Oracle数据库不会恢复表之前相关的统计信息。表目前存在的索引将被还原并反映闪回点处的表的状态。如果索引现在存在但尚未存在于闪回点,则数据库将更新索引以反映闪回点处表的状态。但是,在闪回点和当前时间之间的时间间隔内丢弃的索引不会被恢复

先决条件

  1. 要将表闪回到较早的SCN或时间戳记,您必须具有FLASHBACK TABLE上的对象特权或FLASHBACK ANY TABLE系统特权。此外,你必须对表有SELECT,INSERT,DELETE,和ALTER对象权限。
  2. 除非FLASHBACK TO BEFORE DROP,否则必须为闪回列表中的所有表启用行移动TO BEFORE DROP。
  3. 要将表闪回到还原点,您必须具有SELECT ANY DICTIONARY或FLASHBACK ANY TABLE系统特权或SELECT_CATALOG_ROLE角色。
  4. 要将表格闪回到DROP TABLE操作之前,只需要删除表格所需的特权

flashbackup table

限制因素

闪回表操作对于以下类型对象无效:作为群集,物化视图,高级队列(AQ)表,静态数据字典表,系统表,远程表,对象表,嵌套表或单个表的一部分的表分区或子分区。

以下DDL操作会更改表的结构,导致您不能随后使用TO SCN 或者 TO TIMESTAMP子句将表闪回到操作前的时间:升级,移动或截断表; 向表中添加约束,将表添加到集群; 修改或删除列; 更改列加密密钥; 添加,删除,合并,拆分,合并或截断分区或子分区(除添加范围分区外)。

示例

回退到一个小时前

1
flashback table employees to timestamp(sysdate-1/24);

回退到指定的SCN

1
flashback table employees to scn 3775124;

FLASHBACK QUERY

10g/11g的Flashback Query技术可使用户查询过去时间点或过去SCN号的记录数据。该技术利用回滚段中的旧数据构建某个时间点的数据版本。

假设您在12:30发现员工Chung的行已从employees表中删除,并且您知道在上午9:30,Chung的数据已正确存储在数据库中。您可以使用Oracle闪回查询在上午9:30检查表中的内容,以了解丢失的数据。如果合适,您可以恢复丢失的数据。

1
2
3
4
SELECT * FROM employees
AS OF TIMESTAMP
TO_TIMESTAMP('2004-04-04 09:30:00', 'YYYY-MM-DD HH:MI:SS')
WHERE last_name = 'Chung';

恢复丢失的数据

1
2
3
4
5
6
INSERT INTO employees (
    SELECT * FROM employees
    AS OF TIMESTAMP
    TO_TIMESTAMP('2004-04-04 09:30:00', 'YYYY-MM-DD HH:MI:SS')
    WHERE last_name = 'Chung'
);

Flashback Version Query

当COMMIT提交时会创建行的版本,使用Oracle闪回版本查询来检索给定时间间隔内存在的特定行的不同版本。

  • Flashback Versions Query不支持外部表、系统临时表、系统内部表和视图
  • Flashback Versions Query不支持改变表结构的DDL操作
  • Flashback Versions Query将过滤掉shrink操作

语法

1
select * from table_name VERSIONS {BETWEEN {SCN | TIMESTAMP} start AND end}

相关数据伪列

名称 描述
VERSIONS_STARTSCN / VERSIONS_STARTTIME 行版本创建时的SCN或TIMESTAMP
VERSIONS_ENDSCN / VERSIONS_ENDTIME 版本结束时的SCN或TIMESTAMP。如果这个伪列是NULL,那么行版本在查询时是最新的,或者行对应于一个DELETE操作
VERSIONS_XID 版本创建时事务的标识符
VERSIONS_OPERATION 交易执行的操作:I插入,D删除或U更新

示例

1
2
3
4
5
6
7
8
9
SELECT versions_startscn, versions_starttime,
              versions_endscn, versions_endtime,
              versions_xid, versions_operation,
              last_name, salary
    FROM employees
    VERSIONS BETWEEN TIMESTAMP
            TO_TIMESTAMP('2008-12-18 14:00:00', 'YYYY-MM-DD HH24:MI:SS')
    AND TO_TIMESTAMP('2008-12-18 17:00:00', 'YYYY-MM-DD HH24:MI:SS')
    WHERE first_name = 'John';

注:您可以使用闪回事务查询中的VERSIONS_XID来查找此事务的元数据,包括撤消行更改所需的SQL以及负责更改的用户。闪回版本查询仅允许索引访问IOT(索引组织表),但不允许索引快速全面扫描。

Flashback Transaction Query

使用Oracle闪回事务处理查询来检索给定事务或给定时间间隔内所有事务的元数据和历史数据。

  • 当表、用户被删除之后,Flashback Transaction Query将不返回这些表名和用户名,而是返回相应的系统内部表编号和用户编号
  • Flashback Transaction Query技术运用时,最好使数据库运行在supplemental log data方式下,保证Oracle提供更全面的日志信息

Oracle闪回事务查询将查询静态数据字典视图FLASHBACK_TRANSACTION_QUERY,该视图字段说明如下:

字段 描述
XID 事务标识符
START_SCN 事务开始的SCN
START_TIMESTAMP 事务开始的时间戳
COMMIT_SCN 事务提交的SCN
COMMIT_TIMESTAMP 事务提交的时间戳
LOGON_USER 登陆事务的用户
UNDO_CHANGE# 撤消系统更换号码
OPERATION 事务执行的操作
TABLE_NAME 操作的表
TABLE_OWNER 表的所有者
ROW_ID DML修改行的ROWID
UNDO_SQL 用来撤销DML的SQL

查询事务信息

1
2
3
SELECT xid,operation,start_scn,commit_scn,logon_user,undo_sql
FROM flashback_transaction_query
WHERE xid = HEXTORAW('000200030000002D');

查询闪回版本查询的事务信息

1
2
3
4
5
6
7
SELECT xid, logon_user
FROM flashback_transaction_query
WHERE xid IN (
    SELECT versions_xid FROM employees VERSIONS BETWEEN TIMESTAMP
    TO_TIMESTAMP('2003-07-18 14:00:00', 'YYYY-MM-DD HH24:MI:SS') AND
    TO_TIMESTAMP('2003-07-18 17:00:00', 'YYYY-MM-DD HH24:MI:SS')
);

注:如果查询FLASHBACK_TRANSACTION_QUERY视图XID存在空,则查询大量不相关的行,从而降低性能

Oracle Flashback Transaction Query with Oracle Flashback Version Query

插入测试数据

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
SQL> DROP TABLE emp;
SQL> CREATE TABLE emp (
    empno   NUMBER PRIMARY KEY,
    empname VARCHAR2(16),
    salary  NUMBER
);
SQL> INSERT INTO emp (empno, empname, salary) VALUES (111, 'Mike', 555);
SQL> COMMIT;
  
SQL> DROP TABLE dept;
SQL> CREATE TABLE dept (
    deptno   NUMBER,
    deptname VARCHAR2(32)
);
SQL> INSERT INTO dept (deptno, deptname) VALUES (10, 'Accounting');
SQL> COMMIT;

删除empno=111的数据

1
2
3
4
SQL> UPDATE emp SET salary = salary + 100 WHERE empno = 111; 
SQL> INSERT INTO dept(deptno,deptname)VALUES(20,'Finance'); 
SQL> DELETE FROM emp WHERE empno = 111; 
SQL> commit;

新插入一些测试数据到emp

1
2
3
4
SQL> INSERT INTO emp(empno,empname,salary)VALUES(111,'Tom',777); 
SQL> UPDATE emp SET salary = salary + 100 WHERE empno = 111; 
SQL> UPDATE emp SET salary = salary + 50 WHERE empno = 111; 
SQL> commit;

查询empno=111对应的版本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
SELECT versions_xid XID, versions_startscn START_SCN,
    versions_endscn END_SCN, versions_operation OPERATION,
    empname, salary
FROM emp
VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE
WHERE empno = 111;
XID               START_SCN    END_SCN O EMPNAME              SALARY
---------------- ---------- ---------- - ---------------- ----------
09001100B2200000   10093466            I Tom                     927
030002002B210000   10093459            D Mike                    555
0800120096200000   10093375   10093459 I Mike                    555

3 rows selected.

注:第三行对应emp于创建表时在表中插入表中的行的版本。第二行对应于emp删除了错误事务的行。第一行对应于emp重新插入新员工姓名的行的版本

通过闪回事务查询,查询事务标识030002002B210000所做的变更

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
SELECT xid,start_scn,commit_scn,operation,logon_user,undo_sql 
FROM flashback_transaction_query 
WHERE xid = HEXTORAW(' 000200030000002D ');
XID               START_SCN COMMIT_SCN OPERATION LOGON_USER              -UNDO_SQL
---------------- ---------- ---------- --------- ---------------------- ------------------------------------------
030002002B210000   10093452   10093459 DELETE    HR
insert into "HR"."EMP"("EMPNO","EMPNAME","SALARY") values ('111','Mike','655');
  
030002002B210000   10093452   10093459 INSERT    HR
delete from "HR"."DEPT" where ROWID = 'AAATjuAAEAAAAJrAAB';
  
030002002B210000   10093452   10093459 UPDATE    HR
update "HR"."EMP" set "SALARY" = '555' where ROWID = 'AAATjsAAEAAAAJ7AAA';
  
030002002B210000   10093452   10093459 BEGIN     HR

4 rows selected.

查询错误事务和所有后续事务的信息

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
SELECT xid,start_scn,commit_scn,operation,table_name,table_owner 
FROM flashback_transaction_query 
WHERE table_owner ='HR' AND start_timestamp> = TO_TIMESTAMP('2002-04-16 11:00:00','YYYY-MM-DD HH:MI:SS “);
XID               START_SCN COMMIT_SCN OPERATION TABLE_NAME TABLE_OWNER
---------------- ---------- ---------- --------- ---------- -----------
02000E0074200000   10093435   10093446 INSERT    DEPT       HR
030002002B210000   10093452   10093459 DELETE    EMP        HR
030002002B210000   10093452   10093459 INSERT    DEPT       HR
030002002B210000   10093452   10093459 UPDATE    EMP        HR
0800120096200000   10093374   10093375 INSERT    EMP        HR
09001100B2200000   10093462   10093466 UPDATE    EMP        HR
09001100B2200000   10093462   10093466 UPDATE    EMP        HR
09001100B2200000   10093462   10093466 INSERT    EMP        HR

8 rows selected.

DBMS_FLASHBACK

10g/11g的DBMS_FLASHBACK包具有与Flashback Query相似的功能。不同的是Flashback Query需要AS OF字句,用于查询某个时间点或SCN号的记录,而DBMS_FLASHBACK包可以通过调用DBMS_FLASHBACK.ENABLE_AT_TIME或DBMS_FLASHBACK.ENABLE_AT_SYSTEM_CHANGE_NUMBER的,将数据库设置为某个时间点或SCN号,而不用改动SQL,就可直接查询指定时间点或SCN号的记录

  • Flashback Query一般用于少量记录的恢复,而DBMS_FLASHBACK则用于大量表的大量记录的恢复
  • Flashback Query和DBMS_FLASHBACK可用于当前数据与历史数据之间的对比分析
  • 可通过Flashback Query和DBMS_FLASHBACK技术,运行历史数据报表生成等批处理应用
  • 可简化应用设计。例如不需要临时表存储历史数据,直接通过Flashback Query和DBMS_FLASHBACK查询历史数据

示例

将数据库置为9:30的状态

1
EXEC dbms_flashback.enable_at_time(TO_TIMESTAMP('2009-10-04 09:30:00', 'YYYY-MM-DD HH:MI:SS'));

将数据库恢复当前状态

1
EXECUTE dbms_flashback.disable;

Total Recall

Oracle 11g的Total Recall技术实际上基于新的Flashback Data Archive(FDA)技术。在Oracle 11g中, Flashback Data Archive为用于保存历史数据的一组表空间。11g在表级启动FDA功能,通过新后台进程FBDA,自动将具有FDA特性表的历史记录由UNDO表空间写入FDA区域。

通过CRATE FLASHBACK DATA ARCHIVE语句创建闪回数据库归档,该归档提供了自动跟踪和存档事务数据更该到指定数据库对象。闪回数据归档由多个表空间组成,并存储来自所有业务的历史数据和跟踪表。 闪回数据归档保留使用RETENTION参数指定的持续时间内的历史数据。历史数据可以用FLASHBACK QUERY查询。

  • FDA按照定义的保存期限(Retention)自动进行历史数据的清理,无需人工操作
  • FDA对现有生产系统的开销非常小。
  • FDA可以压缩形式进行存储,降低历史数据的存储开销。
  • FDA可进行扩容、调整保存期限等维护操作。
  • FDA不支持导致表结构变化的DDL操作,也不支持对表的Drop和Truncate操作

先决条件

创建闪回数据归档需要FLASHBACK ARCHIVE ADMINISTER权限,此外还需要CREATE TABLESPACE权限。要将闪回数据归档指定为系统默认闪回数据归档,还需要sysdba权限

语法

create_flashback_archive

create_flashback_archive

flashback_archive_quota

flashback_archive_quota

flashback_archive_retention

flashback_archive_retention

alter_flashback_archive

alter_flashback_archive 示例

创建FLASHBACK DATA ARCHIVE

1
2
3
4
CREATE FLASHBACK ARCHIVE DEFAULT test_archive1
 TABLESPACE example
 QUOTA 1 M
 RETENTION 1 DAY;

为emp表启用FDA

1
ALTER TABLE inventory FLASHBACK ARCHIVE test_archive1;

修改保留期

1
ALTER FLASHBACK ARCHIVE test_archive1 MODIFY RETENTION 1 MONTH;

利用归档闪回表

1
ALTER TABLE oe.customers FLASHBACK ARCHIVE;

删除归档

1
DROP FLASHBACK ARCHIVE test_archive;

闪回扩展场景

Flashback与测试

1、测试环境准备 2、记录测试开始时间,系统SCN号或日志序列号 3、进行业务测试 4、通过Flashback Database技术,将数据库整体快速回退到测试开始之间的时间, SCN号或日志序列号 5、进行其他测试

Flashback与审计

通过FlashBack Version Query查询某个表、某条记录在指定时间段或SCN之间的数据变更。例如查询最近5分钟对employees表进行DML操作

1
2
3
select versions_xid,versions_startscn, versions_endscn,versions_operation
from employees
versions between timestamp (sysdate – 1/288) and sysdate

通过Flashback Transaction Query查询上述XID对应的事务详细信息

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
select operation,undo_sql
from flashback_transaction_query
where xid=HEXTORAW(‘0200200038020000’)
and table_name=’EMPLOYEES’

OPERATION UNDO_SQL
——— ————————————————————–
DELETE    insert into “JFV”.”EMPLOYEES_DEMO”(“EMPNO”,”EMPNAME”,”SALARY”) values (‘111′,’Mike’,’655′);
INSERT    delete from “JFV”.”DEPARTMENTS_DEMO” where ROWID = ‘AAAP95AAGAAAAAlAAB’;
UPDATE    update “JFV”.”EMPLOYEES_DEMO” set “SALARY” = ‘555‘ where ROWID 

Flashback与Data Guard

在Data Guard中,可以将物理备用数据库以读写方式打开,进行各种开发、测试、报表等用途,再利用Flashback Database技术,将数据库回退到读写打开的时间点,恢复物理备份数据库的灾备功能.

flashback8

读写DG库

  1. 在物理备用数据库中先创建一个Restore Point。
  2. 将物理备用数据库以读写方式打开。此时物理备用数据库可以进行各种开发、测试、报表等读写操作。同时物理备用数据库继续接收生产系统传输的日志文件,但没有应用(Apply)。即物理备用数据库与生产系统数据库处于数据不同步状态。
  3. 通过Flashback Database技术,将物理备用数据库回退到Restore Point时间点。
  4. 此时,物理备用数据库开始通过日志应用(Apply),重新与生产系统数据库进行数据同步操作,俗称“追数据”

快速恢复生产库

  1. 通过Flashback Database技术,将原生产系统数据快速退回到灾难发生之前的状态。
  2. 通过传输和应用新生产系统的日志,将原生产系统的数据与新生产系统数据同步,快速建立新容灾系统。
  3. 通过Switchover快速恢复原生产系统

Tips

1. askmaclean 2. Doc ID 1138253.1 3. Oracle Database Advanced Application Developer’s Guide

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus