原文转载自:http://systmet.com/forum.php?mod=viewthread&tid=297&fromuid=4
上周软件供应商的工程师在给更新系统是,不小心更新错oracle数据库的表了,好在系统不是很繁忙而且这个表示一个维护用的表,不影响业务的正常运行。
碰到这类的事情确实很悲剧,但是作为一个技术人员。只有在这个时候才能体现出价值。
恢复这个表可以通过备份恢复,可以通过oracle的flashback来恢复。
通过备份恢复可以比较麻烦,而且耗时较长。而flashback比较快捷,而且简单。
我们来模拟一下这个过程。
SQL> conn /as sysdba
已连接。
创建测试用户,并赋权
SQL> create user test identified by test;
用户已创建。
SQL> SQL>
SQL> grant resource,connect to test;
授权成功。
SQL> conn test/test;
已连接。
创建测试所用的表
SQL> create table t1 as select * from all_objects;
表已创建。
SQL> select count(*) from t1;
COUNT(*)
----------
40703
SQL> select count(*) from t1 where owner='SYSTEM';
COUNT(*)
----------
9
SQL> host date
Mon Apr 8 14:03:42 CST 2013
SQL> update t1 set owner='test' where owner='SYSTEM';
已更新9行。
SQL> commit;
提交完成。
SQL> host date
Mon Apr 8 14:05:41 CST 2013
SQL> SELECT COUNT(*) FROM t1 where owner='SYSTEM';
COUNT(*)
----------
0
SQL> select count(*) from t1 where owner='test';
COUNT(*)
----------
9
如果现在接到通知说update错乱,需要技术支持,大概操作时间是14点5分左右,
SQL> host date
Mon Apr 8 14:11:30 CST 2013
使用flashback query,查询中能个时间点能找到正确的数据
SQL> select count(*) from t1 as of timestamp to_timestamp('2013-04-08 14:10:00','YYYY-MM-DD HH24:MI:SS') where owner='SYSTEM';
COUNT(*)
----------
0
SQL> c/10/08/
1* select count(*) from t1 as of timestamp to_timestamp('2013-04-08 14:08:00','YYYY-MM-DD HH24:MI:SS') where owner='SYSTEM'
SQL> /
COUNT(*)
----------
0
SQL> select count(*) from t1 as of timestamp to_timestamp('2013-04-08 14:04:00','YYYY-MM-DD HH24:MI:SS') where owner='SYSTEM';
COUNT(*)
----------
9
我们在14:04找到数据,有开发人员验证这些数据是不是之前的数据,如果没问题,下面就可以flashback操作了。
SQL> select * from t1 as of timestamp to_timestamp('2013-04-08 14:04:00','YYYY-MM-DD HH24:MI:SS') where owner='SYSTEM';
OWNER OBJECT_NAME
------------------------------ ------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- -------------------
CREATED LAST_DDL_TIME TIMESTAMP STATUS T G S
-------------- -------------- ------------------- ------- - - -
SYSTEM DEF$_TEMP$LOB
4947 4947 TABLE
20-4月 -10 20-4月 -10 2010-04-20:08:25:40 VALID N N N
SYSTEM OL$
5522 TABLE
20-4月 -10 20-4月 -10 2010-04-20:08:26:19 VALID Y N N
OWNER OBJECT_NAME
------------------------------ ------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- -------------------
CREATED LAST_DDL_TIME TIMESTAMP STATUS T G S
-------------- -------------- ------------------- ------- - - -
SYSTEM OL$HINTS
5523 TABLE
20-4月 -10 20-4月 -10 2010-04-20:08:26:19 VALID Y N N
SYSTEM OL$NODES
5526 TABLE
OWNER OBJECT_NAME
------------------------------ ------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- -------------------
CREATED LAST_DDL_TIME TIMESTAMP STATUS T G S
-------------- -------------- ------------------- ------- - - -
20-4月 -10 20-4月 -10 2010-04-20:08:26:19 VALID Y N N
SYSTEM PRODUCT_PRIVS
10443 VIEW
20-4月 -10 20-4月 -10 2010-04-20:08:30:09 VALID N N N
SYSTEM HELP
OWNER OBJECT_NAME
------------------------------ ------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- -------------------
CREATED LAST_DDL_TIME TIMESTAMP STATUS T G S
-------------- -------------- ------------------- ------- - - -
10447 10447 TABLE
20-4月 -10 20-4月 -10 2010-04-20:08:30:09 VALID N N N
SYSTEM MVIEW$_ADV_INDEX
46943 46943 TABLE
20-4月 -10 20-4月 -10 2010-04-20:08:37:00 VALID N N N
OWNER OBJECT_NAME
------------------------------ ------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- -------------------
CREATED LAST_DDL_TIME TIMESTAMP STATUS T G S
-------------- -------------- ------------------- ------- - - -
SYSTEM MVIEW$_ADV_PARTITION
46944 46944 TABLE
20-4月 -10 20-4月 -10 2010-04-20:08:37:00 VALID N N N
SYSTEM MVIEW$_ADV_OWB
46945 TABLE
20-4月 -10 20-4月 -10 2010-04-20:08:37:00 VALID Y N N
OWNER OBJECT_NAME
------------------------------ ------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- -------------------
CREATED LAST_DDL_TIME TIMESTAMP STATUS T G S
-------------- -------------- ------------------- ------- - - -
已选择9行。
SQL> flashback table t1 to timestamp to_timestamp('2013-04-08 14:04:00','YYYY-MM-DD HH24:MI:SS');
flashback table t1 to timestamp to_timestamp('2013-04-08 14:04:00','YYYY-MM-DD HH24:MI:SS')
*
第 1 行出现错误:
ORA-08189: 因为未启用行移动功能, 不能闪回表
SQL> alter table t1 enable row movement;
表已更改。
SQL> flashback table t1 to timestamp to_timestamp('2013-04-08 14:04:00','YYYY-MM-DD HH24:MI:SS');
闪回完成。
已经闪回完成,验证数据。
SQL> select * from t1 where owner='SYSTEM';
OWNER OBJECT_NAME
------------------------------ ------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- -------------------
CREATED LAST_DDL_TIME TIMESTAMP STATUS T G S
-------------- -------------- ------------------- ------- - - -
SYSTEM PRODUCT_PRIVS
10443 VIEW
20-4月 -10 20-4月 -10 2010-04-20:08:30:09 VALID N N N
SYSTEM HELP
10447 10447 TABLE
20-4月 -10 20-4月 -10 2010-04-20:08:30:09 VALID N N N
OWNER OBJECT_NAME
------------------------------ ------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- -------------------
CREATED LAST_DDL_TIME TIMESTAMP STATUS T G S
-------------- -------------- ------------------- ------- - - -
SYSTEM DEF$_TEMP$LOB
4947 4947 TABLE
20-4月 -10 20-4月 -10 2010-04-20:08:25:40 VALID N N N
SYSTEM MVIEW$_ADV_INDEX
46943 46943 TABLE
OWNER OBJECT_NAME
------------------------------ ------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- -------------------
CREATED LAST_DDL_TIME TIMESTAMP STATUS T G S
-------------- -------------- ------------------- ------- - - -
20-4月 -10 20-4月 -10 2010-04-20:08:37:00 VALID N N N
SYSTEM MVIEW$_ADV_PARTITION
46944 46944 TABLE
20-4月 -10 20-4月 -10 2010-04-20:08:37:00 VALID N N N
SYSTEM MVIEW$_ADV_OWB
OWNER OBJECT_NAME
------------------------------ ------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- -------------------
CREATED LAST_DDL_TIME TIMESTAMP STATUS T G S
-------------- -------------- ------------------- ------- - - -
46945 TABLE
20-4月 -10 20-4月 -10 2010-04-20:08:37:00 VALID Y N N
SYSTEM OL$
5522 TABLE
20-4月 -10 20-4月 -10 2010-04-20:08:26:19 VALID Y N N
OWNER OBJECT_NAME
------------------------------ ------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- -------------------
CREATED LAST_DDL_TIME TIMESTAMP STATUS T G S
-------------- -------------- ------------------- ------- - - -
SYSTEM OL$HINTS
5523 TABLE
20-4月 -10 20-4月 -10 2010-04-20:08:26:19 VALID Y N N
SYSTEM OL$NODES
5526 TABLE
20-4月 -10 20-4月 -10 2010-04-20:08:26:19 VALID Y N N
OWNER OBJECT_NAME
------------------------------ ------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- -------------------
CREATED LAST_DDL_TIME TIMESTAMP STATUS T G S
-------------- -------------- ------------------- ------- - - -
已选择9行。
SQL>
oracle 10g提供三种闪回方式
1.flashback query 闪回查询,这种不实际修改表的数据,只是能够查询早期的数据
2.flashback table 闪回表格,把表恢复到早期的一个时间点
3.flash database 闪回数据库,这个动静比较大,类似于不完全恢复
flashback query和flashback table都是使用undo表空间的数据,不要开启数据库的flashback功能就可以使用。
但是受到undo_retention的影响,默认是1440分钟也就是一天。
select和flashback都可以使用as of timestamp或 as of scn这两种方式中的任一种,timestamp早期的一个时间点,scn是早期的一个scn号。这里的select是通过undo表空间的数据构造一份 镜像数据。而flashback把表恢复到之前的一个时间点。
timestamp和scn直接可以相互转化,这个可以参照http://www.eygle.com/archives/2007/01/scntimestamp_function.html
flashback table常用的几个语法
1.flashback table table_name to timestamp ....
2.flash table table_name to scn ...
3.flashback table table_name to timestamp ... enable triggers
4.flashback table testFlashTable to timestamp systimestamp - interval '10' minute;
flashback table可以闪回已经drop的表。
删除刚刚使用的测试表t1
SQL> drop table t1;
表已删除。
现在查询就会发现这个表已经不存在了
SQL> select * from t1;
select * from t1
*
第 1 行出现错误:
ORA-00942: 表或视图不存在
但是这个表并没有从数据库中彻底删除,而是移动到了回收站,并分配了一个新名字
SQL> show recyclebin;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
T1 BIN$2dS79kJZfhDgQKjAeKN7Vg==$0 TABLE 2013-04-08:14:42:01
把数据库t1闪回到drop之前的状态
SQL> flashback table 'BIN$2dS79kJZfhDgQKjAeKN7Vg==$0' to before drop;
flashback table 'BIN$2dS79kJZfhDgQKjAeKN7Vg==$0' to before drop
*
第 1 行出现错误:
ORA-00903: 表名无效
单引号报错,使用双引号就正常了。
SQL> flashback table "BIN$2dS79kJZfhDgQKjAeKN7Vg==$0" to before drop;
闪回完成。
SQL> select count(*) from t1;
COUNT(*)
----------
40703
SQL>
闪回drop掉的表是还可以使用flashback table t1 to before drop;