某客户需要将基于 Mycat[1] 中间件分库分表的数据迁移至 ActionDB[2]。计划使用 ActionOMS 迁移工具实施,从后端 MySQL 拉取数据。
客户环境存在源端分片设计不合理的情况,后端分片存在主键字段数据重复的情况,但客户希望这些重复的数据不要直接迁移到目标端,而是在目标端重新生成新的唯一的主键。
聚合后发现主键数据重复
源端分库分表架构
本文探究如何在这种情况下,在目标端生成不重复的主键并保留 ActionOMS 的数据校验功能来进行数据迁移。
了解完以上概念,下面说具体的迁移思路。
我们分表结构和表数据两个部分说。
根据架构图可知,源库上每个分片上的表结构是一样的。我们只需要取其中一个分片的表结构,应用在目标端即可。
我们根据逻辑表的类型分为三种情况来说。
根据上面的解释可知,全局表意味着所有分片上都是一样的完整的数据。所以选取一个分片拉去数据即可,不可重复拉取。
假设 MyCat 后端有 N 个 MySQL 实例,则需要 N 条链路(每个分片的数据汇总迁移到目标端一个库作为一份完整的数据)。
此处的链路数量,统计 MySQL 主实例数量即可。
为什么会有重复的数据?
笔者做以下猜测:源端存在多个分片,表中存在自增主键,但主键不是分片键。此时主键的数据只能确保分片内唯一,全局范围可能重复。
注意:数据冲突时,迁移工具的策略可能会存在忽略(
insert ignore into …
)或覆盖(replace into …
)的情况。
解决思路就是对表结构进行改造,但有三种改造的方式:
需判断表结构改造之后迁移工具能否进行数据校验。
下面,将用第 3 种表结构改造方式,达成目标端主键数据不重复并可以进行数据校验。
先将源端和目标端改造完,我们再进行数据迁移。
将源端每一个分片表的字段 c2
设置为 NOT NULL UK,用于数据校验。
ALTER TABLE test02
MODIFY c2 varchar(36) COLLATE utf8mb4_bin NOT NULL;
ALTER TABLE test02
ADD UNIQUE KEY (c2);
Mycat 端确认源端表结构更改已生效。
[root@10-186-64-61 ~]# mysql -h10.186.64.61 -uroot -p'123456' -P8066 -DEVANDB -e "show create table test02;"
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| test02 | CREATE TABLE `test02` (
`c1` int(11) NOT NULL AUTO_INCREMENT,
`c2` varchar(36) COLLATE utf8mb4_bin NOT NULL,
`c3` datetime DEFAULT NULL,
PRIMARY KEY (`c1`),
UNIQUE KEY `c2` (`c2`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin |
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
手动创建表结构,将字段 c2
设置为 NOT NULL UK,用于数据校验。在数据校验之前暂时不能建立主键。
因为源端字段 c1
当前在各个分片上数据是重复的,所以 c1
字段不能直接同步到目标端。目标端将主键 c1
列改成 c1_new
。
(可选)由于目标端存在分区需求,我们将 c2
作为 KEY 分区字段,分区数量为 4 。
迁移前创建基础表结构:
CREATE TABLE `test02` (
`c1_new` int(11) NOT NULL AUTO_INCREMENT,
`c2` varchar(36) NOT NULL,
`c3` datetime DEFAULT NULL,
UNIQUE KEY `c2` (`c2`))
PARTITION BY KEY(c2)
PARTITIONS 4;
数据校验完成之后执行添加主键,由于 ActionDB 主键必须包含分区键,主键则需设置为(c1_new,c2):
alter table test02 add primary key (c1_new,c2);
最终表结构:
CREATE TABLE `test02` (
`c1_new` int(11) NOT NULL AUTO_INCREMENT,
`c2` varchar(36) NOT NULL,
`c3` datetime DEFAULT NULL,
PRIMARY KEY (`c1_new`,`c2`),
UNIQUE KEY `c2` (`c2`))
PARTITION BY KEY(c2)
PARTITIONS 4;
进行迁移选项配置。
选择迁移对象。
全量迁移设置:设置参数 sink.ignoreRedunantColumnsReplicate=true
,忽略 c1
字段。
增量同步设置:设置参数 sink.ignoreRedunantColumnsReplicate=true
,忽略 c1
字段。
全量校验设置 :更改全量校验组件的 condition.whiteCondition
,设置需要校验的字段是 c2
和 c3
,忽略 c1
字段。
修改后的配置。
迁移数据校验。
分片表的数据是各自独立一份,同一个 MySQL 实例的两个库各自约有一半的数据,加起来就是这个实例的这个分片表数量总数。
全量校验时:
目标端字段 c1_new
不存在重复数据,迁移成功!
c1_new
字段换回 c1
。ActionDB 作为一款卓越的企业级分布式数据库,其设计核心依托于 OceanBase 的开源内核,辅以爱可生在开源数据库领域的深厚积累与技术专长,荣获原厂的正式授权及内核级技术支持。
ActionDB 集 OceanBase 的稳健性与高性能于一身,更进一步强化了与 MySQL 的兼容性,融合爱可生独有的安全特性与用户友好的运维管理工具,缔造了更高品质、更全面的数据库解决方案。
ActionDB 的 MySQL 8.0 协议全面兼容能力,辅以基于 MySQL binlog 的双向复制技术,为业务系统与下游数据平台提供了安全无虞、无缝迁移的完美方案,确保数据迁移的零风险与无感知。
更多了解:ActionDB 扩展 OB GIS 能力:新增 ST_PointN 函数
ActionOMS 基于 OMS 本身的优秀能力,并依托于爱可生公司在数据库及周边工具的多年开发经验、对数据迁移/同步过程的深刻理解与运维经验,推出的定制化版本。
ActionOMS 由 OceanBase 向爱可生进行了全部代码授权,可对 OMS 问题进行源码解释并修复,同时可以接受定制化开发的 OMS 版本。
更多了解:
[1]
Mycat: https://github.com/MyCATApache/Mycat-Server
[2]
ActionDB: https://www.actionsky.com/actionDB
本文关键字:#OceanBase# #ActionDB# #ActionOMS# #数据迁移# #Mycat#