简介:一份面向B端产品经理与系统实施团队的数据迁移实战总结,聚焦新老系统切换过程中的核心难点与应对策略。文档基于作者多项目的外采转自研经历,整理了常见的系统切换方式(如并行运行、一次性切换、按结算区间切换),并系统梳理了迁移内容,包括基础数据、字典数据、用户数据、业务数据以及需要特别关注的在途数据,同时兼顾数据间关联关系映射与附件文件同步等细节。对于迁移方式,文档对比了离线迁移(Excel导入、Sql批量导入)与在线迁移(接口传输、数据库同步全量+增量)的适用场景,并强调了数据验证的重要性,给出了基础数据预同步、历史数据关联验证、在途数据业务操作验证等实操思路。资源为单个docx文档,仅15KB,内容精炼,共126人学习,适合正在规划系统升级或数据迁移的B端产品相关人员快速查阅。
1. 切换前必须想清楚的三件事
1.1 迁移范围的界定——别一上来就全量搬
接手B端产品新老系统切换的数据迁移工作,第一件事不是打开数据库导出工具,而是先坐下来把迁移范围掰开揉碎看清楚。我从经验里总结出一个教训:迁移范围界定的颗粒度,直接决定了后面所有工作的复杂度。
很多人一听到数据迁移,下意识就是“把老库里所有表所有数据都搬到新库”。但在真实的B端产品里,数据并没有那么简单。老系统运行了五六年,里面可能有几十张甚至几百张表,其中相当一部分是临时表、日志表、归档表,甚至还有历史遗留的废弃表。这些表要不要迁?迁过去会不会拖垮新系统的性能?新系统数据库如果是达梦,表空间和Oracle不一样,数据量级的承载方式也不同,这时候全量搬过去就是给自己挖坑。
我当时的做法是先做一轮表清单盘点。具体来说,分三步走:第一步,从老库中导出全部表的清单和行数统计,按行数倒序排列;第二步,和业务方逐个确认每张表的业务归属和留存价值,把明确不再使用的表打上“不迁移”标记;第三步,对需要迁移的表做数据保留期限评估,比如日志表只保留最近半年。这样一轮下来,实际需要迁移的表数量可能只有原库的一半左右,迁移工作量直接砍半。
另一个容易被忽略的点是序列、视图、存储过程、触发器和函数这类数据库对象。B端系统的业务逻辑往往有一部分沉淀在数据库里,这些对象在切换时必须一并迁过去,否则应用上线后一调用存储过程就报错,属于那种“表面看着表都迁完了、实际一跑就崩”的情形。我在迁移方案里把数据库对象单独列了一个章节,每一类对象都标注了迁移方式和验证方法,这一点后面细说。
1.2 数据质量摸底——脏数据比预想的多
迁移范围定下来之后,紧接着要做的是数据质量摸底。这句话听起来像废话,但实际操作时,几乎所有第一次做迁移的人都栽在“我以为老库数据是干净的”这个假设上。
B端产品运行多年,数据质量问题几乎不可避免:客户主数据有重复记录,订单表里有测试数据没清理,身份证号字段里存了汉字,日期字段里混入了非法格式,编码字段出现NULL值但业务逻辑里没有做空值判断。这些问题在Oracle里可能一直“平安无事”,因为Oracle的约束宽松、类型转换宽容,很多脏数据就这么静默存了多年。但迁到达梦数据库之后,字段类型映射、约束校验逻辑可能发生变化,这些脏数据就会变成迁移报错的源头,更麻烦的是——它可能在迁移工具里不报错,但到了新系统上线后某个夜间跑批任务里突然炸出来。
所以我在正式迁移前,专门安排了一轮数据质量探勘。操作上不复杂,写一批SQL去逐表逐字段做规则校验:主键是否有重复、外键关联是否能对上、非空字段是否有NULL、日期字段能否被TO_DATE正常解析、编码字段是否在字典表范围内。每张表跑完生成一份报告,标注问题行数和样例。这个过程比较枯燥,但必须做,因为它是后面迁移执行阶段减少返工的最大保障。
有一个非常典型的案例:老系统客户表里面有大量“已删除”状态的记录,删除标记只是一个状态位,数据本身还躺在表里。业务方说可以一起迁过去,于是我就没有单独过滤。结果迁移完成后,新系统里查询客户列表时,应该默认过滤已删除客户的逻辑因为状态位定义不同没生效,导致线上出现大量废弃客户的脏数据,花了整整一周才清理干净。后来我在迁移方案里强制加了一条规则:所有需要过滤的数据,必须在迁移SQL里明确写清楚过滤条件,不允许“全量搬过去再说”。
1.3 停机窗口评估与迁移策略选型
B端产品做新老系统切换,最核心的一个限制条件是停机窗口。很多企业不允许业务长时间中断,尤其像订单、财务、库存这类系统,停机时间通常以小时甚至分钟计算。停机窗口的长度直接决定了你选择哪种迁移策略。
我总结下来,常用的迁移策略有四种,分别是停机全量迁移、全量加增量迁移、双写迁移和滚动迁移。停机全量迁移最简单,适用于数据量不大、业务允许停几个小时的场景;全量加增量迁移适用于数据量较大,先迁全量快照,再在停机窗口内追平增量;双写迁移最复杂,要求新老系统同时写入,适合几乎不允许停机的场景;滚动迁移则需要按业务模块逐个切换,周期长但风险可控。
实际项目中,绝大多数情况落在第二种,即全量加增量。这个策略的核心在于老系统在导出全量数据之后仍然会持续产生新数据,所以必须在停机窗口内把这段时间产生的新数据也同步过去,才能保证最终一致性。我倾向于在迁移方案里设计两个阶段:预迁移和正式切换。预迁移阶段先跑一次全量搬迁,把大表历史数据运过去,同时记录这个时间点;正式切换阶段,业务方在停机窗口开始时停止写操作,然后对预迁移之后产生的新数据做增量同步,最后校验、启用新系统。
Oracle 12c到国产达梦数据库的迁移,有一个和传统同构数据库迁移不同的地方:Oracle的物化视图、分区表、高级队列等特性,在达梦里不一定有完全对等的实现。我遇到的情况是,老系统一张分区表,在达梦里最简单的做法是退化为普通大表,然后靠定期归档来控制表体量。这个改动会直接影响未来几年的运行效率,所以必须在迁移方案里明确写清楚,而不是等工具报错之后再来临时决策。
提示:不要跳过“迁移策略选型”这一步直接进入执行。策略选型的核心产物是一份明确了时间节点、负责人和回退条件的迁移计划书,它既是执行依据,也是出事时的应急手册。
2. 迁移方案设计与工具链评估
2.1 Oracle 12c到达梦数据库的适配难点
信创背景下,从Oracle迁移到达梦数据库已经是非常常见的场景。市面上有很多工具声称“一键迁移”,但实际操作后你会发现,所谓的一键迁移只能覆盖最基础的表结构转换,一旦涉及存储过程、包、函数、序列、触发器等PL/SQL代码,适配工作才刚刚开始。
Oracle和达梦虽然都是关系型数据库,语法绝大部分兼容,但在细节上存在不少差异。举几个我实际踩过的坑:Oracle的NVARCHAR2类型在达梦中需要映射为VARCHAR2,长度单位也要从字节调整为字符;Oracle的SYSDATE在达梦中对应SYSDATE,但SYSTIMESTAMP的行为有差异;ROWNUM和ROWID在达梦中虽然支持,但某些复杂查询下性能表现完全不同;Oracle的CONNECT BY层级查询在达梦中语法兼容但部分写法会报错。这些都是迁移工具不会帮你处理的,必须靠人工逐个排查。
另一个典型问题是隐式类型转换行为。Oracle在很多场景下允许隐式转换,比如字符串和数字比较时会自动转换,而达梦在某些版本下对这种写法会直接报类型不匹配错误。这意味着老系统里写得很随意的SQL,到了达梦上可能第一步解析就失败。我在做应用侧适配时,专门让开发团队给所有SQL执行计划做了一遍回归测试,重点排查那些依赖隐式转换的写法。
2.2 达梦自带迁移工具与第三方工具的取舍
达梦数据库官方提供的迁移工具是DTS(DM Migration Tool),支持从Oracle、MySQL等多种数据库迁移到达梦。我在项目中第一轮用的就是它。总体感受是:对于表结构和常规数据的搬迁,DTS够用,操作也不算复杂,但在处理大规模数据、复杂对象和进度反馈方面体验一般。
DTS最让我不满意的是数据搬迁环节缺少可靠的断点续传机制。我当时迁移一张大约七八亿行的大表,跑了两个多小时,结果在最后阶段因为网络闪断导致任务中断,整个迁移过程要从头再来,给项目造成了很大压力。后来我改用DTS做小表迁移,大表则用达梦的dmfldr工具配合自定义分页导出脚本,虽然前期准备麻烦一些,但至少断点续传和并发控制都有了保障。
除了官方工具,我还评估过另外两种路径:第一种是先导出为通用格式文件(如CSV或文本格式),再通过达梦的批量导入工具加载;第二种是使用开源ETL工具如Kettle或DataX,将Oracle作为源端、达梦作为目标端。最终我的选择是混合方案:普通小表走DTS,大表走DataX或dmfldr,存储过程和代码对象走手工适配。这里没有统一的银弹,工具选型的核心原则就一条——小表要快、大表要稳、代码对象要人肉盯。
注意:无论使用哪种迁移工具,都必须在正式迁移前做一次全流程的演练。演练和正式迁移的流程、参数、账号权限必须完全一致。演练时发现的所有问题,逐条记录并给出解决方案,这是正式切换顺利进行的底气。
3. 实操过程与核心环节落地
3.1 迁移前的完整检查清单
在动手执行迁移之前,我习惯先按一份固定清单做逐项检查。这份清单不是在项目初期就确定下来的,而是在整个过程中不断扩充、完善出来的,几乎每次出问题都能往里面补一条。以下是我最终定稿的检查清单精华版:
- 数据库版本和补丁级别是否确认?Oracle源库的字符集、时区、数据库版本要和迁移方案里写的一致;
- 源库和目标库的账号权限是否最小化开放?至少在迁移期间,需要源库具备读取所有待迁移对象权限,目标库具备建表、插入、创建对象的权限;
- 磁盘空间是否充足?目标库表空间剩余空间要留出至少1.5倍数据量的余量,因为迁移过程中的临时表、索引重建、日志文件都会额外占用空间;
- 网络链路是否稳定?源库和目标库之间的网络延迟、带宽、是否有防火墙策略,都直接影响大表搬迁的速度和稳定性;
- 字符集是否已对齐?Oracle的AL32UTF8和达梦的UTF-8在理论上兼容,但实际迁移时建议先用几张小表做字符集验证,特别是那些包含生僻字、表情符号的字段;
- 迁移期间的日志记录是否开启?建议同时开启工具日志和数据库会话级日志,方便事后回溯;
- 回退方案是否明确?如果迁移后面临不可控问题,是否有办法在最短时间内切回老系统?数据变更的逆操作怎么处理?
很多人看到清单会觉得麻烦,但实际经历过一次迁移事故之后,你就会明白清单的每一行背后都是鲜血换来的教训。我当时因为在清单上漏了“源库归档日志空间检查”这一项,迁移过程中源库归档日志撑爆了磁盘空间,导致源库整体不可写,差点酿成生产事故。
3.2 表结构迁移的完整过程
表结构迁移看起来是最简单的环节,拿着工具点一下“转换”按钮就完事,但实际上这里面的坑最多。我建议不要完全依赖工具自动生成建表语句,因为工具的转换规则是通用的,它不认识你的业务,不知道哪些表是大表、哪些字段是高频查询条件,这些信息会直接影响表结构在目标库中的设计。
我的做法是:先用工具生成一份结构转换对比报告,然后人工审核所有建表语句。审核的核心点包括:字段类型是否映射正确;VARCHAR2的长度单位变化是否会导致长度截断;主键、唯一约束、外键、检查约束是否完整保留;索引是否丢失;分区策略是否需要调整;表的存储参数(如表空间、PCTFREE等)是否需要重设。
以大表为例。老系统在Oracle里建了一张订单流水表,行数超过五亿,按月份做了范围分区。迁到达梦之后,我决定同样按月份建分区,但达梦的分区表在建表语法和分区修剪执行计划上和Oracle有些差异,不能直接照抄。我参照达梦的官方文档重写了建表语句,并且在迁移完成后专门验证了分区裁剪是否生效——查询某个窄时间范围时,执行计划里必须体现只扫描对应分区,否则相当于全表扫描,性能会差几十倍。
索引迁移也是结构迁移的重点。Oracle里一张表通常有三个到五个索引,包括主键索引、业务查询索引和部分唯一索引。这些索引在迁移时不能原封不动地搬,因为查询模式的差异和优化器的差异可能导致原本在Oracle里效率正常的索引到了达梦上变成性能瓶颈。我在迁移后花了不少时间用达梦的慢查询日志找出那些没有走索引的SQL,逐条分析原因,有选择地增加组合索引或调整索引字段顺序。这一步对上线后的用户体验影响非常大,绝对不能省。
3.3 数据搬迁的三种核心方式与实测对比
数据搬迁是整个迁移过程中最耗时、最容易出问题的环节。我在项目里实测了三种方式,各有优缺点,下面逐一说明。
第一种方式是官方迁移工具DTS。优点是配置简单、图形化操作、对小白友好;缺点在前文已经提过,大表迁移缺少断点续传能力,且并发度默认设置比较保守。实测下来,DTS迁移一张千万行的表大概耗时二十分钟左右,但如果这张表行数过亿,耗时呈线性增长,任务失败的风险也随之上升。
第二种方式是DataX,阿里巴巴开源的离线数据同步工具。它的优势在于支持自定义并发度和切片逻辑,能充分利用多线程能力;缺点是需要自己写JSON配置文件,对使用者有一定门槛。实测下来,DataX在目标库表结构已经预先创建好的前提下,三千万行的表配置八个并发通道,耗时大概在八分钟到十分钟之间,速度比DTS明显快。DataX还内置了数据校验功能,可以在同步完成后按行数或摘要做快速比对,这一点非常实用。
第三种方式是达梦的dmfldr批量加载工具。它适合从文本文件快速加载数据,性能在三种方式里最强悍,但前处理工作最多:需要将Oracle的数据先导出为定长或分隔符格式的文本文件,且要求字段顺序与目标表严格一致。实测中,一亿行的表用dmfldr加载,加上文件生成和传输的时间,整体耗时可能和DataX差不多,但如果只算纯加载时间,它是最快的。
我最终的策略是:行数在五百万以内的表,直接用DTS处理,快且省事;行数超过五百万的表,统一走DataX加并行通道的方式;个别超过一亿行的超大表,先用Oracle的datapump导出为文本格式,再用dmfldr批量加载。每种方式我都记录了执行耗时和数据校验结果,这些记录最终汇集成一份迁移执行报告,作为项目验收材料的一部分。
3.4 增量同步与一致性校验的实操记录
增量同步是切换过程中最考验细节的环节。预迁移阶段把存量数据搬过去之后,源库原有的数据还在持续变化,增量同步要解决的就是这段“追上”的问题。
Oracle 12c本身有物化视图日志机制,达梦也有相应的同步方案,但两者对接起来并不顺利。我最终采用的是最简单的方案:利用Oracle到点恢复机制和达梦的逻辑备份恢复功能,在停机窗口开始时将源库切换到归档模式,做一次最后的增量日志应用,然后把这个增量应用到目标库。这套流程虽然朴素,但胜在可控,不会引入复杂的实时同步中间件。
一致性校验环节我分两层做。第一层是行数校验,用SQL分别统计两张表的行数做对比;第二层是摘要校验,通过计算某些关键字段的聚合值(比如金额字段的SUM值)做对比。两层都通过了,我才会在切换评审会上签确认单。如果校验不一致,必须追溯到具体的差异记录,定位到差异原因并且解决之后,才能允许切换继续。这里提醒一下:校验SQL务必在源库和目标库都做同样的去重和过滤处理,否则条件不一致会导致假差异,白白浪费时间排查。
注意:迁移工作做完并不代表切换成功,新系统上线后需要持续观察一周左右,重点关注日常查询响应时间、夜批任务执行时长、后台报表生成速度等指标,中途建议安排专人值守。等新系统真正稳定跑过一轮完整的业务周期之后再精简运维措施。
4. 常见问题与排查技巧实录
4.1 迁移中断与恢复策略
在B端数据迁移项目里,迁移中断几乎是必然会发生的事情,只是时间早晚的问题。网络抖动会导致同步工具断连,目标库磁盘空间不足会导致写入失败,源库数据库触发一个长时间的锁等待也会拖垮迁移任务。问题不在于怎么避免中断,而在于中断之后怎么快速恢复。
我总结了一套恢复策略:所有迁移任务在执行前都记录一个“检查点”,包含当前已完成的表清单、每张表已导入的行数、导入会话的日志位置。一旦任务中断,根据检查点判断是从头开始还是从断点继续。对于DTS这类不支持断点续传的工具,我会事先把大任务拆成若干小任务,每个小任务独立运行并记录状态,中断后只需要重跑未完成的小任务即可,不需要全量重来。
另外,迁移任务的服务器和数据库之间,强烈建议通过稳定的内网链路传输,尽量不要走公网。公网传输的抖动概率和带宽波动都不是你能控制的,一次大表迁移跑到一半断掉,重跑的代价巨大。
4.2 字符集与编码问题
字符集问题是跨数据库迁移里最容易阴人的隐藏坑。Oracle的AL32UTF8和达梦的UTF-8虽然都叫UTF,但在生僻字的存储方式、排序规则、长度计算等方面存在细微差异。我在项目里专门找了一批包含生僻字、繁体字、emoji表情的测试数据做迁移验证,结果确实发现部分生僻字在达梦里出现了乱码现象。
排查之后发现,问题出在客户端连接字符集配置上。Oracle客户端的NLS_LANG设置和达梦客户端的CHARACTER_CODE设置如果不一致,数据传输过程中会发生转码错误。解决办法是统一两端客户端的字符集配置,并在迁移完成后用SQL查询的方式抽检特殊字符数据,而不是只看工具日志里的“迁移成功”状态。
还有一个更隐蔽的点:Oracle的VARCHAR2在AL32UTF8字符集下最大长度是字节数,而达梦的VARCHAR更倾向于字符数计算。如果老系统的字段长度定义刚好压着边界,迁到达梦后同样的数据可能存不下。我建议在结构转换时统一将字符型字段的长度按字符数重新评估,并且留出一定的扩展余量,避免上线后出现“正常业务写入时报ORA-12899类似错误”的情况。
4.3 性能回退的排查思路
数据迁移完成只是第一步,新系统上线后的性能表现才是真正检验迁移成果的标尺。我遇到过的典型情况是:同一套业务SQL,在Oracle里执行几十毫秒,迁到达梦后变成几秒钟。这种性能回退如果不能及时解决,业务部门会直接质疑整个切换项目的价值。
排查性能回退,我通常按以下顺序处理:先看执行计划,确认是否走索引,扫描行数是否合理;再看统计信息,达梦如果没有及时更新统计信息,优化器可能做出错误判断;然后检查索引策略,是否需要增加组合索引或调整索引顺序;最后看SQL本身是否有依赖Oracle特殊优化器特性的写法,比如在海量数据上使用NOT IN或NOT EXISTS,这些在达梦上往往会有完全不同的执行方式。
有一个让我印象很深的例子:老系统一条列表查询SQL在Oracle里用了ROWNUM做分页,迁到达梦后虽然语法兼容,但执行计划是全表扫描加排序,导致接口响应从几百毫秒涨到十几秒。后来按达梦的推荐方式改写成使用LIMIT关键字分页,并且在排序字段上增加了组合索引,响应时间才降回到可接受范围。性能问题没有银弹,必须一条SQL一条SQL地排查,这也是为什么迁移项目上线前一定要安排充分的回归测试周期。
4.4 应用侧兼容性适配的经验总结
数据迁移只是新老系统切换的一部分,真正的难点往往在于应用侧如何适配新数据库。B端产品的业务逻辑除了页面交互,还有大量后台任务、定时调度、报表计算,这些逻辑里暗藏的数据库依赖,很多时候连开发人员自己都没意识到。
我这边实际遇到的兼容性问题包括:老系统代码里用到了Oracle特有的(+)外连接写法,达梦虽然兼容但建议改写为标准的LEFT JOIN;使用了WM_CONCAT之类的非标准聚合函数,在达梦里需要用LISTAGG替代;还有应用连接池的配置,Oracle JDBC驱动和达梦JDBC驱动在URL、驱动类名、校验SQL上都有差异,如果没配置对,服务一启动就报连接失败。
针对这一类问题,我建议在迁移项目中设置一个“应用适配专项”,由开发团队和DBA团队一起参加,按模块逐个梳理DB相关代码,建立“数据库语法兼容性”清单,逐条验证替代方案。这个过程没有太多捷径,但可以通过引入SQL审核工具或静态代码扫描来辅助发现潜在的兼容性问题。我实际用下来,静态扫描能筛出大概六成的问题,剩下的还得靠代码审阅和回归测试来兜底。
切换过程中数据迁移这场仗打到后面,拼的就是细心和预案。每个环节的确认单、每个工具的执行日志、每次问题的记录与复盘,这些平时看起来不起眼的文档,在关键时刻可能是救命的依据。老系统切换到新系统,真正让人安心的不是某一次“迁移成功”的提示,而是整套流程里每一个不确定点都有对应的验证结果和备选方案。
本文还有配套的精品资源,点击获取