注册

Oracle 到 DM8 的迁移与 dmfldr 装载实验记录

DSR 2026/11/12 100 0

摘要:这篇文章记录两组实验:一组用 dexp/dimp 把对象和数据从一个模式迁到另一个模式,一组用 dmfldr 装载 10004 行数据文件。重点不在命令本身,而在迁完之后怎么核对——对象有没有迁全、行数是否一致、中文有没有截断、错误行去了哪里、空值口径是否与预期一致。文中行数、错误码和日志结论都来自实际执行结果。
关键词:DM8;数据迁移;dexp/dimp;dmfldr;数据核对;BADFILE
一、三个工具各管什么
DM 里做数据迁移,常用的是 DTS、dexp/dimp 和 dmfldr,它们解决的问题不一样。DTS 是图形化工具,以对象为单位迁移,表、视图、序列、存储过程都能带过去,自带迁移评估和类型映射;dexp/dimp 是命令行下的逻辑导出导入工具,适合写进脚本、与备份配合;dmfldr 面向格式化平文件的高速装载,核心是数据文件、控制文件、日志和错误文件四样东西。
如果任务还包括持续增量同步或复杂的数据交换,那是 DMHS、DMETL 的范围,不要让这三个工具去承担。
E8AB26543CCC4F40B854F0ED35C2DCB8.png
图1 按数据形态选择迁移与同步工具(原创示意)
二、迁移前先记基线
不管用哪个工具,动手前先留两份底:源端对象清单和数据行数口径。这次实验的记录如下:
表1 迁移基线记录
项目 实际记录
目标端 单机 DM8(dminit 版本 03134284552-20260414-322369-20221),实例 DMSERVER,端口 5236
实例关键参数 页大小 8K,簇大小 16,大小写敏感 Y,字符集 UTF-8
目标规划 表空间 MIG_TS,用户 MIG_TEST(默认表空间 MIG_TS)
迁移范围 1 张表 FLDR_TEST(ID INT,NAME VARCHAR(50)),数据文件 10004 逻辑行
验证口径 源逻辑行数=成功行数+拒绝行数+跳过行数;空值与字符串分别核对

