闪回查询之闪回表查询

闪回表查询:
从概念上说,闪回表很简单。oracle将会查询撤销段以提取已更改的所有行,然后构造并执行将会取消更改的语句。闪回操作是一个单独的事务,如果可能,它就会抵消以前所有事务的效果。数据库仍然保持联机并且正常的运行不受影响,除非行锁定成为一个问题。
表闪回只是另一个事务,通常的规则仍适用。不同于正常处理的唯一之处是, 表上的触发器对闪回操作默认是禁用的。
表闪回经常涉及一个存在外键关系的表,在这种情况下,几乎不可避免的是闪回操作会因为违反约束而失败。为了避免这个问题,语法支持用一条命令闪回多个表。
启用闪回的第一步是在表上支持行移动。

测试表employees和departments
向表中插入一行数据:
HR@orcl 08-OCT-14>insert into departments values(300,'SUPPORT',NULL,1700); 

1 row created. 

HR@orcl 08-OCT-14>insert into employees values(800,'WATSON','JANE','JWHALE','650.507.9833','13-JAN-08','SH_CLERK',2600,NULL,124,300); 

1 row created.

查看当前的时间,注意要设置好时间格式,如果时间格式不正确,那么后面进行表闪回会出现找不到snapshot的错误:
HR@orcl 08-OCT-14>alter session set nls_date_format='yy-mm-dd hh24:mi:ss'; 

Session altered. 

HR@orcl 14-10-08 07:26:28>select sysdate from dual; 

SYSDATE 
----------------- 
14-10-08 07:26:33

接下来删除该部门和员工,要注意先删除员工以避免违反约束:
HR@orcl 14-10-08 06:59:05>delete from departments where department_id=300; 
delete from departments where department_id=300 

ERROR at line 1: 
ORA-02292: integrity constraint (HR.EMP_DEPT_FK) violated - child record found

HR@orcl 14-10-08 07:01:15>delete from employees where employee_id=800; 

1 row deleted. 

HR@orcl 14-10-08 07:01:56>delete from departments where department_id=300; 

1 row deleted. 

HR@orcl 14-10-08 07:02:11>commit; 

Commit complete.

现在尝试将表闪回到该部门和员工存在的时刻:
HR@orcl 14-10-08 07:02:14>flashback table employees to timestamp to_timestamp('14-10-08 06:59:05','yy-mm-dd hh24:mi:ss'); 
flashback table employees to timestamp to_timestamp('14-10-08 06:59:05','yy-mm-dd hh24:mi:ss') 

ERROR at line 1: 
ORA-08189: cannot flashback the table because row movement is not enabled 

可以看到该操作会失败,因为默认情况下没有为任何表 启用行移动(作为表闪回的前提条件):
HR@orcl 14-10-08 07:04:25>select table_name, row_movement from  user_tables; 

TABLE_NAME ROW_MOVE 
------------------------------ -------- 
LOCATIONS DISABLED 
LOC DISABLED 
T DISABLED 
RETRIED_EMPS DISABLED 
REGIONS_BACKUP DISABLED 
COUNTRIES DISABLED 
SYS_TEMP_FBT DISABLED 
EMPLOYEES  DISABLED 
REGIONS  DISABLED 
DEPARTMENTS DISABLED 
JOB_HISTORY DISABLED 

TABLE_NAME ROW_MOVE 
------------------------------ -------- 
JOBS DISABLED 

12 rows selected. 

HR@orcl 14-10-08 07:05:04>alter table employees  enable row movement; 

Table altered. 

HR@orcl 14-10-08 07:06:37>alter table departments enable row movement; 

Table altered.

HR@orcl 14-10-08 07:06:48>select table_name,row_movement from user_tables; 

TABLE_NAME ROW_MOVE 
------------------------------ -------- 
LOCATIONS DISABLED 
LOC DISABLED 
T DISABLED 
RETRIED_EMPS DISABLED 
REGIONS_BACKUP DISABLED 
COUNTRIES DISABLED 
SYS_TEMP_FBT DISABLED 
EMPLOYEES ENABLED 
REGIONS DISABLED 
DEPARTMENTS ENABLED 
JOB_HISTORY DISABLED 

TABLE_NAME ROW_MOVE 
------------------------------ -------- 
JOBS DISABLED 

12 rows selected.


再次尝试闪回:
HR@orcl 14-10-08 07:28:46>flashback table employees to timestamp to_timestamp('14-10-08 07:26:33','yy-mm-dd hh24:mi:ss'); 
flashback table employees to timestamp to_timestamp('14-10-08 07:26:33','yy-mm-dd hh24:mi:ss') 

ERROR at line 1: 
ORA-02091: transaction rolled back 
ORA-02291: integrity constraint (HR.EMP_DEPT_FK) violated - parent key not found

这一次造成失败的原因更加微妙。闪回试图通过插入此员工来取消对员工800的删除---但是员工800属于部门300,已经删除了该部门而不存在它。因此,违反了外键约束。要避免此问题可以首先闪回departments表,这样可以插入部门300.但是,如果闪回涉及多个表和许多DML语句,那么在逻辑上很难找到一个生效的顺序。解决方法就是一起闪回两个表:
HR@orcl 14-10-08 07:30:39>flashback table employees,departments to timestamp to_timestamp('14-10-08 07:26:33','yy-mm-dd hh24:mi:ss'); 

Flashback complete. 

这样闪回会成功,因为一个事务中同时闪回了两张表,并且仅在该事务的结尾检查约束---到那时候数据在逻辑上是一致的。

HR@orcl 14-10-08 07:33:48>select * from employees where employee_id=800; 

EMPLOYEE_ID FIRST_NAME LAST_NAME EMAIL PHONE_NUMBER HIRE_DATE JOB_ID SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID 
----------- -------------------- ------------------------- ------------------------- -------------------- ----------------- ---------- ---------- -------------- ---------- ------------- 
800 WATSON JANE JWHALE 650.507.9833 13-01-08 00:00:00 SH_CLERK 2600 124 300

HR@orcl 14-10-08 07:36:24>select * from departments where department_id=300; 

DEPARTMENT_ID DEPARTMENT_NAME MANAGER_ID LOCATION_ID 
------------- ------------------------------ ---------- ----------- 
300 SUPPORT 1700

闪回也可能由于其他原因失败:
1.如果在删除和闪回之间重用了键值,就会出现主键约束。
2.如果没有足够的撤销信息返回到请求的时间,就会引起一个错误 ORA-08180,"No snapshot found based on specified time"。
3.如果其他用户锁定闪回用户的任何行,则闪回会失败并给出一条信息: ORA-00054:"Resource busy and acquire with NOWAIT specified"。
4.表定义在考察期间内不能改变-------闪回不能跨越DDL,试图这样做会产生错误: ORA-01446:"Uable to read data---table definition has changed".
5.闪回不适用于处于SYS模式下的表,试着想象一下闪回部分数据字典的结果。

如果闪回由于任何原因失败了,就会取消闪回操作:将回滚成功执行的任何一部分操作,并且表将处于闪回命令发出之前的状态。





来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29800581/viewspace-1314431/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/29800581/viewspace-1314431/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值