我们有一批 MySQL 5.7 生产分库,库名类似 shsc_wms_wgb、shsc_wms_wlz、shsc_wms_wxa 等,现在要同步/迁移到 TiDB。
TiDB 目标库的表结构最初是从 shsc_wms_wgb 复制出来的。但实际生产里,其他分库的同名表结构并不完全一致。迁移工具做 table structure / sharding consistency check 时会报错,例如:different column definition
shsc_wms_wlz.w_company.business_object varchar(50)
shsc_wms_wxa.w_company.business_object varchar(50) CHARACTER SET utf8
-
同字段长度不一致
company_name varchar(100) vs varchar(50)
-
字符集/排序规则不一致
varchar(50)
varchar(50) CHARACTER SET utf8
varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
-
部分分库多字段或少字段
upstream has more columns than downstream: weight, volume, loading_dock
-
有些字段在部分生产库比 wgb 更长
所以不能简单把所有库刷成 wgb,否则可能缩短字段
我们已经把所有生产库的 SHOW CREATE TABLE 都导出来了。初步分析下来,如果按 wgb 做基线,TiDB 能对齐 wgb,但源端其他 MySQL 分库之间仍然不一致,迁移校验还是过不了。
现在纠结的是处理顺序和基线选择:
- 是否应该先把所有 MySQL 源端分库的同名表结构统一,再让 TiDB 跟随统一后的结构?
- 源端统一时,是否应该采用“安全超集”原则:字段长度取最大,只扩不缩;缺字段补齐;字符集统一;真实类型冲突人工确认?
- 对字符集/排序规则不一致,应该逐列 MODIFY COLUMN,还是表级 ALTER TABLE … CONVERT TO CHARACTER SET utf8mb4 COLLATE …?生产 MySQL 5.7 下哪个风险更可控?
- 对几百条 DDL,生产上有没有推荐的执行策略?比如按表分批、先小表后大表、用 gh-ost/pt-osc,还是只处理迁移校验报错的点?
- TiDB 目标库应该以 wgb 为准,还是以所有 MySQL 源库统一后的安全超集为准?
我们的目标是:尽量少改生产 MySQL,不丢数据,不缩字段,能让 MySQL 分库结构一致性校验通过,并顺利同步到 TiDB。
想请教这种 MySQL 多分库同步 TiDB 的场景,大家一般怎么定基线、怎么处理字符集和字段定义不一致?
现阶段情况是 字段不一致的都好刷。 主要就是字符集 不一致的问题。 因为生产有70多个库,刷的脚本实在是太多了。 不知道如何是好了。请大佬们指点一二。 
克里克里克
(Ti D Ber H052ej9m)
3
迁移的时候,通常情况下,不会再改动前端了,对前端的修改对应用都是不可控的。
最大化tidb的结构,将数据同步至TiDB把。
mysql 里面是分库分表 由于历史原因 里面的表字符集不一致。导致 同步tidb时报错。无法同步。现阶段只能解决前端问题之后才能同步。
克里克里克
(Ti D Ber H052ej9m)
5
表结构的校验能取消么?校验数据就可以了。
MySQL端能统一是最好的,就看风险是否可控了。
DM进行同步的?
kang
9
选型要看具体场景。如果数据量在百TB以内、读多写少、对强一致性有要求,TiDB 挺合适。如果数据量级不大(单机够用)或业务逻辑复杂(存储过程、触发器多),MySQL 更省事。建议拿业务做 POC 测试对比。
要比较的话得看系统瓶颈在哪。MySQL 是单点写入瓶颈,TiDB 通过 Raft + Region 分片解决。但分布式一致性开销(多数派写入)在跨 AZ 部署时延迟会更明显。关键还是业务场景匹配。
TiDB_001
(Ti D Ber No L Znn Vd)
11
MySQL 保留 utf8/utf8mb4 异构,TiDB 表统一 utf8mb4。 TiDB 完全兼容 MySQL utf8(三字节)数据,读取 / 写入不会乱码
配置 ignore-checking-items跳过分库结构校验,TiDB 表建成超集结构(最长字段、最全字段、utf8mb4 字符集),不改动 MySQL,快速解决同步报错。
狂拽瘸子好腿
(Ti D Ber 8u Uk Olqy)
13
1)先统一所有 MySQL 分库表结构为超集;2)结构校验全部通过;3)再用 DM 同步全量 + 增量至 TiDB。
若先同步再改源库,会触发 TiDB 大量 DDL 同步、增量阻塞,风险更高。
先统一表结构(缺列补齐、类型对齐)再同步;DM 路由合并前做结构巡检。不一致时先只读校验集或灰度单库,避免目标宽表被窄表DDL冲掉。
-
同字段长度不一致
tidb 用 max 长度
-
字符集/排序规则不一致
字符集: tidb 设置 utf8mb4(默认)
如果上游是向下兼容的可以,如果不兼容需要上游改造
排序规则
上游改造成一致 or 统一为下游 tidb 的排序规则
-
部分分库多字段或少字段
tidb 手动建表,包含所有字段,设置 default 值
上游只会少不会多,具体操作看官网文档 https://docs.pingcap.com/zh/tidb/stable/migrate-with-more-columns-downstream/
-
有些字段在部分生产库比 wgb 更长
tidb 用 max 长
另外,上游如果有浮点数精度不一致,下游 tidb 按最长精度设置,可能产生精度偏差。 当然在从 mysql 到 tidb 不同数据库产品本身的 embedding 精度处理就存在差异,都符合 IEEE 754 就是了
https://docs.pingcap.com/zh/tidb/stable/data-type-numeric/
https://docs.pingcap.com/zh/tidb/stable/cast-functions-and-operators/
其实难的是 DDL 管理,上游如果太多,最好挑个冻结期快速切掉,避免上游执行 DDL 处理不了前功尽弃 