共计 3151 个字符,预计需要花费 8 分钟才能阅读完成。
impdp 有一个参数选项 TABLE_EXISTS_ACTION,help= y 的解释为:
Action to take if imported object already exists.
Valid keywords are: APPEND, REPLACE, [SKIP] and TRUNCATE.
官方文档有句话:
“Only objects created by the Import will be remapped. In particular, the tablespaces for preexisting tables will not be remapped if TABLE_EXISTS_ACTION is set to SKIP, TRUNCATE, or APPEND.”。
仅仅是 import 创建的对象会被重新映射,如果使用了 SKIP、TRUNCATE 或 APPEND,已存表对应的表空间不会有变化。
官方文档 (Oracle? Database Utilities11g Release 2 (11.2)) 中对这个参数的描述如下:
这个参数目的是为了告诉 impdp,试图创建的表是否在库中已存在。
默认值是 skip,但若设置了 CONTENT=DATA_ONLY,则默认值是 APPEND,不是 SKIP。
TABLE_EXISTS_ACTION=[SKIP | APPEND | TRUNCATE | REPLACE]
SKIP:跳过这张表,继续下一个对象。如果 CONTENT 设置了 DATA_ONLY 参数,则不能使用 SKIP。
APPEND:会加载数据至对象,但不会影响已存在的行。
TRUNCATE:删除已存在的行,然后加载所有的数据。
REPLACE:drop 已存在的表,然后 create 并加载数据。如果 CONTENT 设置了 DATA_ONLY,则不能使用 REPLACE。
还有一些其他的考虑:
1. 使用 TRUNCATE 或 REPLACE,确保所有涉及的表行不会存在其他的参照约束关系。容易理解,例如目标表是和其他表存在外键关联,但只导入这张表,就可能会破坏这种关系。
2. 使用 SKIP,APPEND,TRUNCATE,已存在表的依赖对象,例如索引、grants 授权、触发器和约束,不会被修改。对于 REPLACE,如果依赖对象未被显式或隐式使用 EXCLUDE 排除,并且存在于 dump 文件中,则会 drop 然后 create 重建。
3. 使用 APPEND 或 TRUNCATE,会在执行操作前进行一些检查,以确保源 dump 和已存表兼容,包括:
(1) 若已存在的表有 active 的约束和触发器,就会使用外部表访问的方法加载数据。如果任何行违反了约束,则加载失败,不会有任何数据加载进来。当然,可以使用 DATA_OPTIONS=SKIP_CONSTRAINT_ERRORS 来跳过这环节。
(2) 如果需要加载一些可能会违反约束的数据,可以考虑先 disable 这些约束,加载数据后,删除这些有问题的记录,然后再 enable 约束。
(3) 使用 APPEND,数据会加载至新的空间,即使现有空间仍能重用。可以加载完成后,压缩数据。
另外,如果数据泵发现原表和目标表不匹配 (例如两张表的列数量不同,或者目标表中有一列不在原表中),他会比较两张表的列名。如果两张表至少有一个列相同,则会导入这个列的数据(前提是数据类型兼容)。这种做法也有一些限制,
(a) 如果使用 network 参数导入则不能使用。
(b) 以下列的类型不能删除:列对象、列属性、嵌套表列、基于主键的引用列。
还有就是 TRUNCATE 不能用于聚簇表。
通过对一张表使用以上四种选项的实验,来看看区别。
测试表:
create table test(id number);
insert into test values(1);
commit;
expdp user_exp/user_exp directory=EXPDP_DIR dumpfile=user_exp.dmp
insert into test values(2);
commit;
此时 user_exp.dmp 包含 test 表,且有一条 id= 1 的记录。表中有 id= 1 和 id= 2 两条记录。
REPLACE 选项:
impdp user_exp/user_exp TABLE_EXISTS_ACTION=replace dumpfile=user_exp.dmp directory=expdp_dir
SQL> select * from test;
ID
———-
1
此时表中只有 id= 1 的记录,说明使用 dmp 覆盖了 test 表。
SKIP 选项:
impdp user_exp/user_exp TABLE_EXISTS_ACTION=skip dumpfile=user_exp.dmp directory=expdp_dir
ORA-39151: Table “USER_EXP”.”TEST” exists. All dependent metadata and data will be skipped due to table_exists_action of skip
SQL> select * from test;
ID
———-
1
2
此时导入报错,说明是 skip 了已存在的对象,test 表仍保持原状。
APPEND 选项:
impdp user_exp/user_exp TABLE_EXISTS_ACTION=append dumpfile=user_exp.dmp directory=expdp_dir
ORA-39152: Table “USER_EXP”.”TEST” exists. Data will be appended to existing table but all dependent metadata will be skipped due to table_exists_action of append
SQL> select * from test;
ID
———-
1
2
1
虽然报错,但仍插入了 test 记录,报错提示了数据会 append 附加至已存在表中,但若有依赖关系的元数据,则会忽略。
TRUNCATE 选项:
impdp user_exp/user_exp TABLE_EXISTS_ACTION=truncate dumpfile=user_exp.dmp directory=expdp_dir
ORA-39153: Table “USER_EXP”.”TEST” exists and has been truncated. Data will be loaded but all dependent metadata will be skipped due to table_exists_action of truncate
SQL> select * from test;
ID
———-
1
报错提示对象已被 truncate,但若有依赖关系的元数据,会被忽略。
利用 Oracle 自带的 impdp 和 expdp 进行简单备份 http://www.linuxidc.com/Linux/2016-05/131497.htm
Oracle impdp 的 skip_constraint_errors 选项跳过唯一约束错误 http://www.linuxidc.com/Linux/2016-03/129616.htm
expdp/impdp 使用 version 参数跨版本数据迁移 http://www.linuxidc.com/Linux/2016-01/127524.htm
更多 Oracle 相关信息见Oracle 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=12
本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-05/131838.htm