介绍
如果你不小心删错了一行或多行数据,并且事务已经提交,没有回滚的可能。此时,你的额头可能已经冒冷汗了,心里想着“完了完了没救了”。我要告诉你的是,在一定条件下,这些数据也能够恢复,这就是Oracle的Flashback Table特性。
在Oracle中,你执行增、删、改、查语句后,无论事务是否提交,Oracle都会将旧值记录到UNDO表空间中。我们的Flashback Table(闪回表)特性,就是用到了UNDO,将旧的数据再从UNDO中“捞”出来。
与UNDO有关的参数有两个,分别是:UNDO_MANAGEMENT和UNDO_RETENTION。
UNDO_MANAGEMENT指定数据库使用的UNDO空间管理模式。它有两个选项,分别是AUTO和MANUAL。当设置为AUTO后,实例会自动管理UNDO空间段;而设置为MANUAL后,实例需要手动管理UNDO段。Oracle强烈建议使用自动段管理。UNDO_MANAGEMENT参数不可动态修改,修改参数后需要重启数据库才会生效。另外值得说的是,手动管理是9i之前的管理方式,11G中默认已经是自动管理方式,不需要去修改它的值,也不建议去修改。
UNDO_RETENTION参数是指定UNDO保留的阈值,阈值可以理解为数据保留时间。例如更新一条记录,UNDO_RETENTION确定的是这条记录的新值和旧值会在UNDO表空间中的最大保留时间,也可以认为是Flashback Table的最大可恢复时间。当记录超过此时间后,UNDO表空间中的记录就可能会被新事务产生的值覆盖掉(如果UNDO管理模式是手动管理的话,则该参数会略有差异,但考虑到现在基本不会有人使用淘汰的手动管理模式,就不再说明差异性)。UNDO_RETENTION在11G中的默认值是900,单位是秒。该参数可以动态修改,不需要重启数据库生效。需要注意的是,即使该参数值为900秒,也不能说明事务的旧值就一定能保留900秒。UNDO_RETENTION参数仅在UNDO表空间有足够空间时才会保留到最后,在事务需要UNDO空间并且UNDO表空间已经不足时,它会重用未过期的空间。这就会导致在闪回时提示“快照过旧”的信息。
语法
FLASHBACK TABLE
[ schema. ] table
[, [ schema. ] table ]...
TO { { { SCN | TIMESTAMP } expr
| RESTORE POINT restore_point
} [ { ENABLE | DISABLE } TRIGGERS ]
| BEFORE DROP [ RENAME TO table ]
} ;
说明:
- schema 表的拥有者
- table 表名
- SCN expr 将表中的数据恢复至指定的系统更改号(SCN)时。
- TIMESTAMP expr 将表中的数据恢复至指定的时间戳时,该时间戳与指定的时间戳可能有3秒的误差。
- RESTORE POINT restore_point 将表中的数据恢复至指定还原点,使用还原点恢复时,必须要先有还原点。
- TRIGGERS 指定在闪回过程中是否启用触发器,默认情况下,Oracle会禁用表的触发器,在闪回完成后,再重新启用定义在表上的所有触发器。
先决条件
- 当前用户必须在闪回的表中具有FLASHBACK权限或者具有FLASHBACK ANY TABLE系统权限。
- 当前用户必须在闪回的表中具有READ或SELECT对象权限,并且还要有INSERT、DELETE和ALTER对象权限。
- 闪回的表必须开启行移动功能。
限制
flashback table对以下情况下无效:
- 闪回表对这些对象无效:表属于簇表;物化视图;高级队列(AQ)表;静态数据字典表;系统表;远程表;对象表;嵌套表;单个表分区或子分区。
- 下面的操作改变了表结构,无法再使用TO SCN或TO TIMESTAMP子句返回到操作前的一段时间:对表进行升级(upgrading);对表进行移动(moving);对表进行截断(truncating);对表添加过约束;将表加入到簇中;修改或删除过列;将列改成加密主键;添加(adding)、删除(dropping)、合并(merging)、分割(splitting)、结合(coalescing)或截断(truncating)表的分区或子分区(除添加范围分区外)
案例
说了这么多,可能你还是不会使用或者不知道怎么使用。接下来就简单看两个使用闪回表恢复表中数据的例子吧!
注意,启用行移动闪回完成时要记得禁用哦!
SCN闪回表
假设,我有一张表testa,表中的数据如下:
此时,我查询当前数据库的SCN号,如下图所示:
查询完毕后,我执行了个语句,将表中全部数据的性别字段改成女,然后提交,伪造误操作。
伪造完成后,再次查询表中的数据可以看到,表中的所有性别字段已经改为女了。
接下来就是见证Flashback Table特性的奇迹之处了。
我们启用testa表的行移动,然后将数据闪回到刚刚的SCN,也就是964219这里,再关闭行移动。
alter table testa enable row movement;
flashback table testa to scn 964219;
ALTER TABLE testa DISABLE ROW MOVEMENT;
执行完闪回后,再次查看表中的数据,会发现表中的数据已经恢复到SCN为964219时的全部数据。
这就是使用SCN进行表的闪回操作了。
TIMESTAMP闪回表
测试TIMESTAMP(时间戳)还是使用testa表,数据依然如下:
在修改之前,查看数据库的当前时间戳。
然后,将表中全部数据的姓名改为张三,然后提交。
模拟误操作后,就可以再次查看testa表中的数据。
testa表中的数据已经被改错后,我们还是使用Flashback Table进行闪回,只不过不同的是,这次我们使用TIMESTAMP闪回。
alter table testa enable row movement;
flashback table testa to timestamp to_timestamp('2021-12-27 20:57:02','yyyy-mm-dd hh24:mi:ss');
ALTER TABLE testa DISABLE ROW MOVEMENT;
执行完后,再次查看testa表即可看到数据已经被闪回了。
至此,使用TIMESTAMP(时间戳)的闪回也完成了。
评论区