测试在数据库开启闪回功能后,对数据库进行闪回操作
-
闪回查询
闪回查询将会话临时退回到过去的时间点,查询这个过去的时间点数据库的状态。
- 测试详情
查看表修改之前的状态和时间
SQL> select * from t3;
C
-
2
2
2
SQL> select sysdate from dual;
SYSDATE
-------------------
2020-04-09 11:00:11
修改表
SQL> update t3 set C1='3' where C1='2';
3 rows updated.
SQL> commit
2 ;
Commit complete.
查看表修改之后的状态和时间
SQL> select * from t3
2 ;
C
-
3
3
3
SQL> select sysdate from dual;
SYSDATE
-------------------
2020-04-09 11:05:48
闪回查询方式1
SQL> select * from alios3.t3 as of timestamp to_timestamp('2020-04-09 11:00:11' ,'yyyy-mm-dd hh24:mi:ss');
C
-
2
2
2
闪回查询方式2--将会话回退到过去某个时间点
SQL> grant execute on dbms_flashback to alios3;
Grant succeeded.
SQL> conn alios3/alios3
Connected.
SQL> exec dbms_flashback.enable_at_time(to_timestamp('2020-04-09 11:00:11' ,'yyyy-mm-dd hh24:mi:ss'));
PL/SQL procedure successfully completed.
SQL> select * from t3;
C
-
2
2
2
SQL> exec dbms_flashback.-
> disable;
PL/SQL procedure successfully completed.
其他说明
1、sys用户不支持闪回查询
exec dbms_flashback.enable_at_time(to_timestamp('2020-04-09 11:00:11' ,'yyyy-mm-dd hh24:mi:ss'));
begin dbms_flashback.enable_at_time(to_timestamp('2020-04-09 11:00:11' ,'yyyy-mm-dd hh24:mi:ss')); end;
ORA-08185: 用户 SYS 不支持闪回
ORA-06512: 在 "SYS.DBMS_FLASHBACK", line 3
ORA-06512: 在 line 1
2、普通用户未授权情况下闪回查询报错
SQL> conn alios3/alios3
Connected.
SQL> exec dbms_flashback.enable_at_time(to_timestamp('2020-04-09 11:00:11' ,'yyyy-mm-dd hh24:mi:ss'));
BEGIN dbms_flashback.enable_at_time(to_timestamp('2020-04-09 11:00:11' ,'yyyy-mm-dd hh24:mi:ss')); END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'DBMS_FLASHBACK' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
2、闪回查询小结
- 用户基于会话回退到过去的时间点exec dbms_flashback.enable_at_time(to_timestamp('2020-04-09 11:00:11' ,'yyyy-mm-dd hh24:mi:ss'));其前提是被授予了相应的权限。
- 授予用户会话闪回到过去的时间点:grant execute on dbms_flashback to alios3
- select * from alios3.t3 as of timestamp to_timestamp('2020-04-09 11:00:11' ,'yyyy-mm-dd hh24:mi:ss');不需要额外授予查询权限
- sys用户不支持闪回查询闪回表
闪回表
SQL> alter table t3 enable row movement;
Table altered.
SQL> flashback table alios3.t3 to timestamp to_timestamp('2020-04-09 11:00:11' ,'yyyy-mm-dd hh24:mi:ss');
Flashback complete.
SQL> conn alios3/alios3
Connected.
SQL> select * from t3;
C
-
2
2
2
其他问题
1、一般普通用户不具备闪回表权限;闪回表的前提是对表开启行移动功能。
SQL> flashback table t3 to timestamp to_timestamp('2020-04-09 11:00:11' ,'yyyy-mm-dd hh24:mi:ss');
flashback table t3 to timestamp to_timestamp('2020-04-09 11:00:11' ,'yyyy-mm-dd hh24:mi:ss')
*
ERROR at line 1:
ORA-08189: cannot flashback the table because row movement is not enabled
SQL> alter table t3 enable row movement;
Table altered.
SQL> flashback table t3 to timestamp to_timestamp('2020-04-09 11:00:11' ,'yyyy-mm-dd hh24:mi:ss');
flashback table t3 to timestamp to_timestamp('2020-04-09 11:00:11' ,'yyyy-mm-dd hh24:mi:ss')
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-01031: insufficient privileges
表闪回小结:
1、一般普通用户不具备闪回表权限;闪回表的前提是对表开启行移动功能。
2、当多个表有约束限制,比如外键约束时,可以同时闪回多个表 flashback table t3,t4 to timestamp to_timestamp('2020-04-09 11:00:11' ,'yyyy-mm-dd hh24:mi:ss');
行版本查询
SQL> select * from t3 ;
C C2
- --------------------
2 1
2 2
2 3
SQL> update t3 set C1='1' where C2='1';
1 row updated.
SQL> commit;
Commit complete.
SQL> select sysdate from dual;
SYSDATE
-------------------
2020-04-09 15:55:54
SQL> update t3 set C1='2' where C2='2';
1 row updated.
SQL> commit;
Commit complete.
SQL> select sysdate from dual;
SYSDATE
-------------------
2020-04-09 15:57:00
闪回版本查询
闪回版本查询允许看一个行的所有提交版本。
可以看到C2=1的记录更改的版本信息
SQL> set numwidth 20;
SQL> set linesize 200;
SQL> select C1,C2,versions_xid,versions_startscn,versions_endscn from t3 versions between scn minvalue and maxvalue;
C C2 VERSIONS_XID VERSIONS_STARTSCN VERSIONS_ENDSCN
- -------------------- ---------------- -------------------- --------------------
4 1 06000B0014A40000 5975532786694
1 1 5975532786694
2 2
2 3
SQL> select C1,C2,versions_xid,versions_startscn,versions_endscn from t3 versions between scn minvalue and maxvalue;
C C2 VERSIONS_XID VERSIONS_STARTSCN VERSIONS_ENDSCN
- -------------------- ---------------- -------------------- --------------------
4 1
2 2
2 3
闪回删除
SYS@orcl1>create user droper identified by droper;
User created.
SYS@orcl1>grant create session,resource,unlimited tablespace to droper;
Grant succeeded.
SYS@orcl1>conn droper/droper
Connected.
DROPER@orcl1>create table names(name varchar2(10));
Table created.
DROPER@orcl1>create index name_idx on names(name);
Index created.
DROPER@orcl1>insert into names values('john');
1 row created.
DROPER@orcl1>commit;
Commit complete.
DROPER@orcl1>set linesize 200;
DROPER@orcl1>select object_name,object_type from user_objects;
OBJECT_NAME OBJECT_TYPE
-------------------------------------------------------------------------------------------------------------------------------- -----------------------
NAMES TABLE
NAME_IDX
DROPER@orcl1>select constraint_name,constraint_type,table_name from user_constraints;
CONSTRAINT CONSTRAINT TABLE_NAME
---------- ---------- --------------------------------------------------------------------------------------------------------------------------------
NAME_U U NAMES
DROPER@orcl1>drop table names;
Table dropped.
DROPER@orcl1>select object_name,object_type from user_objects;
no rows selected
DROPER@orcl1>select constraint_name,constraint_type,table_name from user_constraints;
CONSTRAINT CONSTRAINT TABLE_NAME
---------- ---------- --------------------------------------------------------------------------------------------------------------------------------
BIN$our4aF U BIN$our4aFCzJ0DgU1AGCgpv3w==$0
CxJ0DgU1AG
Cgpv3w==$0
DROPER@orcl1>col ORIGINAL_NAME format a20;
DROPER@orcl1>col type format a20;
DROPER@orcl1>col OBJECT_NAME format a40;
DROPER@orcl1>select object_name,original_name,type from user_recyclebin;
OBJECT_NAME ORIGINAL_NAME TYPE
---------------------------------------- -------------------- --------------------
BIN$our4aFCzJ0DgU1AGCgpv3w==$0 NAMES TABLE
BIN$our4aFCyJ0DgU1AGCgpv3w==$0 NAME_IDX INDEX
从上可以看到,表删除之后,其约束没有在回收站。
DROPER@orcl1>select * from "BIN$our4aFCzJ0DgU1AGCgpv3w==$0";
NAME
----------
john
可以看到,可以在回收站里执行查询
DROPER@orcl1>insert into "BIN$our4aFCzJ0DgU1AGCgpv3w==$0" values('hehe');
insert into "BIN$our4aFCzJ0DgU1AGCgpv3w==$0" values('hehe')
*
ERROR at line 1:
ORA-38301: can not perform DDL/DML over objects in Recycle Bin
可以看到,在回收站里不能执行DML操作
DROPER@orcl1>flashback table names to before drop;
Flashback complete.
闪回删除表
DROPER@orcl1>select object_name,object_type from user_objects;
OBJECT_NAME OBJECT_TYPE
---------------------------------------- -----------------------
NAMES TABLE
BIN$our4aFCyJ0DgU1AGCgpv3w==$0 INDEX
DROPER@orcl1>select constraint_name,constraint_type,table_name from user_constraints;
CONSTRAINT CONSTRAINT TABLE_NAME
---------- ---------- --------------------------------------------------------------------------------------------------------------------------------
BIN$our4aF U NAMES
CxJ0DgU1AG
可以看到,执行闪回删除后,表名恢复了,但是索引和约束还保留这它们在回收站里的名称。
DROPER@orcl1>alter index "BIN$our4aFCyJ0DgU1AGCgpv3w==$0" rename to name_idx;
Index altered.
DROPER@orcl1>alter table names rename constraint "BIN$our4aFCxJ0DgU1AGCgpv3w==$0" to name_u;
Table altered.
DROPER@orcl1>select object_name,object_type from user_objects;
OBJECT_NAME OBJECT_TYPE
---------------------------------------- -----------------------
NAMES TABLE
NAME_IDX INDEX
DROPER@orcl1>select constraint_name,constraint_type,table_name from user_constraints;
CONSTRAINT CONSTRAINT TABLE_NAME
---------- ---------- --------------------------------------------------------------------------------------------------------------------------------
NAME_U U NAMES
将索引和约束重命名会原来的名称
闪回删除小结:
- drop删除的表,实际上会对表重命名,放在回收站
- 表删除后,其约束和索引会重命名和自动放入回收站。
- 闪回删除flashback table before drop后,原来的表名恢复,但是其索引和约束需要手动从回收站恢复 。
- flashback drop 不适用于存储在system表空间的表
闪回数据库
SYS@orcl1>select flashback_on from v$database;
FLASHBACK_ON
------------------
YES
确认闪回功能已经开启
ALIOS3@orcl1>select * from t3;
C C2
- --------------------
4 1
2 2
2 3
ALIOS3@orcl1>select sysdate from dual;
SYSDATE
-------------------
2020-04-10 16:01:15
ALIOS3@orcl1>update t3 set C1='5' where C2='1';
1 row updated.
ALIOS3@orcl1>commit;
Commit complete.
ALIOS3@orcl1>select sysdate from dual;
SYSDATE
-------------------
2020-04-10 16:02:31
ALIOS3@orcl1>update t3 set C1='6'where C2='1';
1 row updated.
ALIOS3@orcl1>commit ;
Commit complete.
ALIOS3@orcl1>select sysdate from dual;
SYSDATE
-------------------
2020-04-10 16:05:16
SQL> set sqlprompt "_user'@'_connect_identifier>"
SYS@orcl2> select * from alios3.t3;
C C2
- --------------------
6 1
2 2
2 3
闪回恢复开始
[oracle@testdb1 ~]$ sqlplus / as sysdba
SQL*Plus: Release 12.1.0.2.0 Production on Fri Apr 10 16:15:57 2020
Copyright (c) 1982, 2014, Oracle. All rights reserved.
Connected to an idle instance.
SQL> startup mount;
ORACLE instance started.
Total System Global Area 9462349824 bytes
Fixed Size 3720312 bytes
Variable Size 1946160008 bytes
Database Buffers 6945767424 bytes
Redo Buffers 29831168 bytes
In-Memory Area 536870912 bytes
Database mounted.
SYS@orcl1>flashback database to timestamp to_timestamp('2020-04-10 16:01:15','yyyy-mm-dd hh24:mi:ss');
Flashback complete.
SYS@orcl1>flashback database to timestamp to_timestamp('2020-04-10 16:01:15','yyyy-mm-dd hh24:mi:ss');
Flashback complete.
SYS@orcl1>alter database open read only;
Database altered.
SYS@orcl1>select * from alios3.t3;
C C2
- --------------------
4 1
2 2
2 3
可以看到利用闪回数据库恢复到了满足时间点的数据
如果此时没有恢复到目标数据,可以继续利用归档日志和在线日志做恢复操作
SYS@orcl1>recover database until time '2020-04-10 16:05:16';
ORA-00279: change 5975532881777 generated at 04/10/2020 16:01:16 needed for
thread 1
ORA-00289: suggestion :
+DATA/ORCL/ARCHIVELOG/2020_04_10/thread_1_seq_231.13878.1037376561
ORA-00280: change 5975532881777 for thread 1 is in sequence #231
Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
auto
Log applied.
Media recovery complete.
SYS@orcl1>alter database open read only;
Database altered.
SYS@orcl1>select * from alios3.t3;
C C2
- --------------------
6 1
2 2
2 3
恢复成功
SYS@orcl1>shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SYS@orcl1>startup mount;
ORACLE instance started.
Total System Global Area 9462349824 bytes
Fixed Size 3720312 bytes
Variable Size 1946160008 bytes
Database Buffers 6945767424 bytes
Redo Buffers 29831168 bytes
In-Memory Area 536870912 bytes
Database mounted.
SYS@orcl1>alter database open resetlogs;
Database altered.
SYS@orcl1>select * from alios3.t3
2 ;
C C2
- --------------------
6 1
2 2
2 3
确认恢复到目标值后,使用restlogs打开数据库
闪回数据库小结
- 闪回功能开启后,可以在mount模式下执行闪回数据库
- 可以将闪回数据库与recover databse 相结合来用,以此达到接近目标恢复点。在打开数据库之前,可以重复执行闪回和recover操作