说明: 这次环境是单机 DM8,手上没有 Oracle 源库。为了把流程走完整,源端数据用同一实例里的 MIG_TEST 模式模拟,对象迁移用 dexp/dimp 的 REMAP_SCHEMA 完成;DTS 部分按官方文档保留为操作步骤。真正从 Oracle 迁过来时,下文的核对方法同样适用,差别只在源端连接和驱动配置。
对象按类型统计、名称单独导出留档:
SELECT OBJECT_TYPE, COUNT()
FROM ALL_OBJECTS
WHERE OWNER = 'MIG_TEST'
GROUP BY OBJECT_TYPE
ORDER BY 1;
注意: 不要拿统计信息里的 NUM_ROWS 当验收行数。统计信息可能没更新,关键表用 SELECT COUNT(
) 查,或用双方认可的口径复验。
三、dexp/dimp:脚本化迁移

  1. 导出源模式
    cd /home/dmdba/dmdbs/bin
    ./dexp SYSDBA/****@localhost:5236
    FILE='/dmdata/load/mig_test.dmp'
    LOG='/dmdata/load/mig_exp.log'
    DIRECTORY='/dmdata/load' SCHEMAS=MIG_TEST
    实际输出(节选):
    成功导出 第1 个SCHEMA :MIG_TEST
    共导出 1 个SCHEMA
    整个导出过程共花费 1.957 s
    成功终止导出, 没有出现警告
    导出的 mig_test.dmp 实际大小 248K。
  2. 建目标用户、重映射导入
    先建 MIG_TEST2 用户并授权,再用 REMAP_SCHEMA 把对象迁入新模式:
    ./dimp SYSDBA/****@localhost:5236
    FILE='/dmdata/load/mig_test.dmp'
    LOG='/dmdata/load/mig_imp.log'
    REMAP_SCHEMA=MIG_TEST:MIG_TEST2
    输出(节选):
    表 MIG_TEST2.FLDR_TEST 的数据导入完成,共导入数据:10001 行, 大小 241.989 KB
    [2/2]模式[MIG_TEST2]导入完成......
    整个导入过程共花费 0.660 s
    成功终止导入, 没有出现警告
  3. 交叉核对
    迁移前后用同一口径查一遍:
    SELECT OWNER, TABLE_NAME, TABLESPACE_NAME FROM DBA_TABLES
    WHERE TABLE_NAME='FLDR_TEST';
    MIG_TEST FLDR_TEST MIG_TS
    MIG_TEST2 FLDR_TEST MIG_TS
    SELECT COUNT():MIG_TEST 10001 行;MIG_TEST2 10001 行
    SELECT COUNT(
    ) WHERE NAME IS NULL:两边一致
    所有者、表空间、行数三项都对上了,这次迁移才算完成。这也是后面坑点 1 的由来:核对必须查对象所有者,只数对象个数发现不了问题。
    四、dmfldr 装载
  4. 建表、造数据文件
    CREATE TABLE MIG_TEST.FLDR_TEST (
    ID INT,
    NAME VARCHAR(50));
    数据文件 /dmdata/load/fldr_test.txt 共 10004 行。前 10000 行是正常数据,NAME 带中文“装载测试_N”;末尾 4 行是特意加的特殊记录:1 行整数列写了 abc(类型错误)、1 行 NAME 写了 60 个字符(超过 VARCHAR(50))、1 行少一列、1 行 NAME 写字符串 NULL(验证空值口径)。
  5. 写控制文件
    控制文件 /dmdata/load/t2.ctl:
    LOAD DATA
    INFILE '/dmdata/load/fldr_test.txt'
    INTO TABLE MIG_TEST.FLDR_TEST
    FIELDS '|'
    ( ID,
    NAME)
    INFILE 指数据文件位置,FIELDS 指分隔符,括号里的列顺序要和数据对上。LOG 和 BADFILE 建议显式指到可写目录,否则排错时可能找不到关键文件——这一点我这次真实踩到,见坑点 5。
  6. 执行装载、检查日志
    实际执行的命令:
    cd /dmdata/load
    ./dmfldr SYSDBA/****@localhost:5236
    "CONTROL='t2.ctl'"
    "LOG='fldr_demo.log'"
    "BADFILE='fldr_demo.bad'"
    NULL_MODE=TRUE
    装载结果:
    10001 行加载成功。
    3 行由于数据错误没有加载。
    1 行由于数据格式错误被丢弃。
    跳过的逻辑记录总数: 0
    读取的逻辑记录总数: 10004
    拒绝的逻辑记录总数: 3
    三类错误行与预期一一对应:abc 行报 [-6128]:无效的数字,60 字符行报 [-6108]:字符串截断,缺列行按“数据文件少列”被丢弃。行数关系也对上:10004(读取)= 10001(成功)+ 3(数据错误)+ 0(跳过)+ 1(格式丢弃,不计入拒绝总数)。
    A1D95D39B43C497DAFD0F031A564F201.png
    图2 dmfldr 装载实际执行结果(真实实验截图)
  7. 核对行数与空值口径
    ./dmfldr help 显示 NULL_MODE 缺省为 FALSE,即文本中的 NULL 默认按普通字符串装载。这次做了两组对照:
    表2 NULL_MODE 两种取值下的空值口径对照
    装载参数 总行数 WHERE NAME IS NULL ID=10003 的 NAME 实际值
    缺省(NULL_MODE=FALSE) 10001 0 字符串 'NULL'(LENGTH=4)
    NULL_MODE=TRUE 10001 1 真空值

1376449AE8574E88A6E997A6D3DCDA7F.png
图3 装载后行数与空值口径核对(真实实验截图)
终端显示“装载成功”不代表空值处理正确。NULL_MODE 要在控制文件或命令行里显式确定,装完用 IS NULL 和普通字符串各查一次。
五、踩坑记录
坑点 1:对象数量不少,却迁到了错误的用户或表空间
根因: 目标端没有提前规划用户、默认表空间和模式映射,迁移时沿用了默认目标。
处理: 迁移前把目标用户和默认表空间定好。这次先建 MIG_TS 表空间和 MIG_TEST 用户再迁移,核对时用 DBA_TABLES 确认所有者与表空间;dexp/dimp 路径用 REMAP_SCHEMA 显式指定目标模式。
坑点 2:中文被截断,标识符大小写异常
根因: 建实例时没评估字符集、字符长度和大小写敏感规则,这几项建完无法直接修改。
处理: 先用带中文、长字符串、混合大小写标识符的小样本试。这次数据文件全含中文,装载后 LENGTH(NAME) 与源文件一致,没有截断;60 字符超长行被正确拒绝并记入错误日志,说明字段长度约束在装载环节真实生效。
坑点 3:约束名称不同,被误判为对象丢失
根因: 源库和目标库都可能自动生成约束名。官方 DTS 文档说明,这类对象可能名称不同但功能相同。
处理: 对自动命名的对象比较定义、字段、约束类型和功能,不要求系统生成的名称完全一致。
坑点 4:dmfldr 报“参数分析出错”,引号被 shell 剥掉了(这次真实遇到)
现象: 按 ./dmfldr help 的说明书写命令:
./dmfldr SYSDBA/@localhost:5236 CONTROL='t2.ctl'
程序没有读控制文件,直接报错:
initialize fail.
参数分析出错[t2]
把控制文件换成绝对路径,报错变成“参数分析出错[/]”——报错里始终是参数值的第一个片段。
根因: 当前版本的 dmfldr 要求字符串参数的引号保留在参数值内部。写 CONTROL='t2.ctl' 时,shell 先剥掉单引号,dmfldr 实际收到 CONTROL=t2.ctl,解析失败。
处理: 把引号包进参数值再传给程序:
./dmfldr SYSDBA/
@localhost:5236 "CONTROL='t2.ctl'"
改完立即正常解析并完成装载。“帮助文档示例在脚本里跑不通”这类问题,卡在 shell 引号处理和程序参数解析的交界上,排查时先想办法看程序实际收到了什么参数,不要一直在数据文件上找原因。
D31ADA112CD6477C8351E56C086B8D01.png
图4 参数引号被剥掉时的报错现场(真实实验截图)
坑点 5:终端显示完成,错误行却写到了别处(这次真实遇到)
现象: 第一次装载没显式指定 BADFILE,终端显示 load success 和错误统计,但计划目录 /dmdata/load 下找不到 BADFILE。错误行实际写到了工具默认路径 /home/dmdba/dmdbs/log/fldr.bad。
排查: 把 LOG 和 BADFILE 对照着看。BADFILE 里完整记录了 3 条拒绝行(缺列行 10002、类型错误行 abc、超长行 10001),与终端统计一致。
处理: LOG 和 BADFILE 一律显式指到规划目录;验收时核对“源逻辑行数=成功+拒绝+跳过”的关系。这次结果是 10004=10001+3+0(另有 1 行格式丢弃单独说明)。
6AA21E9EB30D4A779BFCAC7BE5017E62.png
图5 BADFILE 与 LOG 中记录的拒绝行及错误码(真实实验截图)
坑点 6:字符串 NULL 和数据库空值当成了一回事(这次真实遇到)
根因: NULL_MODE 决定文本里的 NULL 怎么解释:缺省 FALSE 按普通字符串装,设 TRUE 才按数据库空值处理。
处理: 在命令行或控制文件里明确口径,装完用 WHERE NAME IS NULL 和普通字符串查询各查一次(结果见表 2)。两种口径下 IS NULL 计数分别是 0 和 1,只看终端那句“装载成功”发现不了。
六、验收清单
5774E0588ED944CE904829548E351E85.png
图6 迁移完成后的验证环节(原创示意)
迁移最后一步是逐项核对,这次留下的证据:
表3 迁移验收清单
验证维度 核对方法 实际结果
对象清单 DBA_TABLES 查所有者与表空间 两侧模式均含 FLDR_TEST,表空间 MIG_TS
表行数 同一口径 SELECT COUNT(*) MIG_TEST 10001 = MIG_TEST2 10001
内容抽检 中文、超长、类型错误、空值样本 中文无截断;异常行进 BADFILE;空值口径一致
失败与拒绝行 检查 dmfldr LOG 与 BADFILE 3 拒绝+1 格式丢弃,错误码可复现
程序对象 检查视图、函数、存储过程是否可用 本次范围仅含表;含程序对象时应逐个编译验证
迁移后保护 验证通过后执行全量备份 应纳入例行计划,不能省略

七、小结
迁移工具把对象搬运和平文件装载做成了可配置、可追踪的过程,但迁移质量最终看留下的证据:迁之前的对象和行数基线,执行中的参数和日志,迁完之后的行数和内容核对。这次实验里,参数引号、BADFILE 默认位置、空值口径三个问题都属于“终端不报错、结果不正确”的类型。把 LOG、BADFILE 和 SQL 核对变成固定动作,“任务成功”才算真的成功。
参考资料
[1] 达梦技术文档:《DM 数据迁移工具》。
[2] 达梦技术社区:《dmfldr 快速装载工具》;具体参数以当前版本 ./dmfldr help 和使用手册为准。

回答 0
暂无回答
扫一扫
联系客服