Oracle 10g之后,官方推荐使用数据泵(Data Pump)替代传统的exp/imp工具完成数据的导出与导入。数据泵采用服务端并行处理架构,速度比老工具快数倍,还支持断点续传、网络导入、按条件过滤等能力,是数据库迁移、备份和升级场景的首选方案。本文将从目录对象准备开始,完整讲解expdp导出和impdp导入的常用操作。

一、使用数据泵前的准备工作
1. 创建目录对象
数据泵只能把文件写到服务端指定的目录,不能直接写到客户端本地磁盘。这个目录必须先在数据库中注册成Directory对象,导出导入命令都通过这个对象来定位文件路径。登录DBA账号执行以下语句:
-- 用sys或system登录 sqlplus / as sysdba -- 创建目录对象,指向服务器上的真实路径 CREATE OR REPLACE DIRECTORY dump_dir AS '/u01/backup/dump'; -- 把目录的读写权限授予执行导出的用户 GRANT READ, WRITE ON DIRECTORY dump_dir TO scott;
需要注意两点:一是操作系统层面该路径必须真实存在,且Oracle用户对其有读写权限;二是普通用户必须拿到GRANT授权,否则导出时会报ORA-39002无效操作或ORA-39213元数据错误。如果不清楚当前有哪些目录对象,可以通过查询dba_directories视图确认路径指向。
2. 确认用户权限
执行expdp的用户如果导出的是其他用户的对象,需要具备EXP_FULL_DATABASE角色或对应的对象权限;导入时同理需要IMP_FULL_DATABASE角色。用sys用户执行虽然最省事,但生产环境更建议用专门的迁移账号并授予最小权限,避免误操作。另外,数据泵依赖数据库中的Master表和Worker进程协调任务,如果数据库处于只读模式或资源紧张,任务可能挂起,提前检查实例状态很有必要。
二、expdp导出的常用命令与模式
1. 按用户导出(最常用)
按Schema导出适合做整个用户的数据搬迁,命令中的schemas参数指定要导出的用户:
expdp scott/tiger@orcl directory=dump_dir dumpfile=scott_%U.dmp \ logfile=exp_scott.log schemas=scott parallel=4
dumpfile中的%U是占位符,配合parallel参数会生成多个文件(scott_01.dmp、scott_02.dmp等),多个进程并行写入能显著提升导出速度。实际测试中,大表场景下并行度为4通常能比单进程快两到三倍,但并行度并非越大越好,一般不超过CPU核数的两倍。
2. 按表导出与按表空间导出
只需要搬个别表时用tables参数,按表空间整体搬迁用tablespaces参数:
-- 只导出两张表 expdp scott/tiger@orcl directory=dump_dir dumpfile=tab.dmp \ tables=emp,dept -- 导出整个表空间 expdp system/oracle@orcl directory=dump_dir dumpfile=ts.dmp \ tablespaces=users
3. 按条件过滤与排除对象
数据泵支持在导出阶段就做数据裁剪。query参数按WHERE条件过滤行数据,exclude参数排除不需要的对象类型:
-- 只导出2024年之后的订单数据,注意query需要加双引号
expdp scott/tiger@orcl directory=dump_dir dumpfile=order.dmp \
tables=orders query=orders:"WHERE create_date > TO_DATE('2024-01-01','YYYY-MM-DD')"
-- 排除统计信息和物化视图,减小导出文件体积
expdp scott/tiger@orcl directory=dump_dir dumpfile=scott.dmp \
schemas=scott exclude=statistics,materialized_view
query参数的语法比较容易被忽视:条件中要写明表名前缀,整个条件用双引号包裹,在Linux下还要注意转义,否则会报ORA-39001参数值无效。exclude和include不能同时使用,对象类型名称要求数据库内部的规范拼写,写错时建议先查阅官方文档的对象类型列表。
三、impdp导入的核心参数详解
1. 基础导入与覆盖已有表
最基础的导入命令与expdp对应:
impdp scott/tiger@orcl directory=dump_dir dumpfile=scott_%U.dmp \ logfile=imp_scott.log schemas=scott
如果目标库中同名表已经存在,table_exists_action参数决定处理方式:skip跳过该表,append在原表上追加数据,truncate先清空再导入,replace直接删表重建。迁移重复执行的场景建议用replace,日常增量补数则用append更安全,但要注意主键冲突问题。
impdp scott/tiger@orcl directory=dump_dir dumpfile=scott_%U.dmp \ schemas=scott table_exists_action=replace
2. 换用户与换表空间导入
源端和目标端用户名、表空间不一致时,用remap系列参数做重映射:
-- 源用户scott的数据导入到目标用户hr名下 impdp system/oracle@orcl directory=dump_dir dumpfile=scott_%U.dmp \ remap_schema=scott:hr -- 同时把USERS表空间的数据搬到NEW_TS表空间 impdp system/oracle@orcl directory=dump_dir dumpfile=scott_%U.dmp \ remap_schema=scott:hr remap_tablespace=USERS:NEW_TS
3. 只导入元数据或只导入数据
有时只需要搬表结构做环境搭建,有时只需要灌数据,content参数可以控制导入内容:content=metadata_only只导入表、索引、存储过程等定义;content=data_only只导入数据行。配合sqlfile参数还能不真正执行导入,而是把DDL语句导出成脚本文件,方便审查目标端的结构差异。
-- 只导表结构 impdp scott/tiger@orcl directory=dump_dir dumpfile=scott_%U.dmp \ content=metadata_only -- 把DDL语句写入脚本而不实际导入 impdp scott/tiger@orcl directory=dump_dir dumpfile=scott_%U.dmp \ sqlfile=ddl_script.sql
四、常见报错与排查思路
1. ORA-39002与ORA-39070
ORA-39002表示操作无效,最常见原因是目录对象名写错或未授权;ORA-39070表示无法打开日志文件,通常是操作系统路径不存在或Oracle用户没有写权限。排查顺序建议是:先查dba_directories确认路径,再登录服务器检查目录权限,最后确认命令中directory参数与创建的对象名完全一致,包括大小写。
2. ORA-31626与任务挂起
遇到ORA-31626任务不存在或任务卡住不动,多半是之前失败的任务留下了残留的Master表。可以在DBA_DATAPUMP_JOBS视图中查找状态为NOT RUNNING的作业,用drop table删除对应的系统表名(形如SYS_EXPORT_SCHEMA_01),然后重新执行。如果频繁中断,还应检查UNDO表空间和临时表空间的大小是否充足。
3. 字符集与版本兼容问题
从高版本往低版本导出时会报ORA-39142版本不兼容,解决办法是导出时指定version参数,例如version=11.2,让生成的文件可以被低版本读取。字符集不一致则可能出现中文乱码,导入前确认两端的NLS_LANG设置一致,必要时通过中间环境做转码转换。
五、实用建议汇总
大表迁移务必使用parallel参数,并让dumpfile生成多个文件分散IO压力;正式迁移前先用estimate_only=yes估算导出体积,评估磁盘空间是否够用;迁移完成后记得重建统计信息,因为exclude了statistics的文件导入后优化器缺少统计数据,执行计划可能异常,用exec dbms_stats.gather_schema_stats收一遍即可;最后核对两端的对象数量与行数,确认迁移完整再切换应用。