6. Oracle闪回特性

  Oracle 闪回 (flashback)是9i版本提供的新特性。这一特性;其他数据库(PostgreSQL,Mysql)是羡慕不已。对数据恢复提供非常便捷的方式。闪回技术通常用于快速简单恢复数据库中出现的认为误操作等逻辑错误。
  从闪回的方式可以分为:

    • FLASHBACK DATABASE 数据库级别闪回
    • FLASHBACK TABLE 表级别闪回
    • FLASHBACK QUERY 事务级别闪回

一. 启动 Oracle 闪回

  Oracle 闪回特性在 Oracle 数据库安装界面有配置打开 Oracle 闪回;若当时没配置;可以按照下列方法进行配置:

1.1 要求数据库必须处于归档模式

  查看数据库的归档模式及闪回是否启用;

SQL> select log_mode,open_mode,flashback_on from v$database;

LOG_MODE     OPEN_MODE    FLASHBACK_ON
------------ -------------------- ------------------
ARCHIVELOG   READ WRITE    NO

1.2 设置闪回目录、闪回目录空间大小

  由 db_recovery_file_dest 和 db_recovery_file_dest_size 决定闪回目录和闪回目录的空间大小;用于来存放闪回日志。

SQL> alter system set db_recovery_file_dest_size=1G;

System altered.

SQL> alter system set db_recovery_file_dest = '/data/flash_dir';

System altered.

SQL> show parameter db_recovery;

NAME         TYPE  VALUE
------------------------------------ ----------- ----------------
db_recovery_file_dest       string  /data/flash_dir
db_recovery_file_dest_size      big integer 1G

1.3 设置闪回保留目标生存期

  默认是保留目标生存期是1天;

SQL> show parameter db_flashback;

NAME         TYPE  VALUE
------------------------------------ ----------- ---------------------
db_flashback_retention_target      integer  1440

1.4 启动闪回特性

  需要将 Oracle 数据库启动到 mount 状态;

SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.

Total System Global Area  780824576 bytes
Fixed Size      2257312 bytes
Variable Size    511708768 bytes
Database Buffers   264241152 bytes
Redo Buffers      2617344 bytes
Database mounted.
SQL> alter database flashback on;

Database altered.

SQL> alter database open;

Database altered.

  当启用 flashback database,则 sga 中会开辟一块新区域作为闪回缓冲区,大小由系统分配。启用新的 rvwr进程:rvwr进程将闪回缓冲区的内容写入到闪回日志中,注意闪回日志不同于联机重做日志,闪回日志在联机重做日志基础之上生成,是完整数据块映像的日志。联机日志则是变化的日志。闪回日志不能复用,也不能归档。闪回日志使用循环写方式。

二. 数据库级别闪回 (flashback database)

  数据库级别闪回:flashback database闪回到过去的某一时刻。类似于PITR。恢复方式比较简单。但是只能恢复时间点在闪回区的目标生存期;且恢复数据库中出现的认为误操作等逻辑错误。想误删数据文件这种是恢复不了的。
  闪回步骤:

  1. 关闭数据库
  2. 启动数据库到mount状态
  3. 闪回至某个时间点,SCN或log sequence number
  4. 使用resetlogs打开数据库

闪回方法:

-- 基于时间点;常用该方式
flashback database to timestamp to_timestamp('2010-10-24 13:04:30','yyyy-mm-dd hh24:mi:ss');
-- 基于scn
flashback database to scn 918987;
-- 基于恢复点
flashback database ro restore point b1_load;

2.1 闪回数据库演示:

SQL> conn lottu/li0924
Connected.
-- 创建实验对象表tbl_flash_01
SQL> create table tbl_flash_01 (id number,name varchar2(20));
Table created.

SQL> insert into tbl_flash_01 values (1001,'lottu');
1 row created.
SQL> commit;
Commit complete.

