行业资讯
📅 2026/9/6 19:30:21
数据库迁移实战:Oracle 12c到达梦DM8全量+增量+停机切换方案
简介新老系统切换中的数据迁移往往决定B端产品上线成败也是信息化建设中外采转自研最易踩坑的环节。这份总结来自企业真实项目经验面向产品经理、项目经理与系统实施人员完整还原数据迁移全流程先分析迁移场景与系统切换方式双系统并行、一次性切换、按结算区间过渡再梳理基础数据、字典、用户、业务及在途数据的迁移范围与关联关系处理并对比Excel导入、数据库同步、接口传输、全量增量等离线与在线方案的适用条件最后给出数据验证与预演要点。文档按迁移场景、切换方式、迁移内容、迁移方式、数据验证五大模块组织可直接用于方案设计对照。整包为1个docx文档大小约15KB内容紧凑、结构清晰。目前已有126人学习适合正在处理新老系统替换或数据割接工作的从业者快速建立完整方案框架。 做过B端系统切换的人都有体会新系统开发半年上线前最重要但又最不起眼的环节其实是数据迁移。方案写得再漂亮数据迁不过去或者迁过去核对不平切换就得延期。B端项目里老系统往往跑了好几年核心表单表加流水类表动辄一两百张累计数据量十几个GB部分大表一天新增几十万条。新系统要上线老系统的数据不能丢、不能乱还得保证切换后业务能无缝接续。我最近刚完成的一个项目正好是典型的 Oracle 12c 迁到达梦数据库DM8场景。迁移过程中遇到过字符集乱码、大字段丢失、序列冲突、外键顺序报错、增量同步重复数据等一系列问题。这篇文章我会把整个过程中的方案设计、兼容性排查、全量迁移、增量追平、停机切换、校验回滚的做法完整整理出来顺手附上踩过的坑和最终的解决方式。对于正在准备数据迁移、系统切换相关工作的架构师、DBA 和后端开发应该能帮你省下不少试错时间。1. 方案选型与整体设计1.1 为什么不能直接“导出导入”完事数据迁移不是一个技术动作而是一条工程链路。很多人第一反应是把老库用工具导出再导入新库完事。真这么做大概率会在切换当天翻车。首先B端业务的表结构不会完全一致。换新系统通常伴随着业务模型调整比如老系统把客户联系方式存在一张副表里新系统可能直接在主表加了几列老系统的字典表用中文存新系统改成编码。数据迁移要先做映射而不是“把表导过去”。其次一致性要求高。B端数据错一条可能就是一笔对不上的订单、一条漏掉的客户记录。迁移后必须能做行数、金额、唯一性层面的双重核验。还有一个容易忽略的点新老系统切换往往不是“一次性复制”而是从准备迁移到正式切换之间隔着一段时间老系统还在持续产生新数据。方案里必须包含增量同步否则你导完的数据只是某个时间点的快照到切换当天又落后一大截。1.2 我采用的“全量 增量 停机切换”三阶段方案这次项目最终选择的是经典的三段式流程全量迁移先把老库的表结构和存量数据整体搬到新库得到一个基线增量追平每次按固定间隔把老库新写入或变更的数据同步到新库让两边尽量接近停机切换正式切换时先停老系统写入再做最后一次增量追平然后新系统接手这套方案的核心思想是把成本最高的全量迁移放到早期慢慢做把风险最高的增量追平压缩到切换前几十分钟内完成。我们实际安排的停机窗口大约是4小时其中真正花在“最后追平 校验”上的时间不超过30分钟。为什么不做在线双写同步B端核心链路一般没有现成的双写机制像订单、库存这类强一致场景做应用层双写等于把两个系统的代码耦合在一起成本高还容易出隐性 bug。停机窗口虽然影响体验但可控、可回滚反而更稳。1.3 数据一致性、回滚与演练正式迁移前我准备了两层保障缺一不可。第一层是“切换演练”。我们在正式切换前一周用生产数据的全量备份做了一次完整演练包括全量迁移、增量追平、校验、回滚。演练时发现的问题基本都被提前清掉了正式切换时候心里就有底了。第二层是“回滚预案”。数据迁移不是迁完就行还要考虑如果新系统上线后发现重大问题能不能退回去。我们当时把老系统设置为“只读”模式保留了7天而不是直接停掉。一旦新系统出现短时间内修不了的问题可以切回老系统继续服务只是不能写入新数据。迁移方案的本质不是“搬运方案”而是“保障业务连续性的方案”。2. 迁移准备与兼容性差异排查2.1 表结构、字段类型与字符集迁移前我们先把老库 DDL 全部导出和业务开发一起逐表梳理再在达梦上跑一遍。Oracle 12c 和达梦 DM8 在 SQL 语法上兼容度很高但细节差异仍然不少。Oracle 类型达梦推荐类型说明NUMBER(1)INT布尔语义字段统一用整型NUMBER(10,0)INT常规整数NUMBER(15)BIGINT超过 10 位整数建议用 BIGINTNUMBER(18,2)DECIMAL(38,6)金额类字段保留足够精度NUMBER(38)DECIMAL(38)注意达梦 DECIMAL 精度上限超长建议用 VARCHAR 存储VARCHAR2(4000)VARCHAR(4000)有中文时要注意按字符还是按字节定义BLOB / CLOBBLOB / CLOB迁移时需单独处理默认配置容易出问题DATETIMESTAMP达梦推荐使用 TIMESTAMP 避免精度丢失字符集方面老库是AL32UTF8新库我们统一约定用 UTF-8客户端连接参数里也强制指定 UTF-8。这个不提前处理好导进去的中文很容易变成“口口口”。而且字符集问题往往发生在连接层工具不报错数据悄悄烂掉所以必须提前锁定。2.2 SQL 语句与函数习惯差异迁移过程中最隐蔽的难点其实是业务流程里那几百条 SQL 没改干净。比如分页老系统用 Oracle 经典的ROWNUM方式SELECT * FROM (SELECT t.*, ROWNUM rn FROM USER_ORDER t WHERE STATUS 0) WHERE rn BETWEEN 1 AND 20;达梦支持LIMIT可以直接改成SELECT * FROM USER_ORDER WHERE STATUS 0 LIMIT 20;如果你只是简单搬库不动应用这个差异无所谓。但只要新系统还带着老代码做二次开发这类 SQL 就是隐藏坑。建议迁移前全局搜一遍ROWNUM、SYSDATE、NVL、DECODE等写法光排查就要花不少时间。函数方面我也整理过一张对照表Oracle 写法达梦推荐写法说明SYSDATENOW() 或 CURRENT_TIMESTAMP语义基本一致格式化输出不同NVL(a, b)NVL(a, b) / COALESCE(a, b)达梦兼容 NVL复杂表达式建议用 COALESCEDECODE(a, b, c)CASE WHEN a b THEN c END迁移时建议统一改成 CASE 结构TO_CHAR(d, YYYY-MM-DD HH24:MI:SS)TO_CHAR(d, YYYY-MM-DD HH24:MI:SS)基础格式通用部分格式修饰符 FM 有差异SEQUENCE.NEXTVALNEXT VALUE FOR sequence序列对象需要单独创建2.3 主键、自增列与外键约束老系统很多表靠序列生成主键。新系统如果用自增列要注意“历史数据已有主键”的冲突。我们当时用的是达梦序列 默认值方案迁移后先把序列的起始值设置为老数据最大主键 1再开启应用写入这样不会撞主键。外键约束也是重灾区。如果全量导入时按原表结构建了外键导入顺序不对就直接报主键冲突。我们全量导入时统一先禁用外键约束数据导入完成后再逐个启用校验能省非常多时间。不过要记住启用外键之前一定要跑一遍完整数据校验否则后面查问题更难。3. 全量迁移、增量追平与停机切换实操3.1 全量迁移工具选择与批量优化全量迁移我们用了达梦自带的数据迁移工具 DTS图形界面连上 Oracle选择目标库后它能自动识别表结构和大部分数据类型生成迁移脚本。小表直接迁移大表建议用命令行工具dmfldr做批量导入速度差别非常大。印象最深的是批量提交参数。默认情况下 JDBC 提交频率比较保守一次性提交几千条没问题但碰到几十万行的流水表就会很慢。实测下来把批量提交大小调到 5000 到 10000并且使用预编译语句迁移速度能提升 5 倍左右。表结构迁移完之后先别着急导数据。应先建“基本索引 主键”但大表的二级索引等数据导完再建。因为导入过程中每插入一条都要维护索引代价极高数据导完再统一创建索引编译一遍反而更快。3.2 增量追平数据同步点位设计增量追平是整套方案里最需要接住业务细节的地方。每一张需要同步的表都要判断能用什么条件做增量表里有CREATE_TIME/MODIFY_TIME时间戳直接按时间过滤没有时间戳但有递增主键按最大 ID 作为同步点位只有“插入”没有“更新”的流水表最简单既有插入又有更新、删除的表必须额外处理。我当时就用了一张CHANGE_LOG表由触发器在 Oracle 端记录变动的主键和操作类型增量同步程序读这张表做增删改增量任务我们设置的是每 15 分钟跑一次。每次跑之前先检查上次的同步状态比如LAST_SYNC_TIME、LAST_MAX_ID跑完把最新点位更新回去。这里容易踩的坑是如果你自己手写同步逻辑一定要把“同步点位更新”和“数据写入”放在同一个事务里。否则同步中途挂了重启后会重复拉同一批数据导致主键冲突或重复数据。3.3 停机切换当天的时间线我们的正式切换从周五晚高峰结束后开始安排如下23:30 老系统应用入口进入维护页禁止用户发起新写入交易23:35 停掉老系统所有后台任务、定时批处理23:40 执行最后一次增量追平追平窗口约 15 分钟00:00 开始做关键表行数校验、金额汇总校验、唯一性校验00:30 新系统正式启动开放内部白名单用户验证01:00 核心业务验证通过切换入口流量每个时间节点的操作都在迁移手册里提前写清楚负责人一目了然。切换当天一定不要即兴发挥所有命令行、数据库连接字符串、校验 SQL 都要提前准备好到时只是执行确认动作。3.4 重点表数据的校验方法校验是迁移的重中之重。光看日志“迁移成功”没有意义必须做数据级验证。我用三个方法交叉确认第一是行数比对老库新库逐张表SELECT COUNT(*)要求完全一致。第二是金额类汇总比如订单表、流水表对关键字段做SUM(金额)或SUM(ABS(字段))对比防止行数一致但内容错位。第三是抽样比对。我写了一个抽样工具从老库随机抽取若干条记录用多个字段拼业务主键后到新库回查比对关键字段是否一致。尤其是那些没有时间戳但业务含义很重要的描述性字段靠抽样最容易发现问题。校验结果要保留审计记录方便后续追溯。4. 新老系统切换中的典型问题与排查实录4.1 问题速查表迁移过程中遇到不少问题把典型问题整理成一张速查表基本都是直接用得上的经验。现象根因解决方式导入后中文乱码客户端字符集与数据库字符集不一致统一 UTF-8连接参数指定字符集后重新导入BLOB/CLOB 数据丢失或损坏工具默认对 LOB 处理不彻底使用 DTS 指定 LOB 处理策略或分表单独迁移主键冲突序列起始值设置不对迁移后执行 ALTER SEQUENCE 校准起始值外键校验失败全量导入时未禁用约束先禁用约束导数再逐个启用大批量导入慢JDBC 批次设置不合理调整批量提交大小关闭自动提交预编译 SQL达梦建索引失败字段类型或长度超限检查源字段映射定义长度按字符数重新定义存储过程报错Oracle 语法细节与 DM 不兼容逐个编译排查重点检查动态 SQL 中的函数写法增量同步重复数据同步点位和写入不在同一事务将更新点位与写入放在同一事务中时间数据错位老库带时区新库使用无时区 TIMESTAMP统一使用客户端时区转换或改用带时区类型4.2 最典型的三类坑中文乱码是我这次遇到的第一个坑。一开始用 DTS 迁移时看着导入进度正常但随机抽查发现部分描述字段变成了乱码。排查到最后发现问题不是工具而是客户端环境变量里的NLS_LANG没有设置成 UTF-8连接用的还是旧数据库字符集。这个很隐蔽因为错误发生在连接层不是数据层工具不会报任何异常。大字段迁移是第二个重灾区。BLOB 存图片、附件、合同文件量一大就麻烦。DTS 对 LOB 字段在默认配置下可能会分批读取失败导致个别记录丢失。解决办法是把含 LOB 的表拆出来用 DTS 的“仅结构”先迁移数据再用dmfldr单独导入并且导入完做一次字段级别抽样比对。第三个是自增序列。老系统用 Oracle 的SEQUENCE生成主键历史数据主键已经排到 100 万。迁到新库后如果直接把序列起点设成 1新插入数据立刻撞主键。迁移完需要执行一条类似ALTER SEQUENCE seq_user_order RESTART WITH 1000001的调整语句给每条序列按照对应表的最大值重新校准这类问题才会被根除。4.3 增量同步中的隐蔽问题增量同步还有一个容易忽略的场景老系统中存在定时任务批量 UPDATE 数据比如每天凌晨统一更新订单状态。如果同步任务恰好跨过这个时间点而表的增量字段用的是更新时间可能会有漏项或者重复。我们当时的处理是在增量同步 SQL 里设置一个“重叠窗口”每次查询条件往前多退 5 分钟拉到的数据先根据主键去重再写入能有效避免边界问题。另外增量追平阶段我不建议直接用MERGE或者UPSERT一把梭因为 B 端核心表通常有审计字段、版本号之类的逻辑直接覆盖容易造成数据丢失。更稳的做法是先记录到一张同步临时表再由业务方确认更新逻辑后统一应用。5. 切换完成后的验证与灰度放量5.1 上线初期的双轨监控正式切换完成之后不代表数据迁移工作就结束了。我在切换后的第一个业务周期内保持“双轨监控”老系统保留只读入口新系统记录所有关键操作的审计日志。两个系统同时能看到同一份数据源让业务同学在新老页面各查一遍核对计算结果是否一致。这种双轨监控不要持续时间过长一般 3 到 7 天即可。时间太长团队会疲于在两个系统间来回核对而且老系统数据不再增加比对的意义会越来越小。5.2 灰度放量与回滚开关对于重要系统我会再加一层灰度放量。先让某个事业部、某个仓库或某个客户群使用新系统观察数据有没有异常没异常再逐步放量。放量粒度要小最好能通过配置开关动态调整而不是发版改代码。回滚开关也需要提前埋好。我们的做法是新系统所有写操作都要走一层抽象接口一旦出现严重问题应用层可以一键把写操作切换到“拒绝/记录”模式业务链路切回老系统只读页面。这种开关平时是不开启的但必须经过演练验证不能到关键时候发现开关失灵。5.3 收尾工作旧库归档和监控清理切换稳定后还有两个容易被忽略的收尾工作。老库不建议立刻删除我一般保留只读状态 15 天然后转成离线归档打包再保存一段时间。数据迁移这件事上老库是最后的保险绳删早了风险极大。新库的监控要持续观察一段时间特别是慢查询、锁冲突、大事务这些指标。因为迁移后统计信息、执行计划可能和原来不同原本在 Oracle 上跑得飞快的 SQL在达梦上不一定同样快。要给新库建好索引、更新统计信息把执行计划调优做扎实。这次项目做完我最大的体会是技术工具只是数据迁移的入口真正决定成败的是流程、校验、回滚这些看起来很笨的功夫。如果你正准备做 B 端新老系统切换建议把迁移方案拆成可执行的步骤、可验证的口径和可回滚的预案切换当天才会从容很多。本文还有配套的精品资源点击获取