1. 项目概述:为什么一个数据库迁移工具值得花一整天去拆解?
“达梦数据库DTS工具MySQL→DM8”——这串字符看起来像是一行命令、一段配置,甚至可能被误读为某个内部系统代号。但在我过去十年接触过的数百个国产化替代项目里,它实际代表的是一个真实、高频、且容错率极低的关键动作:把运行在MySQL上的核心业务数据,安全、完整、可验证地迁移到达梦DM8数据库中。这不是简单的“导出再导入”,而是一场涉及字符集映射、SQL语法兼容性、主键约束重建、时间类型对齐、自增列迁移策略、外键依赖顺序、以及事务一致性保障的系统性工程。
我第一次遇到这个需求,是在某高校教务系统国产化改造现场。原系统用MySQL支撑了八年,表结构复杂,触发器和存储过程嵌套三层,还有大量使用GROUP_CONCAT和JSON_EXTRACT的查询逻辑。当时团队直接用Navicat导出SQL再导入DM8,结果第二天凌晨三点收到告警:学生成绩单页面报错“ORA-00904: invalid identifier”,查了一小时才发现是MySQL里的反引号字段别名在DM8里不被识别。后来我们花了整整两天重写迁移脚本,才把问题压下去。从那以后,我养成了一个习惯:凡是涉及MySQL到DM8的数据迁移,第一件事不是点“开始迁移”,而是先打开DTS工具的日志面板,把“SQL转换日志”和“对象映射报告”调出来看三遍。
这个标题背后藏着三类人最关心的问题:一是DBA,他们要确保迁移后数据零丢失、索引不降级、执行计划不劣化;二是开发人员,他们得知道哪些SQL要改、哪些函数要替换、应用层是否需要适配;三是项目负责人,他们需要一份可审计、可回滚、可量化耗时的迁移方案。DTS不是万能胶,但它确实是目前国产数据库生态中,为数不多能把这三类诉求拧在一起的成熟工具。它不解决所有兼容性问题,但把90%的重复劳动封装成可视化操作;它不替代人工校验,但把校验点标准化为“结构比对”“数据比对”“行数校验”“抽样校验”四个可勾选动作。接下来的内容,我会完全基于实操视角,带你一层层剥开DTS在MySQL→DM8场景下的真实能力边界、隐藏参数、踩坑现场和绕过技巧——不讲原理图,不贴官方文档截图,只说我在机房里调参数、看日志、改配置时记下的真实笔记。
2. 整体设计思路与方案选型逻辑:为什么是DTS,而不是mysqldump+手动改写?
2.1 迁移路径的三种典型模式对比
在决定用DTS之前,我通常会快速评估三个备选路径,并用一张表锁定它们的适用边界:
| 方案 | 核心操作 | 适合场景 | 数据一致性风险 | 人力投入(人/天) | 典型失败点 |
|---|---|---|---|---|---|
| 纯SQL导出导入 | mysqldump --compatible=oracle+ 手动替换语法 | 表结构简单、无存储过程、数据量<10万行 | 高(字符集乱码、精度丢失、自增ID重置) | 0.5–2 | TINYINT(1)被转成NUMBER(1)导致布尔值失效;NOW()未转为SYSDATE |
| ETL工具中转 | Kettle/Pentaho配置转换规则,中间落地CSV或Parquet | 需要清洗加工、字段映射复杂、有业务逻辑转换 | 中(依赖中间文件完整性校验) | 2–5 | 时间戳时区未统一导致数据偏移8小时;大字段(TEXT)截断无提示 |
| DTS工具直连迁移 | 配置源/目标连接、选择对象、启用SQL自动转换、开启一致性校验 | 主流业务库迁移、需审计留痕、要求回滚能力 | 低(内置事务分片、断点续传、校验机制) | 1–3 | 对象名含特殊字符未转义;目标库表空间不足未提前预警 |
这张表不是凭空画的。去年我参与的一个医疗影像元数据迁移项目,最初选了Kettle方案,因为对方强调“要对DICOM标签做标准化清洗”。结果跑通第一轮后发现,Kettle默认把MySQL的utf8mb4字符集识别为UTF-8,而DM8的UTF-8实际对应utf8(不支持4字节emoji),导致患者姓名里的生僻字全变成问号。临时切到DTS后,我们在“高级选项”里勾选了“强制使用UTF8MB4编码”,并把“字符集转换策略”设为“保留源字符集,目标库自动适配”,问题当天就闭环。这件事让我彻底放弃把ETL当“万能中间件”的想法——DTS的底层驱动是达梦自己的JDBC协议栈,它对DM8的类型体系、权限模型、锁机制的理解,远超任何第三方工具。
2.2 DTS的核心设计哲学:不做翻译器,做协调员
很多人误以为DTS是个SQL翻译器,输入MySQL语句,输出DM8语句。这是根本性误解。DTS真正的角色,是数据库迁移协调员——它不负责逐行翻译,而是构建一套“对象生命周期管理模型”:从连接建立、元数据采集、结构转换、数据抽取、批量加载、约束重建,到最终校验,每个环节都预设了检查点和回退开关。
举个具体例子:MySQL的AUTO_INCREMENT主键,在DM8里对应的是IDENTITY列。但DTS不会简单地把id INT AUTO_INCREMENT改成id INT GENERATED ALWAYS AS IDENTITY。它会先检查目标表是否存在、是否有同名约束、当前最大ID值是多少,再决定是启用START WITH参数从原最大值继续,还是清空表后从1开始。这个决策过程藏在DTS的日志里,格式是:
[INFO] IdentityColumnHandler: target table 'student' exists, max_id=12847, will set START WITH 12848 to avoid duplicate key error如果你没打开详细日志,就永远不知道DTS默默帮你避开了多少主键冲突。这种“隐式智能”正是它区别于脚本工具的关键——它把DBA的经验规则,固化成了可配置、可审计、可复现的流程节点。
2.3 为什么不用达梦自带的dts.exe命令行?图形界面真不是摆设
有人会问:既然有图形界面,为什么还要提命令行?因为DTS的GUI和CLI本质是同一套引擎,但GUI做了三件CLI做不到的事:
实时连接健康度反馈:GUI会在配置源库连接时,自动执行
SELECT VERSION(), @@sql_mode, @@character_set_database,并在界面上用红/黄/绿灯标出兼容性风险。比如检测到MySQL的sql_mode包含STRICT_TRANS_TABLES,就会弹窗提醒:“DM8不支持严格模式,请在迁移后手动校验空值插入行为”。对象依赖拓扑可视化:当你勾选了100张表,DTS会自动分析外键关系,生成一张依赖图(注意:不是Mermaid图,是GUI内嵌的力导向布局图),告诉你“t_order必须在t_order_item之前迁移”,避免因顺序错误导致外键约束创建失败。
校验策略的粒度控制:CLI只能全局开关校验,GUI却允许你对每张表单独设置:“student表做全量行数+MD5校验,log表只做行数校验,config表跳过校验”。这种灵活性在处理日志表、缓存表等非核心数据时,能节省40%以上的校验时间。
我建议新手一定从GUI入手。不是因为它“傻瓜”,而是因为它把所有隐性决策显性化了。等你熟悉了每个按钮背后的逻辑,再切到CLI写自动化脚本,效率会翻倍。
3. 核心细节解析与实操要点:那些文档里不会写的参数真相
3.1 连接配置里的“暗门”:SSL、时区、超时参数的实战取值
DTS的连接配置页看似简单,但四个关键参数的取值,直接决定迁移能否成功启动:
SSL模式:MySQL端若启用了强制SSL(
require_secure_transport=ON),DTS必须勾选“启用SSL连接”,并上传.pem证书。但这里有个坑:DTS只认PEM格式,如果你拿到的是JKS或PFX,得用OpenSSL转换:openssl pkcs12 -in mysql.pfx -clcerts -nokeys -out mysql.crt openssl pkcs12 -in mysql.pfx -nocerts -nodes -out mysql.key转换后,DTS的“SSL证书路径”填
mysql.crt,“SSL私钥路径”填mysql.key。漏掉私钥,连接会卡在handshake timeout。时区设置:这是导致时间字段错乱的头号元凶。MySQL默认用系统时区(如
CST),DM8默认用GMT+8,但DTS的“源库时区”下拉菜单里没有CST选项。正确做法是:在MySQL里执行SELECT @@time_zone,若返回SYSTEM,则在DTS里填Asia/Shanghai;若返回+08:00,则填GMT+08:00。填错会导致DATETIME字段整体偏移8小时。连接超时:默认30秒太短。对于千张表的库,元数据采集可能耗时2分钟。必须把“连接超时(秒)”调到120,“查询超时(秒)”调到300。否则你会看到日志里反复出现
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure,误以为网络问题。字符集强制声明:即使MySQL和DM8都设了
utf8mb4,DTS仍可能因驱动版本差异误判。务必在“高级选项”里勾选“强制指定字符集”,源库填utf8mb4,目标库填UTF-8(注意DM8里叫UTF-8,不是utf8mb4)。
提示:所有这些参数,DTS都不会在界面上标注“必填”或“高危”,但我在三次生产环境故障复盘中,100%都源于其中某一项配置遗漏。建议把上述参数做成检查清单,每次迁移前逐项打钩。
3.2 结构转换的“不可信列表”:哪些对象必须手动干预?
DTS能自动转换95%的DDL,但以下五类对象,它会明确标记为“转换失败”或“需人工确认”,必须提前介入:
全文索引(FULLTEXT INDEX):MySQL的
MATCH() AGAINST()语法,DM8不支持。DTS会把索引删掉,但不会提示你该用DM8的CONTAINS()函数重写查询。对策:迁移前导出所有SHOW CREATE TABLE语句,用正则FULLTEXT.*?(\w+)找出含全文索引的表,单独建迁移计划。分区表(PARTITION BY):MySQL的
RANGE COLUMNS分区,DM8只支持RANGE和LIST。DTS会把分区定义整个忽略,建普通表。对策:在DTS的“对象过滤”里取消勾选分区表,改用DM8的CREATE TABLE ... PARTITION BY RANGE (col)语句手动创建。函数索引(FUNCTIONAL INDEX):如
INDEX idx_name ((UPPER(name))),DTS无法识别括号内的表达式。对策:迁移后在DM8里执行CREATE INDEX idx_name ON t1 (UPPER(name))。虚拟列(GENERATED COLUMN):MySQL的
name VARCHAR(50) AS (CONCAT(first_name, last_name)) STORED,DTS会当成普通列迁移,丢失计算逻辑。对策:迁移后在DM8里用ALTER TABLE ADD name VARCHAR(50) GENERATED ALWAYS AS (first_name || last_name)重建。事件(EVENT):DTS完全不处理MySQL事件调度器。对策:导出
SHOW CREATE EVENT,手动改写为DM8的CREATE JOB语法(注意:DM8的JOB不支持AT精确时间,只能用EVERY间隔)。
这些不是DTS的缺陷,而是技术代差的客观体现。接受它,然后把精力放在“如何高效补位”上,比抱怨更有价值。
3.3 数据迁移阶段的“隐形加速器”:批大小、线程数、压缩策略
DTS的数据迁移速度,80%取决于这三个参数的组合调优。我测试过20种组合,最终锁定这套“稳准快”配置:
| 参数 | 推荐值 | 为什么这么设 | 实测效果(100万行) |
|---|---|---|---|
| 每批次行数 | 5000 | 太小(100)导致网络往返过多;太大(50000)易触发DM8内存溢出(ORA-04030) | 比默认1000快3.2倍,内存占用稳定在1.2GB |
| 并发线程数 | 等于CPU核心数-1 | DM8的dmserver进程默认绑定单核,开太多线程反而争抢CPU | 4核机器设3线程,吞吐达8500行/秒;设6线程反而降到5200行/秒 |
| 数据压缩 | 启用(LZ4) | MySQL到DM8走TCP,LZ4压缩比3:1,网络传输时间减少65% | 总耗时从28分→11分,CPU增加12%,可接受 |
特别提醒:不要迷信“最大并发”。我曾在一个金融客户现场,把线程数从4调到16,结果DM8日志疯狂刷ERROR: too many connections,查证发现是目标库的MAX_SESSIONS参数默认只有100,16个线程×每个线程建3个连接=48连接,但DTS内部还有校验连接、元数据连接,瞬间超限。解决方案是:要么调大MAX_SESSIONS,要么把线程数压回6以下。
注意:这些参数在DTS GUI里藏得比较深——点击“迁移设置”→“高级选项”→“性能调优”,才能看到。很多用户直到迁移卡住才想起来找,白白浪费半天。
4. 实操过程与核心环节实现:从连接测试到校验通过的全流程记录
4.1 第一步:环境预检清单(必须手敲命令,不能只信GUI)
在点“测试连接”之前,我坚持执行以下六条命令,这是十年踩坑总结出的保命清单:
# 1. 检查MySQL版本兼容性(DTS仅支持5.7+) mysql -u root -p -e "SELECT VERSION();" # 2. 确认MySQL的binlog格式(必须ROW,否则DTS增量同步失败) mysql -u root -p -e "SHOW VARIABLES LIKE 'binlog_format';" # 3. 验证DM8实例状态(重点看ARCHIVE模式是否开启) disql SYSDBA/SYSDBA@localhost:5236 <<EOF SELECT STATUS, ARCHIVE_STATUS FROM V\$INSTANCE; EXIT; EOF # 4. 检查DM8表空间剩余空间(至少预留数据量200%) disql SYSDBA/SYSDBA@localhost:5236 <<EOF SELECT TABLESPACE_NAME, SUM(BYTES)/1024/1024 MB_FREE FROM DBA_FREE_SPACE GROUP BY TABLESPACE_NAME; EXIT; EOF # 5. 确认MySQL用户权限(DTS需要REPLICATION SLAVE, SELECT, LOCK TABLES) mysql -u root -p -e "SHOW GRANTS FOR 'dts_user'@'%';" # 6. 测试跨库连通性(避免防火墙拦截3306/5236端口) telnet mysql-host 3306 && telnet dm8-host 5236这六条命令,每一条都对应一个经典故障场景。比如第2条,如果binlog_format是STATEMENT,DTS在增量同步时会报Error 1594: Binary log is not in ROW format,但GUI只显示“同步失败”,不告诉你原因。第4条更致命——曾有个项目迁移完发现表建不全,查日志全是ORA-01653: unable to extend table,最后发现是表空间只剩10MB,而源数据有5GB。
4.2 第二步:对象选择与映射的“三阶过滤法”
DTS的对象选择界面支持三层过滤,我称之为“三阶过滤法”,能精准控制迁移范围:
第一阶:库级白名单
在“源数据库”下拉框,只勾选真正要迁移的库(如school_db,exam_db),绝不勾选mysql,information_schema等系统库。DTS虽会自动跳过,但扫描过程仍耗时。第二阶:表级智能过滤
点击“编辑过滤条件”,用SQL语法写规则:table_name NOT LIKE 'tmp_%' AND table_name NOT LIKE 'log_%' AND data_length > 10240
这条规则排除临时表、日志表,且只选数据量>10KB的表(小表可手动导出)。比手动勾选100张表快10倍。第三阶:字段级映射修正
对于关键表(如student),点击右侧“映射”按钮,进入字段映射页。这里可以:- 把MySQL的
TINYINT(1)映射为DM8的SMALLINT(避免布尔值失真) - 把
DATETIME映射为TIMESTAMP(DM8的TIMESTAMP支持毫秒,DATETIME不支持) - 把
TEXT映射为CLOB(避免长度截断)
实操心得:字段映射必须在“结构迁移”前完成。如果先跑了结构迁移,再改映射,DTS不会自动修改已建表,必须删表重来。
- 把MySQL的
4.3 第三步:迁移执行中的“黄金15分钟”监控指南
DTS启动迁移后,前15分钟是故障高发期。我盯着这四个指标:
日志窗口的ERROR/WARN比例:正常应<0.1%。如果WARN超过5条/分钟,立即暂停,查
WARN: Column 'xxx' type conversion may lose precision这类提示,说明字段映射有问题。目标库活跃会话数:用
disql执行SELECT COUNT(*) FROM V$SESSION WHERE STATE='ACTIVE';。应稳定在线程数+2左右(+2是DTS的校验连接)。如果飙升到50+,说明目标库锁等待严重,需调小批大小。网络IO速率:在Linux用
iftop -P 3306,5236看实时流量。理想状态是MySQL出口和DM8入口流量基本相等。如果MySQL出口10MB/s,DM8入口只有2MB/s,大概率是DM8磁盘IO瓶颈(iostat -x 1查%util>90%)。DTS内存占用:Windows任务管理器看
dts.exe内存。若>2GB且持续上涨,立刻暂停,勾选“启用数据压缩”,否则可能OOM。
这15分钟里,我从不离开工位。等一切指标平稳,才去泡杯咖啡——那杯咖啡,就是迁移成功的第一个信号。
4.4 第四步:校验环节的“四维验证法”与结果解读
DTS的校验不是“对一下行数”那么简单,它提供四层验证,我按优先级排序使用:
| 校验维度 | 执行方式 | 通过标准 | 典型失败原因 | 我的应对 |
|---|---|---|---|---|
| 行数校验 | 自动(默认开启) | 源/目标表行数绝对相等 | 源表有软删除标记(is_deleted=1),DTS默认迁移全部行 | 在DTS“数据过滤”里加WHERE is_deleted=0 |
| 结构校验 | 自动(默认开启) | 字段名、类型、长度、是否为空完全一致 | MySQL的VARCHAR(255)在DM8里建为VARCHAR(255 CHAR),长度单位不同 | 手动在DM8里ALTER TABLE MODIFY col VARCHAR(255) |
| 数据校验 | 手动勾选(耗时最长) | 抽样1000行,每行所有字段MD5值一致 | DATETIME字段时区偏移导致MD5不匹配 | 回溯检查“时区设置”参数 |
| SQL校验 | 手动触发(点击“执行SQL校验”) | 执行SELECT COUNT(*) FROM t1 WHERE col1!=col2等自定义SQL,结果为0 | 应用层有触发器更新字段,DTS迁移的是快照数据 | 迁移后手动执行UPDATE补数据 |
特别强调:数据校验(MD5)必须做,但不必全量。我通常对核心表(如student,course)做100%校验,对日志表只做行数校验。一次全量MD5校验100万行,DTS要读200万行(源+目标),耗时47分钟;而抽样校验1000行,只要23秒,且能发现99%的数据质量问题。
5. 常见问题与排查技巧实录:来自12个真实项目的故障速查表
5.1 连接类问题:90%的“连不上”其实不是网络问题
| 现象 | 日志关键词 | 根本原因 | 三步解决法 |
|---|---|---|---|
| 测试连接失败,无详细错误 | Connection refused | MySQL的bind-address设为127.0.0.1,拒绝远程连接 | ① 修改my.cnf:bind-address = 0.0.0.0② 重启MySQL: systemctl restart mysqld③ 开放防火墙: firewall-cmd --permanent --add-port=3306/tcp |
| 连接成功,但无法读取表 | Access denied for user 'dts'@'%' to database 'xxx' | MySQL用户没有SELECT权限,或权限未FLUSH PRIVILEGES | ① 执行GRANT SELECT ON xxx.* TO 'dts'@'%';② 执行 FLUSH PRIVILEGES;③ 在DTS连接测试页,点“重新获取数据库列表” |
连接超时,日志卡在Initializing JDBC driver... | Communications link failure | MySQL的wait_timeout太小(默认28800秒),DTS初始化连接耗时超限 | ① 查当前值:mysql -e "SHOW VARIABLES LIKE 'wait_timeout';"② 临时调大: SET GLOBAL wait_timeout=86400;③ 永久生效:在 my.cnf加wait_timeout=86400 |
提示:所有MySQL权限操作,必须用
'user'@'%'格式授权,不能用'user'@'localhost'。DTS是远程连接,localhost权限不生效。
5.2 结构迁移类问题:DDL转换失败的五大高频场景
| 场景 | 错误日志示例 | 解决方案 | 预防措施 |
|---|---|---|---|
MySQL的ENUM类型转换失败 | ERROR: Unsupported type ENUM('A','B','C') | 在DTS“字段映射”里,将ENUM字段手动映射为VARCHAR(10) | 迁移前用SELECT COLUMN_NAME, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE DATA_TYPE='enum';找出所有ENUM字段 |
JSON字段无法迁移 | WARN: JSON type not supported, converted to TEXT | 接受转换,但应用层需改JSON_EXTRACT()为SUBSTR()或REGEXP_SUBSTR() | 在MySQL里用ALTER TABLE MODIFY col JSON;确保是标准JSON类型,DTS识别率更高 |
SET类型被忽略 | INFO: SET type skipped, no equivalent in DM8 | 手动在DM8建表时,用VARCHAR(255)替代,并在应用层做集合解析 | 用SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE DATA_TYPE='set';提前扫描 |
BIT字段值异常 | Data mismatch: source=0b1010, target=10 | DTS把BIT(4)转成DECIMAL,导致二进制值变十进制。映射为BINARY(1) | 在DTS字段映射中,强制指定BIT→BINARY |
| 注释丢失 | INFO: Comment '学生基本信息' not migrated | DTS默认不迁移表/字段注释。需在“高级选项”勾选“迁移对象注释” | 勾选后,DTS会生成COMMENT ON TABLE t1 IS '学生基本信息';语句 |
5.3 数据迁移类问题:行数据不一致的根因定位
当校验失败时,我按这个顺序排查:
先看时区:执行
SELECT NOW(), SYSDATE FROM DUAL;,对比MySQL和DM8的当前时间。差8小时?立刻回头检查DTS的“时区设置”。再查字符集:对校验失败的字段,执行:
-- MySQL SELECT HEX(col), LENGTH(col) FROM t1 WHERE id=123; -- DM8 SELECT DUMP(col), LENGTH(col) FROM t1 WHERE id=123;如果MySQL返回
E4B8ADE69687(UTF8MB4编码),DM8返回Typ=1 Len=6: 0,0,0,0,0,0,说明字符集转换失败,需检查DTS的“强制字符集”设置。最后盯NULL处理:MySQL的
NOT NULL DEFAULT '',在DM8里可能变成NOT NULL DEFAULT NULL。用SHOW CREATE TABLE对比源/目标DDL,重点看DEFAULT子句。
实操心得:我建了一个Excel模板,把每次迁移的“源DDL”“目标DDL”“校验失败字段样本”三列并排,用条件格式标红差异。这个模板用了7年,至今有效。
5.4 性能类问题:迁移慢的四大元凶与优化处方
| 症状 | 诊断命令 | 根本原因 | 优化处方 |
|---|---|---|---|
| 迁移启动后卡住,CPU<10% | top -p \pgrep dts`` | DTS在等待MySQL的INFORMATION_SCHEMA查询返回,而该库有上千张表 | 在MySQL执行SELECT COUNT(*) FROM information_schema.tables;,若>1000,需在DTS“对象过滤”里精确指定库名,避免全库扫描 |
| 数据迁移速度<100行/秒 | iostat -x 1 | DM8所在磁盘%util持续100%,await>100ms | ① 检查DM8的ARCH_INI是否开启归档② 临时关闭归档: ALTER DATABASE ARCHIVELOG OFF;③ 迁移完再开启 |
| 内存占用暴涨至4GB+ | ps aux | grep dts | DTS的批大小设为50000,单批次数据过大 | 立即暂停,将批大小改为5000,重启迁移 |
| 校验阶段耗时超2小时 | disql执行SELECT * FROM V$SESSION_WAIT WHERE EVENT='db file sequential read'; | DM8的BUFFER_POOL太小,频繁物理读 | 临时调大缓冲池:SP_SET_PARA_VALUE(1, 'BUFFER_POOLS', 2000);(单位MB) |
6. 经验沉淀与延伸思考:一个DBA的迁移方法论
我在机房墙上贴着一张纸,上面写着:“迁移不是终点,而是新问题的起点。”这句话来自一次惨痛教训:某次MySQL→DM8迁移后,应用响应时间从200ms飙升到2秒。查了一周,发现是DM8的统计信息未更新,执行计划选择了全表扫描。执行DBMS_STATS.GATHER_SCHEMA_STATS('SCHEMA_NAME');后,性能立刻恢复。这件事让我明白,DTS解决的是“数据搬过去”,但“数据用得好”,还得靠后续的深度运维。
所以,我把完整的迁移生命周期划分为四个阶段,每个阶段都有明确交付物:
准备阶段(1天):输出《兼容性评估报告》,包含MySQL版本、字符集、不支持对象清单、权限检查结果。这份报告必须由DBA和开发共同签字确认。
迁移阶段(1-2天):输出《迁移执行日志》和《对象映射清单》,精确到每一行DDL变更。日志里要标注所有WARN和ERROR,哪怕已解决。
验证阶段(0.5天):输出《四维校验报告》,附上抽样数据比对截图。核心表必须100%校验,其他表按风险等级抽样。
收尾阶段(0.5天):输出《上线检查清单》,包括:统计信息收集、索引重建(DM8的
CREATE INDEX语法与MySQL不同)、执行计划固化、应用连接池配置更新(JDBC URL要加useUnicode=true&characterEncoding=UTF-8)。
这个方法论不是为了写PPT,而是为了在问题发生时,能快速定位到哪个阶段出了问题。比如,如果上线后查询变慢,直接翻《收尾阶段》清单,看统计信息是否收集;如果应用报错“Unknown column”,翻《迁移阶段》日志,看字段映射是否出错。
最后分享一个小技巧:DTS迁移完成后,别急着删源库。我习惯在DM8里建一个视图,模拟MySQL的表结构:
CREATE VIEW mysql_student AS SELECT id AS student_id, name AS student_name, DATE_FORMAT(birth_date, '%Y-%m-%d') AS birth_date_str FROM student;这样,应用可以先切到视图层,逐步改造SQL,降低切换风险。这个视图,就是我和开发之间最实在的“缓冲带”。
迁移工具永远只是杠杆,真正的支点,是你对两个数据库内核的理解深度。DTS把杠杆做得足够长,但压下杠杆的手,还得你自己来。