Oracle 19c 数据导入教程(基于 expdp 导出的 dmp 文件)

📋 文档说明

 
项目说明
适用场景 从一台机器用 expdp 全量导出后,将 .dmp 文件导入到另一台新安装的 Oracle 19c 数据库
操作人员 拥有 SYSTEM 密码,对服务器有远程或本地操作权限
预计耗时 取决于 dmp 文件大小,通常 5-30 分钟
适用导出方式 expdp ... full=y 导出的 .dmp 文件

⚠️ 开始前的必要确认

在开始操作之前,必须先确认以下三个信息

 
序号确认项查看命令(用 SYSTEM 登录 SQL*Plus)说明
1 数据文件存放路径 SELECT name FROM v\$datafile; 记下路径,后面创建表空间要用
2 源 dmp 文件中的表空间列表 impdp directory=MY_DUMP_DIR dumpfile=你的文件.dmp show=y sqlfile=check.sql 然后打开 check.sql 搜索 CREATE TABLESPACE 提前知道要创建哪些表空间,避免导入时因路径不存在而失败
3 源 dmp 文件中的用户名 同上,搜索 CREATE USERALTER USER 提前知道要导入到哪个用户下

如果第 2 步你嫌麻烦,也可以先不查,直接执行导入,等报错 ORA-01119 时再根据错误日志中的表空间名来创建。但更推荐提前查好,一次性成功。

第一步:准备工作

1.1 将 dmp 文件放到目标机器上

将旧机器上的 .dmp 文件(以及可选的 .log 日志文件)复制到新机器的任意目录,建议放在一个路径简单的位置,例如 D:\backup\E:\data\

注意:路径中不要有中文、空格或特殊字符。

1.2 确认目标机器的 Oracle 数据文件存放路径

SYSTEM 用户登录 SQL*Plus:

bash
sqlplus system/你的密码@ORCL

执行以下命令,查看当前数据库的数据文件放在哪里:

sql
SELECT name FROM v$datafile;

示例输出

text
NAME
--------------------------------------------------------------------------------
P:\APP\ORACLE19C_DATA\ORCL\SYSTEM01.DBF
P:\APP\ORACLE19C_DATA\ORCL\SYSAUX01.DBF
P:\APP\ORACLE19C_DATA\ORCL\UNDOTBS01.DBF
P:\APP\ORACLE19C_DATA\ORCL\USERS01.DBF

记下这个路径(如 P:\APP\ORACLE19C_DATA\ORCL\),后面创建表空间时都放到这里。

1.3 创建 Directory 指向 dmp 文件所在位置

在 SQL*Plus 中执行(假设你的 dmp 文件放在 D:\backup\):

sql
CREATE OR REPLACE DIRECTORY MY_DUMP_DIR AS 'D:\backup';

不需要执行 GRANT 授权给自己,用 SYSTEM 用户创建时默认就有权限。

1.4 退出 SQL*Plus

sql
exit

第二步:提前创建表空间(关键!规避路径不存在的坑)

这一步是为了提前创建好源库中使用的表空间,避免导入时因为路径不存在而导致 ORA-01119 错误。

为什么要提前创建?

impdp 在执行 full=y 导入时,会先尝试在目标库创建源库中的表空间。如果源库表空间的物理路径在目标机器上不存在,导入就会失败。

解决方案:提前在目标机器上创建好这些表空间,使用目标机器的标准数据文件路径,导入时用 REMAP_TABLESPACE 参数将数据重定向到新表空间。

2.1 查看源 dmp 文件中有哪些表空间需要创建

在 CMD 中执行(这只是查看,不会真正导入数据):

bash
impdp system/你的密码@ORCL directory=MY_DUMP_DIR dumpfile=你的文件.dmp show=y sqlfile=tablespace_list.sql

然后打开生成的 tablespace_list.sql 文件,搜索 CREATE TABLESPACE,记录下所有表空间名称。

示例:从日志中看到源库有这四个表空间:MES_SPEC_DATMES_CUS_DATMES_RTM_DATMES_DCL_DAT

2.2 在目标机器上创建这些表空间

SYSTEM 重新登录 SQL*Plus,执行以下命令(路径换成你自己机器上的数据文件路径):

sql
-- 创建表空间,使用目标机器的标准路径
CREATE TABLESPACE MES_SPEC_DAT 
DATAFILE 'P:\APP\ORACLE19C_DATA\ORCL\MES_SPEC_DAT.DBF' 
SIZE 100M AUTOEXTEND ON NEXT 100M MAXSIZE 10G;

CREATE TABLESPACE MES_CUS_DAT 
DATAFILE 'P:\APP\ORACLE19C_DATA\ORCL\MES_CUS_DAT.DBF' 
SIZE 100M AUTOEXTEND ON NEXT 100M MAXSIZE 10G;

