联系我们
18591797788
hubin@rlctech.com
北京市海淀区中关村南大街乙12号院天作国际B座1708室
18681942657
lvyuan@rlctech.com
上海市浦东新区商城路660号乐凯大厦26c-1
18049488781
xieyi@rlctech.com
广州市越秀区东风东路华宫大厦808号1608房
029-81109312
service@rlctech.com
西安市高新区天谷七路996号西安国家数字出版基地C座501
在数字化转型浪潮席卷各行各业的今天,数据已成为企业的核心资产。而数据库作为数据的承载基石,其性能、可扩展性、稳定性和成本效益,直接关系到企业业务的敏捷性与未来发展。许多企业最初选择开源MySQL数据库,是因其简单易用、生态丰富而备受青睐,但随着业务规模的飞速扩张,MySQL在面临海量数据、高并发事务及分布式部署等场景时,常常在扩展性、容灾能力和运营成本上遇到瓶颈。
OceanBase 作为原生分布式数据库,凭借其强大的水平扩展能力、金融级高可用性(RPO=0,RTO<30秒)、高度兼容MySQL协议以及优异的成本控制优势,成为企业数据库升级换代、应对未来挑战的理想选择。将数据从MySQL迁移至OceanBase,不仅是数据库平台的更替,更是一次架构的现代化演进,旨在为企业的核心业务系统注入新的活力,构建坚实、弹性的数据底座。
然而,数据库迁移并非简单的“数据搬家”,是涉及评估、设计、实施、验证等多个环节的系统性工程,本文结合实战项目经验,梳理从 MySQL 迁移至 OceanBase 4254 版本的全流程实操方案,帮你规避数据的迁移之坑!
OceanBase版本:4254
Mysql版本:5.7/8.0
OMS工具:425BP1/431
OCP:425
连接信息:域名/IP + 端口。
版本:mysql5.6/5.7以及mysql8.0,不同版本默认字符集字符序和部分变量参数值可能存在不同。
源实例资源占用情况:CPU、内存
统计数据类型以及使用的字符集类别,评估在 OceanBase 的兼容性。
统计数据库、表的总数量,以及总数据量(GB/TB级别);这决定了迁移时间和资源需求。
切换OB后可以使用OB提供的jdbc驱动,也可以使用mysql原生驱动,如使用后者:
对于Mysql Connector/J5.x版本,推荐使用5.1.40-5.1.49之间的版本。
对于Mysql Connector/J8.x版本,推荐使用8.0.7-8.0.25以及8.2.0-8.4.0之间的版本。
Mysql原生驱动和OB数据库不一定能完全兼容,V8版本不推荐使用8.0.26-8.0.33这个区间的版本,有项目case案例,介于使用场景不同,非100%复现。
连接串可沿用原来的,适当加上参数useLocalSessionState=true&tinyInt=false,如使用V8遇到兼容性问题可尝试添加compatibleMysqlVersion=8参数测试能否规避。
梳理需迁移的对象(包括库、表、视图、触发器、主外键约束、存储过程、函数等)。注意 OceanBase 对 MySQL 语法的兼容性,但并非 100% 兼容。
注意事项:(使用OMS工具迁移)
1、对于无主键或者非空唯一键,主要影响有两个:
无法做反向同步(未在OBMysql业务租户创建__oceanbase_inner_drc_user情况下)
OBMysql->Mysql,不支持无主键或者非空唯一键表的迁移。
无法做全量校验
在Mysql->OBMysql,无法做全量或者增量校验。所以对于这部分表需要评估对业务重要性程度进行改造。
-- 查找无主键或者非空唯一键的表
select table_schema,table_name
from information_schema.tables b
where table_schema=database()
and not exists(
select 1
from (
select distinct table_name,table_schema
from information_statistics where table_schema=database()
group by table_schema,table_name,index_name
having count(*)=count(
if(upper(nullable) !='YES'
and non_unique=0,1,null)))a
where b.table_schema=a.table_schema
and b.table_name=a.table_name);
2、OMS无法迁移check约束和非noaction属性的外键,需要找出来在正向切换停机窗口补上。
-- 找出check和外键约束
select constraint_schema,
constraint_name,
table_name,
constraint_type
from information_schema.table_constraints
where constraint_schema=database()
and constraint_type in('FOREIGN KEY','CHECK');
-- 找出非no action属性的外键
select constraint_schema,
constraint_name,
table_name,
referenced_table_name,
update_rule,
delete_rule
from information.referential_constraints
where constraint_schema=database()
and (update_rule !='NO ACTION' or delete_rule!='NO ACTION');
-- 字符集确认
show variables like '%character%';
show global variables like '%character%';
-- 字符序(不同字符序可能会导致查询结果不同)
show variables like '%collation%';
show global variables like '%collation%';
--sql_mode SQL模式检查
show variables like '%sql_mode%';
show global variables like '%sql_mode%';
注意:列举以上比较关键的变量值,其中sql_mode在
mysql5.6:
mysql5.7:ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION
mysql8默认值为:ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_ENGINE_SUBSTITUTION
OB42版本默认值为:STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_AUTO_CREATE_USER
可以看出OB42X版本对于SQL模式限制相对宽松,因此建议OB42X SQL_MODE为:ONLY_FULL_GROUP_BY, STRICT_ALL_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER
增量迁移需确保源端Mysql开启binlog,需满足binlog_row_image为full,binlog_format=row,且至少保留24小时以上(建议3天以上);
记录关键业务查询的 QPS、TPS 和延迟,作为迁移后性能对比的基准。
1、创建数据迁移用户omsmgr并授予相应的权限;
-- 创建用户
create user `omsmgr`@`%` identified by ****;
-- 授予迁移数据库的读权限
grant select on .* to 'omsmgr';
grant show view on .* to 'omsmgr';-- 如果是mysql8.0版本需要授予show view的权限
-- 增量迁移场景下,需要具备replication_client、replication_slave和select *.*权限
grant replication_client,replication_slave on *.* to 'omsmgr' [with grant option];
grant select on *.* to 'omsmgr';
-- 反向增量(OB->Mysql)需要授予相应的DML和DDL权限
grant update,delete,insert on .* to 'omsmgr'; -- dml
grant alter,create,create view,drop,index on .* to 'omsmgr'; -- ddl
⚠️:如果勾选了 增量同步时,允许 OMS 自动向该实例写入心跳数据,以解决源端在无业务写入场景下的高延时问题,并且填写的数据库用户具备创建表、写表的权限,OceanBase 迁移服务(OceanBase Migration Service,OMS)会向对应的数据库中创建心跳表,并以 5 秒/次的频率更新心跳表。
CREATE DATABASE IF NOT EXISTS drc;
GRANT CREATE ON drc.heartbeat TO 'omsmgr';
CREATE TABLE IF NOT EXISTS drc.heartbeat (`id` smallint(6) NOT NULL DEFAULT 1,`ts` int(11) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB comment='心跳表';
GRANT CREATE ON drc.heartbeat TO 'omsmgr';
GRANT INSERT, UPDATE, DELETE ON drc.heartbeat TO 'omsmgr';
部分场景下OMS会识别不到源端给予迁移用户对表drc.heartbeat的DML权限,因此可将授权语句改成drc.*
GRANT INSERT, UPDATE, DELETE ON drc.* TO 'omsmgr';
本文介绍的是通过OMS工具迁移Mysql数据到Ocebase数据库,所以需要确保OMS所在的服务器能访问源端mysql实例;需要开通访问源实例的域名/IP+端口;
待迁移数据库的数据除了应用业务本身的读写,是否还存在上下游数据来源,上游如通过OGG或者DTS等迁移到mysql数据库,以及下游是否存在往该库抽取数据的情况。如存在后续切换到OB后,上下游的目标库也需要相应的切到OB。
相比Oracle而言,跑在Mysql实例上的业务系统相对轻量,因此一个 OceanBase 集群可用承载多个轻量的mysql实例。4F1A双活架构(两地三中心)因具备高可用、高容灾能力可作为参考选型架构(具体可参考实际项目需求和POC测试情况,本架构在笔者所在项目经过综合方面考虑选定)。
创建租户需要指定租户字符集、字符序以及部分变量值设置如sql_mode等影响结果集等关键变量。因此可关注《源库分析-变量参数》,根据源库的使用情况再配置响应的变量值。另外源mysql主键一般自增列int类型,在OB存在自增列跳变的情况(如副本切主、唯一键冲突、事务回滚、宕机重启、自增cache失效),如果同样设置为int类型,跳变情况下容易拉暴自增列的值,因此可以将int改为bigint或者将自增列缓存个数变量(auto_increment_cache_size)的值调小(默认为100万),可调整10万以内。
为避免夏令营时区问题,可将时区变量time_zone设置为Asia/Shanghai,其默认值为+8:00。
关于sql_mode:
mysql5.6:
mysql5.7:ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION
mysql8默认值为:
ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_ENGINE_SUBSTITUTION
OB42版本默认值为:
STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_AUTO_CREATE_USER
可以看出OB42X版本对于SQL模式限制相对宽松,因此建议OB42X SQL_MODE为: ONLY_FULL_GROUP_BY, STRICT_ALL_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER
大部分传统数据都是运行在非信创服务器上,而信创不光是数据库产品,而是涉及整个系统链路。所以需要考虑信创服务器和非信创服务器在CPU 算力上的差距;压力测试阶段CPU可按1:1.5,1:2递增测试实际所需资源。内存需保持大于等于源内存。
创建数据库并指定字符集和字符序,根据源端使用情况而定。需要结合表的字符集和字符序情况,在mysql可能经历过5.6/5.7->8.0升级的情况,Mysql5X版本默认字符序为utf8mb4_general_ci,Mysql8.0默认为utf8mb4_0900_ai_ci,因此有必要确认好业务常用的字符序。
根据源端业务用户使用情况进行创建和授权。在切换前,除了迁移用户和root用户,其他用户一律给只读权限,避免在割接期间误操作带来的数据一致性问题。
目标段除了配置业务用户以为,还需要迁移用户,可直接使用root用户或者创建迁移用户并给予所需的权限。具体权限可参考《源库分析-迁移用户创建》反向增量时所需的权限。
此外,反向增量需要以oceanbase作为源,因此需要在OB端的SYS租户和业务租户创建相应的用户。
-- SYS租户下创建(当使用 OceanBase 数据源作为源端进行结构迁移、结构同步或增量同步时,以及使用 OceanBase 数据源作为目标端进行反向增量时需要创建drc_user用户)
CREATE USER drc_user IDENTIFIED BY '';
GRANT SELECT ON *.* TO drc_user;
-- 业务租户下创建(可选):该用户为可选用户,仅在需要迁移无唯一键表时创建
CREATE USER __oceanbase_inner_drc_user IDENTIFIED BY '';
GRANT SELECT ON *.* TO __oceanbase_inner_drc_user;
建议将业务租户主副本落在同机房的一个或者多个zone上,轻量级可设置单zone,具体看资源消耗情况。
-- 创建用户
create user `omsmgr`@`%` identified by ****;
-- 授予迁移数据库的读权限
grant select on .* to 'omsmgr';
grant show view on .* to 'omsmgr';-- 如果是mysql8.0版本需要授予show view的权限
-- 增量迁移场景下,需要具备replication_client、replication_slave和select *.*权限
grant replication_client,replication_slave on *.* to 'omsmgr' [with grant option];
grant select on *.* to 'omsmgr';
-- 反向增量(OB->Mysql)需要授予相应的DML和DDL权限
grant update,delete,insert on .* to 'omsmgr'; -- dml
grant alter,create,create view,drop,truncate,rename,index on .* to 'omsmgr'; -- ddl
⚠️:如果勾选了 增量同步时,允许 OMS 自动向该实例写入心跳数据,以解决源端在无业务写入场景下的高延时问题,并且填写的数据库用户具备创建表、写表的权限,OceanBase 迁移服务(OceanBase Migration Service,OMS)会向对应的数据库中创建心跳表,并以 5 秒/次的频率更新心跳表。
CREATE DATABASE IF NOT EXISTS drc;
GRANT CREATE ON drc.heartbeat TO 'omsmgr';
CREATE TABLE IF NOT EXISTS drc.heartbeat (`id` smallint(6) NOT NULL DEFAULT 1,`ts` int(11) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB comment='心跳表';
GRANT CREATE ON drc.heartbeat TO 'omsmgr';
GRANT INSERT, UPDATE, DELETE ON drc.heartbeat TO 'omsmgr';
部分场景下OMS会识别不到源端给予迁移用户对表drc.heartbeat的DML权限,因此可将授权语句改成drc.*
GRANT INSERT, UPDATE, DELETE ON drc.* TO 'omsmgr';
-- 创建用户
create user `omsmgr`@`%` identified by ****;
-- 授予用户相应的读写权限
grant update,delete,insert on .* to 'omsmgr'; -- dml
grant alter,create,create view,drop,truncate,rename,index on .* to 'omsmgr'; -- ddl
-- SYS租户下创建(当使用 OceanBase 数据源作为源端进行结构迁移、结构同步或增量同步时,以及使用 OceanBase 数据源作为目标端进行反向增量时需要创建drc_user用户)
CREATE USER drc_user IDENTIFIED BY '';
GRANT SELECT ON *.* TO drc_user;
-- 业务租户下创建(可选):该用户为可选用户,仅在需要迁移无唯一键表时创建
CREATE USER __oceanbase_inner_drc_user IDENTIFIED BY '';
GRANT SELECT ON *.* TO __oceanbase_inner_drc_user;
如果都是数据量比较小的库,建议创建单个链路进行。如果数据量比较大,可按如下规则拆分:
按数据类型区分:LOB和非LOB数据
-- 在源实例查找数据库清单并确认要创建的业务数据库
show database;
-- 在源实例导出业务用户及权限然后在OB端执行
show grants for user_a;
注意:在割接前,除root和迁移用户以外的所有用户只授予只读权限。
配置Mysql数据源
登录OMS界面->
单击左侧数据源管理->
新建数据源->
数据库类型(选择Mysql)->
数据库属性选择(默认主库)->
IP/端口/用户名/密码等按实际环境信息填写。
登录OMS界面->
单击左侧数据源管理->
新建数据源->
数据库类型(选择OceanBase )->
租户类型(选择Mysql)->
IP/端口/租户名/集群名/用户名/密码等按实际环境信息填写
登录OMS界面->
数据迁移->
新建迁移项目(定义名称、源端、目标端)->
迁移选项(结构迁移+全量迁移+全量校验)->
迁移对象:
1、指定对象:根据已经显示的进行勾选
2、匹配规则:按照SCHAME.TABLE_NAME格式匹配,若想改变目标表名称可以SCHAME.TABLE_NAME=SCHAME.NEW_TABLE_NAME进行匹配,需要点击校验和预览对象确认->
迁移选项:
1、全量迁移/增量迁移/全量校验:可自定义资源根据机器资源及规划链路数酌情分配,后续亦可调整。
2、迁移高级配置:不做任何处理。
3、处理策略为停止迁移,允许索引后置。
4、增量记录保存时间:根据实际需求,无则默认120小时即可->
预检查通过后,启动项目。
登录OMS界面->
数据迁移->
新建迁移项目(定义名称、源端、目标端)->
迁移选项(增量迁移:根据实际需求勾选DML/DDL+全量校验)->
迁移对象:
迁移选项:
预检查通过后,启动项目
OMS430版本开始支持迁移除表和视图意外的其他数据库对象。也可以通过DBCAT转换成obmysql支持的语法,再进行批量执行。
OMS430版本开始支持配置全量检验、行数校验、增量校验。
源端对业务用户进行锁定和kill相应的活跃会话,或者只授予只读权限。并授予迁移用户omsmgr相应的读写权限。
注意:部分mysql实例业务用途范围可能比较广泛,在源MYSQL实例用户权限变更前需要做评审和复合,避免有生产影响。
对原有的增量迁移链路上执行正向切换,停止该链路。停止后OMS上发起全量或者增量数据校验,确保数据一致性后。如果全量校验时间较长,可在切换前先做全量校验,源端停写后再拉增量校验,减少应用停服时间。
源端启用外键和触发器
目标端启用外键和触发器
可参考《创建增量迁移链路》,注意这时的源为oceanbase,目标端为mysql。
反向增量链路创建后,原有OB端只有只读权限,这时可以放开所有业务用户的读写权限。
应用切换链接到OB端
功能、性能、用户权限等方面测试。
1、mysql8.0->OB过程中,如果两边字符序不一致,在增量的create同步过程中,会按照各自默认的字符序进行表的创建,因此需要注意增量产生的新表的字符序问题。
2、在OB mysql租户模式下,字符序utf8mb4_0900_ai_ci和utf8mb4_general_ci是冲突的,即两表关联,且各自对应以上字符序时会报Illegal mix of collations(utf8mb4_0900_ai_ci,IMPLICIT),(utf8mb4_general_ci,IMPLICIT)-invalid query。需要将两表字符序设置为一致。
1、由于 OB 默认字符集为utf8mb4,且不支持utfmb3。因此如果源mysql实例字符集为utfmb3,在反向同步的时如有特殊符号是mb3不支持的,可能会造成两边的数据不一致。
2、特殊符号在OB能正常显示,但是在源mysql会显示乱码或者?。这部分理论是符合预期的,说明源mysql在之前就是这样存储特殊符号的。因此可忽略这部分不一致的数据问题。
如果你在实际操作中遇到问题,或是有独到的优化经验,欢迎在评论区留言分享,下次见!