--1.造测试数据
create table tmp_wrh_flashbak_test(id number not null,name varchar2(10));
insert into tmp_wrh_flashbak_test (id,name)
select 1,'a' from dual
union
select 2,'b' from dual
union
select 3,'c' from dual;
--2.
select * from tmp_wrh_flashbak_test;
select sysdate from dual;--2018/3/13 17:13:52
delete from tmp_wrh_flashbak_test t where t.id=3;
commit;
select * from tmp_wrh_flashbak_test;
select sysdate from dual;--2018/3/13 17:14:52
--3.启用行移动功能
alter table tmp_wrh_flashbak_test enable row movement;
--闪回恢复
Flashback table tmp_wrh_flashbak_test to timestamp to_timestamp('2018/3/13 17:13:52','yyyy-mm-dd hh24:mi:ss');
--查看,恢复成功
select * from tmp_wrh_flashbak_test;
转载
11g的flashbackup 分好几种,分别用途不一样。
A.flashback database 闪回数据库,简单理解就是把数据库闪回到某个以前的时间点,
能恢复到的最早的SCN, 取决与Flashback Log中记录的最早SCN
B.flashback drop 回收数据库表,用于表误drop后恢复。类似Windows的回收站。
C.flashback query 闪回表记录,用于数据表记录的恢复
D.falshabck Table 闪回数据库表,
后两个是重点,下面说明。
*/
– A.flashback database相关
/*
1.默认情况数据库的flashback database是关闭,可以在mount exclusive状态下打开。
在设置了闪回恢复区后,可以启动闪回数据库功能。
*/
–1.检查是否启动了flash recovery area
show parameter db_recovery_file
–2.检查是否启用了归档
archive log list;
–3.flashback database 默认是关闭的,查看方法
select flashback_on from v$database;
–4.查询当前的scn
SELECT CURRENT_SCN FROM V$DATABASE;
–5.查询当前的时间
select to_char(sysdate,’yy-mm-dd hh24:mi:ss’) time from dual;
–6.查看SCN 和 timestamp 之间的对应关系:
select scn,to_char(time_dp,’yyyy-mm-dd hh24:mi:ss’)from sys.smon_scn_time;
–7.恢复到时间点,或者恢复到SCN
flashback database to timestamp to_timestamp(’09-10-14 14:37:05′,’yy-mm-dd hh24:mi:ss’);
flashback database to scn 947921;
– B. flashback table 恢复误drop表
drop table sphsy.login_table;
select * from flash_table;
–purge table sphsy.login_table;清空回收站
flashback table sphsy.login_table to before drop;
select * from sphsy.login_table;
– C. flashback query 实现行级恢复
/*
flashback查询用于获取先前时间点的表行级数据。当使用flashback查询时,
需要在表名后指定as of timestamp子句或as of SCN子句,其中as of timestamp用于指定早期时间点,
而as of SCN用于指定早期的SCN值,示例如下:
*/
– 1.查原始记录 ,区间内有62 行
select *
from sphsy.login_table a
where a.id > 201204171078
and a.id < 201204171141
order by a.id ;
– 2.晚于区间的有 3016
select program,count(*)
from sphsy.login_table a
where a.id >= 201204171141
group by program ;
–3. 删除
delete from sphsy.login_table a
where a.id > 201204171078
and a.id < 201204171141
–4.利用闪回特性查到区间内,有62行
select * from sphsy.login_table
as of timestamp to_timestamp(’2012-04-17 17:20:30′,’YYYY-MM-DD HH24:MI:SS’)
where id > 201204171078
and id < 201204171141
– 5.不利用闪回特性,直接查询发现没有
select * from sphsy.login_table
where id > 201204171078
and id < 201204171141
– 6.进行数据恢复
– 禁止表上的触发器
alter trigger sphsy.T_INS_LOGIN_TABLE disable ;
– 恢复数据
insert into sphsy.login_table
select * from sphsy.login_table
as of timestamp to_timestamp(’2012-04-17 17:20:30′,’YYYY-MM-DD HH24:MI:SS’)
where id > 201204171078
and id < 201204171141
– 恢复触发器
alter trigger sphsy.T_INS_LOGIN_TABLE enable ;
– 7.晚于区间的数据回来了3130 = 3016 +62 + 后来的数据。实现了区间恢复误删除。
select program,count(*)
from sphsy.login_table a
where a.id >= 201204171078
group by program ;
– D. flashback table 恢复表到先前状态
/*
flashback查询可以用于恢复被误删除的表行数据,但是用户在表上执行了其他的DML语句误操作(insert或update),则不能直接使用flashback查询将表数据恢复到先前时间点,从oracle10g开始,使用flashback table语句可以将表恢复到先前时间点,通过使用该特征,可以避免执行基于时间点的不完全恢复,注意如果要在某个表上使用flashback table特征,则要求必须具有以下条件:
a.用户必须具有flashback any table系统权限或flashback对象权限
b.用户必修在表上具有select insert delete和alter权限
c.必须合理设置初始化参数undo_retention,以确保UNDO信息保留足够时间
d.必须激活行移动特征:alter table table_name enable row movement;
*/
– 1.查原始记录 ,区间内有62 行
select *
from sphsy.login_table a
where a.id > 201204171078
and a.id < 201204171141
order by a.id ;
– 2.晚于区间的有 3074
select count(*)
from sphsy.login_table a
where a.id >= 201204171141;
–3. 删除 ,先记下时间点,2012-04-17 17:43:46
select to_char(sysdate,’YYYY-MM-DD HH24:MI:SS’) from dual ;
delete from sphsy.login_table a
where a.id > 201204171078
and a.id < 201204171141
– 4.删除之后表 sphysy.login_table继续有修改 ,行3082
select count(*)
from sphsy.login_table a
where a.id >= 201204171141;
–5.激活行移动特征
alter table sphsy.login_table enable row movement
–6.利用闪回特性,直接恢复到删除时间点前
flashback table sphsy.login_table to timestamp to_timestamp(’2012-04-17 17:43:46′,’YYYY-MM-DD HH24:MI:SS’);
– 7.晚于区间的数据 回到了3080 ,说明时间点之后的修改丢失。
select count(*)
from sphsy.login_table a
where a.id >= 201204171141
– 8.往前推1分,恢复到删除之前,删除的62条也回来了。
flashback table sphsy.login_table to timestamp to_timestamp(’2012-04-17 17:40:46′,’YYYY-MM-DD HH24:MI:SS’);
– 62 行
select count(*)
from sphsy.login_table a
where a.id > 201204171078
and a.id < 201204171141
– 删除之后的数据为3074,代表还有修改丢失。
select count(*)
from sphsy.login_table a
where a.id >= 201204171141
--------------------------------------------------------------------------------------------------------------------------------------------------------------
1.基本概念
Flashback(闪回)
实现从回滚段中读取表一定时间内操作过的数据,可用来进行数据比对,或者恢复意外提交造成的错误数据,该项特性也被称为Flashback(闪回)。
回滚段:回滚段用于存放数据修改之前的值。
Oracle delete数据或drop表时,并不是直接删除,而是像windows系统会把数据先放到回收站,
使用SELECT * FROM user_recyclebin,可以查看被删除的表或索引等
2.恢复表中误删除的记录
前提:1.表的结构未改动;如果在删除后表结构发生改动则不能使用闪回;
2.用户必须有足够的权限
直接用个例子来说明更加直观:
表:
create table TEST1
(
ID NUMBER(10) not null,
CREATE_DATE DATE
)
SQL> select count(*) from test1;
COUNT(*)
----------
57158
SQL> delete test1 where id<1000;
已删除999行。
SQL> select count(*) from test1;
COUNT(*)
----------
56159
SQL>select sysdate from dual;
SYSDATE
--------------
2013-06-03 15:35:57
//开始恢复数据
SQL> alter table test1 enable row movement;//在闪回前必须 启动行移动功能 否则会报错误: ORA-08189: 因为未启用行移动功能, 不能闪回表
表已更改。
SQL> FLASHBACK TABLE test1 TO TIMESTAMP to_timestamp('2013-06-03 15:35:00','yyyy-mm-dd hh24:mi:ss');//注意:恢复时间点必须是在删除数据之前 这里是2013-06-03 15:35:57 之前就可以
闪回完成。
SQL> select count(*) from test1;
COUNT(*)
----------
57158
数据已经恢复成功,57158行 跟未删除前是一样的,如果想看被删除了哪些行(在删除后闪回前):
SELECT * FROM test1 AS OF TIMESTAMP to_timestamp('2013-06-03 15:35:00','yyyy-mm-dd hh24:mi:ss')
MINUS
SELECT * FROM test1
3.恢复被删除的表
SQL> drop table test1;
表已删除。
SQL> flashback table test1 to before drop;
闪回完成。
SQL> select count(*) from test1;
COUNT(*)
----------
57158
当然flashback还可以把整个数据库恢复到一定的时间点,有兴趣可以google下
注意:对 drop table test1 purge;
或 TRUNCATE TABLE test1;
的数据是不能使用flashback恢复的,因为这drop table tableName purge 和truncat操作都不会把数据放到回收站,会直接删除。
/*
总结:方法C,方法D均可以用数据恢复。
方法C安全,恢复麻烦。方法D简单,有可能数据丢失。
*/