携程:从MySQL迁移OceanBase的数据库发布系统实践

本文主要是介绍携程:从MySQL迁移OceanBase的数据库发布系统实践,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

作者简介:杨晓军 现就职于携程的数据库团队,主要负责携程数据库的研发与管理,专注于提升数据库的稳定性。

自分布式关系型数据库OceanBase开源以来,携程已经在线上环境中进行了广泛的应用,取代了原先以MySQL为主力的业务数据库系统。在转型过程中,确保与MySQL的高度兼容性成为了我们选型的关键考量。为此,我们自主研发了一套数据库发布系统,旨在通过该系统,DBA、业务专家及运维团队能够迅速识别并理解MySQL与OceanBase在DDL语句执行上的差异,从而加速对OceanBase数据库的掌握与适应,最终提升整体应用系统的稳定性。

本文从以下三个方面介绍携程自研数据库发布系统的实践。

  • 数据库发布系统研发的四个步骤
  • MySQL 与 OceanBase 的兼容性与差异性
  • MySQL 数据同步 OceanBase 过程中 DDL 遇到的问题

一、数据库发布系统研发的四个步骤

MySQL 作为全球最受开发者欢迎的数据库,被广泛应用于各类场景中。其中,MySQL 5.7 版本正是携程在大规模使用的数据库。但在 MySQL 系统中,并不是所有的 DDL 操作都是线上实时进行的,导致了主从复制延迟的问题,即使是 MySQL 8.0 版本也不能避免这个问题的发生。随着表中数据规模越来越大,DDL 的危险系数就越来越高,我们自研的数据库发布系统通过第三方工具 gh-ost 不断监听从节点的复制延迟,解决了长时间执行 DDL 时导致的延迟问题,确保了 MySQL 的高可用。

数据库发布系统的研发共分为四个步骤:设计系统、生成 SQL 语句和发布计划、发布测试环境、发布生产环境。

第一步,设计系统。

设计系统的分工可能在每个公司略有差异,就携程而言,由于系统中的库、表太多,DBA 不参与表结构评审,表结构的设计及变更都由研发人员进行。如下图,研发人员可以通过界面或通过导入 SQL 来完成表结构的变更操作。

第二步,生成 SQL 语句和计划发布。

所有的表结构变更提交后就进入第二步:生成 SQL 语句和发布计划。生成 SQL 语句比较好理解,基于设计系统中的修改生成代码,比如,在界面上添加一个字段 testindex,并在新加的字段上创建索引,就会生成如下 SQL 语句,包括添加的 testindex 在哪个前置字段的后面、是否为空及默认值信息等,最重要的是找到对应数据库所在的 MySQL 实例:

alter table `testyxj_part` add `testindex` varchar(10) not null default ‘’  comment ‘test’ after `datachange_lasttime`;
alter table `testyxj_part` add key test(testindex);

前面说到的系统设计对应的是开发环境,而此处的 SQL 语句其实是对比开发环境和测试环境的表结构差异生成的。在携程,数据库部署环境分为开发环境、测试环境和生产环境,我们会根据配置表来生成数据库最终在哪个环境以及要去哪些集群上执行。从下图的数据库配置信息中可以看到,在每个环境中数据库的类型是不固定的,比如,在设计系统中是 MySQL,在测试环境也可以是 OceanBase。除拉数据库和 OceanBase 的集群关系外,我们还会将数据库和租户的对应关系的元数据放置在这个配置表中。

第三步:发布测试环境。

因为我们会定期检查表数据量,可以保证单表大小基本不会超过 10GB,所以测试环境的发布直接使用了原生的 MySQL DDL 命令。发布测试环境时,没有对同一个发布单下的同一张表做 DDL 合并,比如,同一张表添加2个字段,发布系统会按照字段顺序进行两次拷贝整表的过程。因此,测试环境可以兼容 OceanBase 的表结构变更,只需在连接数据库的时候带上租户即可。

第四步:发布生产环境。

