写这一篇关于数据泵的博客,我一直抱有一种感恩之情,因为数据泵作为一种逻辑导出导入手段,在刚开始接触oracle的时候,军哥给我了大量的指导,所以每次我用到它的时候,都会想起前辈们对我不遗余力的指导。写此篇博客,我将重忆学习历程,对所有帮助过我的前辈们表示真诚的谢意。
特性描述:
oracle数据泵包括expdp导出和impdp导入,它是oracle 10g提供的一个新功能,是对旧的导出(exp)和导入(imp)工具的增强,但是它的特性还远远不止这些,我列出几点:
1、对记录的过滤更为细致,包括
include--正规则,exclude--反规则,query,sample参数来对记录进行过滤;
2、
parallel和filesize参数的结合使用,使得数据泵具有强大的并行处理能力;
3、支持修改schema的属主,表空间和临时表空间的属主;
4、支持暂停和重启导入导出任务。
下面开始正式进入expdp和impdp的学习:(我的测试系统版本是centos6.6)
一、建立directory
SQL> create directory dmp as '/opt/dmp';
注释:directory目录是oracle 10g提供的一个新功能,它是系统目录和实际路径的一个对应,比如在这里,我创建的目录名为dmp,它与/opt/dmp这个物理路径对应,导出数据的时候,我将数据导出到dmp目录,实际上导出文件存储在/opt/dmp。
二、赋予导出用户read,write on directory的权限,同时赋予导出用户expdp和impdp权限
SQL>grant read,write on directory dmp to ceshi;
SQL> grant datapump_exp_full_database,datapump_imp_full_database to ceshi;
注释:关于导出用户,在这里用户名为ceshi,使用ceshi这个用户,只要赋予其权限,它可以导出导入任何schema,tablespace,table等。
如果使用特权用户sys导出,那么必须使用sys导入。
三、expdp导出
(1)导出schema
[oracle@oracledb ~]$ expdp ceshi/*** directory=dmp dumpfile=ceshi0224.dmp logfile=ceshi0224.log
schemas=ceshi
注释:
可以看出,expdp和impdp命令都是系统命令,是在操作系统级别下操作的。expdp 用户名/密码 directory=系统目录 dumpfile=导出文件名字.dmp logfile=导出日志名.log shemas=导出的schema。在这里,用户名/密码 只要具有expdp权限且对指定目录具有读写权限的用户都可以,directory=系统目录 这个是需要将数据导出的位置,它对应了一个实际的物理路径,dumpfile 是导出的数据文件,后缀为.dmp,logfile 是导出日志,后缀为.log,schemas 导出schema用户下的所有对象,如果不指定schemas,默认为执行导出操作用户的schema。在导出完毕的时候,有这样一段JOB "CESHI"."SYS_EXPORT_SCHEMA_01" successfully completed at 01:21:41,其中SYS_EXPORT_SCHEMA_01"是本次expdp的任务名(任务名相关请看下面的job_name和attach参数)。
结果如下:

(2)导出tables,我将会以导出表为例,列出expdp一些参数
<1>tables参数
[oracle@oracledb ~]$ expdp ceshi/*** directory=dmp dumpfile=ceshi0224.dmp logfile=ceshi0224.log tables=ceshi.GER_DIAGNOSIS,ceshi.OP_DRGS_ONLY
注释:tables可以指定导出哪一个chemas下的表
结果如图:

<2>query和sample参数
[oracle@oracledb ~]$ expdp ceshi/*** directory=dmp dumpfile=ge.dmp logfile=ge.log tables=ceshi.GER_DIAGNOSIS,ceshi.GER_OPERATION query=ceshi.GER_DIAGNOSIS:\"where code=\'A16.211\'\" sample=ceshi.GER_OPERATION:50
注释:这个导出的是ceshi.GER_DIAGNOSIS满足 code='A16.211'和ceshi.GER_OPERATION总记录的百分之50,其中query=A:"where",表示对A表进行过滤,双引号(")和单引号(')前都要加转义符(\),sample=B:50,表示取B表50%的记录行。如果没有指定tables参数,那么默认导出该导出用户下的所有对象,只是给query和sample的对象做了过滤。
结果如图:

<3>include和exclude参数
[oracle@oracledb dmp]$ expdp ceshi/*** directory=dmp dumpfile=ge.dmp logfile=ge.log include=table:\"in\(\'ceshi.GER_DIAGNOSIS\',\'ceshi.GER_OPERATION\'\)\"
[oracle@oracledb dmp]$ expdp ceshi/*** directory=dmp dumpfile=ge.dmp logfile=ge.log exclude=table:\"in\(\'ceshi.GER_DIAGNOSIS\',\'ceshi.GER_OPERATION\'\)\"
注释:include(正规则)和exclude(反规则)可以对表,索引和约束等对象进行过滤,这里表示只导出GER_DIAGNOSIS和GER_OPERATION这两张表,当然,exclude=table:A,表示不导出A表。
结果如下:(只贴出include的结果)

<4>parfile参数
[oracle@oracledb tmp]$ expdp ceshi/*** parfile=/tmp/p.txt
注释:parfile参数的使用,可以直接调用已经写好的命令行文本,而不用在界面上写长串的命令,因为界面所能容纳的字符数是有限的,同时由于不同的操作系统对特殊字符的转义,必须在命令行加上转义字符,通过上面就可以看出来,对字符的转义实在是比较麻烦,但是如果写到文本中直接调用,就不用担心不同的平台字符转义问题。
命令行文本如下:
[oracle@oracledb tmp]$ cat p.txt
directory=dmp
dumpfile=ge.dmp
logfile=ge.log
include=table:"in('GER_DIAGNOSIS','GER_OPERATION')"
导出结果如图:

<5>进入交互模式
当正在expdp的时候,可以按ctrl+c进入交互模式,对于ctrl+c后还在执行的任务,可以export>kill_job,中断正在执行的任务,可以export>stop_job,停止当前正在运行的任务,export>start_job,启动停止的任务,export>status查看当前任务的详细状态信息。
如图:

<6>add_file和continue_client参数
Export> add_file=ge02.dmp
Export> continue_client
注释:进入交互模式之后,可以用add_file增加新的dmp文件,在这里还可以对dmp文件名指定命名参数,比如U%,这样如果我指定ge03.dmp,ge04.dmp,expdp命令会根据需要,自动附加序号对文件名进行填充。添加完新的dmp文件之后,可以输入continue_client退出交互界面,进入导出界面。
<7>grants,indexes,constraints,triggers参数
[oracle@oracledb dmp]$ expdp ceshi/*** directory=dmp dumpfile=ger.dmp logfile=ger.log tables=ceshi.GER_DIAGNOSIS,ceshi.GER_OPERATION grants=n
注释:grants指定是否导出对象的授权信息,授权信息指的是通过grant命令授予的对象访问,操作权限,默认为Y,也就是默认导出;indexes指定是否导出表的索引,默认为Y;constraints指定是否导出表的约束,默认为Y;triggers是否导出与表相关的触发器,默认为Y。
<8>filesize和parallel参数
[oracle@oracledb dmp]$ expdp ceshi/*** parfile=/tmp/p.txt filesize=300m parallel=2
注释:这两个参数的结合使用,使得expdp的效率更高,filesize指定每个dmp文件的大小,最大不能超过1G,parallel指定导出的并行度,相当于多个进程同时执行expdp这个任务,速度当然更快,效率也当然更高,建议parallel参数的设置小于或者等于生成的dmp文件个数。
结果如图:(由于导出单个表太小,因此这里导出了整个schema)

<9>network_link和nologfile参数
[oracle@oracledb dmp]$ expdp ceshi/*** directory=dmp dumpfile=link.dmp nologfile=y network_link=to_qj tables=qj.t1,qj.t2
注释:expdp是一个服务端命令,也就是说导出的数据会存在服务器端。但是可以通过network_link参数将远程数据库数据导出到本地,在导出之前,需要建立一个dblink连接到远程数据库,expdp ceshi/ceshi directory=dmp dumpfile=link.dmp 这几个部分不变,执行导出的用户要求为本地用户,nologfile=y的意思是不生成导出日志,默认会生成导出日志,tables表明如果想指定具体的表,需要在表的前面加上远程数据库schema名。
dblink的创建脚本如下:
create public database link to_qj connect to qj identified by qj
using '(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.0.47)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ORCL.168.0.111))
)';
导出结果如图:

<10>job_name和attach参数
通过(1)导出schemas的例子我们可以看到,对于每次的expdp,如果不指定任务名,那么系统会自动生成一个任务名,可以通过job_name参数来显式指定一个任务名。
[oracle@oracledb dmp]$ expdp ceshi/*** directory=dmp dumpfile=link.dmp nologfile=y network_link=to_qj tables=qj.t1,qj.t2,qj.feedback job_name=expdp_qj
结果如图:

对于异常退出,可以通过attach=任务名来重新执行未完成的任务。
[oracle@oracledb dmp]$ expdp ceshi/*** directory=dmp dumpfile=link.dmp nologfile=y network_link=to_qj job_name=expdp_qj
在执行的过成功ctrl+c进入交互模式,然后exit_client退出交互模式,可以通过如下sql来查看异常退出的expdp任务:
select job_name,operation,job_mode,state from user_datapump_jobs;

可以看到,job_name为expdp_qj的任务异常,如果想再次进入导入界面,则使用attach=任务名,来重新连接到未完成的任务
[oracle@oracledb dmp]$ expdp ceshi/*** attach=expdp_qj

可以看到再次进入了交互模式,然后在交互模式输入contiune_client 就可以接着导出数据了
Export> contiune_client
(3)导出表空间
[oracle@oracledb dmp]$ expdp ceshi/*** directory=dmp dumpfile=tbs.dmp nologfile=y tablespaces=ceshi
注释:tablespaces参数可以指定导出固定表空间,对于schemas,tables,tablespaces,如果导出多个,中间以逗号(,)隔开。
(4)导出整个库
[oracle@oracledb dmp]$ expdp ceshi/*** directory=dmp dumpfile=full.dmp nologfile=y full=y
注释:full参数可以指定对于整个库的导出,full=y,表示导出整个数据库,它将会导出这个数据库下的所有对象。
(5)只导出对象的定义,而不导出具体的记录
[oracle@oracledb dmp]$ expdp ceshi/*** directory=dmp dumpfile=ceshi0224.dmp logfile=ceshi0224.log tables=ceshi.GER_DIAGNOSIS,ceshi.OP_DRGS_ONLY content=metadata_only
注释:指定content=metadata_only,表示只导出表的定义,而不导出表的数据。
四、impdp导入
(1)默认导入(适合源库和目标库表空间和用户建立方式一样的情况,比如,建立了一个测试库,结构和生产库类似,需要定期将生产库数据备份到测试库)
[oracle@oracledb dmp]$ impdp imp1/*** directory=dmp dumpfile=ceshi.dmp
注释:ceshi.dmp这个文件是从其他库导出来的(比如从生产库导出的),导出了ceshi这个schema,它所在的表空间名为ceshi(我只是为了方便,将用户名和表空间名起成一样的了,他们之间命名没有任何关系)。拿到从其他库导出来的ceshi.dmp这个二进制文件,到需导入的库进行操作,impdp imp1/imp1 directory=dmp dumpfile=ceshi.dmp的意思是以imp1这个用户(具有impdp权限)将目录dmp中名为ceshi.dmp的文件导入进去,没有其他参数;那就意味着将数据导入到ceshi这个用户,当前库中有没有ceshi这个用户都无所谓,如果有的话直接导入ceshi用户,如果没有ceshi用户,oracle会自动建立一个名为ceshi的用户(不过此用户所在表空间为默认表空间,这一点不太好,用户所在表空间人为控制最好),导入的表空间名必须为ceshi,所以当前库必须已经建立了名为ceshi的表空间,否则默认导入会报错。综上,如果不指定其他参数,那么数据将会导入到和源数据相同的用户和表空间。我对于此种方式还是比较诟病的,一个是目标库和源库用户名和表空间名很可能不同,我不能每次都要建立一个同名表空间;二:如果我当前库没有这个用户,系统自动建立的用户所在表空间很多时候不是我想要的,当然,如果我提前建立用户就可以避免这个问题了。
(2)使用remap_schema和remap_tablespace参数(这两个参数也是数据泵中相当令人欣喜的地方)
[oracle@oracledb ~]$ expdp imp1/*** directory=dmp dumpfile=ceshi.dmp logfile=ceshi.log remap_schema=ceshi:user01 remap_tablespace=ceshi:users
注释:remap_schema参数可以该变数据的属主,这里将ceshi变为了user01,remap_tablespace参数可以改变数据的默认表空间,这里将默认表空间由ceshi改为了users。这样一来,就可以完全对数据的存储位置进行控制,让整个数据的管理更为集中,更为科学化。我个人习惯于使用这种方式导入数据。
结果如图:


(3)content参数
[oracle@oracledb ~]$ expdp imp1/*** directory=dmp dumpfile=ceshi.dmp logfile=ceshi.log content=metadata_only remap_schema=ceshi:user01 remap_tablespace=ceshi:users
注释:content参数,该参数有3个属性值:all(导入对象定义和数据,该参数的默认值就是all),data_only(只导入数据),metadata_only(只导入对象定义)。
(4)table_exists_action参数
[oracle@oracledb ~]$ expdp imp1/*** directory=dmp dumpfile=ceshi.dmp logfile=ceshi.log table_exists_action=replace remap_schema=ceshi:user01 remap_tablespace=ceshi:users
注释:table_exists_action参数,该参数有4个属性值:skip(跳过该表,继续下一个对象的处理,这也是table_exists_action参数的默认值,不过需要注意,如果你同时指定了content参数为data_only的话,skip参数值无效,默认为append),append(向现有的表中添加数据),truncate(truncate当前表,然后再添加记录,使用这个参数需要谨慎,除非确认当前表中数据确实无用,或者与要导入的数据有重复,不然有可能造成数据丢失), replace(删除并重建表对象,然后再向其中添加数据,不过需要注意,如果同时指定了content参数值为data_only的话,replace参数值也无效)。
(5)以下参数和expdp一样,就不再贴图了
指定schemas参数,表明导入哪些schema,例如:
[oracle@oracledb ~]$ impdp imp1/*** directory=dmp dumpfile=ceshi.dmp logfile=ceshi.log schemas=ceshi remap_schema=ceshi:user01 remap_tablespace=ceshi:users
指定tables参数,表明导入哪几张表,例如:
[oracle@oracledb ~]$ impdp imp1/*** directory=dmp dumpfile=ceshi.dmp logfile=ceshi.log tables=ceshi.OP_DRGS_ONLY,ceshi.GER_DIAGNOSIS, remap_schema=ceshi:user01 remap_tablespace=ceshi:users
指定tablespaces参数,表明导入哪些表空间,例如:
[oracle@oracledb ~]$ impdp imp1/*** directory=dmp dumpfile=ceshi.dmp logfile=ceshi.log tablespaces=ceshi remap_schema=ceshi:user01 remap_tablespace=ceshi:users
指定query参数,表明导入条件,例如:
[oracle@oracledb ~]$ impdp imp1/*** directory=dmp dumpfile=ceshi.dmp logfile=ceshi.log tables=ceshi.GER_DIAGNOSIS,ceshi.GER_OPERATION query=ceshi.GER_DIAGNOSIS:\"where code=\'A16.211\'\" remap_schema=ceshi:user01 remap_tablespace=ceshi:users
指定parfile参数,调用文本命令,例如:
[oracle@oracledb ~]$ impdp imp1/*** parfile=/tmp/p.txt
ctrl+c进入交互界面,可以import>kill_job,中断正在执行的任务,可以import>stop_job,停止当前正在运行的任务,import>start_job,启动停止的任务,import>status查看当前任务的详细状态信息。
continue_client参数,可以继续进入导入界面。
指定parallel参数,进行并行导入,例如:
[oracle@oracledb ~]$ impdp imp1/*** directory=dmp dumpfile=ceshi.dmp logfile=ceshi.log parallel=2 remap_schema=ceshi:user01 remap_tablespace=ceshi:users
指定network_link参数,将远端用户中的数据导入本地用户下,例如:
[oracle@oracledb ~]$ impdp imp1/*** network_link=to_qj remap_schema=qj:user01 remap_tablespace=qj01:users
指定nologfile参数,指定是否导出导入日志,例如:
[oracle@oracledb ~]$ impdp imp1/*** directory=dmp dumpfile=ceshi.dmp nologfile=y remap_schema=ceshi:user01 remap_tablespace=ceshi:users
指定job_name参数,为导入任务命名,例如:
[oracle@oracledb ~]$ impdp imp1/*** directory=dmp dumpfile=ceshi.dmp nologfile=y job_name=impdp_qj remap_schema=ceshi:user01 remap_tablespace=ceshi:users
同样对于异常退出,可以通过attach=任务名来,重新执行未完成的任务。
五、与君共勉
数据泵在日常的数据库管理中使用非常频繁,可以非常方便的对数据进行迁移,虽然命令比较多,但这是一个非常好的地方,命令多,意味着灵活,对于各种要求的数据迁移游刃有余,因此还是需要勤加练习,在练习中将会遇到expdp和impdp各种问题,解决问题的过程本身就是一种学习,就是一种成长。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/30485601/viewspace-2151455/
,如需转载,请注明出处,否则将追究法律责任。