跳到主要内容
博客
首页>技术博客>信创适配不是换个数据库:回归测试清单、工期估法与三类缺陷
工程实践 · Engineering Notes

信创适配不是换个数据库:回归测试清单、工期估法与三类缺陷

信创适配的真实成本不在搬数据,而在行为回归。按五个层次划清改配置与改代码的边界,用三因子估工期,盯住金额精度、分页错行、时区三类缺陷。

优码云团队阅读约 15 分钟
信创适配国产数据库迁移去O改造回归测试达梦

国产化改造最常见的误区,是把它当成一次「数据库换壳」:用迁移工具把数据搬过去,跑一遍冒烟测试,功能页面能点开,就算适配完成。搬数据其实是整个工程里最确定、最容易自动化的那一段。真正决定成败的,是搬完之后那些既不报错、也不进日志的行为差异。

信创适配的本质是一次跨技术栈的行为回归,同时发生在操作系统、数据库、中间件、浏览器与终端、处理器架构五个层次。每一层的「必须改代码」与「只改配置」边界都不一样,混在一起谈,工期必然估不准。

一、先分清五个层次的替换边界

判断某处改动属于改配置还是改代码,标准不是「能不能启动」,而是「代码里有没有对旧环境的隐含假设」。硬编码路径、中间件的私有接口、对默认排序规则的依赖,都是假设。这类假设在替换后不会报错,只会悄悄改变结果。

层次典型替换对象大概率只改配置通常要改代码
操作系统麒麟、统信等国产发行版服务托管方式、文件路径、字体与时区、安全加固策略依赖特定内核接口的采集组件、硬编码库路径的加载器、依赖旧运行时行为的二进制
数据库达梦、人大金仓等国产库连接串与驱动包、初始化参数、账号权限SQL 方言、存储过程与触发器、隐式类型转换、分页与排序、序列与自增
中间件应用服务器、消息队列、缓存部署描述符、线程池与连接池参数、日志路径容器私有接口、类加载顺序假设、事务传播的边界行为
浏览器与终端国产浏览器、信创终端机浏览器标识白名单、下载与打印策略依赖私有插件的功能、依赖特定字体度量的报表排版
处理器架构x86 转 ARM(鲲鹏、飞腾)或龙芯依赖包版本、镜像基础层含本地库的第三方组件、内存对齐与字节序敏感代码、自编译扩展

这一层的现实约束是:官方兼容清单按「处理器 × 操作系统」组合逐条列,不是一句「支持麒麟」。以人大金仓某版本的「支持平台」表为例,飞腾 FT2000+ 配 UOS 20 是一行,龙芯 3A R4 配麒麟服务器版 V10 是另一行,同一颗处理器换发行版就是另一个登记组合。

所以选型时拿整机型号去对表,比拿「处理器品牌加系统品牌」分别对表更靠谱。原表可在金仓产品手册的支持平台章节核对。

二、兼容性盘点:把方言差异变成可勾选清单

数据库这一层最容易被低估的是初始化参数。达梦的若干关键参数只能在实例初始化时指定,后续不可修改。这意味着方言兼容策略必须在建库之前定下来,不能等测试报错再调。

按达梦技术社区的迁移实践,至少要提前拍板四件事。其一是字符集,默认国标编码,文档提示只存中文和字母数字时用国标编码更省空间,最好与源库一致。其二是长度单位,决定变长字符串按字符还是按字节计长,默认按字节。

其三是结尾空格。文档说明该参数置 0 时「’A’和’A ’被认为是相同的值」,置 1 时视为两个不同的值,而且「只能在初始化时候指定,后续不可以修改」,源端为 Oracle 时建议置 1。

其四是兼容模式。文档写明置 2 为兼容 Oracle,并提醒默认 0 的情况下,「达梦视null不等同于空字符串,用户可能会插入空串,会导致is null查不出全部数据」。这段分析和后面的截断、分区两个报错,都出自达梦技术社区《DTS 迁移的快速准备与常见问题解决》。

具体后果有两个。字符集不一致会截断:「数据中含有中文,目的端达梦为UTF-8,源端为GBK,因两个字符集中文所占字节数不同,导致目的端存储数据报错」。另一条是单条记录长度,「受到页大小的限制,不可以超过页大小的一半,所以建议一开始规划页大小为32K」。

