不装中间件的 MySQL→金仓在线迁移:mysql_fdw 全流程,和一个差点漏掉的 emoji

一、迁移的两种痛

把一个 MySQL 业务库迁到 KingbaseES,传统路径通常绕不开两样东西:一个导出/导入的停机窗口 ,和一个额外部署的数据同步中间件。前者要业务方点头给时间,后者要多维护一个组件、多配一套规则。对中小库或灰度试点来说,这两样都嫌重。

有没有更轻的办法?有------用金仓自带的 mysql_fdw (MySQL Foreign Data Wrapper,外部数据包装器)。它让金仓能像访问本地表一样直接读远端 MySQL,于是迁移可以简化成一条 INSERT ... SELECT:不导文件、不装中间件、源库不停机。

这篇我在鲲鹏服务器上把这条路走通,并且------在最后的对账环节,抓到了一个只数行数绝对发现不了的静默数据损坏。这个坑,正是整篇文章我最想分享的东西。

二、造一个"有刺"的迁移源

为了让测试有意义,我在 MySQL 侧造了一个电商库 shop,特意埋了迁移中最容易翻车的几类数据:

customers(8 行)+ orders(10 行),刺埋在这些地方:中文 名字和城市、NULL 邮箱、decimal(12,2) 精确金额、datetime 时间戳,以及最关键的------orders 里有一行 note 是 生日礼物🎁,含一个 utf8mb4 的 emoji(4 字节字符)。这个 16 字节的字段,后面会成为全场焦点。

三、mysql_fdw:不搬数据,先"挂载"

迁移第一步不是搬数据,而是让金仓能"看见"MySQL。三条 DDL 搞定:

复制代码

CREATE EXTENSION mysql_fdw; CREATE SERVER shop_mysql FOREIGN DATA WRAPPER mysql_fdw OPTIONS (host '127.0.0.1', port '3306'); CREATE USER MAPPING FOR system SERVER shop_mysql OPTIONS (username 'fdw', password 'Fdw#2026');

然后为 MySQL 表建"外部表",把 MySQL 类型映射成 KES 类型。挂载完成,直接在金仓里 SELECT:

\d ft_customers 能看到外部表的定义(列类型、所属 Server、OPTIONS (dbname 'shop', table_name 'customers'))。执行 SELECT 时,数据物理上还在 MySQL 里,SQL 由金仓执行、实时拉取 。类型映射很自然:MySQL 的 int/decimal(12,2)/datetime/tinyint 分别落到 KES 的 int/numeric(12,2)/timestamp/smallint

这一步的价值在于:它先建立了"通路"。有了通路,迁移、对账、增量追平都在同一条通路上完成,不需要第二个工具。

四、高潮:一个差点漏掉的 emoji

正当我准备一把梭迁移时,随手验了下那行 emoji------出事了

金仓通过 fdw 读到的 note 是 生日礼物?emoji 变成了问号。用字节数一验,真相触目惊心:

  • MySQL 源:16 字节 ,hex 结尾 F09F8E81(🎁 的 utf8mb4 4 字节编码);

  • fdw 读到:13 字节 ,hex 结尾 3F(就是一个 ?)。

那 4 个字节,在传输途中被悄悄吃掉了。 根因是 mysql_fdw 默认用 3 字节的 utf8 字符集连接 MySQL,遇到 4 字节的 utf8mb4 字符(emoji、部分生僻字、CJK 扩展区汉字)就地转成 ?

我先试了给 server 加 character_set 选项,被拒------它不是合法选项(有效选项里没有它)。但报错的 HINT 列出的合法选项里,有一个 init_command:它能在每次建立连接时执行一条 SQL。于是:

复制代码

ALTER SERVER shop_mysql OPTIONS (ADD init_command 'SET NAMES utf8mb4');

再查------生日礼物🎁 回来了,16 字节,hex 结尾 F09F8E81 ,分毫不差。

这个坑最可怕的地方在于它的"静默":不报错、不中断、行数一分不少,只是每个 4 字节字符悄悄变成 ?。如果迁移验证只对一下行数、甚至只对一下金额总和,它能一路蒙混过关,直到某天用户投诉"我的备注里的表情怎么变问号了"。迁移前先校准 fdw 字符集,是我用这次经历换来的第一条铁律。

五、迁移:一条 INSERT 搞定

字符集校准好,迁移就是水到渠成的一条语句:

复制代码

CREATE TABLE customers (...); -- KES 本地表 INSERT INTO customers SELECT * FROM ft_customers; -- 8 行 CREATE TABLE orders (...); INSERT INTO orders SELECT * FROM ft_orders; -- 10 行