CREATE TABLESPACE MES_RTM_DAT 
DATAFILE 'P:\APP\ORACLE19C_DATA\ORCL\MES_RTM_DAT.DBF' 
SIZE 100M AUTOEXTEND ON NEXT 100M MAXSIZE 10G;

CREATE TABLESPACE MES_DCL_DAT 
DATAFILE 'P:\APP\ORACLE19C_DATA\ORCL\MES_DCL_DAT.DBF' 
SIZE 100M AUTOEXTEND ON NEXT 100M MAXSIZE 10G;

参数说明

 
参数含义推荐值
SIZE 初始分配空间 100M(首次占用的实际大小)
AUTOEXTEND ON 空间用完后自动扩展 必须开启
NEXT 每次扩展的大小 100M
MAXSIZE 最大允许扩展到多大 10G(可根据硬盘空间调整,不预先占用)

关于 MAXSIZE 的说明MAXSIZE 只是设置一个增长上限,不会提前占用硬盘空间。实际占用从 SIZE 开始,随数据增长逐步扩展。建议根据硬盘剩余空间设置,一般设为 10G20G

2.3 确认表空间创建成功

sql
SELECT tablespace_name, file_name, bytes/1024/1024 AS size_mb 
FROM dba_data_files 
WHERE tablespace_name LIKE 'MES%'
ORDER BY tablespace_name;

应该能看到四个新表空间及对应的 .DBF 文件。

第三步:清理残留数据(如果是重复导入)

如果你之前已经执行过导入并且失败了,需要先清理残留数据,避免第二次导入时出现冲突。

以下操作只在重复导入时执行,如果是全新安装的数据库,直接跳过这一步。

SYSTEM 登录 SQL*Plus 执行:

sql
-- 1. 删除业务用户(包含其所有对象)
DROP USER MES_PROD CASCADE;

-- 2. 删除表空间(如果之前创建失败,会报"不存在",直接忽略)
DROP TABLESPACE MES_SPEC_DAT INCLUDING CONTENTS AND DATAFILES;
DROP TABLESPACE MES_CUS_DAT INCLUDING CONTENTS AND DATAFILES;
DROP TABLESPACE MES_RTM_DAT INCLUDING CONTENTS AND DATAFILES;
DROP TABLESPACE MES_DCL_DAT INCLUDING CONTENTS AND DATAFILES;

如果报错 ORA-00959: 表空间不存在,说明本来就没有,直接忽略即可。

第四步:执行全量导入

在 CMD 命令窗口(不是 SQL*Plus)中执行:

bash
impdp system/你的密码@ORCL directory=MY_DUMP_DIR dumpfile=你的文件.dmp logfile=import.log full=y remap_tablespace=源表空间1:目标表空间1 remap_tablespace=源表空间2:目标表空间2

参数说明

 
参数说明
system/密码@ORCL 用 SYSTEM 用户登录
directory=MY_DUMP_DIR 指向 dmp 文件所在目录
dumpfile=你的文件.dmp dmp 文件名
logfile=import.log 导入日志文件名,会生成在 dmp 同目录下
full=y 全量导入
remap_tablespace=旧:新 关键参数:将源表空间的数据重定向到目标表空间

完整示例

bash
impdp system/yyl07041018@ORCL directory=MY_DUMP_DIR dumpfile=FULL_BACKUP.DMP logfile=import.log full=y remap_tablespace=MES_SPEC_DAT:MES_SPEC_DAT remap_tablespace=MES_CUS_DAT:MES_CUS_DAT remap_tablespace=MES_RTM_DAT:MES_RTM_DAT remap_tablespace=MES_DCL_DAT:MES_DCL_DAT

注意:因为我们在第二步创建的表空间名称和源库一致,所以写法是 MES_SPEC_DAT:MES_SPEC_DAT(自己映射给自己)。如果希望改名,可以写成 MES_SPEC_DAT:NEW_NAME

第五步:等待导入完成并查看日志

导入过程会在屏幕上显示进度,等待出现 Job "SYSTEM"."SYS_IMPORT_FULL_01" completed 字样即表示完成。

然后打开 dmp 文件同目录下的 import.log,拉到最后,查看:

text
作业 "SYSTEM"."SYS_IMPORT_FULL_01" 已经完成, 但是有 XX 个错误

日志中常见"错误"的含义

 
错误代码含义是否要处理
ORA-31684 对象已存在(表空间、用户等) ❌ 不需要,正常跳过
ORA-39151 内部表已存在,跳过 ❌ 不需要
ORA-39082 触发器编译有警告 ⚠️ 业务用到时报错再处理
ORA-31693 某张表数据无法加载 ⚠️ 检查该表在源库是否有数据
ORA-01119 表空间创建失败(路径不存在) ⚠️ 说明表空间没提前创建好,回到第二步补建

