资讯动态

Oracle迁移KingbaseES实战:KDTS工具与兼容性改造全记录

发布时间:2026/10/20 7:23:54 来源:尧图企业网站定制
干这行十多年Oracle到国产数据库的迁移任务接过不少但真正把 Oracle 12c 全量迁到人大金仓 KingbaseES V8.6还是最近才完整跑通。工具用的是人大金仓官方自带的迁移工具 KDTSKingbase Data Trans Studio也顺带处理了一批手工改写和兼容性适配的脏活。整个过程做下来我的感受是工具能解决大部分“搬数据”的问题但迁移项目真正的难点永远在搬完之后的应用适配。这篇文章就基于这个实操过程把从评估、配置、执行、校验到应用层改写和踩坑排查的完整链路都记录下来给正在做国产化迁移评估或已经进场的 DBA、架构师、开发同学做个参考。1. 转库前的准备工作与迁移方案评估1.1 迁移工具选型为什么我选了 KDTS先回答一个最常见的问题Oracle 转 Kingbase 一定得用官方工具吗不一定市面上有 Kettle、DataX、自研直连脚本等方式但我的建议是第一选择用官方迁移工具。对比项KDTS 官方工具自研脚本 / JDBC直连DataX / Kettle 等ETL对象迁移支持表、视图、序列、存储过程、触发器、同义词等都能覆盖基本只能搬表数据结构要自己写主要做数据同步复杂对象基本不适用数据类型映射内置 Oracle 到 Kingbase 的映射规则可手工调整自己写映射逻辑工作量大映射规则通用国产库特性支持弱转换日志与报告生成对象迁移报告逐条列出成功/失败项自己打日志有日志但对象兼容性判断要人工做学习成本图形化界面配置直观高中高要理解 channel 和插件机制回刷与增量处理支持任务重新执行和指定对象重迁自己控制数据同步可以做到准实时但结构迁移帮不上忙这个表列出来就能看出KDTS 最核心的价值是“结构对象迁移 数据迁移”一体化的能力而且它的迁移报告能直接告诉你哪些对象需要人工干预。对于 Oracle 12c 这种一堆存储过程、触发器、分区表的老库用 ETL 工具只能搬数据结构层面的兼容性判断你还得另写一套脚本去比对等于多干一份活。当时我们迁移的源库是某业务系统核心库Oracle 12c 双节点 RAC数据量不到 1TB业务表 800 多张另外还有 200 多个存储过程、几十个视图、少量物化视图和定时任务。这种规模如果用自研脚本光结构迁移部分没有一周搞不定还不算反复调试的时间。实际上用 KDTS结构迁移和数据迁移加起来一个工作日内跑完主流程是可行的。1.2 迁移前的对象普查与兼容性预判工具选好之后别急着装。先花半天时间把源库的家底摸清楚这会直接影响后面的迁移策略。我在 Oracle 侧跑了一组查询把评估对象分成了几类这里直接列 SQL-- 查看业务用户下所有表的行数波动区间抽样评估大表 SELECT table_name, num_rows, last_analyzed FROM all_tables WHERE owner APP_SCHEMA ORDER BY num_rows DESC; -- 统计大字段和分区表 SELECT table_name, column_name, data_type FROM all_tab_columns WHERE owner APP_SCHEMA AND data_type IN (CLOB,BLOB) ; SELECT table_name, partition_count FROM all_part_tables WHERE owner APP_SCHEMA; -- 统计存储过程、函数、触发器、序列、同义词数量 SELECT object_type, COUNT(*) FROM all_objects WHERE owner APP_SCHEMA GROUP BY object_type ORDER BY 2 DESC;为什么先跑这些因为 KingbaseES V8.6 虽然提供了 Oracle 兼容模式但“兼容”不代表“完全等价”。比如 Oracle 的 VARCHAR2 在非空约束下会把空字符串当作 NULLKingbase 的行为可能不同又比如位图索引 Oracle 支持Kingbase 需要手动调整为普通索引再比如间隔分区、复合分区这类特性迁移后可能需要改写或者降级为普通分区表。另外我习惯把全库的存储过程源码导出到本地直接用 IDE 搜几个特征函数DBMS_SCHEDULER、UTL_FILE、DBMS_LOCK、DBMS_ALERT、SYS_REFCURSOR、ROWNUM、CONNECT BY。这些基本就是迁移后必改的高频点。提前排查出来就不至于到了转换报告出来才发现一片红。1.3 目标端数据库初始化与兼容模式目标端安装 KingbaseES V8.6 时有个容易忽略但影响巨大的点数据库初始化阶段的“兼容模式”。如果安装时没有选择 Oracle 模式后面迁移进去的存储过程、函数、数据类型会有大量报错。我的建议是在做initdb或图形化安装选择模板库时显式选择 Oracle 兼容模式的模板库不同版本叫法可能有差异有的叫“Oracle模式”有的需要指定模板数据库安装文档里都写得很清楚。这一步和后面迁移是否顺畅强相关。目标端还需要提前准备好表空间和迁移用户。演示中我建了一个专用表空间并创建了与源业务用户同名的模式用户这样迁移时对象归属关系更清晰应用切换时改动也最小CREATE TABLESPACE tbs_app_data OWNER app_schema LOCATION /kingbase/data/app_data; CREATE USER app_schema WITH PASSWORD 请改成强密码 SUPERUSER; GRANT ALL PRIVILEGES ON TABLESPACE tbs_app_data TO app_schema;需要注意这里给迁移用户设置了超级用户权限方便迁移过程中自动建表、建索引、建约束。如果是生产环境我会建议迁移期间临时授权迁移完成后再回收并收紧权限。2. KDTS 迁移任务配置实战从连接配置到对象勾选2.1 源端 Oracle 连接参数与常见连接失败原因打开 KDTS 后第一步是新建迁移任务源库类型选 Oracle。这里需要填连接信息最常见的形式是 JDBC URL 直连。我当时源库是 Oracle 12c RAC 架构配置如下数据库类型Oracle主机地址192.168.x.xRAC 的 SCAN IP端口1521服务名/数据库名proddb注意这里要填 Service Name不是 SID用户名/密码迁移专用账号不是业务账号本身如果是 PDB 架构比如 CDB 里挂着 PDB那连接时要填 PDB 的 Service Name而不是根容器 CDB 的 Service Name。最开始我们一位同事填了根库的 service name连接测试一直报“ORA-01017: invalid username/password; logon denied”这其实不是密码问题而是连接到了错误的容器。KDTS 客户端本身自带 Oracle JDBC 驱动不需要在客户端机器上安装完整的 Oracle 客户端软件。但有个坑源端防火墙必须放通 1521 端口并且数据库的REMOTE_LOGIN_PASSWORDFILE相关设置不能影响远程连接。我在演示环境里把源库实例都正常运行但如果源库处于mount状态测试连接也会失败这个容易让人误判。连接测试成功后KDTS 会读取源库的元数据在对象列表里把表、视图、序列、函数、存储过程、触发器、同义词都列出来。这一步如果列表加载慢多半是源库的dba_objects视图查询慢不是什么工具 bug。2.2 目标端 Kingbase 连接配置与迁移对象勾选目标端配置比较简单填 Kingbase 的连接信息JDBC URLjdbc:kingbase8://192.168.y.y:54321/app_db用户名app_schema密码目标库密码注意 Kingbase 默认端口是 54321不是 5432。第一次连的时候我习惯先确认目标端kingbase.conf里的port参数免得拿着默认端口去套。接下来就是对象选择的环节。我的建议是第一次不要全选先勾“仅结构”跑一遍预迁移把对象层面的兼容性摸底完成了再跑“结构和数据”的全量迁移。原因是结构迁移失败会直接跳过数据迁移如果一上来就全选日志里会混着一堆结构失败导致数据未迁移的记录排错成本很高。我实际操作时把对象分成了三批第一批基本结构对象——表、视图、序列、约束、索引。这一批跑完库就“有架子”了。第二批逻辑对象——函数、存储过程、触发器、同义词。这一批是报错重灾区需要逐个看转换报告。第三批数据。结构没问题了才开始搬数据。还有一个细节如果你只想迁业务表不想迁日志表或中间表可以在勾选时把这类表排除掉。演示环境里就有几张几百 GB 的归档日志表业务上没必要迁到新库直接排除能省下不少时间。2.3 高级选项与映射规则批量提交、并行度、精度控制KDTS 的高级选项里有两类参数直接影响迁移性能一是批量提交行数。默认是 500 行一批但迁移大表时我习惯调整到 1000~2000 行。这个值不是越大越好——太大会拉长单批事务时间目标端 WAL 膨胀内存压力也上来太小的坏处是交互次数多整体吞吐上不去。比较稳的做法小表用默认值大表单独调高分批跑。二是并行度。KDTS 支持多个表并行迁移也支持单表内分片并行。演示环境是一台 8 核 16G 的虚拟机我没有把所有表都调成高并行而是控制总并行度在 4 左右避免 OOM。如果目标是物理机或者资源比较充足并行度可以提高到 8。字段数据类型映射默认是自动匹配的但有几个点必须人工确认NUMBER 类型Oracle 的NUMBER不带精度时Kingbase 里推荐映射成NUMERIC不要默认映射成DECIMAL(38,0)否则小数位会被截断。曾经遇到一个报表金额字段本身是NUMBER转换后直接变成整数对账全错。VARCHAR2(n)映射到VARCHAR(n)或CHARACTER VARYING(n)都能接受。但如果源库有中文数据且目标库字符集是 UTF8那么VARCHAR2(20)到底是按字节算还是按字符算需要看两端配置否则可能出现字段长度不足的报错。CLOB/BLOB自动映射问题不大但大批量 CLOB 写入会显著拖慢迁移最好单独一个批次跑并且适当调大批量。这里的核心原则是不要完全相信自动映射重点表的关键字段要人工过一遍映射结果。3. 迁移执行中的观察点与数据校验方法论3.1 结构迁移阶段哪些对象会失败哪些需要人工改写结构迁移跑完后KDTS 会生成一份迁移报告按对象类型分组汇总成功率。我们在模拟项目 X 中遇到的情况比较典型表结构、序列、索引、约束成功率接近 100%。个别索引因长度问题报错原因是 Kingbase 索引条目长度上限和 Oracle 不同字符集叠加后超出了限制需要改小索引列长度或改用函数索引/前缀索引。视图大部分能自动转换但带有CONNECT BY层级查询、ROWNUM分页、()外连接写法的视图会挂红或转换结果需要人工检查。KDTS 能把外层语法改过来但不代表逻辑等价。我自己遇到过一个视图里用了ROWNUM 10转换后语义正确但性能极差后来手动改成了窗口函数的写法性能才恢复正常。存储过程/函数这是重灾区。普通增删改查过程迁移成功率尚可但只要用到 Oracle 特有的包或特性就只能人工参与。比如UTL_FILE读写文件、DBMS_LOCK、DBMS_SCHEDULER、SYS_REFCURSOR动态游标以及大量隐式类型转换这些在 Kingbase 的 Oracle 兼容模式下部分有替代 API部分需要重写逻辑。迁移报告里每条失败记录都会附带转换日志类似这样[ERROR] Function: GET_EMP_NAME, 转换失败, cause: 不支持函数调用: DBMS_UTILITY.GET_TIME [ERROR] Procedure: SYNC_DATA, 转换失败, cause: 语法不支持: MERGE INTO xxx [ERROR] Trigger: TRG_AUDIT_LOG, 转换失败, cause: 触发器事件不兼容: BEFORE INSERT ON table我的工作习惯是拿到报告后先按对象类型统计失败数量再按失败原因归类。如果某类原因出现 20 次就统一写一个改写模板而不是一个对象一个对象地去翻代码。比如大量存储过程在EXECUTE IMMEDIATE里拼接了 Oracle 特有函数那我可以先用正则批量替换公共模式再逐个确认。3.2 数据迁移阶段大表与中断恢复结构迁移干净后开始数据迁移。KDTS 支持把对象任务拆成多个批次执行。我按表大小分了几个批次小表合并跑大表单独跑。执行过程中重点看两个指标当前表的已迁移行数、迁移速度。这里有个经验迁移大表时先把目标表的约束和索引全部跳过等数据搬完再补建索引和约束。因为带着索引迁数据每次提交都要同步更新索引速度会差很多。更稳的做法是在目标端先以无约束、无索引的堆表结构接收数据全部写入完成后统一建主键、唯一约束和常用索引。这也能避免数据迁移过程中因为约束冲突导致任务中断。中断恢复也是实际项目里绕不开的场景。有一次数据迁到一半源库那边有人误跑了批量更新导致同一批数据的前后快照不一致。KDTS 的任务重跑机制可以基于对象级别重新执行但不代表数据会自动做增量合并。稳妥的做法是数据迁移期间源业务应用暂停写入或者至少暂停和迁移表相关的写入。如果不能完全暂停就在迁移完成后对最后时间窗口内的增量数据单独导一次比如只导业务时间晚于迁移开始时间的数据。全量迁移完成后再补做一次数据一致性比对。另外连接超时也是数据迁移阶段最容易遇到的问题。目标端kingbase.conf里的tcp_keepalives_idle和statement_timeout如果设置得太短大批量写入期间连接可能被服务端杀掉。我习惯在迁移前把目标库的statement_timeout设为 0关闭或一个很大的值迁移完成后再按业务要求设回去。这个细节来自一次真实踩坑默认超时参数在大表迁移时频繁中断日志里全是连接被终止的记录当时还一度怀疑是网络问题。3.3 迁移后的数据校验三板斧数据迁移完千万不能看一眼 KDTS 显示“任务成功”就认为大功告成。任务成功只能说明两边的行数在迁移完成那一刻是一致的不能证明数据语义一致。我用的校验方法是三板斧第一板斧行数校验。对每张表分别在源和目标执行SELECT COUNT(*)做一个自动化的对比脚本。这里提示一个小技巧两张表聚合比对行数时尽量用两张表同时取数而不是先后取。因为先后取数的话如果中间有增量写入结果就不一致最后还要花时间排查是不是迁移漏了。脚本大概长这样-- 源库 SELECT orders AS table_name, COUNT(*) AS cnt FROM app_schema.orders UNION ALL SELECT user_accounts, COUNT(*) FROM app_schema.user_accounts; -- 目标库 SELECT orders AS table_name, COUNT(*) AS cnt FROM app_schema.orders UNION ALL SELECT user_accounts, COUNT(*) FROM app_schema.user_accounts;两边跑完直接人工或写个简单脚本比对输出。第二板斧抽样内容校验。行数一致不代表值一致。重点表要抽数据出来做内容比对尤其是金额字段、状态字段、日期字段。我一般每个表抽 1000~5000 行用主键关联对比若干关键字段的哈希值。更直接的方法是对关键表做MIN(id)、MAX(id)、SUM(amount)的聚合对比这种校验能在秒级发现“丢了数据”或“金额不一致”的问题。第三板斧业务试运行。找几条核心业务链路直接在目标库跑一遍。比如查订单列表、做一次对账、执行一个存储过程。这一步能发现数据校验发现不了的兼容性问题比如日期格式化规则差异、函数返回值和源库不一致。4. 应用层适配与高频问题排查4.1 应用 SQL 与存储过程重点改写清单迁移完成只是“数据库层面”完成应用层能不能跑起来是另一回事。KingbaseES 的 Oracle 兼容模式能消解掉大部分语法差异但总有一些类型和语义差异需要改写。就这次演示而言应用层需要动手的地方集中在以下几类第一类隐式类型转换。Oracle 允许某些情况下字符串和数字自动互转但 Kingbase 的行为更严格。比如WHERE amount 100在 Oracle 里大概率能跑Kingbase 里如果字段是数值类型就可能报类型不匹配。这种不必全改但应用新代码里建议直接写成WHERE amount 100。第二类分页查询。老代码里常见ROWNUM BETWEEN 1 AND 20的写法虽然 Kingbase 兼容模式下有函数和序列体系来模拟 rownum但性能通常不理想。建议统一改成LIMIT ... OFFSET ...或窗口函数方式。这也是性能优化的一部分不是单纯为了兼容性。第三类函数和包。存储过程和函数里用到 Oracle 特有包的场景上面已经提到过。典型案例是定时任务Oracle 里用DBMS_SCHEDULER创建的任务迁移后需要转成 Kingbase 的 job 机制比如通过扩展机制兼容CREATE JOB语法。这类改写不能靠 KDTS 自动完成需要应用开发介入。第四类自增列和序列。Oracle 12c 支持 identity columnKingbase 也支持序列和自增列但迁移后序列的当前值不会自动同步到历史数据的最大值。如果不处理应用插入新数据时会报唯一键冲突。这个必须有一步“重置序列到当前数据最大值”的操作。-- 假设表 app_schema.orders 的主键 id 使用序列 seq_orders_id SELECT setval(app_schema.seq_orders_id, (SELECT COALESCE(MAX(id),1) FROM app_schema.orders));这个命令每条序列都要执行一遍写个小脚本批量生成就行。4.2 高频报错与解决记录把这次迁移和过去几次国产化迁移里碰到的典型问题整理成一张速查表按场景和报错分类报错或现象原因分析解决办法连接源库报 ORA-01017连到了 CDB/PDB 错误的容器或密码错误确认 URL 里填 PDB 的 Service Name确认用户名密码function xxx does not exist存储过程里调用了 Kingbase 不存在的函数查兼容函数列表必要时新建同名自定义函数做桥接中文字段乱码源库字符集与目标库字符集不一致迁移前统一源和目标库字符集尽量都用 UTF8并在 JDBC URL 指定编码数据行数一致但金额对不上NUMBER 自动映射成整数类型引起精度损失迁移前人工调整映射规则NUMBER 映射为 NUMERIC大表迁移频繁中断目标库 statement_timeout 过短或网络不稳定临时调大 statement_timeout分批迁移禁用自动重试之外的人工干预插入数据报唯一键冲突迁移后序列起点小于表内已有数据最大值用 setval 重置序列视图/存储过程转换后逻辑异常工具转换语法不保证语义等价人工 review 高危对象重点测试涉及金额、日期、层级查询的逻辑索引创建报长度超限字符集和索引键长度共同导致减小索引列长度或改用哈希/前缀索引这里要单独提一下中文乱码问题。它的隐蔽性在于源库字符集如果是 ZHS16GBK目标库是 UTF8如果 JDBC 连接串上没有显式指定编码读出来的中文字符串可能是正确的写进目标库就变成乱码。而且肉眼看到乱码的时候往往已经有一批数据写进去了。更早的规避方法是迁移前确认两端字符集能在链路上正确转换用少量抽样表先试迁验证一下编码再做全量。4.3 上线前检查清单迁移演示做到最后一步必须把应用切到目标库。切换前我习惯跑一遍检查清单防呆对象完整性表数量、视图、序列、索引、约束、存储过程数量是否与源库一致结构迁移报告为准。数据完整性全表行数比对、抽样内容比对、关键业务试跑是否都通过。权限完整性目标库中应用账号是否有足够的增删改查、执行存储过程权限。经常有项目迁移完数据一切正常但应用访问报权限不足。统计信息目标库所有迁移过来的表重新执行ANALYZE或VACUUM ANALYZE否则优化器走错执行计划。回滚方案保留源库只读状态或者做一套“目标库切回源库”的演练。数据量越大这个越重要。监控与基线切换后记录关键业务的响应时间基线和源库对比尽早发现性能回退。这份清单打印出来逐项打勾而不是拍脑袋觉得“应该没问题”。我个人实际操作里的一点体会最后聊点感受。KDTS 这类官方迁移工具最大的价值是把“搬家和装修”的第一步自动化了让我能把精力放在那些工具替代不了的地方——语义检查、性能调优、应用改造。不要期待任何工具按一个按钮就完成全部国产化迁移架构层面的人为判断永远不可省。真要给后来者一个建议的话给自己多留出校验时间。数据迁移占用一天校验和改写可能要占两三天。尤其是存储过程改写很多时候不是语法不会写而是业务逻辑有没有理解清楚。做迁移的 DBA 最好能和业务开发坐在一起过一遍核心过程别只坐在终端前看日志。这是我做完这次迁移后最大的心得。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