把上面这些落成扫描清单,逐条标注「命中」「未命中」「待确认」,比开一次架构评审会有效得多。这类盘查清单的写法,可以参考我们之前整理的接手存量项目的体检清单。

  • 分页写法:旧式行号嵌套、偏移量分页、标准取前若干行三种写法是否混用;
  • 日期函数:当前时间函数、日期格式化、依赖区域格式参数的隐式转换;
  • 隐式类型转换:字符串与数字比较、空串与空值的等价性、布尔与数字互转;
  • 序列与自增:序列取下一个值、自增列、序列缓存与跳号;
  • 存储过程与触发器:存储过程包、自治事务、管道表函数、动态拼串;
  • 字符集与排序:结尾空格、大小写敏感、中文排序规则、函数索引失效;
  • 事务与锁:默认隔离级别、锁等待超时、死锁检测顺序;
  • 分区与索引:分区表主键约束、局部唯一索引、分区交换与分区删除语法。

分区这一项有明确的硬差异。达梦侧会直接报「局部唯一索引必须包含全部分区列」,原因是「Oracle的宽松机制允许主键不包含分区列,但在达梦更为严格,分区表的主键(或唯一索引)必须包含所有分区列」。这类约束在迁移当天就暴露,成本可控;麻烦的是静默通过的那些项。

三、回归测试清单:按业务后果排序

适配回归的排序原则应当是「错了会有什么后果」,而不是「哪个模块代码多」。按这个标准,顺序大致如下。

  1. 报表与统计口径:同一时间范围内,新旧库的汇总数是否逐项一致。金额、数量、税额的差异常来自精度与排序,而不是查询写错。
  2. 批量导入导出:表格导入、批量对账、历史数据导出。字符集、字段长度、空值语义的差异几乎都在这里出现。
  3. 并发与锁:并发领号、库存扣减、单据审批。锁等待与死锁顺序变化,会把偶发问题放大成生产故障。
  4. 长事务:结账、批量核算、月结任务。要测单位时间与回滚耗时,而不只是能不能跑完。
  5. 慢查询与执行计划:迁移后执行计划必然变化,索引是否要重建、统计信息是否要重新收集,都得实测。
  6. 备份与恢复演练:最常被跳过的一项,也是数据事故时唯一能救命的一项。重点不是备份成功,而是从备份恢复到可查询状态并核对行数。

还有一件事常被忽略:跨版本的风险有时比跨数据库更大。金仓的版本兼容说明里,2018.6 与 2019.11 两个历史版本标注为「Data文件不兼容,dump/restore不兼容,依赖SQL做移植」。可见在信创工程里,「同厂商升级」不能默认为零成本。

四、工期估法:三个因子,别数代码行

按代码行数估国产化改造,是最常见的系统性低估。一行查询语句的改造成本,和一行业务注解的改造成本差两个数量级;报表里一段嵌套子查询,可能比一个模块的增删改查加起来更费工。

可行的做法是把工作量拆成三个可盘点、可复核的因子:

因子计量口径取数方式主要误差来源
语句条数 × 方言差异比例去重后的可执行语句条数从数据字典抓存储过程、视图、持久层映射文件、报表模板、嵌入式语句动态拼接语句难静态统计;差异比例需抽样标注后外推
报表张数按「一张输出等于一个用例」计报表清单、打印模板、导出台账口径确认与业务方核对耗时远大于改写
外部接口数按对端系统数乘接口数计接口台账、网关日志、对方给的联调窗口联调排期不受己方控制

写成一个式子:总工作量约等于「语句条数 × 方言差异比例 × 单句修复工时」加「报表张数 × 单张回归工时」加「接口数 × 联调工时」,再加环境与压测固定项。

四项里前两项可以自己盘,第三项必须和外部系统对齐,第四项最容易漏掉——信创环境往往要单独采购、单独申请资源,等待时间可能长于开发时间。接口工期怎么拆,我们在系统对接开发的工期构成里单独写过。

举个纯示意性的算法,只为说明方法:把盘点出的语句条数,乘以抽样标注得到的方言差异比例,再乘单句修复工时(含回归),得到语句部分的工作量;报表按张数乘单张回归工时;接口按个数乘联调工时。三项相加后,再叠加环境与压测固定项,才接近可对外承诺的量级。

并行度建议分三段。试点阶段选两三个「有报表、有导入、有存储过程」的中等模块,单线跑通,用来校准方言差异比例这个系数。核心模块阶段按业务域或表簇切两三条并行线,共用同一套回归基线与对账脚本,否则并行越多、口径越乱。

全量切换阶段把窗口集中到业务低峰,前置条件是前两段的对账全部通过,而不是「代码改完了」。

五、三类最容易翻车的缺陷

1. 金额精度与四舍五入

Oracle 对数值类型相当宽松,换到严格类型上就会暴露。达梦的迁移常见问题文档记录了这类现象:表结构照搬过去、数据却插不进去。文档在分析时指出,源端整型会自动转成 38 位精度的数值类型,而「实际上在做插入的时候,精度超过 38 位,插入也是可以成功的」——源库能存下的数据,目标库未必。

