ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

MySQL迁移达梦数据库(DM8)实战:SQL语法差异与避坑指南

MySQL迁移达梦数据库(DM8)实战:SQL语法差异与避坑指南 去年帮客户做了一套业务系统从 MySQL 往达梦数据库DM8迁移的活儿整个过程中踩的坑、改的脚本、总结的方案比预想中要多得多。MySQL 和达梦虽然都是关系型数据库SQL 大体上长得像但真到了逐条语句、逐个函数、逐个数据类型的层面差异非常细碎。这篇文章就把我在实际迁移中遇到的 SQL 语法问题、处理方式以及整体迁移方案完整梳理出来给后续要做类似迁移的朋友一个参考。1. 迁移前必须想清楚的几件事1.1 明确迁移目标是兼容还是重写拿到达梦数据库这件事之后第一步不是打开工具开始导数据而是先要搞清楚迁移的最终形态。市面上很多项目所谓的从 MySQL 迁移到达梦其实分两种情况第一种是尽可能兼容。达梦 DM8 本身有 MySQL 兼容模式可以把它当作一个方言比较接近 MySQL的数据库来用。这种情况下SQL 改写的工作量小很多很多 MySQL 的写法可以直接跑前提是达梦的兼容参数配置得当。第二种是彻底原生改造。完全按照达梦的习惯来重写 SQL包括分页、自增列、函数写法、日期处理等。这种方案最稳但工作量翻倍。实际项目中我通常建议走兼容优先、原生兜底的路线先把达梦的兼容参数打开让大部分 SQL 能跑通再针对少数报错的语句精修。如果一开始就想着全部重写项目周期和风险往往不可控。1.2 摸清家底先做一次全面的 SQL 资产盘点迁移之前务必要做一次彻底的 SQL 扫描。很多人以为把表结构和数据搞过去就完事了真正的难点全部在应用代码里的 SQL。这步做不好后面上线就是灾难。具体盘点内容至少包括三块表结构清单涉及哪些表、每张表的主键类型、自增字段用什么方式实现、有没有 enum/set/json 这类 MySQL 特有类型、字段默认值是否依赖 MySQL 函数比如 DEFAULT CURRENT_TIMESTAMP。SQL 语句清单把应用代码里的 SQL 全部捞出来重点检查分页写法LIMIT、函数调用DATE_FORMAT、IF、IFNULL 等、锁语法SELECT ... FOR UPDATE、批量插入INSERT ... ON DUPLICATE KEY UPDATE。存储过程与触发器MySQL 的存储过程语法和达梦差异很大如果业务里有大量存储过程这块要单独安排改造时间。我见过一个项目 200 多个存储过程光是改写就花了两周。1.3 工具链准备达梦自带的几板斧达梦数据库安装完成之后自带几个关键工具迁移前要先把它们用熟DM 管理工具图形化界面类似 MySQL Workbench主要用于表结构查看、SQL 调试、数据浏览。DTS 数据迁移工具这一条最关键。达梦自带的 DTS 支持从 MySQL 直接迁数据可以连表结构和数据一起搬是迁移工作的主力工具。disql 命令行工具类似 mysql 命令行适合跑批量脚本、做语法验证。工具准备好之后我习惯先把目标库的初始化参数配一遍特别是影响 SQL 兼容性的那几个COMPATIBLE_MODE设置为 MySQL 模式字符集建议用 UTF-8大小写敏感的配置要想清楚。这些参数牵一发动全身一旦数据迁移进去再改代价非常大。2. SQL 语法差异最容易踩爆的雷区2.1 数据类型差异一张表看懂长得像但不通用数据类型是迁移时第一个照妖镜。MySQL 里很多常用类型到了达梦并不是直接对应过去写错的结果要么是建表失败要么是数据精度丢失。MySQL 类型达梦 DM8 对应类型迁移说明TINYINTSMALLINTMySQL 的 TINYINT(1) 常用来存布尔值达梦里对应 SMALLINTINT/INTEGERINT可以直接用BIGINTBIGINT可以直接用但注意达梦 BIGINT 的显示宽度语法不适用VARCHAR(n)VARCHAR(n)注意字符语义达梦 VARCHAR 长度默认按字节算UTF-8 下中文要占 3 字节上线前必须验证TEXTTEXT/CLOB大字段建议用 CLOB兼容性更稳DATETIMEDATETIME可以直接用但默认值写法不同见下文TIMESTAMPTIMESTAMP达梦的 TIMESTAMP 精度更高默认值处理不一样DECIMAL(m,d)DECIMAL(m,n)语法相同但注意精度上限ENUM不支持迁移时改成 VARCHAR CHECK 约束或者让应用层约束JSON达梦支持 JSON 类型DM8 有如果达梦版本较老建议改成 CLOB 存文本应用层自己解析重点说一下最坑的两个第一个是VARCHAR 的长度语义。MySQL 里VARCHAR(255)意思是 255 个字符。达梦默认情况下VARCHAR(255)是 255 个字节。如果你的表里存中文255 字节只能放 85 个汉字。迁移后短数据都会报字符串长度超出限制当时产品被这个问题折腾得够呛。解决方式有两个一是建表时手动把长度乘以 3比如 MySQL 的 VARCHAR(255) 在达梦写成 VARCHAR(765)二是在建库时把LENGTH_IN_CHAR参数设为 1让 VARCHAR 长度按字符计算。这个参数必须在建库时确定后期没法动态改迁移前一定要想清楚。第二个是ENUM 类型。MySQL 的 ENUM 在达梦里没有对应物DTS 工具迁移的时候会有三种表现直接转成 VARCHAR、报错、或者转成不太合适的类型。我建议提前把 ENUM 字段在源库侧改成 VARCHAR一次性搞定别依赖工具的自动转换。CHECK 约束可以用达梦的CONSTRAINT ... CHECK (col IN (...))替代效果基本等价。2.2 自增列AUTO_INCREMENT 迁移到 IDENTITYMySQL 的自增列写法是id INT AUTO_INCREMENT PRIMARY KEY达梦里对应的是id INT IDENTITY(1,1) PRIMARY KEY。DTS 迁移建表语句的时候工具通常能识别 AUTO_INCREMENT 并转换成达梦的 IDENTITY但有两个细节要注意一是显式插入自增值。MySQL 允许往自增列显式插入值只要不撞主键达梦默认不允许。很多老系统迁移的时候业务代码里会有类似INSERT INTO t(id, name) VALUES (100, x)的语句达梦下会直接报错。需要修改应用代码去掉 id 字段或者对表执行SET IDENTITY_INSERT 表名 ON达梦语法和 SQL Server 类似。注意这个开关在达梦里是有会话级别的限制的不能全局开。二是自增列的缓存机制。MySQL 的自增列重启后会重置缓存达梦也有类似行为但两边在并发插入时的表现略微不同。迁移后建议做一次并发写入压测确认自增值没有冲突、没有跳号异常。还有一个隐藏点达梦的 IDENTITY 列在建表以后不能轻易修改有些业务后期要改自增起始值达梦这边调整要重建表代价比 MySQL 大这一点要提前跟业务方说清楚。2.3 反引号问题MySQL 的习惯在达梦里是语法错误MySQL 里大家写表名、列名都喜欢用反引号包裹比如SELECT name FROM user。达梦的默认方言是不认识反引号的直接报语法错误。这个消息对从 MySQL 迁移过来的人来说几乎是必踩的坑。处理方式如果是少量 SQL直接改掉反引号达梦默认可以用双引号包裹标识符。如果 SQL 特别多可以改达梦的兼容参数COMPATIBLE_MODE4即 MySQL 兼容模式部分情况能支持反引号。这里要提醒一句达梦的双引号有特殊意义。达梦默认的标识符是大写且不敏感的一旦你用双引号包了一个小写表名比如user达梦会认为这是一个区分大小写的对象名。之后所有针对这个表的引用都必须带着双引号且大小写一致否则就会报无效的表名。迁移时如果遇到明明表在那里SQL 却查不到的情况十有八九是双引号的大小写敏感问题。我的建议是迁移后的表名、列名统一用大写应用 SQL 里也别带引号省掉一堆麻烦。2.4 函数差异换了一张脸的同一个人函数层面是迁移中最琐碎、最费时间的部分。下面列几个我实际碰到的高频差异IFNULL 和 NVL。MySQL 的IFNULL(a, b)在达梦里面最接近的是NVL(a, b)达梦也有IFNULL函数但部分版本的实现和 MySQL 不完全一样稳妥起见直接用NVL。这个差异看起来小但应用代码里用的频率极高全局替换即可。IF 函数。MySQL 的IF(expr, a, b)在达梦里没有完全对应的单函数需要用CASE WHEN expr THEN a ELSE b END替代。如果业务代码里有大量 IF 嵌套改写起来比较费眼神最好写个正则先粗筛一遍再人工核对。DATE_FORMAT 和 DATE_TO_CHAR。MySQL 里格式化日期的DATE_FORMAT(now(), %Y-%m-%d)达梦对应的是TO_CHAR(SYSDATE, YYYY-MM-DD)。注意格式串的占位符不一样MySQL 用%Y、%m、%d达梦用YYYY、MM、DD。这个也是最容易漏的错误改了函数名没改格式串跑完出来一堆乱码日期。NOW() 和 SYSDATE。MySQL 里NOW()、CURRENT_TIMESTAMP都很常用达梦里最稳妥的写法是SYSDATE。CURRENT_TIMESTAMP达梦也认但在默认值场景下可能有限制建议统一替换。CONCAT 拼接。MySQL 里CONCAT(a, b)函数在达梦里依然存在可以直接用。但要注意MySQL 里字符串拼接也支持||操作符达梦同样支持。实际中遇到的问题是两个字段拼接时有一个为 NULLMySQL 的 CONCAT 会返回 NULL达梦也有些微妙差异最好在测试环境逐个验证。GROUP_CONCAT。MySQL 的GROUP_CONCAT在达梦里对应的是LISTAGG或者WM_CONCAT。两个函数的排序和去重语法不完全一致改写时建议把内部的ORDER BY拿出来单独处理。STR_TO_DATE。MySQL 的STR_TO_DATE(str, format)对应达梦的TO_DATE(str, format)。同样注意格式串差异。2.5 分页查询LIMIT 不等于删掉重写MySQL 的分页写法是SELECT * FROM t ORDER BY id LIMIT 10, 20;意思是跳过 10 条取 20 条。达梦的分页写法有好几种最推荐的是用LIMIT的变体或者ROWNUM。达梦 DM8 在兼容模式下也支持 LIMIT 语法但细节有差异。稳妥的写法是SELECT * FROM t ORDER BY id LIMIT 10 OFFSET 20;或者干脆用传统的 ROWNUM 方式比如SELECT * FROM ( SELECT t.*, ROWNUM AS rn FROM ( SELECT * FROM t ORDER BY id ) t WHERE ROWNUM 30 ) WHERE rn 10;这里强烈建议如果项目里分页 SQL 很多统一封装一套分页模板不要每个开发各写各的。迁移的时候把模板改掉一次比改几十个分页语句靠谱得多。另外注意 LIMIT 后面跟变量的时候达梦的写法可能要求先声明变量不能直接在 SQL 里LIMIT ? OFFSET ?这会影响 MyBatis 这类 ORM 框架的分页插件迁移后一定要回归测试分页功能。2.6 批量插入与冲突处理ON DUPLICATE KEY UPDATE 的替代方案MySQL 的INSERT ... ON DUPLICATE KEY UPDATE ...在达梦里默认是不支持的这是我迁移时被应用开发问得最多的一句。达梦的替代方案有两个MERGE INTO语句详见下一节。达梦从某个版本开始也支持INSERT ... ON DUPLICATE KEY UPDATE但需要确认版本而且行为可能和 MySQL 有细微差别比如对自增列的影响。实际项目里我更建议用MERGE来改写批量更新插入逻辑。写起来虽然比 MySQL 啰嗦一些但行为可控且达梦对 MERGE 的支持非常好性能也有保障。2.7 空字符串与 NULL 的相爱相杀MySQL 里和NULL是两种不同的值但在很多场景下 MySQL 的排序和比较会对 NULL 有一些特殊处理。达梦对 NULL 的处理整体更接近 OracleNULL 参与比较运算的结果是未知COUNT(字段)不计 NULLORDER BY默认 NULL 值排在最后MySQL 则相反。迁移后最容易出问题的场景WHERE 字段 x在 MySQL 里会排除 NULL 值达梦也一样但如果字段本身有 NULL结果行为可能让业务意外。ORDER BY 字段 ASC时NULL 值的排序位置两边不一致。唯一索引对 NULL 的处理MySQL 唯一索引允许多个 NULL达梦默认也是允许多个 NULL这个两边倒是比较一致但建议实测确认版本行为。我的建议是迁移后先跑一遍数据对比脚本重点关注 NULL 值占比较高的字段把这些字段的排序、比较逻辑全部回归一遍。3. 迁移方案的完整落地步骤3.1 方案选型DTS 迁移还是导出导入达梦提供的从 MySQL 迁移的路径主要有三种达梦 DTS 工具图形化操作可以连源 MySQL 库直接抽数据到达梦支持表结构、数据、部分约束的迁移。适合中小规模项目是我用得最多的方案。MySQL 导出 SQL 手工调整后导入先用 mysqldump 导出手动改掉语法不兼容的部分再在达梦里执行。这种方式看起来原始但对复杂表结构的掌控力最强适合表少但每个表都很复杂的场景。达梦的迁移服务或第三方 ETL 工具适合大规模、跨网络、需要增量同步的场景。如果数据量大到在线迁移时间窗口不够就得考虑数据同步工具做增量。我个人的经验是优先选 DTS 做结构和全量数据迁移SQL 脚本的方式做辅助和补充。DTS 能省掉大量手工建表的工作但 DTS 自动生成的建表语句不一定完全符合预期一定要对迁移结果做一次全面核对。3.2 实操使用 DTS 完成全量迁移DTS 迁移的流程大致如下打开达梦 DTS 工具新建迁移任务。数据源选择 MySQL填好 IP、端口、用户名、库名。注意 MySQL 连接驱动要提前装好达梦 DTS 一般自带 MySQL 驱动但版本如果和你的 MySQL 不匹配连接阶段就会报错。目标端选达梦数据库指定目标模式和表空间。对象选择时默认会勾选表、视图、存储过程等。我建议第一次只勾选表和主键、索引存储过程和视图先跳过避免迁移过程报错中断。第一批先把表和纯数据迁完再单独处理视图和存储过程。执行迁移后查看迁移报告。DTS 会记录每张表的迁移结果、行数、失败原因。这一步千万别跳过要逐条看失败记录。迁移完成后在达梦管理工具里抽查对比表数量、行数、重点字段值。最好写几个校验 SQL比如每张表做SELECT COUNT(*)对比。有一个细节DTS 在迁移表结构时默认可能会把AUTO_INCREMENT转成达梦的IDENTITY但也会出现建表成功却不带自增属性的情况。迁移完以后一定要检查每张表的自增主键是否真的自增。3.3 手工改写让你崩溃的存储过程存储过程和触发器是迁移工作中最消耗精力的部分。MySQL 的存储过程语法和达梦有几个关键差异定界符MySQL 习惯用DELIMITER $$来包裹存储过程达梦不支持这个语法。变量声明MySQL 是DECLARE var INT DEFAULT 0;达梦需要DECLARE var INT : 0;或者用DEFAULT有的版本支持但:更稳妥。游标循环MySQL 的DECLARE CONTINUE HANDLER FOR NOT FOUND SET done TRUE;这类写法达梦语法完全不一样需要改成达梦的游标循环方式。异常处理MySQL 的SIGNAL SQLSTATE和达梦的RAISE完全不同。正因为差异密集我建议给存储过程制定一个逐条翻译的标准流程先分析原存储过程的逻辑结构画出流程图注意并不是让你在文档里画图而是在脑子里理清逻辑然后按达梦语法重写。确认逻辑等价之后再进测试环境跑不要贪快一次性批量转。3.4 视图迁移别被表面成功骗了视图的迁移有个陷阱DTS 能把视图创建语句搬过去但达梦不保证视图内引用的函数和语法都能执行。很多时候视图建成功了一查询就报错。所以我迁移视图后有一个固定动作把每个视图都 SELECT 一遍验证是否能查出数据。视图嵌套多的情况下建议从最底层的视图开始逐层验证哪一层报错改哪一层。3.5 应用层适配连接驱动与配置修改数据库侧的迁移完成只是半程应用连不上、连上了跑不对照样白搭。JDBC 驱动MySQL 的com.mysql.cj.jdbc.Driver要换成达梦的dm.jdbc.driver.DmDriverURL 格式从jdbc:mysql://ip:3306/db换成jdbc:dm://ip:5236/db。注意达梦默认端口是 5236不是 3306。连接池参数MySQL 连接池的autoReconnect、useSSL等参数达梦不认识多余的参数要去掉。字符集参数也改成达梦的支持方式。ORM 框架适配MyBatis 的LIMIT分页插件、MyBatis-Plus 的分页插件默认生成的 SQL 是为 MySQL 设计的迁移后如果不调整数据库类型配置分页会直接报错。MyBatis-Plus 里有dbType配置要改成DM或者ORACLE视版本而定。另外如果项目里大量用到了 MyBatis 的script动态 SQL也要全量回归。3.6 数据校验迁移后的死守环节迁移完不等于验收完数据校验是最后一道防线也是一定不能省的一步。我的校验策略分三层数量校验每张表COUNT(*)两边对比。注意 MYISAM 和 INNODB 的 COUNT 行为差异最好都用COUNT(主键)来对比。抽样校验每张表随机抽几百条记录逐字段对比值。重点看字符串、日期类型有没有乱码、有没有精度丢失。业务级校验跑几遍核心业务的完整链路比如下单→支付→对账确认业务数据在迁移后能正确流转。第三层最容易漏但价值最高。很多隐蔽问题藏在对 NULL 的处理、对时间的格式化、对自增 ID 的依赖上这些光靠数据对比查不出来。4. 常见问题与排查技巧实录4.1 高频报错速查表把我在多个迁移项目里遇到的报错信息整理成一个速查表排查时可以对着查报错信息根本原因处理方式字符串长度超出限制VARCHAR 长度语义差异建库时设 LENGTH_IN_CHAR1或调整字段长度无效的关系名 / 表不存在标识符大小写敏感双引号包裹了小写名字统一使用大写不加引号引用对象self-increasing column 不允许显式插入IDENTITY 列限制去掉自增列的显式插入值或临时启用 IDENTITY_INSERT第 N 行附近出现错误: 语法错误反引号/函数/LIMIT 语法不兼容定位具体语句按兼容语法改写无效的列名 rownum达梦 ROWNUM 是关键字列名不要用 rownum或加引号不建议数据类型不匹配DATE_FORMAT 返回字符串目标列是日期类型增加 TO_DATE/TO_CHAR 做类型转换无法解析的日期时间字符串格式串用错将 %Y-%m-%d 改成 YYYY-MM-DD锁等待超时达梦事务隔离和锁行为不同检查事务是否没提交调整事务粒度4.2 一个完整的语法排错实战过程举个例子。迁移一个订单分页查询功能时应用报了一个诡异的语法错误。原始 SQL 长这样SELECT * FROM orders WHERE status 1 ORDER BY create_time DESC LIMIT 0, 15问题是这张 SQL 在 MySQL 里跑了三年都很稳到了达梦死活报错。排查过程如下第一步拿到完整报错信息。达梦提示第 1 行附近出现错误: 语法错误这种报错非常粗只告诉你语法不对定位不到具体哪个词需要自己拆 SQL。第二步逐段验证。把 SQL 砍掉LIMIT执行发现能跑通。说明问题出在分页部分。再测试LIMIT 0, 15的写法时发现达梦不认换LIMIT 15 OFFSET 0就能跑。这就是典型的方言差异。MySQL 的LIMIT offset, count偏移量在前和达梦的LIMIT count OFFSET offset偏移量在后正好是反的报错也很正常。改写后SELECT * FROM orders WHERE status 1 ORDER BY create_time DESC LIMIT 15 OFFSET 0第三步发现还有隐患。这个 SQL 里ORDER BY create_time如果 create_time 有的是 NULL达梦在降序时 NULL 排行为和 MySQL 不同。虽然这个例子中 create_time 有默认值但生产环境还是要确认一下。这个排查过程本身没什么秘诀核心方法是拆分语句、逐段验证、确认行为一致。不要试图一次性看懂一大段复杂 SQL。4.3 连接工具和调试建议达梦的图形化管理工具DM 管理工具日常调试够用但某些场景不如命令行的 disql 明确。我迁移时的调试习惯是先用 DM 管理工具逐条执行有问题的 SQL观察报错。遇到疑难语法用 disql 配合SET ECHO ON看详细执行过程。所有改写后的 SQL在达梦的执行计划里过一眼避免迁移后性能严重滑坡。还有一个建议如果用的是 Navicat 连接达梦数据库很多人有这个习惯Navicat 对达梦的支持是有限的收费版本也不一定支持所有达梦功能遇到诡异问题时换官方工具试一下排除工具本身的坑。4.4 容易被忽略的字符集与乱码问题MySQL 迁移到达梦乱码问题集中在两类场景第一类是迁移过程乱码。DTS 迁移时源库和目标库的字符集不一致导出来的数据直接变问号。处理方式是迁移前确认 MySQL 的字符集通常是 utf8mb4目标达梦建库时也选 UTF-8两边对齐后再跑 DTS。达梦的字符集在建库时选定后期想改非常麻烦这里务必一次到位。第二类是应用连接乱码。JDBC 连接串中设置字符集参数的方式和 MySQL 不一样达梦要用characterEncodingUTF-8之类的参数。如果应用连接后查询中文正常但写入中文变问号重点查应用层连接串的编码参数和表的列字符集。4.5 注意 MySQL 独有特性在达梦里静默失效的情况迁移过程中我比较警惕的是那种不报错但行为不同的情况比直接报错更隐蔽。举几个实际例子MySQL 的GROUP BY在ONLY_FULL_GROUP_BY关闭时允许查询非聚合列达梦在兼容模式下也可能允许但返回的行可能和 MySQL 不一致。上线前必须把这类 SQL 手工改造成标准聚合写法。MySQL 的ORDER BY可以用列别名达梦在部分场景下也支持但复杂查询尤其含 UNION 的子查询中对别名的处理不一样。MySQL 的CREATE TABLE IF NOT EXISTS达梦有对应语法支持但ALTER TABLE ADD COLUMN IF NOT EXISTS这种写法达梦可能不认。排查这些问题的方法没有捷径就是把核心业务 SQL 在两边各跑一遍比对结果集。迁移项目里最重要的不是SQL 能执行而是SQL 执行的结果和源库一致。5. 一些迁移后性能调优的看法语法跑通只是第一步迁移后如果性能掉链子业务方一样会找上门。5.1 执行计划对比同一套数据同一句 SQLMySQL 和达梦生成的执行计划可能完全不同。迁移后的第一轮性能排查建议直接看达梦的执行计划找全表扫描和排序操作。尤其注意MySQL 惯用的索引(a, b)在达梦里如果查询条件变了索引可能失效。达梦的统计信息在迁移后默认是空的需要跑一遍DBMS_STATS.GATHER_SCHEMA_STATS之类的统计信息收集操作否则优化器可能选出糟糕的执行计划。这一点很关键刚迁移完性能差往往不是 SQL 的问题而是统计信息没更新。达梦的并行度配置如PARALLEL没有默认开启大表查询要手工调。5.2 索引重建与维护DTS 迁移表结构时可能会把索引一起搬过来但搬过来的索引不一定是达梦的最佳形态。我的习惯是迁移完成后把每张表的索引全部列出来和 MySQL 侧的索引做一个对比清单去掉冗余索引、补齐缺失索引按达梦的索引命名规则重命名。索引方面还有一个坑达梦的降序索引和 MySQL 写法不同MySQL 的INDEX(a DESC)达梦不直接支持要看版本需要调整或改用函数索引。如果你依赖降序索引优化顺序查询迁移后要特别测试。5.3 锁相关行为差异MySQL 和达梦在锁方面的行为差异往往是上线后才暴露的问题。MySQL 的默认隔离级别是可重复读InnoDB 使用行锁和间隙锁的组合。达梦默认支持多种隔离级别但并发控制实现细节不同。有几点实测体会SELECT ... FOR UPDATE在 MySQL 里对无索引条件的查询可能会锁大量行达梦的锁行为也有类似情况但锁等待的报错和超时机制不一样应用里如果统一捕获了锁等待超时的异常类型迁移后这个捕获可能失效。MySQL 的INSERT ... ON DUPLICATE KEY UPDATE在冲突时会额外更新一条记录达梦对应实现的加锁范围可能更大并发高的场景下更容易出现锁等待。如果应用里有大事务迁移到达梦后事务长度和锁持有时长对整体吞吐量的影响可能需要调参比如调整锁等待超时参数LOCK_TIMEOUT。这些问题的排查思路是先压测、再对比、最后调优。上线前一定做一轮并发写入压测看看在达梦下面的锁等待情况。6. 写在最后的一些个人体会回头看这几个迁移项目我最大的体会是迁移不是一个技术动作而是一个系统工程。SQL 语法问题只是浮在水面上的冰山一角水面之下是数据类型的语义差异、NULL 和空字符串的哲学区别、事务和锁的行为差异、字符集的血泪教训。所以如果你正准备做 MySQL 到达梦的迁移我有几句实在话第一别指望一把梭。无论 DTS 工具多智能、兼容模式多强大手工核对和改造都是逃不掉的。把工作量和时间预算打足尤其是存储过程和应用 SQL 的回归测试。第二尽早拉通应用开发团队。数据库迁移不是 DBA 一个人的事应用代码里的 SQL 才是大头。让开发团队提前介入了解达梦的方言习惯可以减少大量低效沟通。第三测试环境一定要模拟生产数据量。空库和只有几千行的库跑不出真实问题字符串超长、性能退化、锁冲突这些问题往往都是上了几百万行数据之后才暴露。第四建立完善的比对机制。每次 SQL 改写之后都要有对应的回归验证。我习惯维护一份SQL 转换对照表把 MySQL 原文、达梦改文、验证结果、踩坑记录都存下来。这个表不仅是当前项目的交付物也是后续团队接手和维护的宝贵资料。迁移达梦这件事说难不难说简单也确实繁琐。只要掌握好语法差异的关键点、用对迁移工具、把数据校验做实整个过程是完全可以顺利拿下来的。希望这篇整理能帮正在迁移的朋友少走一些弯路尤其是那些在报错信息面前摸不着头脑的时刻能想起这里还有一个速查表可以看。
返回列表