INSERT 0 8 / INSERT 0 10,数据从 MySQL 直接流进金仓本地表。没有中间的 CSV 文件、没有 mysqldump、没有第三方同步工具------外部表就是管道。迁移完成后,本地表是纯粹的 KES 原生表,不再依赖 MySQL。

六、对账:为什么只数行数会出事

迁移完成不等于迁移正确。第四节的 emoji 事件已经证明:数据可以在"行数完全一致"的情况下悄悄损坏。所以我做三级对账,一级比一级严:

|----------------|---------------|-------------------|
| 对账级别 | 能抓住什么 | 会漏掉什么 |
| ① 行数 count | 整行丢失/重复 | 行在但内容错(如 emoji→?) |
| ② 数值列 SUM | 金额、数量类错误 | 字符串损坏、时间偏移 |
| ③ MD5 全表指纹 | 逐行逐列的任何差异 | ------ |

第三级是关键。我在金仓里对"外部表(源)"和"本地表(目标)"执行完全相同 的 SQL,把每行拼成字符串、排序后求 MD5:因为都由金仓引擎执行、口径一致,只要有任何一个字节不同,指纹就会不同

结果:customers 三项全等(8=8 行、374550.02=374550.02、MD5 d4835ee4... 相同),orders 三项全等(含那行 emoji,MD5 572d7a44... 相同)。MD5 一致,等于逐行逐列宣告无损。 如果我没修字符集就迁移,这里的 MD5 会立刻不匹配------这正是三级对账存在的意义:让静默损坏无所遁形。

但这里还藏着一个"坑中坑"。 我的迁移目标库是 MySQL 兼容模式,而在 MySQL 兼容模式下,|| 不是字符串拼接、而是"逻辑或" 。我第一版对账脚本顺手用了 id||'|'||name||... 拼接------结果 MD5 指纹是"假"的:我做过一个验证,故意把目标表某行的 email 改成错误值,用 || 拼的指纹竟然源目标依旧相同 (因为逻辑或运算把真实字段值"吃"掉了),篡改被完全漏检;而换成 concat(id,'|',name,...) 后,指纹立刻不一致、篡改无所遁形。一个会漏检数据损坏的对账脚本,比不对账更危险 ------它给你虚假的安全感。所以在金仓 MySQL 兼容库里做对账,拼接一律用 concat(),不要用 ||

七、双轨共存与增量追平

真实迁移往往不能"一刀切",需要一段灰度窗口:源库还在接单,新库先并行验证。mysql_fdw 天然支持这种双轨------因为那条"通路"一直在,随时能对账。演示一下:

  1. 源库继续接单:MySQL 新增一单(id=99,灰度期订单);

  2. 对账兜底:立刻发现源 11 行 vs 目标 10 行,MD5 指纹不一致------差异被秒级抓到;

  3. 增量追平INSERT INTO orders SELECT * FROM ft_orders WHERE id NOT IN (SELECT id FROM orders),只补目标缺的那行;

  4. 再对账:11=11 行、MD5 恢复一致。

这套"源库持续写入 → fdw 增量追平 → MD5 对账兜底"的循环,就是平滑迁移窗口的核心机制。切换当天,反复跑对账直到追平,确认一致后再把应用连接串从 MySQL 换到金仓,风险可控。

八、结论

我用 mysql_fdw 走通了一条不停机、不装中间件 的 MySQL→金仓迁移路径:外部表建通路、一条 INSERT...SELECT 迁数据、三级对账验正确、双轨增量做平滑、源库只读可回退。

相关推荐
奔跑中的小象1 小时前
统信UOS + 天数AI卡部署SGLang服务手册
人工智能·uos·sglang·天数智芯
DevSecOps选型指南2 小时前
中国版Mythos,为何是悬镜安全灵脉CodeAI?
人工智能·安全
Shockang2 小时前
LangGraph 状态机实战
人工智能
刹那芳华19922 小时前
循环神经网络的从零开始实现(RNN)
人工智能·rnn·深度学习
阿童木写作2 小时前
跨境图片翻译工具多合一,批量图片视频字幕翻译加智能抠图
人工智能·python·音视频·语音识别
科技之门2 小时前
AI3D从建模到贴图、绑骨和动画的完整流程怎么做?V2Fun完整工作流指南
人工智能·3d·贴图
宇宙第一小趴菜2 小时前
二、机器学习的应用领域和发展史
人工智能·机器学习
前端开发江鸟2 小时前
我写过 MCP Server,却一直以为 MCP 只有 Tool
人工智能
天国梦3 小时前
自习室智能化升级避坑指南:天学网AI智习室方案实测与选型建议
大数据·人工智能
阿里云云原生3 小时前
可用性从 99.9% 跃升至 99.995%:畅捷通如何用 AI 重塑运维底座?
运维·网络·人工智能