信创改造里数据库替换最难。这篇记录把炬鲸 OBSERVE 存储层从 MySQL 迁到人大金仓 KingbaseES 的过程,覆盖兼容模式、自增主键、大小写与排序规则、执行计划差异、性能对拍与回滚方案。
信创改造里,数据库是替换难度最高的组件之一。可观测平台本身要落地,先得过存储这一关:元数据、配置、告警历史这些业务库,能不能跑在人大金仓 KingbaseES 上?这篇记录我们把炬鲸 OBSERVE 的存储层从 MySQL 迁到 KingbaseES 的过程和踩的坑。
KingbaseES 提供了 MySQL 兼容模式,初始化时指定 --case-insensitive 和 MySQL 兼容参数,能覆盖大部分 INSERT、SELECT、JOIN 场景。迁移的第一步不是重写 SQL,而是先让驱动连上、把兼容模式调对。
驱动上,KingbaseES 官方提供了 JDBC 驱动,也可以走 PostgreSQL 协议用标准驱动连接。我们在 Go 服务里用 pgx 直连,配置里把 search_path 指到业务 schema,省掉大量前缀。
迁移顺序我们按"先结构后数据"走:先用官方迁移工具导出 MySQL 的表结构,转成 KingbaseES 的 DDL 后建表;再用批量方式(一次几千行)导数据,别一条条插,大表逐条插能跑一天。迁移过程中 MySQL 保持在线,两边同时写一段时间做双跑对拍,确认一致了再切流量。
第一个是自增主键。KingbaseES 用序列模拟自增,MySQL 的 AUTO_INCREMENT 迁移后要手动建 sequence 并绑默认值,否则插入直接报"列不能为空"。我们用脚本把每张表的主键都改成 serial 或显式序列,序列名统一用 表名_列名_seq 的规范,方便后续维护。
第二个是大小写。即便开了兼容模式,未加引号的标识符在 KingbaseES 里仍会折叠成小写,而 MySQL 默认保留原样。迁移前统一把表名、列名改成小写下划线,别留驼峰。代码里的 ORM 字段映射也要跟着核对,避免"查得到表、读不出字段"。
第三个是字符集和排序。KingbaseES 默认排序规则和 MySQL 的 utf8mb4_general_ci 不一致,模糊查询 LIKE '%中文%' 的结果可能不同。初始化时指定 --encoding=UTF8 并选对 collation,上线前用同一批查询做对拍。
KingbaseES 的执行计划风格和 MySQL 不同,同一条复杂查询的索引选择可能不一样。迁移后我们对慢查询逐条 EXPLAIN,给几张高频表补了联合索引,查询延迟从迁移初期的 3 倍降到基本持平。别想当然地沿用 MySQL 时代的索引设计,重查一遍执行计划比什么都实在。
另外注意连接数。KingbaseES 默认 max_connections 较低,而可观测平台的采集器、告警引擎、API 都会开连接池,容易撞上限。部署时把 max_connections 调高,连接池的 max_idle 也对应收紧,否则高峰期会出现"等待连接"的排队。
MySQL 兼容模式能覆盖大部分场景,但不是全部。我们在迁移中遇到的边界包括:部分存储过程语法、JSON 函数的行为差异、以及 GROUP BY 的宽松模式(ONLY_FULL_GROUP_BY)。建议迁移前先跑一遍真实 SQL 清单,把用到的函数、存储过程、触发器逐项过一遍,别等上线了才撞上。实在不兼容的,就改造成 KingbaseES 原生写法,反而更稳。
迁移一定要留后路。我们把 MySQL 作为回滚点保留到双跑结束、观察一周无异常后再下线;KingbaseES 侧每天做逻辑备份,出问题能按时间点恢复。
落地清单:
跑通 KingbaseES 之后,平台的国产化组件清单上就少了一块硬骨头。数据库适配没有捷径,但坑是固定的,踩过一次就能写成 SOP。