生产环境的表容量大小不一,大则上百 GB,小则几 MB,为了保证 MySQL 大表做表结构变更时主从复制延迟低,我们使用了开源工具 gh-ost。在发布生产环境时,将 DDL 任务放到一个 gh-ost 队列中,进入队列后会进行待发布数据库的检测,比如,待发布数据库所在的集群主从复制是否正常、剩余磁盘空间是否可以支撑一次全量拷贝并在发布完成后磁盘剩余空间是否仍在90%以下,等等。同一个数据库的同一个表会将 DDL 操作合并发布。例如,一个发布要加2个字段,而在 gh-ost 处理时实际只会做一次全量拷贝的动作。其他的 DDL 可以使用 in-place 方法的 DDL 操作判断,如下图,将 varchar10 改为 varchar20,没有跨越 255 字节这个边界,此外,创建表删除、表索引等没有压力的 DDL 都使用原生 DDL 加速发布。

二、MySQL 与 OceanBase 在系统中的兼容性与差异性

1、MySQL 与 OceanBase 在系统中的兼容性。

携程开始使用 OceanBase 数据库后,需要和原来的 MySQL 系统兼容。有两种兼容方案,一是在 OceanBase 数据库上线后,进行表结构变更并发布,开发环境、测试环境、生产环境都采用 OceanBase;二是在迁移过程中进行兼容部署,比如,测试环境是 OceanBase,生产环境使用 MySQL。如下图,在设计系统加入 OceanBase,初期,我们把开发环境的 OceanBase 放在 MySQL 实例上,因为大部分研发人员要做的表结构变更如添加字段、索引都是常规动作,而 hash 分区、key 分区都还刚起步,这部分对于设计表结构的研发人员可能比较陌生,所以暂时将OceanBase数据库部署在 MySQL 实例上用于兼容设计系统。

将 OceanBase DB 和租户、集群的关系加入发布的配置表,这样才能正常生成发布计划,并且代码根据对应的租户连接到数据库之后执行 DDL,如下图。

得益于 OceanBase LSM Tree 的存储引擎,几乎所有 DDL 操作都是真正的 “Online DDL”,因此,OceanBase 数据库发布时我们直接采用了原生 DDL 进行发布(下图为代码判断逻辑)

2、MySQL 与 OceanBase 在系统中的差异性。

在开发环境中,携程将 MySQL 和 OceanBase 做了分离,在 OceanBase 设计时可能会使用分区、特殊压缩等与 MySQL 语法不兼容的功能,这部分在 MySQL 上无法实现,同时前端也会对这些差异功能提供默认值选项,比如,OceanBase 的索引功能可以选 local 索引和 global 索引,在携程,默认使用 global 索引。

但是,Range 分区类型的 Oceanbase 表发布索引自动转换成 local 类型。我们有一张 MySQL 的表,表上索引如下图所示:

研发人员为了实现 MySQL 业务迁移到 Oceanbase 的同时能自动完成数据清理,可能会将原先 MySQL 的普通表在 Oceanbase 中改成 range 分区表,由于分区键必须包含在主键和唯一索引中,并且唯一索引只能创建为 global 类型,因此表结构迁移到 OceanBase 之后演变成下图所示:

从 MySQL 迁移到 OceanBase 时有数据实时同步任务,某一天我们发现使用这个唯一索引查询数据出现了重复数据,如下图所示:

我们在排查时发现,原来是唯一索引失效了,如下图 show index from 的结果显示为 index error,最终,我们判断可能是 drop partition 这个分区清理的动作超时导致了索引失效。

因此,我们放弃了 range 分区,仍然保持了 MySQL 的结构,也就是对原有的表结构进行迁移。经过这次的“踩坑”,我们在发布系统中增加了一个判断,当 OceanBase 的表是 range 类型的分区表时,不能创建唯一索引,并且在生成的发布 SQL 中我们会自动将 global 的索引转换成 local 索引,以保证索引不会失效引发性能问题或其他问题,效果如下图。

三、MySQL 数据同步 OceanBase 时 DDL 遇到的问题

场景一:添加字段。

  • OceanBase 添加不允许为空有默认值的字段,增量同步正常;MySQL 添加相同字段,发布期间写入数据,增量同步 OceanBase 正常。
  • OceanBase 添加不允许为空无默认值的字段,增量同步报错;MySQL 添加相同字段,无法添加,非空字段需要设置默认值。
  • OceanBase 添加允许有默认值的字段,增量同步正常;MySQL 添加相同字段,增量同步正常。
  • OceanBase 添加允许为空无默认值的字段,增量同步正常;MySQL侧 添加相同字段,增量同步正常。

场景二:删除字段。

  • MySQL 删除字段,增量同步正常; OceanBase 删除相同字段,增量同步正常。

