首页 > 代码库 > Oracle Flashback 详解
Oracle Flashback 详解
Oracle flashback 是一种方便快捷的数据库恢复技术,它不使用备份文件,通过闪回日志可以使数据库恢复到过去的某个状态,当用户发生逻辑错误时(误删表数据、表、表空间等)需要快速恢复数据库,可以使用Flashback 实现。
1 启用Flashback 数据库
Oracle 默认不启动flashback 数据库,使用flashback 技术必须先启动数据库到flashback 状态,且数据库必须处于archive 模式下,并启用闪回恢复区,因为闪回日志文件必须存放在闪回恢复区中。
1) 检查数据库的归档状态
SQL> archive log list;
Database log mode Archive Mode
Automatic archival Enabled
Archive destination USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence 4
Next log sequence to archive 6
Current log sequence 6
SQL>
如果数据库没有启动到归档模式,需要手动启动到模式下。
SQL> shutdown immediate
SQL> startup mount
SQL> alter database archivelog
2) 确定闪回恢复区的目录
SQL> show parameter DB_RECOVERY_FILE_DEST;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest string /usr/oracle/app/flash_recovery
_area
db_recovery_file_dest_size big integer 3882M
3) 查看并设置db_flashback_retention_target参数
该参数是一个以分为单位的数字,默认为1440分钟,表示从当前开始计算最大可以把数据库闪回到过去的时间。
SQL> show parameter db_flashback_retention_target;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_flashback_retention_target integer 2880
此处必须明确Oracle 不保证一定可以闪回到时间段内的某个时间点,因为闪回日志是由快闪恢复区自动维护的,如果由于备份数据库或者其他操作引起磁盘空间不足,闪回日志将会被删除,所以我们在数据库运行时要评估快闪恢复区的空间,可以通过下面的参数查看
4) 评估快闪恢复区的空间
可以通过访问数据字典v$flashback_database_log来评估需要的快闪恢复区空间。
SQL> select *
2 from v$flashback_database_log;
OLDEST_FLASHBACK_SCN OLDEST_FLASHBACK_TIME RETENTION_TARGET FLASHBACK_SIZE ESTIMATED_FLASHBACK_SIZE
-------------------- --------------------- ---------------- -------------- ------------------------
6202363 2017/6/19 星期一 22:24:4 2880 92143616 546471936
ESTIMATED_FLASHBACK_SIZE表示系统估计的快闪恢复区的大小为546471936字节, FLASHBACK_SIZE表示当前闪回数据的大小为92143616字节。
5) 启动数据库到可闪回状态
要启动闪回数据库,必须先将系统启动到mount状态,然后启动闪回数据库
SQL> startup mount
SQL> alter database flashback on
SQL> alter databse open
查看当前数据库是否启动了闪回状态,可以访问数据字典v$database
SQL> select dbid, name, flashback_on from v$database;
DBID NAME FLASHBACK_ON
---------- --------- ------------------
1452257309 ORCL YES
6) 查询表空间是否处于闪回保护状态
SQL> select name, flashback_on
2 from v$tablespace;
NAME FLASHBACK_ON
------------------------------ ---------------
SYSTEM YES
SYSAUX YES
UNDOTBS1 YES
USERS YES
TEMP YES
CTRR_DATA YES
APSALU3_DATA YES
DEFAULT_TABLESPACE YES
TEMP02 YES
RMAN_TS YES
7) 开启或者关闭某个表空间闪回状态
首先数据库必须处于mount状态下才能进行此操作
SQL> startup mount
SQL> alter tablespace users flashback on/off
2 闪回数据库的实施步骤
1) 数据库级别闪回
使用scott用户建立测试表插入一部分数据然后删除。
获取一个删除前的时间点用于闪回恢复
select to_char(sysdate,‘yyyy-mm-dd hh24:mi:ss‘) from dual;
2017-06-21 12:36:49
删除测试表
drop table t_test1;
drop table t_test3;
commit;
关闭数据库启动到mount状态
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.
Total System Global Area 450953216 bytes
Fixed Size 2214256 bytes
Variable Size 348128912 bytes
Database Buffers 96468992 bytes
Redo Buffers 4141056 bytes
Database mounted.
使用闪回命令将数据库恢复到删除表之前的时间点
flashback database to timestamp to_timestamp(‘2017-06-21 12:36:49‘,‘yyyy-MM-dd hh24:mi:ss‘);
SQL> flashback database to timestamp to_timestamp(‘2017-06-21 12:36:49‘,‘yyyy-MM-dd hh24:mi:ss‘);
Flashback complete.
然后使用read only 模式打开数据库验证删除的表是否已经恢复
alter database open read only
验证无误之后再重新启动数据到mount状态,然后使用resetlogs 打开数据库,闪回日志仍然有效,我们还可以继续闪回到resetlogs以前的某一个时间点,但是这里需要明确一点数据库不能再闪回到resetlogs 之后的某个时间点了,例如这次我们闪回的时间点为:2017-06-21 12:36:49,我们只能闪回到此时间点之前的某个时间点,之后的时间点不能再闪回了。
SQL> startup mount
SQL> alter database open resetlogs
查看之前删除的两个表已经恢复回来了。
2) 删除用户测试
新建用户
create user latiny identified by XXXXX
default tablespace default_tablespace
temporary tablespace temp;
grant connect, resource to latiny;
创建表插入测试数据
create table t_test1(id number not null primary key);
循环插入1000条数据
获取系统当前时间,用以删除之后闪回恢复时间点
select to_char(sysdate,‘yyyy-mm-dd hh24:mi:ss‘) from dual;
2017-06-21 12:36:49
latiny用户退出登录,使用sys用户删除新建的用户
drop user latiny cascade;
关闭数据库启动到mount状态下
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.
Total System Global Area 450953216 bytes
Fixed Size 2214256 bytes
Variable Size 352323216 bytes
Database Buffers 92274688 bytes
Redo Buffers 4141056 bytes
Database mounted.
将数据库恢复到latiny用户被删之前的时刻
SQL> flashback database to timestamp to_date(‘2017-06-21 12:36:49‘,‘yyyy-MM-dd hh24:mi:ss‘);
Flashback complete.
只读方式打开数据检查被删的用户latiny是否已被恢复。
SQL> alter database open read only;
Database altered.
用户跟用户创建的表都已恢复
关闭数据库,启动到mount状态,然后再以resetlogs状态启动到open状态
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.
Total System Global Area 450953216 bytes
Fixed Size 2214256 bytes
Variable Size 352323216 bytes
Database Buffers 92274688 bytes
Redo Buffers 4141056 bytes
Database mounted.
SQL> alter database open resetlogs;
Database altered.
2 闪回删除
如果用户使用drop table命令,该表不会立即删除,而是保持原本位置,并且将删除的表信息存储在回收站中保留原表名并且赋予一个新的名字,显然此时被删除的表占有的空间没有立刻被释放,记录的信息在回收站中会保留一段时间,直到回收站空间不足或者使用purge 指令永久删除回收站中的记录。
回收站是一个逻辑结构,不具有物理数据结构,只要删除的表信息记录在其中就可以通过闪回技术恢复。
1) 查看数据库闪回删除是否启动
SQL> show parameter recyclebin;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
recyclebin string on
已启动,如未启动可以使用如下命令
SQL> alter system set recyclebin=on scope=both;
2) 回收站的使用
通过查询数据字典USER_RECYCLEBIN与 DBA_RECYCLEBIN 可以得到回收站删除表的所有信息
select *
from dba_recyclebin;
select *
from user_recyclebin;
删除latiny用户下创建的测试表
SQL> drop table t_test1;
Table dropped
SQL> commit;
Commit complete
然后用sql查看回收站信息,可以发现被删除的表信息。
恢复删除的表
SQL> flashback table T_TEST1 to before drop;
Done
可以查看到该表已恢复。
这里需要注意一点,表被删除之后相关的数据库对象(索引,触发器)等都将被删除闪回之后这些对象也会跟着被恢复,但是名字不再是未删除之前的名字,它会改变,是系统自动起的名字,不易阅读理解,需要手工修改。
3) 多个同名的表恢复
在实际使用中,可能不同的库或者同一库在不同时间里删除相同名字的表,那么在恢复前我们需要通过表的结构,删除时间等来确定哪一个表是真正需要恢复的表。
建立测试表t_test1,并且插入一些数据
create table t_test1(id number not null primary key);
然后删除
再建立测试表t_test1,并且插入一些数据
create table t_test1(id number not null primary key, name varchar2(25));
查看回收站发现两个一样的表
SQL> select object_name, original_name, type, droptime
2 from user_recyclebin;
OBJECT_NAME ORIGINAL_NAME TYPE DROPTIME
------------------------------ -------------------------------- ------------------------- -------------------
BIN$UneF8OUhYlbgUAB/AQBq2g==$0 T_TEST1 TABLE 2017-06-21:19:36:23
BIN$UneF8OUgYlbgUAB/AQBq2g==$0 SYS_C0012828 INDEX 2017-06-21:19:36:23
BIN$UneF8OUkYlbgUAB/AQBq2g==$0 SYS_C0012830 INDEX 2017-06-21:19:36:39
BIN$UneF8OUlYlbgUAB/AQBq2g==$0 T_TEST1
使用desc 查看表结构,注意一定要在系统里通过sqlplus进去使用该命令,使用PL/SQL或者其他远程连接工具的command 窗口查询不到表结构,会提示object_name对应的表名不存在。
SQL> desc "BIN$UneF8OUhYlbgUAB/AQBq2g==$0";
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NOT NULL NUMBER
SQL> desc "BIN$UneF8OUlYlbgUAB/AQBq2g==$0";
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NOT NULL NUMBER
NAME VARCHAR2(25)
使用object_name恢复表
SQL> flashback table "BIN$UneF8OUlYlbgUAB/AQBq2g==$0" to before drop rename to t_test1_new;
Flashback complete.
查询恢复的表存在,并且就是之前建立的有两个字段的t_test1;
4) purge 永久删除表
如果非常确定一个表没有用了,可以永久删除,可以使用purge命令,此命令删除的表回收站不会存它的任何记录。
SQL> drop table t_test1_new purge;
Table dropped
如果一个表已经在回收站想永久删除,可以使用如下命令
SQL> purge table t_test1;
Done
此时查看回收站已经没有任何信息了,因为之前的两个测试表信息都已经使用带purge命令删除与清空了
SQL> show recyclebin;
SQL>
Oracle Flashback 详解