Chinaunix首页 | 论坛 | 博客
  • 博客访问: 894844
  • 博文数量: 101
  • 博客积分: 2256
  • 博客等级: 大尉
  • 技术积分: 1481
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-19 17:52
文章存档

2017年(1)

2013年(2)

2012年(25)

2011年(73)

分类: Oracle

2011-04-19 18:44:58

二.闪回错误的DML操作

前提:oracle版本必须oracle10g以上。
原理:oracle是利用还原段(回滚段)中的数据来进行这一恢复的。

undo_retention参数:提交DML操作之后,该操作所使用的还原段就可以被其他的操作使用了,为

了保证在进行闪回操作时这些数据仍然在还原段中,可以能要重新设置undo_retention参数,该参

数的单位是秒,表示一个事物提交后,该事物的数据至少要在还原段中保留该参数所定义的时间。

实际示例演示这个参数:


SQL> conn as sysdba;
已连接。
SQL> --显示参数;
SQL> show parameter undo_retention;

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_retention integer 900
SQL> --默认是900秒(15分钟),现在改成7200秒(2个小时);
SQL> alter system set undo_retention=7200;

系统已更改。

SQL> show parameter undo_retention;

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_retention integer 7200
SQL> --修改成功;

提示:闪回技术并不能保证两个小时内提交的DML操作一定能恢复,因为还原表空间没用足够的
空间时oracle仍然会使用undo_retention参数要求保留的磁盘空间,即这部分表空间中的数据
有可能被覆盖掉。因为该参数是针对整个数据库的,所以这个参数不能设置的太大。

下面是具体示例如何使用闪回命令恢复数据;
C:/Documents and Settings/jacky>sqlplus/nolog

SQL*Plus: Release 10.2.0.1.0 - Production on 星期六 4月 2 13:30:17 2011

Copyright (c) 1982, 2005, Oracle. All rights reserved.

SQL> conn ;
已连接。
SQL> select * from shandml;

SD SJ ID
---------------------------------------- ---------- ----------
3.18日22点-----3.19日01点 30000 20
3.19日01点-----3.19日04点 30000 21
3.19日04点-----3.19日07点 30000 22
3.19日07点-----3.19日10点 30000 23
3.17日16点-----3.17日19点 30000 24

SQL> update shandml set sj=50000;

已更新5行。

SQL> select versions_xid,sd,sj,id from shandml
2 versions between scn minvalue and maxvalue
3 ;

VERSIONS_XID SD SJ ID
---------------- ---------------------------------------- ---------- ----------
3.18日22点-----3.19日01点 30000 20
3.19日01点-----3.19日04点 30000 21
3.19日04点-----3.19日07点 30000 22
3.19日07点-----3.19日10点 30000 23
3.17日16点-----3.17日19点 30000 24

SQL> --上面输出表示version_xid为空,是因为我们没有提交刚才的dml,现在我们提交;
SQL> commit;

提交完成。

SQL> select versions_xid,sd,sj,id from shandml
2 versions between scn minvalue and maxvalue;

VERSIONS_XID SD SJ ID
---------------- ---------------------------------------- ---------- ----------
07001A00EC010000 3.18日22点-----3.19日01点 50000 20
07001A00EC010000 3.19日01点-----3.19日04点 50000 21
07001A00EC010000 3.19日04点-----3.19日07点 50000 22
07001A00EC010000 3.19日07点-----3.19日10点 50000 23
07001A00EC010000 3.17日16点-----3.17日19点 50000 24
3.18日22点-----3.19日01点 30000 20
3.19日01点-----3.19日04点 30000 21
3.19日04点-----3.19日07点 30000 22
3.19日07点-----3.19日10点 30000 23
3.17日16点-----3.17日19点 30000 24

已选择10行。

SQL> --从上面可以看出SJ这列的值做了修改且相应的version_xid也有了值了,
SQL> --切换到拥有DBA权限的用户,因为jacky有dba的权限,所以不用切换;
SQL> --下面介绍一个新的数据字典flashback_transaction_query;
SQL> col operation for a10
SQL> col undo_sql for a80
SQL> set line 150
SQL> select operation,undo_sql from flashback_transaction_query
2 where xid=hextoraw('07001A00EC010000');

OPERATION UNDO_SQL
---------- ---------------------------------------------------------------------
-----------
UPDATE update "JACKY"."SHANDML" set "SJ" = '30000' where ROWID = 'AAAMrOAAEA
AAAB0AAA';
UPDATE update "JACKY"."SHANDML" set "SJ" = '30000' where ROWID = 'AAAMrOAAEA
AAAB0AAB';
UPDATE update "JACKY"."SHANDML" set "SJ" = '30000' where ROWID = 'AAAMrOAAEA
AAAB0AAC';
UPDATE update "JACKY"."SHANDML" set "SJ" = '30000' where ROWID = 'AAAMrOAAEA
AAAB0AAD';
UPDATE update "JACKY"."SHANDML" set "SJ" = '30000' where ROWID = 'AAAMrOAAEA
AAAB0AAE';
BEGIN

已选择6行。

SQL> --undo_sql表示要恢复到原来的所需执行的语句;
SQL> --看一下表中现在的值;
SQL> select * from shandml;

SD SJ ID
---------------------------------------- ---------- ----------
3.18日22点-----3.19日01点 50000 20
3.19日01点-----3.19日04点 50000 21
3.19日04点-----3.19日07点 50000 22
3.19日07点-----3.19日10点 50000 23
3.17日16点-----3.17日19点 50000 24

SQL> --因为已经提交了,所以SJ的值已经修改了;
SQL> --重要步骤,因为俺突然后悔了,俺想将刚才的DML操作撤销;
SQL> --首先是查询刚刚提交事务的对应的SCN号;
SQL> select operation,start_scn from flashback_transaction_query
2 where xid=hextoraw('07001A00EC010000');

OPERATION START_SCN
---------- ----------
UPDATE 1121240
UPDATE 1121240
UPDATE 1121240
UPDATE 1121240
UPDATE 1121240
BEGIN 1121240

已选择6行。

SQL> --重要时刻,我们要回到查询到的SCN的那个时刻点,来恢复到当时的状态;
SQL> --不过之前先要打开该表的行移动功能,oracle默认是关闭的;
SQL> alter table jacky.shandml enable row movement;

表已更改。

SQL> --然后再执行恢复操作;
SQL> flashback table jacky.shandml to SCN 1121240;

闪回完成。

SQL> --进下来便是验证奇迹的时刻;
SQL> select * from jacky.shandml;

SD SJ ID
---------------------------------------- ---------- ----------
3.18日22点-----3.19日01点 30000 20
3.19日01点-----3.19日04点 30000 21
3.19日04点-----3.19日07点 30000 22
3.19日07点-----3.19日10点 30000 23
3.17日16点-----3.17日19点 30000 24

SQL> --OMG,果然SJ的值已经变回原来的了,看来这个闪回功能还真是有用;呵呵!


补充说明:闪回DML操作还可以闪回到指定的时间;
例如: flashback table jacky.shandml
to timestamp to _timestamp('2011-04-02 13:30:00','yyyy-mm-dd hh24:mi:ss');

提示:对比起来用SCN号恢复更加保险和安全。


阅读(792) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~