前言:为什么这次迁移让我印象这么深
去年年底的时候,我们公司接了个政务系统的国产化替代项目。要把一套跑了七八年的MySQL数据库,迁移到金仓数据库也就是KingbaseES上面。说实话,刚接到这个活儿的时候,我心里其实是打鼓的。
这套MySQL库本身不算大,也就五百多个表,两千多万条数据。但它的业务逻辑特别绕。里面有几百个存储过程,还有一堆触发器和视图。最头疼的是,很多核心的业务逻辑都写在存储过程里面,注释还特别少。
以前我也做过几次MySQL的迁移,用的都是各种开源工具凑出来的方案。要么是导出导入慢得不行,要么就是兼容性特别差,迁过去之后一堆报错,最后还得人工一条条改SQL。所以这次我决定试试金仓官方推荐的那套工具链,里面包括KDTS迁移工具和KStudio管理平台。
最后做下来,结果比我想象的要顺利得多。整个流程走下来,我觉得金仓这套针对MySQL的数据库管理工具,确实有点东西。这篇文章我就详细跟大家讲讲这次迁移的全过程,包括我是怎么用这些工具的,中间遇到了哪些坑,还有最后都是怎么解决的。
一、金仓数据库管理工具概览
在讲具体的操作步骤之前,先简单跟大家介绍一下金仓数据库自带的管理工具生态。这套工具是和金仓数据库的商业授权配套的,没有开源的版本。这一点,跟很多开源数据库不太一样。
金仓的工具链还挺全的,从开发、迁移到运维管理,基本都覆盖到了。我这次主要用到的是这么几个:
- KStudio:这个是金仓的图形化管理平台,差不多相当于商业数据库的企业管理器。可以直接连接金仓数据库,做开发、调试、性能分析这些工作。
- KDTS:专门用来做数据迁移的工具,支持从好几种源数据库往金仓数据库迁,MySQL也在支持范围内。
- KMonitor:数据库的监控平台,可以实时查看数据库的运行状态。
- KFS:金仓的数据同步工具,一般是用来做实时同步的。
我这次主要用的是KDTS和KStudio这两个。KDTS专门负责数据迁移,KStudio负责后续的管理和优化工作。
说实话,一开始我对金仓这套工具没抱太大期望。毕竟国产数据库的工具链生态,跟Oracle、MySQL这种成熟的商业产品比,还是有差距的。但真正用了之后才发现,金仓在MySQL兼容这块,做得确实挺细的。
二、迁移前的评估工作
正式动手迁之前,我先用KDTS的评估功能,对MySQL库做了一次全面的扫描。这个功能我个人觉得特别实用。
KDTS可以连接MySQL的源库,自动分析里面所有的对象,包括表、视图、存储过程、函数、触发器这些都算。分析完之后,会生成一份兼容性的评估报告。
这份评估报告还挺详细的,会按对象的类型,分别统计兼容的情况:
| 对象类型 | 总数 | 完全兼容 | 需改造 | 不兼容率 |
|---|---|---|---|---|
| 表 | 523 | 519 | 4 | 0.8% |
| 视图 | 87 | 79 | 8 | 9.2% |
| 存储过程 | 342 | 328 | 14 | 4.1% |
| 函数 | 56 | 51 | 5 | 8.9% |
| 触发器 | 23 | 21 | 2 | 8.7% |
看到这个结果,我心里基本就有底了。大部分对象都是兼容的,只有少数几个需要改造。而且KDTS还给出了具体的改造建议,比如哪些SQL语法需要调整,哪些函数得用金仓的等效函数来替代。
这份评估报告,对项目排期的帮助特别大。我可以根据需要改造对象的复杂程度,大概估算出需要多少工作量。
三、实际迁移过程
评估做完,就开始正式迁移了。整个过程我大概分成了四步来做。
第一步:结构迁移
用KDTS做结构迁移其实很简单。先配置好MySQL源库的连接,还有金仓目标库的连接,选好要迁移的对象,点开始就可以了。
KDTS会自动转换表结构、索引、约束这些DDL语句。举个例子,MySQL的AUTO_INCREMENT,会被转换成金仓的IDENTITY,VARCHAR类型也会做对应的映射。
我特意留意了一下表名的转换。KDTS默认是不会改表名前缀的,但我在配置里指定了规则,把原来的mysql_前缀,统一改成了sys_前缀。这样更符合金仓的命名习惯,也能跟系统里的其他表保持一致。
结构迁移的速度很快,五百多个表,也就十几分钟就搞定了。比自己手动写转换脚本要快多了。
第二步:数据迁移
数据迁移用的是KDTS的“数据同步”功能。它既可以做全量迁移,也可以做增量同步。我这次因为业务可以停机,就直接做了全量迁移。
KDTS是支持并行迁移的,可以开多个线程同时跑。我当时配了8个并行度,两千多万条数据,不到一个小时就迁完了。
数据迁移的过程中,我盯着进度看了一会儿。KDTS会显示每个表的迁移进度和速度。大部分表都迁得很快,只有几个大表慢一点,但也都在可控的范围里。
第三步:存储过程迁移
这一步是最麻烦的。金仓虽然兼容大部分的MySQL语法,但有些写法还是得改。
KDTS能自动转换大部分的存储过程,但那些用了MySQL特有语法,或者复杂动态SQL的,就只能人工处理了。
我的做法是,先用KDTS自动转换一遍,然后再逐个测试。有问题的地方,就用KStudio的调试功能来定位。
KStudio的调试功能确实挺好用的。可以设置断点,单步执行,还能查看变量的值。跟平时用IDE开发的感觉差不多。
举个例子,有个存储过程用了MySQL的PREPARE语句做动态SQL:
-- MySQL原版
SET @sql = CONCAT('SELECT * FROM sys_', table_name, ' WHERE id = ?');
PREPARE stmt FROM @sql;
EXECUTE stmt USING @id;
DEALLOCATE PREPARE stmt;
金仓的等效写法是:
-- 金仓版本
EXECUTE 'SELECT * FROM sys_' || table_name || ' WHERE id = ' || id;
KDTS能自动转换大部分这种写法,但有些特别复杂的动态SQL,还是得手动调整。
第四步:验证和切换
所有对象都迁移完成之后,我用KStudio的“数据比对”功能,做了一次全库的数据一致性校验。
KStudio可以对比两个数据库的结构和数据,找出不一样的地方。我一共跑了两次全库比对,第一次发现有几个表的数据有差异。排查之后发现,是迁移过程中还有并发写入导致的。虽然业务停了,但有些后台任务还在跑。
把差异处理完之后,第二次比对就全通过了。所有数据都完全一致。
四、KStudio管理平台体验
迁移完成之后,我就用KStudio来做日常的管理和优化。这个平台给我的印象还挺深的。
界面和操作
KStudio的界面有点像Oracle SQL Developer,但要更简洁一些。主要的功能都集中在几个面板里:
- 对象浏览器:用树状结构显示数据库、模式、表、视图这些对象
- SQL工作区:支持语法高亮、自动补全,还能显示执行计划
- 管理控制台:管用户、权限、表空间这些内容
它的操作逻辑,跟其他图形化管理工具差不多,上手很快。
性能分析功能
KStudio的性能分析功能特别实用。可以查看会话、锁、等待事件,还能抓取慢SQL。
我还用了它的“SQL调优建议”功能,对几个核心的查询做了优化。它给出的建议挺全的,包括加索引、改写SQL、调整参数这些都有。
举个例子,有个查询在MySQL上跑要0.8秒,迁移到金仓之后变慢了,要2.3秒。用KStudio的执行计划一分析,发现是走了全表扫描。加了个复合索引之后,直接降到了0.15秒,比原来还快。
对MySQL的兼容性
金仓对MySQL的兼容性,做得确实挺细的。不只是语法层面,连行为层面也尽量对齐。
比如MySQL的LIMIT语法、AUTO_INCREMENT、NOW()函数这些,金仓都支持。
最让我意外的是,金仓还支持MySQL的ON DUPLICATE KEY UPDATE语法,等效于金仓的ON CONFLICT。这就意味着,很多MySQL的INSERT语句,几乎不用改就能直接在金仓上跑。
五、遇到的坑和解决方法
整个迁移过程也不是完全顺顺利利的,还是遇到了几个坑。
坑一:字符集问题
MySQL用的是utf8mb4,金仓默认是UTF8。大部分情况下是兼容的,但遇到有些特殊字符就会出问题。
比如有个字段里存了emoji表情,MySQL里能正常存取,但迁到金仓之后就变成乱码了。
查了好半天,才发现是金仓的UTF8实现,跟MySQL的utf8mb4,在处理4字节字符的时候有差异。
解决方法也简单,在金仓端启用utf8mb4兼容模式就行。在kingbase.conf里加上:
# 字符集兼容配置
default_with_utf8mb4 = on
重启数据库之后,问题就解决了。
坑二:存储过程里的用户变量
MySQL的存储过程里,大量使用了用户变量,也就是带@的变量。金仓虽然也支持,但行为上有差异。
比如这段MySQL代码:
SET @count = 0;
SELECT COUNT(*) INTO @count FROM sys_users WHERE status = 1;
IF @count > 100 THEN
-- 做点什么
END IF;
这段代码在金仓里跑是没问题的,但@count的值,在存储过程结束之后不会保留,下次调用的时候又会重新初始化。
解决方法就是用局部变量替代用户变量,或者确保每次调用的时候都重新赋值。
坑三:事务隔离级别
MySQL默认的事务隔离级别是REPEATABLE READ,金仓默认的是READ COMMITTED。
有些业务逻辑是依赖REPEATABLE READ的行为的,迁移之后就出现了数据不一致的情况。
解决方法就是在金仓端设置事务隔离级别:
-- 会话级别设置
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- 或者在连接串里指定
kingbase://host:port/db?transactionIsolation=REPEATABLE_READ
六、迁移后的性能表现
迁移完成之后,我做了性能测试,对比了一下MySQL和金仓的表现。
测试环境是统一的,同样的硬件配置,同样的数据量,同样的并发压力。
测试结果:
| 测试场景 | MySQL平均响应 | 金仓平均响应 | 提升 |
|---|---|---|---|
| 单表查询 | 0.15秒 | 0.12秒 | ↑20% |
| 多表关联 | 0.8秒 | 0.5秒 | ↑38% |
| 事务处理 | 0.3秒 | 0.2秒 | ↑33% |
| 复杂报表 | 5.2秒 | 2.8秒 | ↑46% |
总体来看,金仓在这些场景下都比MySQL要快。尤其是复杂查询的场景,优势更明显。
分析了一下原因,主要是金仓的查询优化器更智能,执行计划选得更合理。另外金仓的MVCC实现也比较高效,减少了锁的竞争。
七、运维成本对比
迁移之后,运维成本也降了不少。主要体现在这么几个方面:
- DBA人力:以前MySQL得两个DBA轮流盯着,现在金仓一个人就够了。金仓的KMonitor平台自动化程度高,很多日常巡检的工作都自动完成了。
- 故障处理时间:以前MySQL出问题,得排查半天。金仓的日志和诊断信息更全,问题定位要快多了。
- 备份恢复:金仓的备份工具更强大,支持增量备份和并行恢复。RTO也就是恢复时间目标,直接从小时级降到了分钟级。
八、总结
这次从MySQL迁移到金仓数据库的项目,让我对国产数据库改观不少。尤其是金仓配套的这套管理工具,从评估、迁移到运维管理,覆盖了整个生命周期。
KDTS迁移工具效率高,兼容性也好;KStudio管理平台功能全面,易用性也强。这两个工具配合起来,让原本复杂的迁移工作,变得简单又可控。
当然,金仓也不是完美的。对MySQL的兼容虽然已经做得很好了,但有些细节上还是有差异,需要人工处理。不过总体来说,改造的工作量比我想象的要小得多。
如果你也在考虑做MySQL到国产数据库的迁移,我觉得金仓这套方案值得试试。