select * from TBL_A as of timestamp to_timestamp('2018-08-26 09:09:00','yyyy-mm-dd hh24:mi:ss');
但是使用这种闪回查询是有条件的,首先,undo段要足够。我们的数据库默认设置的undo保留时间是900秒,即15分钟,且没有设置guarantee特性,就是说不保证15分钟内发生的事务都在undo里面保存。当数据库不繁忙,undo用的少时,可能我们还可以查得到15分钟甚至更久以前的数据,但是当数据库繁忙的时候,由于undo段是复用的,很可能我们想要闪回查询的数据在undo段里面已经没有了。这个时候,我们越早执行闪回查询,找回数据的概率就越大,并且我们需要创建一张临时表,赶紧先把查询出来的数据写进临时表中,比如刚才如果我们意识到9点10分的操作失误了,要将数据拿回到操作之前的时间点,赶紧建一个临时表
create table TBL_A_BAK as ( select * from TBL_A as of timestamp to_timestamp('2018-08-26 09:09:00','yyyy-mm-dd hh24:mi:ss') );
也可以按SCN闪回查询,不过大家第一反应都是对时间比较敏感,而SCN还是需要查一下。所以对于不慎update、delete表中的数据,大家在联系DBA的同时,第一时间也可以利用闪回查询,抓住这段宝贵的时间点,将数据插回临时表,为后续更加具体细致的恢复工作做好准备。
Recycle Bin
Oracle的Recycle Bin功能与windows的回收站类似,当有表不小心被drop的时候,可以从回收站中拿回来。使用回收站拿回表有3个前提:
(1)数据库的回收站功能是打开着的;
(2)drop table不能使用purge,如果使用了purge是不经回收站的;
(3)回收站可用空间充足,并且没有对回收站进行清理。
比如我们不慎将TBL_A给drop掉了,从回收站可以拿回来,语句也比较简单:
flashback table TBL_A to before drop;
不过还是有注意事项,如果现在生产也已经有了同名的表,那么闪回表的时候需要rename,比如:
flashback table TBL_A to before drop rename to TBL_A_2;
当发现这张表被drop两次了,而我们只想回复其中正确的一次,也是可以的,在这里不详述,具体可以咨询DBA。
所以当不慎drop table的时候,第一时间联系DBA。
expdp
以上两种方法都是应急措施,恢复成功是有条件的。最重要的还是需要在变更的时候有回退方案,比如我们在操作之前对数据先进行备份。建立临时表备份仅限于小表,对于大表,不适用这种方式,一来是速度太慢,二是会耗费数据库表空间,当表空间不足时,业务也会中断。这时我们可以使用oracle的expdp工具,这个工具可以导出指定用户的指定表,指定分区,也可以指定where条件导出想要备份的数据,不仅导出速度快,并且占用的是备份专用的文件系统空间,而不占用宝贵的数据库表空间。当变更完成,安全渡过了观察期之后,我们再将备份文件删除。
俗话说,“有备无患”。人在极度疲惫与极度紧张的时候,判断是会出现些许偏差的,做好备份,做好回退方案,是最好的选择。
最后,在数据恢复完成后,提醒大家检查是否存在索引失效的情况。数据找回来后,也要确保索引正确,才不会影响生产系统。