oracle 10g引入最新的 Data pump 技术,可以将数据库元数据和数据快速移动到另一个oracle数据库中。
数据泵导入/出的作用:数据泵和imp/emp的区别:
- 实现逻辑备份和恢复。
- 在数据库用户之间迁移对象。
- 在数据库之间移动对象。
- 实现表空间搬移。
10g之前,只有imp/emp,imp/emp是客户端工具,但可以在客户端和服务器端使用。
10g之后,新增了expdp/impdp。是服务器端工具,且只能运行在服务器端。
数据泵与传统的产生的dump文件 在使用中互不兼容。
第一章、数据泵
导入导出执行用户要有足够的系统权限(create session,create table,exp_full_database,imp_full_database),还要在数据库内建立目录对象并被授予读写权限,
操作语句:create directory 目录对象名字 as '系统路径';
grant read,write on 目录对象 to 用户;
select * from dbf_directories;
1. expdp 样例
1.1 全库导出
$ expdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp logfile=???.log full=y
当导出文件过大时,可以用多个文件,并配合filesize 参数限制单个文件大小,具体操作如下:
- filesize 是每个文件最大尺寸,可接受单位 B,K,M,G,默认是字节(B)
- paraller是并行度,默认为1。
- dumpfile=%U,将自动生成导出文件
$ expdp \'/ as sysdba\' directory=目录对象 dumpfile=???01.dmp,???02.dmp, ???03.dmp logfile=???.log full=y filesize=20G parameter=2
1.2 全库导出到多个路径里
有时路径所在的文件系统的容量不足以存放导出文件,可以将导出文件分散在多个路径所在的文件系统下,如:
$ expdp \'/ as sysdba\' dumpfile=目录对象:???01.dmp,其他的目录对象:???02.dmp logfile=???.log full=y filesize=20G parameter=2
1.3 按schema导出
如果数据库只有少数schema,也可使用schemas参数进行导出,以提高导出速度并减少问题几率。
$ expdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp logfile=???.log schemas=Scott,hr,tlsi
- schemas指定的分别为同一数据库内的不同用户,可以指定一个或多个。
1.4 按表导出
$ expdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp logfile=???.log tables=(用户名.)表名
- 如果想指定某个用户的某张表,需要在表前指定用户的名字,如括号位置。
1.5 按表空间导出
$ expdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp logfile=???.log tablespaces=users
⚠️ 导出的数据范围默认为动作执行的用户,且TABLES SCHEMAS FULL不能同时使用
1.6 部分导出
exclude参数 来导出且屏蔽不需要的数据,且依赖这个对象的其他对象也一并被屏蔽,例如屏蔽一张表,则该表的索引,触发器都被屏蔽。
include参数来导出且只包含需要的数据,语法与exclude相同,意义相反。
且导出导入job对象时,不应该指定schemas参数。
以上两个参数互斥,不能同时使用。
- exclude 屏蔽部分SCHEMAS样例
例如导出数据不包含scott用户的数据
$ expdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp logfile=???.log exclude=SCHEMA:\"like \'scott\'\"
语句中的exclude参数中的“\”为转义符,在unix中使用,为了正确识别引号,而在windows中不需要。
语句中的 like 也可以换成 = 。
$ expdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp logfile=???.log exclude=SCHEMA:\"IN\( \'scott\',\'HR\'\)\"
- exclude 屏蔽部分对象
可以屏蔽的主要对象包括:table function package procedure sequence grant view index db_link constraint ref_constraint job statistics等,语法如下:
$ expdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp logfile=???.log exclude=function,package,table:\"in \(\'test\',\'test2\'\)\"
其中,如果名字类似,可以使用通配符“%”,示例如下
expdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp logfile=???.log schemas=hr exclude=table:\"like \'TE%\'\"
- exclude 屏蔽统计信息
统计信息包含表的平均行长、行数、字段直方图信息等,也是可以用exclude屏蔽的对象,之所以把它单拿出来,是因为数据泵有时候会因为统计信息的问题导致导出时间过长,甚至失败。我们完全可以在导出全库或较大schemas是屏蔽统计信息,待导入完成后再手工收集。语法如下:
expdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp logfile=???.log schemas=hr exclude=statistics
1.7 带查询条件导出
有时需要导出符合一定条件的数据,可以使用 query 参数。exp 和 expdp 的用法稍不同,exp 里只允许以 tables 方式使用;expdp 可以在 tables , schemas , full 三种方式导出时使用query 选项。
示例:导出hr 用户所有表的10行数据,语法如下:
$ expdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp logfile=???.log schemas=hr qurey=\"where rownum\< 11\"⚠️ 在 unix 里,特殊符号前都需要加转义符“\”
1.8 估算导出数据大小
$ expdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp logfile=???.log schemas=hr ESTIMATE=statistics estimate_only=y
⚠️ estimate 有两个选项:block 和 statistics,默认是block,即数据块的多少;statistics根据统计信息计算导出数据的大小,为了精确,在导出前分析各个表。
estimate_only默认是 n,如果选择 y 则不进行数据导出,只估算大小,⚠️ 当使用此参数时,无法同时使用dumpfile参数。
1.9 只导出元数据或数据
数据泵默认导出数据和元数据,当只希望导出数据库结构时,可使用content参数:
$ expdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp logfile=???.log full=y content=metadata_only
⚠️ content 后还可加 all 、 data_only
1.10 其他参数
- JOB_NAME
该参数用于自定义任务名称,即使不使用该参数,系统也会自动生成一个:$ expdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp logfile=???.log full=y job_name=给此任务进程自动起一个进程名字;
⚠️ 任务进程名不能超过30个字符
- VERSION
该参数用于版本互相兼容,当目标库的版本较低时,需用该参数指定版本,该指定的版本应小于等于目标库。
- STATUS
使用该参数将更新任务状态,单位是秒,默认为0;
- PARFILE
该参数用于指定参数文件,可事先建立参数文件
- SAMPLE
如果只希望按一定比例导出数据,可使用sample:$ expdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp logfile=???.log schemas=hr sample=10;⚠️sample 是希望导出数据的百分比,格式如下:SAMPLE=[[schema_name.]table_name:]sample_percent
2. impdp 样例
通常导入与导出的语法相同,如下:2.1 全库导入
$ impdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp full=y
2.2 按模式导入
$ impdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp schemas=test
2.3 导入部分对象
$ impdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp exclude=procedure,function,table:\"in \(\'test%\'\)\"
2.4 导入job
$ impdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp include=job
第二章、impdp和expdp不同的参数用法
1.导入到不同的schema下
将按模式导出的scott用户下的所有数据重新映射到kif用户下$ impdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp
remap_schema=scott:kif
2.导入到不同的表空间
如果重新映射对象的表空间,可以使用 remap_tablespace,例如:
$ impdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp remap_tablespace=hr:test
3.将元数据以sql形式写入文本文件
如果希望将dump的文件中DDL语句提取出来,可使用 sqlfile 参数,如:
$ impdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp sqlfile=???.sql
4.导入时,使用新存储属性
如果导入时希望使用新的表空间存储参数,或表的存储字句,可使用 transform 参数,例如:$ impdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp transform=segment_attributes:n:table
该命令使用新表空间的存储字句
transform参数的语法如下:
transform = transform_name:value[:object_type]
其中transform_name 有segment_attributes,storage,oid,pctspace 四种。
5.导入时,同名表的处理
如果目标库存在同名表,则使用table_exists_action 参数处理:$ impdp \'/ as sysdba\' directory=目录对象 dumpfile=???.dmp table_exists_action=truncate
table_existis_action 后接参数有四个选项:
skip;append(插入到表后);replace(替换原表);truncate(删除原表并插入)
第三章、管理维护任务
由于数据泵是服务器端进程,即使会话断开,也不妨碍任务的继续。可以通过attach的参数来连接仍在运行的任务,语法如下:$expdp \'/ as sysdba\' attch=expjob_name其中 expjob_name 是导出时指定的任务名,如果导出时未指定任务名,可使用dba_datapump_jobs视图来查看当前数据泵任务名及状态select owner_name,job_name,operation,job_mode,state from dba_datapump_jobs;把job_name 填写到 attach 参数的后面即可连接到该任务。连接到正在运行的任务后,可以使用如下命令:
命令 说明 (默认)
------------------------------------------------------------------------------
CONTINUE_CLIENT 返回到记录模式。如果处于空闲状态, 将重新启动作业。
EXIT_CLIENT 退出客户机会话并使作业处于运行状态。
HELP 总结交互命令。
KILL_JOB 分离和删除作业。
PARALLEL 更改当前作业的活动 worker 的数目。
PARALLEL=
的数目>。 START_JOB 启动/恢复当前作业。
START_JOB=SKIP_CURRENT 在开始作业之前将跳过
作业停止时执行的任意操作。
STATUS 在默认值 (0) 将显示可用时的新状态的情况下,
要监视的频率 (以秒计) 作业状态。
STATUS[=interval]
STOP_JOB 顺序关闭执行的作业并退出客户机。
STOP_JOB=IMMEDIATE 将立即关闭
数据泵作业。
其中KILL_JOB 同时删除任务记录,STOP_JOB并不删除记录。记录需要通过drop table job_name查看活动的数据泵进程 可在 dba_datadump_sessions 查看
第四章、exp/imp
1. exp 样例
1.1 导出全库
(不导 sys 的对象,但是会导出数据字典变化过的数据)$exp userid=system/oracle full=y filesize=50m file=(/客户端系统层绝对路径/???01.dmp,/客户端系统层绝对路径/???02.dmp) buffer=10000 log=/客户端系统层绝对路径/???.log
1.2 按模式导出
导出某个用户的所有数据$exp userid=scott/scott owner=scott file=/系统层绝对路径/???.dmp buffer=10000000 log=/系统层绝对路径/???.log
1.3 导出单张表
$exp userid=scott/scott tables=emp file=/系统层绝对路径/???.dmp buffer=10000000 log=/系统层绝对路径/???.log
1.4 导出时忽略约束
$exp userid=scott/scott tables=emp constraints=n file=/系统层绝对路径/???.dmp buffer=10000000 log=/系统层绝对路径/???.log
1.5 导出表时忽略授权
$exp userid=scott/scott tables=emp grant=n file=/系统层绝对路径/???.dmp buffer=10000000 log=/系统层绝对路径/???.log
1.6 导出表时显示反馈信息
每导出n行数据在屏幕上打印一个“.”$exp userid=scott/scott tables=emp file=/系统层绝对路径/???.dmp buffer=10000000 log=/系统层绝对路径/???.log feedback=2
1.7 导出表的元数据
只导出创建表的命令$exp userid=scott/scott tables=emp rows=n compress=n file=/系统层绝对路径/???.dmp buffer=10000000 log=/系统层绝对路径/???.log
1.8 按条件导出
$exp userid=scott/scott tables=emp query=\'where deptno=30\' file=/系统层绝对路径/???.dmp buffer=10000000 log=/系统层绝对路径/???.log
1.9 闪回导出
$exp userid=scott/scott tables=emp flashback_time=\"to_timestamp\(\'2018-02-04 08:50:00\',\'yyyy-mm-dd hh24:mi:ss\'\)\" file=/系统层绝对路径/???.dmp buffer=10000000 log=/系统层绝对路径/???.log
2. imp样例
1.全库导入
$imp userid=system/oracle full=y file=/系统层绝对路径/???.dmp
2.导入用户数据
$imp userid=system/oracle touser=new_hr file=/系统层绝对路径/???.dmp
3. 导入另个数据库的其他模式下
$imp userid=system/oracle touser=hr file=/系统层绝对路径/???.dmp
⚠️ 原来模式对象所存储的表空间必须在目标库中都存在,且有quota
第五章、导入导出的优化
1. exp优化
采用直接路径可以提高导出速度。所以,在 exp 使用时,就可以采用直接路径模式。这种模式有2个相关的参数:DIRECT和RECORDLENGTH参数。
- direct 参数定义了导出是使用直接路径方式还是常规路径方式。常规路径方式导出使用sql select 语句从表中抽取数据,直接路径导出则是将数据直接从磁盘读到PGA再原样写入导出文件,从而避免了SQL命令处理层的数据转换过程,大大提高了导出效率。在数据量大的情况下,直接路径导出的效率优势更明显,可比常规方法速度提高三倍之多。
- 和直接路径方式(direct=y)配合使用的是recordlength 参数,它定义了 export I/O缓冲的大小,作用类似于常规路径导出使用的 buffer 参数。建议设置recordlength 参数为最大I/O缓冲,即65535.其用法如下:
$exp userid=system/oracle full=y direct=y recordlength=65535 file=/系统层绝对路径/???.dmp log=/系统层绝对路径/???.log
2.imp优化
oracle imp进程需要花比exp进程数倍的时间将数据导入数据库。有些关键时刻,导入是为了应对数据库的经济故障恢复。为了减少宕机时间,加快导入速度显得至关重要。没有特效办法加速一个大数据量的导入,但我们可以做一些适当的设定以减少整个导入时间。
- 避免I/O竞争
imp 是一个 io 密集的操作,避免io 竞争可以加快导入速度。如果可能,不要在系统高峰时间段导入数据,不要在导入数据时运行job 等可能竞争系统资源的操作。
- 增加内存排序区
oracle imp 的进程先导入数据再创建索引,不论 INDEXES 的值设置为 YES或者NO,主键的索引是一定会创建的。创建索引的时候需要到排序区,在内存大小不足的时候,使用临时表空间进行磁盘排序,由于磁盘排序效率和内存排序的效率相差好几个数量级,增加内存排序区可以大大提高创建索引的效率,从而加快导入速度。
- 调整BUFFER 选项
imp 参数BUFFER 定义了每一次读取导出文件的数据量,设置的越大,就越减少import进程读取数据的次数,从而提高导入效率。BUFFER 的大小取决于系统应用,数据库规模,通常来说,设置为百兆就足够了,其用法如下:$imp userid=system/oracle fromuser=hr touser=new_hr file=/系统层绝对路径/???.dmp buffer=10240000;
- 使用commit=y选项
commit=y 表示每个数据缓冲满了之后提交一次,而不是导完一张表提交一次。这样会大大减少对系统回滚段等资源的消耗,对顺利完成导入是有益的。$imp userid=system/oracle fromuser=hr touser=new_hr commit=y file=/系统层绝对路径/???.dmp buffer=10240000;
- 使用INDEXES=N选项
前面说到增加内存排序区时,说明imp 进程先导入数据再创建索引。导入过程中建立用户定义的索引,特别是表上有多个索引或者数据表特别庞大时,需要消耗大量的时间。某些情况下需要以最快的时间导入数据,而索引允许后建,我门就可以使用INDEXES=N 只导入数据不创建索引,从而加快导入速度。我们可以用indexfile 选项生成创建索引的DDL脚本,再手工创建索引。我们也可以用如下方法导入两次,第一次导入数据,第二次导入索引,其用法如下:$imp userid=system/oracle fromuser=hr touser=new_hr rows=y indexes=n file=/系统层绝对路径/???.dmp buffer=10240000; $imp userid=system/oracle fromuser=hr touser=new_hr rows=n indexes=y file=/系统层绝对路径/???.dmp buffer=10240000;
- 增加 LARGE_POOL_SIZE
如果在init.ora 中配置了MTS_SERVICE,MTS_DISPATCHES 等参数,tnsname.ora 中又没有(SERVER=DEDICATED)的配置,那么数据库就使用了共享服务器模式,在MTS模式下,Emp/Imp 的操作会用到LARGE_POOL 建议调整LARGE_POOL_SIZE到150M。检查数据库是否zaiMTS 模式下:SQL> select distinct server from v$session;如果返回值出现none或shared 说明启动了MTS。
3.expdp/impdp 优化
数据泵与imp/emp 来说 性能有很大的提高,其中影响最大的就是paralle。可以这么来看:expdp/impdp=exp/imp+direct more+paralle,所以 使用数据泵,想要提高速度,就要设置并行参数。如果使用如下语句:expdp full=y directory=dump dumpfile=orcl_%U.dmp parallel=4那么,expdp将为parallel 创建4个文件,每个并行进程对应一个文件,这样的话,每个文件大小会因为进程而不同,要解决这个问题,就要设置filesize 参数。来指定每个文件的最大值。这样当一个文件达到最大值之后,就会创建一个新文件。expdp full=y directory=dump dumpfile=orcl_%U.dmp parallel=4 filesize=50M
导出的dump文件和paramel有关系,那么导入也有关系。parallel要小于dump文件数。如果parallel大于dump文件的个数,就会因为超过的那个进程获取不到文件,就不能对性能提高。
一般的parallel 参数值等于cpu的个数。而且要小于dump文件的个数。
查看cpu的个数:
SQL> show parameter cpu
⚠️导入过程中可能会停在某时刻,这个时候切记不要中断过程,可以通过在不同时段观察表空间大小的变化。如果表空间一张变化,说明还在导入,需要耐心等待。