场景三:清空表。

  • MySQL 清空表 DDL 的命令无法同步至 OceanBase。
truncate table hjjtesttable;

  • OceanBase 清空表后可以继续同步。
truncate table hjjtesttable;

场景四:修改字段。

  • OceanBase 修改 allow null 字段为 not null 并设置默认值,需要先处理 MySQL 历史空数据,更新 MySQL 数据后未同步至 OceanBase。
alter table `hjjtesttable` modify `testyxj8` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci  not null  default '888' comment 'test';
ERROR 1138 (22004): Invalid use of NULL value
update hjjtesttable set testyxj8 ='888' where testyxj8 is null;

  • OceanBase 修改 not null 字段为 allow null,并且没有默认值,更新 MySQL 数据后未同步至 OceanBase。
OB:alter table `hjjtesttable` modify `testyxj8` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci null  comment 'test';
MYSQL:update hjjtesttable set testyxj8='8888' where id =1;
OB:select * from hjjtesttable where id =1 and testyxj8='8888';
Empty set (0.00 sec)

  • OceanBase 不允许修改非字符类型和修改列定义,仅支持增加特定字符数据类型(VARCHAR、VARBINARY、CHAR等)的长度。
alter table hjjtesttable modify testyxj7 bigint COMMENT 'test';
ERROR 1235 (0A000): Alter non string type not supported

场景五:创建索引。

  • OceanBase 创建索引,增量同步正常;MySQL 创建索引,增量同步正常。

场景六:删除索引。

  • MySQL创建索引,增量同步正常;OceanBase 创建索引,增量同步正常。
  • 类似上述六个场景中的情况还有很多,因此,在 MySQL 向 OceanBase 迁移的过程中,我们将 MySQL 的发布环境全部冻结了,不允许执行任何 DDL 语句。

以上就是携程通过自研数据库发布系统提高应用稳定性的实践经验,希望我们的经验分享能够帮助到你。另外,在携程与 OceanBase 合作期间,携程的各项测试表明,OceanBase 原生分布式数据库的各方面性能都可以满足携程的业务需求。因此,我们非常感谢 OceanBase 的所有技术支持人员,相信在后续的合作中,OceanBase 能发挥更优越的表现。

这篇关于携程:从MySQL迁移OceanBase的数据库发布系统实践的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1118009

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

SQL中的外键约束

外键约束用于表示两张表中的指标连接关系。外键约束的作用主要有以下三点: 1.确保子表中的某个字段(外键)只能引用父表中的有效记录2.主表中的列被删除时,子表中的关联列也会被删除3.主表中的列更新时,子表中的关联元素也会被更新 子表中的元素指向主表 以下是一个外键约束的实例展示

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

如何去写一手好SQL

MySQL性能 最大数据量 抛开数据量和并发数,谈性能都是耍流氓。MySQL没有限制单表最大记录数,它取决于操作系统对文件大小的限制。 《阿里巴巴Java开发手册》提出单表行数超过500万行或者单表容量超过2GB,才推荐分库分表。性能由综合因素决定,抛开业务复杂度,影响程度依次是硬件配置、MySQL配置、数据表设计、索引优化。500万这个值仅供参考,并非铁律。 博主曾经操作过超过4亿行数据

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

MySQL数据库宕机,启动不起来,教你一招搞定!

作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG、Mongodb数据库运维(如安装迁移,性能优化、故障应急处理等)公众号:老苏畅谈运维欢迎关注本人公众号,更多精彩与您分享。 MySQL数据库宕机,数据页损坏问题,启动不起来,该如何排查和解决,本文将为你说明具体的排查过程。 查看MySQL error日志 查看 MySQL error日志,排查哪个表(表空间

高效+灵活,万博智云全球发布AWS无代理跨云容灾方案!

摘要 近日,万博智云推出了基于AWS的无代理跨云容灾解决方案,并与拉丁美洲,中东,亚洲的合作伙伴面向全球开展了联合发布。这一方案以AWS应用环境为基础,将HyperBDR平台的高效、灵活和成本效益优势与无代理功能相结合,为全球企业带来实现了更便捷、经济的数据保护。 一、全球联合发布 9月2日,万博智云CEO Michael Wong在线上平台发布AWS无代理跨云容灾解决方案的阐述视频,介绍了