一 flashback_transaction_query
如果不小心误删掉了数据,可以通过视图恢复误删掉的数据,或者如果发现表里的数据出现了异常,想要知道最近有哪些用户对该表进行了哪些操作也可以通过该视图进行排查。
首先解释下flashback_transaction_query视图几个比较常用列的意思:
SQL> desc flashback_transaction_query;
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
XID RAW(8) --- 事物ID
START_SCN NUMBER --- 起始SCN号
START_TIMESTAMP DATE --- 执行sql语句的时间
COMMIT_SCN NUMBER --- 事物提交SCN号
COMMIT_TIMESTAMP DATE --- sql语句提交的时间
LOGON_USER VARCHAR2(30) --- 执行sql语句的用户
UNDO_CHANGE# NUMBER ---
OPERATION VARCHAR2(32) --- 进行的操作(增删改)
TABLE_NAME VARCHAR2(256) --- sql语句操作的表
TABLE_OWNER VARCHAR2(32) --- 表的拥有者
ROW_ID VARCHAR2(19) ---
UNDO_SQL VARCHAR2(4000) --- 恢复数据的sql语句
如果是普通用户需要具有(select any transaction 权限)才能查询该视图
select * from flashback_transaction_query where table_name='EMP'
通过查询结果可以分析出最近有哪些用户对emp表进行了什么 操作,执行查询结果中的undo_sql 语句可以将数据恢复到特定时间点
二,Flashback Table
将数据表恢复到之前的一个时间点或SCN号,由于Flashback Table 在默认情况下是不开启的
SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------
NO
而且在非企业版的oracle中是不支持flashbak table的,可以使用下面的sql查看数据库是否支持flashback table 功能,
SQL>select * from v$OPTION where parameter like 'Flashback%' 如果返回的value字段的值为false,表示当前的数据库版本不支持flashback table 功能
如果要启用flashback table 功能要对数据库参数做调整,修改db_recovery_file_dest、db_recovery_file_dest_size及db_flashback_retention_target三个参数内容
1)db_recovery_file_dest、db_recovery_file_dest_size两个参数用于指定闪回日志存放位置及最大大小。可以根据具体环境做相应调整。
SQL> show parameter recovery_file
NAME TYPE VALUE
-------------------------- --------------- --------------------
db_recovery_file_dest string /u01/app/oracle/flash_recovery_area
db_recovery_file_dest_size big integer 3852M
2)确认db_flashback_retention_target参数设置的内容。
db_flashback_retention_target参数限定了闪回可的时间范围,默认是1440分钟,一天的时间。
SQL> show parameter db_flashback_retention_target
NAME TYPE VALUE
------------------------------------ ----------- ---------
db_flashback_retention_target integer 1440
3)重启数据库到mount状态
SQL> shutdown immediate;
Database closed.
Database dismounted.
instance shut down.
SQL> startup mount;
ORACLE instance started.
Total System Global Area 313860096 bytes
Fixed Size 1336232 bytes
Variable Size 239078488 bytes
Database Buffers 67108864 bytes
Redo Buffers 6336512 bytes
Database mounted.
4)在mount状态下启用Flashback功能
SQL> alter database flashback on;
alter database flashback on
*
ERROR at line 1:
ORA-38706: Cannot turn on FLASHBACK DATABASE logging.
ORA-38707: Media recovery is not enabled.
此处报错是由于数据库未运行在归档模式,启用闪回数据库功能的前提是数据库运行在归档模式下。因此需要先调整数据库为归档模式。
SQL> alter database archivelog;
Database altered.
SQL> alter database flashback on;
Database altered.
闪回数据库开启成功。
5)打开数据库
SQL> alter database open;
Database altered.
6)验证Flashback功能已经成功开启
SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------
YES
其他需要修改的系统参数
undo_management,参数需要是“AUTO”,保证回滚段使用模式是SMU mode
undo_retention,单位是秒,调整可回滚的时间范围
原理
闪回表(Flashback table)与闪回查询(Flashback query)的原理大致相同,也是利用undo信息来恢复表对象到以前的某一个时间点(一个快照),因此也要确
保AUM(automatic undo management)有足够的Retention值。Flashback table技术是以Undo segment中的内容为基础的, 因此受限于UNDO_RETENTON参数。要
使用flashback 的特性,必须启用自动撤销管理表空间。
但闪回表不等于闪回查询,其区别如下:
闪回查询只是查询以前的一个快照而已,并不改变当前表的状态。
闪回表则是将恢复当前表及附属对象一起回到以前的时间点。
特性:
1. 在线操作
2. 恢复到指定的时间点(或者SCN)的任何数据
3. 自动恢复相关属性
4. 满足分布式的一致性
5. 数据的一致性,所有相关对象将自动一致。
语法:
SQL> flashback table flashback_table_test to timestamp to_timestamp('2012-12-29 16:44:17', 'yyyy-mm-dd hh24:mi:ss');
SQL> flashback table flashback_table_test to scn 662421;
SQL> flashback table flashback_table_test to timestamp to_timestamp('2012-12-29 16:44:17', 'yyyy-mm-dd hh24:mi:ss') enable triggers;
运用闪回表前提:
1,普通用户中需要有Flashback any table的系统权限。命令如:
2.,有该表的select、insert、delete、alter权限。
3,必须保证该表有row movement(行移动)。
下面是具体的实验:
SQL> show parameter undo
NAME TYPE VALUE
------------------------------------ ---------------------- ------------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
1)创建flashback_table_test表
SQL> conn hr/hr
Connected.
SQL> create table flashback_table_test as select * from employees;
Table created.
2)查询flashback_table_test表中数据量
SQL> select count(*) from flashback_table_test;
COUNT(*)
----------
107
3)为flashback_table_test表创建索引和触发器(触发器为null,不做任何操作)
SQL>create index ind_test on flashback_table_test(employee_id);
SQL> create or replace trigger tr_test
after update on flashback_table_test
for each row
begin
null;
end
tr_test;
/
Trigger created
4)记录当时的时间点,试图恢复到该时间点(如果是普通用户需要有execute on dbms_flashback 的权限)
SQL> select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss') time, to_char(dbms_flashback.get_system_change_number) scn from dual;
TIME SCN
-------------------------------------- --------------------------------------------------------------------------------
2012-12-29 16:44:17 662421
也可以通过下面得到SCN(只不过查出来的scn号会加1,有点类似于sequence.nextval的用法,普通用户需要有select on v_$database的权限,v$databse 是同义词指向v_$database)
SQL> SELECT current_scn from v$database;
CURRENT_SCN
-----------
662403
5)删除flashback_table_test表中数据
SQL> delete from flashback_table_test;
107 rows deleted.
SQL> commit;
Commit complete.
6)查询删除数据后的flashback_table_test,确定其表中已没有数据
SQL> select count(*) from flashback_table_test;
COUNT(*)
----------
0
7)删除flashback_table_test表中索引ind_test
SQL> drop index ind_test;
Index dropped
8)更改tr_test触发器
SQL> create or replace trigger tr_test
after insert on flashback_table_test
for each row
begin
null;
end
tr_test;
/
Trigger created
9)确保该表中的行迁移(row movement)功能
SQL> alter table flashback_table_test enable row movement;
Table altered
10)恢复flashback_table_test表到刚记录的时间点(或scn),由于表中存在触发器,因此使用了关键字enable triggers;
SQL> flashback table flashback_table_test to timestamp to_timestamp('2012-12-29 16:44:17', 'yyyy-mm-dd hh24:mi:ss') enable triggers;
Flashback complete.
11.查看恢复结果如下:(数据回来了)
SQL> select count(*) from flashback_table_test;
COUNT(*)
----------
107
但是索引没有回来
SQL> select index_name from user_indexes where table_name = 'FLASHBACK_TABLE_TEST';
INDEX_NAME
------------------------------
SQL> select object_name, status from user_objects where object_name in('TR_TEST', 'IND_TEST');
OBJECT_NAME STATUS
------------------------------ --------------
TR_TEST VALID
SQL> set pages 0
SQL> set line 100
SQL> set long 2000
SQL> select text from user_source t where t.name = 'TR_TEST';
trigger tr_test
after insert on flashback_table_test
for each row
begin
null;
end
tr_test;
7 rows selected.
总结:
1. Flashback table在真正的高可用环境中,使用意义不大,受限比较多,要必须确保行迁移功能
2. Flashback table过程中,阻止写操作
3. 使用flashback table可以将delete方式删除的表闪回到之前某个时间点,而表中索引却不能正常恢复,因为drop索引的过程是不记录undo的。
4. 恢复的触发器本身还是修改后的,并不随表flashback到修改以前的时间点。说明关键字enable triggers只能保证触发器的状态正常,而不是内容回滚.
5. 由于原理利用其undo信息,来恢复其对象,因此也是不能恢复truncate数据
6. 恢复数据用flashback query实现比较好
7,flashback table功能不能够将被truncate的表内容恢复出来,原因也是truncate操作过程是不记录undo信息。
其他注意:
1.当闪回删除操作之前,如果某个键值如主键被重用,将导致违反主键约束,闪回失败。
2.若闪回所需要的UNDO信息不存在,将引发ORA-08180:no snapshot found based on specified time(未找到基于指定时间的快照)错误
3.如果受闪回影响的记录被其它用户锁定,将引发ORA-00054:resource busy and acquire with NOWAIT specified (资源忙碌)错误
4.表定义在闪回期间不能发生变化,否则导致ORA-01466:unable to read data - table definition has changed(表定义已变化)错误
5.闪回前未启用row movement,将收到ORA-08189: cannot flashback the table because row movement is not enabled 错误
6.对于存在参照关系的情况,建议将主表等一起实施闪回,否则,将收到ORA-02091: transaction rolled back,ORA-02291错误
7.SYS 模式中的表不能使用表闪回技术