判断导入是否成功的标准

导入成功的标志

  1. 日志中有大量 导入了 "XXX" 的记录,显示行数 > 0

  2. 日志末尾显示作业完成

  3. 用业务用户登录后能查到数据

那 4 张表显示 0 行是正常的吗?

如果在源库中这些表本身就是空的,导入后显示 0 行是正常的。可以通过查询确认:

sql
SELECT COUNT(*) FROM MES_PROD.你的表名;

如果结果和旧机器一致(都是 0),说明导入是完整的。

第六步:验证数据完整性

MES_PROD 用户或 SA 用户登录 SQL*Plus 验证:

sql
-- 1. 查看有哪些表
SELECT table_name FROM user_tables ORDER BY table_name;

-- 2. 查看大表的行数
SELECT table_name, num_rows 
FROM user_tables 
WHERE num_rows > 0 
ORDER BY num_rows DESC;

验证表空间归属(确认数据在正确的表空间)

sql
SELECT table_name, tablespace_name 
FROM dba_tables 
WHERE owner = 'MES_PROD' 
ORDER BY tablespace_name, table_name;

如果所有业务表都正确地归属于 MES_SPEC_DATMES_CUS_DATMES_RTM_DATMES_DCL_DAT 这四个表空间,说明导入完全成功。

📝 常见问题及解决方案汇总

 
问题现象原因解决方案
ORA-01119: 创建数据库文件 ... 时出错 目标机器没有源库的表空间路径 提前创建表空间(见第二步)或用 REMAP_TABLESPACE 重定向
ORA-00959: 表空间 'XXX' 不存在 表空间未创建 创建缺失的表空间或用 REMAP_TABLESPACE 映射到已存在的表空间
ORA-31684: 对象类型 TABLESPACE:"XXX" 已存在 表空间已经存在 正常提示,忽略
ORA-39151: 表 "SYSTEM"."XXX" 已存在 之前导入残留的内部表 正常提示,忽略
ORA-01950: 对表空间 'USERS' 无权限 系统表空间权限问题 不影响业务数据,忽略
ORA-39082: 触发器编译警告 触发器依赖的对象未完全就绪 暂时忽略,业务使用时报错再处理
表数据 0 行 该表在源库本身就是空的 去旧机器确认行数,一致即正常

 

🔧 附录:常用检查 SQL

查看所有表空间及数据文件位置

sql
SELECT tablespace_name, file_name, bytes/1024/1024 AS size_mb 
FROM dba_data_files 
ORDER BY tablespace_name;

查看某个用户的所有表及其表空间

sql
SELECT table_name, tablespace_name 
FROM dba_tables 
WHERE owner = 'MES_PROD' 
ORDER BY tablespace_name, table_name;

查看某个用户下各表的数据行数

sql
SELECT table_name, num_rows 
FROM user_tables 
ORDER BY num_rows DESC;

查看表空间使用率

sql
SELECT a.tablespace_name,
       total / 1024 / 1024 AS total_mb,
       free / 1024 / 1024 AS free_mb,
       ROUND((total - free) / total * 100, 2) AS used_pct
FROM (SELECT tablespace_name, SUM(bytes) AS total
      FROM dba_data_files
      GROUP BY tablespace_name) a,
     (SELECT tablespace_name, SUM(bytes) AS free
      FROM dba_free_space
      GROUP BY tablespace_name) b
WHERE a.tablespace_name = b.tablespace_name
ORDER BY used_pct DESC;

📌 快速流程回顾(带命令速查)

bash
# 1. 登录 SQL*Plus
sqlplus system/你的密码@ORCL

# 2. 查数据文件路径
SELECT name FROM v$datafile;

# 3. 创建 Directory
CREATE OR REPLACE DIRECTORY MY_DUMP_DIR AS 'D:\backup';

# 4. 创建表空间(路径换成自己的)
CREATE TABLESPACE MES_SPEC_DAT DATAFILE 'P:\APP\ORACLE19C_DATA\ORCL\MES_SPEC_DAT.DBF' SIZE 100M AUTOEXTEND ON NEXT 100M MAXSIZE 10G;
-- ... 其他表空间类似

# 5. 退出 SQL*Plus
exit

# 6. 执行导入(在 CMD 中)
impdp system/你的密码@ORCL directory=MY_DUMP_DIR dumpfile=你的文件.dmp logfile=import.log full=y remap_tablespace=源表空间1:目标表空间1 remap_tablespace=源表空间2:目标表空间2

# 7. 验证
sqlplus 用户名/密码@ORCL
SELECT COUNT(*) FROM 某张表;

以上就是完整的导入教程。按照这个流程操作,可以规避我们之前遇到的所有问题,实现一次性成功导入。

 

posted @ 2026-08-21 17:03  上清风  阅读(6)  评论(0)    收藏  举报