相信不少可爱的程序猿都拜读过《数据库从删库到跑路》一书,我们常常会因为需求的无限变更而气得发疯,从而使出毕生所学,删库!可惜,这招威力过猛,杀敌一千自损八百,通常跑路还学不会,最后都自食恶果。好了,回归主题,倘若真的手误删除了数据怎么办?第一时间请冷静下来,别方,还有补救的方法。在Oracle数据库中,可以利用闪回来恢复已经删除的表数据。闪回有两种方法,根据时间和scn号恢复。
根据时间恢复
select * from zhxg_xio_test as of timestamp (systimestamp - interval '5' minute)
其中这里的5
是指5分钟前zhxg_xio_test
表的数据,执行完检查是否存在刚误删的数据,如果有的话导出查询出来的数据,重新导入即可。当然,这样查出来的数据不仅包括被误删的数据,还有未删的数据,想要查询出被删的也不难,如下:
select * from zhxg_xio_test as of timestamp (systimestamp - interval '5' minute)
where testid not in (
select testid from zhxg_xio_test
)
这样就能把5分钟前的该表与现在的表做对比,把现在表没有的数据,既被删除的查询出来。查询出来的结果直接利用plsql等工具直接导出,然后重新导进此表。当然,也可以
利用scn号恢复
select current_scn from v$database;
利用这条语句可以查询到目前的scn号,下面演示下如何用scn号恢复数据,其实具体理解跟以上用时间恢复差不多。首先我们查看一开始表中的数据
select * from zhxg_xio_test;
这是原来表中的全部数据
再查看目前的scn号
select current_scn from v$database;
输出34128886129
然后执行删除其中一条数据
delete from zhxg_xio_test where testid = '002';
再查看一次目前的scn号
select current_scn from v$database;
此时输出34128886252
,会发现scn号比上一次的34128886129
增加了不少,其实在每一次的操作后数据库都会自动对scn号增加的。相反,我们可以利用scn号的递减来查看执行删除操作之前的数据,具体操作如下:
select * from zhxg_xio_test as of scn 34128886129;
其中34128886129
是一开始查询时的scn号,查询出来发现数据就是一开始的样子
当然,在真正的环境中并不知道在执行删除操作之前的scn号,只能手动慢慢递减scn号去查询,比如可以从34128886240
再到34128886230
等慢慢递减。那么同理,相应的也可以只查询出被删除的数据
select * from zhxg_xio_test as of scn 34128886129 where testid not in (
select testid from zhxg_xio_test
);
被删除的数据
然后导出成sql脚本,再重新导入即可恢复。