一、概述

exp/imp是oracle中的一个逻辑导出和导入工具,假想一个场景,当我们使用exp命令在对用户进行导出的时候,如果该用户中的某些表的数据有修改,或表结构进行了修改,或者表被删除,那么我们导出来的文件是一个什么状态呢?带着这种疑问,做做实验吧。


二、实验环境

oracle数据库版本选择11.2.0.4

在scott用户下面创建如下实验表

Oracle - exp实战_字段

实验包括以下方案

第一批实验(普通导出)

1. 删除表中的部分行

2. truncate表

3. 删除表的字段

4. drop表

第二批实验(加了闪回导出)

5. 删除表中的部分行

6. truncate表

7. 删除表的字段

8. drop表


三、开始实验

第一批实验(普通导出)

1. 删除表中部分行

session 1:

exp system/123456 owner=scott file=scott.dmp log=exp.log

session 2:

delete from z9 where rownum < 9;

commit;

注:当session1开始执行导出的时候,立刻执行session2,即导出的动作发生之后,赶在z9表导出之前就对z9表做相关修改,后面的所有操作都是。

Oracle - exp实战_删除表_02

观察日志可以看到z9表的数据比z8表的数据少了8行,所以在exp命令发出之后,对表的行进行修改,如果该表还没有开始备份,那么导出为删除行之后的状态。


2. truncate表

session 1:

exp system/123456 owner=scott file=scott.dmp log=exp.log

session 2:

truncate table z9;

Oracle - exp实战_oracle_03

在exp命令发出之后,对表进行truncate,如果该表还没有开始备份,那么导出为truncate之后的状态。


3. 删除表的字段

session 1:

exp system/123456 owner=scott file=scott.dmp log=exp.log

session 2:

alter table z9 drop column object_name;

Oracle - exp实战_数据_04

在exp命令发出之后,对表进行字段的修改,如果该表还没有开始备份,那么导出为字段修改之后的状态。


4. drop表

session 1:

exp system/123456 owner=scott file=scott.dmp log=exp.log

session 2:

drop table z9;

Oracle - exp实战_字段_05

表被drop之后,这张表就不会进行备份了


第二批实验(加了闪回导出)

重新创建z9表

create table z9 as select * from t1;

5. 删除表中的部分行

session 1:

date "+%Y%m%d %H:%M:%S"

20191012 15:06:27

exp system/123456 owner=scott file=scott.dmp log=exp.log flashback_time=\"to_timestamp\(\'20191012 15:06:27\'\,\'yyyy-mm-dd hh24:mi:ss\'\)\"

session 2:

delete from z9 where rownum < 9;

commit;

Oracle - exp实战_删除表_06

可以看到导出的数据z8和z9的总行数一致,也就是说导出的数据是在exp命令发出后的一致性快照,对表中数据的修改不会反映到备注中。


6. truncate表

session 1:

date "+%Y%m%d %H:%M:%S"

20191012 15:10:47

exp system/123456 owner=scott file=scott.dmp log=exp.log flashback_time=\"to_timestamp\(\'20191012 15:10:47\'\,\'yyyy-mm-dd hh24:mi:ss\'\)\"

session 2:

truncate table z9;

Oracle - exp实战_数据_07

导出z9失败


7. 删除表的字段

session 1:

date "+%Y%m%d %H:%M:%S"

20191012 15:13:52

exp system/123456 owner=scott file=scott.dmp log=exp.log flashback_time=\"to_timestamp\(\'20191012 15:13:52\'\,\'yyyy-mm-dd hh24:mi:ss\'\)\"

session 2:

alter table z9 drop column object_name;

Oracle - exp实战_数据_08

导出z9失败


8. drop表

session 1:

date "+%Y%m%d %H:%M:%S"

20191012 15:16:05

exp system/123456 owner=scott file=scott.dmp log=exp.log flashback_time=\"to_timestamp\(\'20191012 15:16:05\'\,\'yyyy-mm-dd hh24:mi:ss\'\)\"

session 2:

drop table z9;

Oracle - exp实战_数据_09

导出z9失败


四、结论

Oracle - exp实战_oracle_10

通过以上实验可以看出,exp在导出的时候会先查下该用户下面有哪些表,然后对这些表依次导出,在这期间对表的dml和ddl都会反映到备份中去。

闪回导出时,如果有表的修改,数据库会试图闪回到闪回的时间节点上去,但是如果对表做了ddl操作,比如truncate,alter都会闪回失败,会造成该表的导出失败。