--记录误操作时间之前的时刻。
SQL> select to_char(sysdate,'yyyymmddhh24miss') from dual;
TO_CHAR(SYSDAT
--------------
20180814224948

-- truncate表tbl_flash_01
SQL> truncate table tbl_flash_01;
Table truncated.

--误操作之后的日志
SQL> insert into tbl_flash_01 values (1002,'rax');
1 row created.
SQL> commit;
Commit complete.

-- 执行闪回操作
--1. 关闭数据库
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.

--2. 启动数据到mount状态
SQL> startup mount;
ORACLE instance started.

Total System Global Area  780824576 bytes
Fixed Size      2257312 bytes
Variable Size    511708768 bytes
Database Buffers   264241152 bytes
Redo Buffers      2617344 bytes
Database mounted.

--3. 执行闪回操作
SQL> flashback database to timestamp to_timestamp('20180814224948','yyyymmddhh24miss');

Flashback complete.

SQL> alter database open resetlogs;

Database altered.

SQL> conn lottu/li0924
Connected.
SQL> select * from tbl_flash_01;

 ID NAME
---------- --------------------
      1001 lottu

  数据恢复到闪回的时间点之前。但是闪回时间之后的操作没法进行恢复。针对这种情况;可以先在备库执行闪回恢复;再逻辑导出到主库进行恢复。

三. 表级别闪回 ( flashback table )

  在 Oracle 中;对 drop table 操作有中闪回保护;即表级别闪回。drop table命令并不真正删除表,在内部被映射为rename命令,即是将其重命名之后放入回收站。需要恢复;就从回收站回收即可。
  语法: flashback table tablename to before drop;

3.1 闪回表演示:

-- 1. 演示drop table后;闪回恢复表
SQL> conn lottu/li0924
Connected.
SQL> drop table tbl_flash_01;

Table dropped.

SQL> show recyclebin;
ORIGINAL NAME  RECYCLEBIN NAME  OBJECT TYPE  DROP TIME
---------------- --------------------------- ------------ ---------
TBL_FLASH_01  BIN$c2hFCisICOXgU+oBqMCsVQ==$0 TABLE 2018-08-14:23:57:40

SQL> flashback table tbl_flash_01 to before drop;

Flashback complete.

SQL> select * from tbl_flash_01;

 ID NAME
---------- --------------------
      1001 lottu
-- 2. 演示purge之后;是不能进行闪回。
SQL> drop table tbl_flash_01 purge;

Table dropped.

SQL> flashback table tbl_flash_01 to before drop;
flashback table tbl_flash_01 to before drop
*
ERROR at line 1:
ORA-38305: object not in RECYCLE BIN

-- 3. 演示闪回对象名已经存在;又该如何恢复
SQL> drop table tbl_flash_01;

Table dropped.

SQL> create table tbl_flash_01 (id number,name varchar2(20));

Table created.

SQL> flashback table tbl_flash_01 to before drop;
flashback table tbl_flash_01 to before drop
*
ERROR at line 1:
ORA-38312: original name is used by an existing object


SQL> flashback table tbl_flash_01 to before drop rename to tbl_flash_02;

Flashback complete.

-- 4. 若回收站中存在两个相同的原表名,则闪回时总是闪回最近的版本,如果闪回特定的表,需要指定该表在回收站中的名称
SQL> create table tbl_flash_01 (id number,name varchar2(20));

Table created.

SQL> drop table tbl_flash_01;

Table dropped.

SQL> create table tbl_flash_01 (id number,name varchar2(20),reg_time date);

Table created.

SQL> drop table tbl_flash_01;

Table dropped.

SQL> show recyclebin;
ORIGINAL NAME  RECYCLEBIN NAME  OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ ---------
TBL_FLASH_01  BIN$c2hFCisLCOXgU+oBqMCsVQ==$0 TABLE 2018-08-15:00:47:38
TBL_FLASH_01  BIN$c2hFCisKCOXgU+oBqMCsVQ==$0 TABLE 2018-08-15:00:24:22

-- 选择恢复最先删除的。
SQL> flashback table "BIN$c2hFCisKCOXgU+oBqMCsVQ==$0" to before drop;

Flashback complete.

SQL> desc tbl_flash_01 ;
 Name        Null?    Type
 -------------- -------- ------------------
 ID          NUMBER
 NAME          VARCHAR2(20)

四.事务级别闪回 ( flashback query )

  用户在执行dml操作;可以通过 flashback query 查询到指定时间点表中的记录。其本身不带有恢复性的操作。至于恢复吗;可以通过insert into table即可。

-- 查询表tab_flash_02 5分钟之前的数据
select * from tab_flash_02 as of timestamp sysdate - 5/1440;
-- 查询表tab_flash_02 某个时间点的记录
select * from tab_flash_02 as of timestamp to_timestamp('2018-08-13 17:26:08','yyyy-mm-dd hh24:mi:ss');
posted @ 2018-08-27 10:28  lottu  阅读(547)  评论(0编辑  收藏  举报