所以报错反而是好事,它把历史脏数据暴露出来了。更危险的是舍入:四舍五入的实现差异、先聚合后舍入还是先舍入后聚合、以分为单位存整数还是以元存定点数,都会造成分位差异。

建议把金额字段单独拉一张对照表,按「字段、精度、舍入方式、展示位数」四列核对;对账脚本以最小货币单位做整数比对,避免浮点误差掩盖差异。原始说明见达梦《从 Oracle 迁移到 DM》常见问题。

2. 排序导致的分页错行

同一句「按时间倒序取第三页」,在两套库上返回的记录可能不是同一批。原因常常不在写法,而在两处:排序键没有唯一键兜底,时间相同的多条记录行序由执行计划决定;以及排序规则差异,例如结尾空格、大小写、中文排序。

结尾空格参数就是典型,它不只影响唯一约束判定,也影响等值比较与排序结果。同一批数据的「第三页」,在两种排序规则下可以是两批不同的单据。

信创适配回归测试中两套数据库引擎的金额精度与排序分页差异对比
金额小数位截断与排序不一致,是信创适配回归里最容易漏测的两类差异。

回归用例的写法要跟着改。分页用例不仅要断言本页条数,还要断言跨页累计行数等于总数、跨页没有重复主键、按业务键求和的校验和一致。这三条断言能抓出绝大多数翻页错行。

3. 时间与时区

时间问题的根因通常有三层:数据库时区、操作系统时区、应用与运行时时区。三者口径不一致,就会在跨天、跨月、跨年边界上出现一天偏差。信创环境下这三层常常同时被替换,风险叠加。

还有一类来自区域格式依赖。金仓的版本说明提到,新增插件实现了基于区域格式参数的日期时间隐式转换,并「加固修复TO_TIMESTAMP()函数,由原先的返回值类型TIMESTAMPTZ调整为TIMESTAMP」。

函数返回类型从带时区改为不带时区,是语义变化,不是纯兼容增强;原来能用的代码,返回值含义可能已经变了。核对方式很朴素:把日期转换与当前时间函数的调用点全部列出来,逐条确认输入格式、返回类型和时区假设。

六、验收与切换:双轨、对账、可回滚

验收的最小单元是业务闭环,不是功能可用。建议双轨并行覆盖一个完整的月度周期,至少包含一次月末结账和一次批量窗口,因为多数精度与排序缺陷只在跨月、跨批次的汇总里显形。

数据一致性核对分四层递进:行数与主键集合差集;关键金额与数量按维度汇总比对;抽样明细逐字段哈希比对;最后是对业务有意义的派生指标比对,例如余额、税额、库存周转。前两层能自动化,第三层要抽样,第四层必须业务方签字。

回滚预案要写清触发条件与动作,而不是写「必要时回滚」。触发条件建议量化到可观测指标,例如切流后某类单据的错误率或对账差异笔数超过阈值。动作至少包含连接串与域名解析回退、切换前备份的可用性验证、回滚期间数据补录的责任人。

切换当天把所有写操作收进单向只读窗口,是把回滚成本压到最低的做法。这类回退链路的设计细节,可对照桌面端应用的签名、更新与回滚里的版本治理思路。

如果你们正在评估存量系统的国产化改造范围,可以先看我们做过的项目案例,或直接把系统清单发过来做一次分层盘点。优码云的做法是先盘语句与报表、再定工期,双周交付一个可验证的增量。

常见问题

信创适配一般要多久?

没有统一答案,但可以先用三个因子框出量级:可执行语句条数与方言差异比例、报表张数、外部接口数。经验上,工时波动主要来自报表口径确认和外部联调排期,而不是语句改写本身。先花一到两周做分层盘点和两百条左右的语句抽样标注,得到的区间比拍一个「三个月」靠谱得多。

迁移工具能自动转换大部分语句吗?

能转换语法,不能保证语义。迁移工具可以把表结构、约束和大部分增删改搬过去,但初始化参数默认值(字符集、长度单位、结尾空格、空值与空串的等价性)、排序规则、数值精度上限这些语义差异,工具不会替你决定。工具跑完显示「迁移成功」,只代表对象建出来了。

测试环境跑通了,是不是就算适配完成?

不算。测试环境通常数据量小、并发低、没有真实的月末批量,恰好绕开了精度、排序和长事务三类缺陷的触发条件。至少要有一段双轨并行,用同一批业务数据在新旧系统上各跑一遍,再做四层对账。

操作系统和处理器架构需要单独测吗?

需要。厂商的兼容清单是按「处理器 × 操作系统」组合登记的,同一颗处理器换个发行版就是另一个组合。项目侧还要额外测含本地库依赖的组件和自编译扩展——这类问题在 x86 上永远复现不出来。

参考

分享到
全国城市服务