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

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

自分布式关系型数据库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 能发挥更优越的表现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2084424.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

虚幻5|技能栏优化(1)---优化技能UI,并添加多个技能

一.添加多一个技能格子并进行初始化清楚 1.打开技能UI把原先的事件构造后面的蓝图,全部选中,右键创建一个函数,命名为初始化 2.添加以下两个蓝图,用于清楚技能格子内容 2.在之前,事件构造后面的蓝图,不需…

人工智能是如何预测足球比赛的?看完这篇文章,你就全懂了!AutoPrediction

2024年欧洲杯开赛至今,德叔已经用人工智能预测了小组赛阶段的36场比赛,以及淘汰赛阶段的8场比赛,并且通过在网络上的发文,记录了所有这些比赛的预测结果。这些文章引来了不少朋友的围观,也让很多人对人工智能预测球赛这…

收藏夹里的“小网站”被误报违规不让上怎么办?如何将Chrome和Edge安装到 D 盘(含用户数据),重装系统也不会丢失收藏夹和密码?

当你用国产浏览器访问网站的时候,有时候会显示这个: 如果确实是违规网站,不让访问也没什么,但是很多都是误报啊,你这样直接来个大红横幅,还让人活不? 那遇到这种误报应当怎么办呢?有…

echarts 中 鼠标悬浮上加单位

tooltip: {trigger: "axis",valueFormatter: function (value: any) {return value "℃";},}, 效果:

开放式耳机的优缺点?开放式耳机王者带你一探究竟

盛夏时节,天气越来越热,小伙伴们都在抱怨,实在没法戴口罩了。实际上,大家只关注了呼吸,却忽视了一个问题,其实,我们的耳朵也是要“呼吸”的,闷热的天气里,长时间佩戴入耳…

S2P销讯通-主数据对于客户关系管理系统的重要性

由于业务发展,各大企业的业务系统经历了从无到有,从简单到复杂,从而形成了一个又一个的业务系统,比如OA、HR、CRM、ERP等等。 主数据在客户关系管理系统(CRM)中扮演着至关重要的角色。主数据是指那些描述企…

SD操作手册

1、创建条件记录 2、创建标准订单/寄售补货订单/寄售发货订单/借贷项凭证/退货订单 3、创建外向交货单 4、开票 创建条件记录-VK11 PR00代表净价 输入销售组织、分销渠道、客户、物料 创建销售订单-VA01 2.1创建标准SO 维护完表头的信息后,双击行项目&#xff…

Python发送多人邮件如何实现高效群发功能?

Python发送多人邮件的教程?怎么使用Python群发邮件? Python,作为一种强大的编程语言,提供了多种库和工具,使得群发邮件变得既简单又高效。AokSend将详细介绍如何使用Python发送多人邮件,并探讨一些提高群发…

wpf prism 《3》 弹窗 IOC

传统的弹窗 这种耦合度高 new 窗体() . Show(); new 窗体() . ShowDialog(); 利用Prism 自动的 IOC 弹窗的 必须 必须 必须 页面控件 弹窗的 必须 必须 必须 页面控件 弹窗的 必须 必须 必须 页面控件 弹窗的 必须 必须 必须 页面控件 弹窗的 必须 必须 必须 页面控件 》》否…

sql-labs41-45关通关攻略

第41关 一.查询数据库 http://127.0.0.1/Less-41/?id-1%20union%20select%201,2,database()--http://127.0.0.1/Less-41/?id-1%20union%20select%201,2,database()-- 二.查表 http://127.0.0.1/Less-41/?id-1%20union%20select%201,2,(select%20group_concat(table_name)…

【Java】—— Java面向对象基础:Java中类的构造器与属性初始化,Student类的实例

目录 定义Student类 在main方法中创建Student对象 结论 在Java中,类的构造器(Constructor)是一个特殊的方法,用于在创建对象时初始化对象的属性。今天,我们将通过一个简单的Student类实例,来探讨如何在J…

【数据分享】2000—2023年250米分辨率逐月归一化植被指数(NDVI)栅格数据(免费获取/全国/分省)

NDVI,全名为Normalized Difference Vegetation Index,中文名称为归一化植被指数。这个指数可以用来定性和定量评价植被覆盖及其生长活力,我们也可以简单地将它理解为体现植被密度和健康状况的一个指标。之前我们给大家分享了来源于MOD13A3数据…

手握15个大厂offer,我在大模型风口起飞

在“金三银四”的招聘季中,社交媒体上分享offer信息的“求助帖”比比皆是。帖子一般只披露公司名称和薪资区间,模糊具体岗位,作为判断是否值得去的衡量标准。 2024年毕业的985硕士生白丁(化名)一口气晒出了自己在秋招…

使用STM32CubeMX新建工程

开发板:STM32h743xi 编程软件:Keil、STM32CubeMX 项目:GPIO外设操作(彩色LED灯) 学习打卡:Day1 学习地址:【野火】STM32 HAL库开发实战指南 教学视频 手把手教学STM32全系列 零基础入门CubeMXHA…

echarts组件——漏斗图

echarts组件——漏斗图 组件代码 <template><div :class"classname" :style"{height:height,width:width}" /> </template><script> import * as echarts from echarts require(echarts/theme/macarons) // echarts theme import…

虚拟试穿(VTON)和虚拟换装(VD)技术分享

虚拟试穿技术&#xff08;VTON&#xff09;和虚拟换装&#xff08;VD&#xff09;技术是一种应用于电子商务和在线零售的技术&#xff0c;旨在通过数字手段提升用户的购物体验&#xff0c;让用户能够在没有实际试穿的情况下&#xff0c;看到自己穿上特定服装的样子。这种技术的…

js 如何获取文件名

"bbb/aaa/ss.pdf" 如何获取到文件名 ss.pdf split(/) 分割字符串 function getFileName(filePath) {// 使用正斜杠 / 分割路径&#xff0c;并获取最后一个元素作为文件名let parts filePath.split(/)// console.log(parts) // [bbb, aaa, ss.pdf]let fileName pa…

深度解析CancellationToken在HttpClient请求中的应用

概述 在现代的Web开发中&#xff0c;爬虫技术已成为数据获取的重要手段。随着Web技术的发展&#xff0c;服务器端的反爬机制也愈发复杂和智能化&#xff0c;因此&#xff0c;我们需要不断优化爬虫的设计和实现&#xff0c;以提高效率和稳定性。在本文中&#xff0c;我们将重点…

Windows中Git对文件名大小写不敏感的问题解决方法

文章目录 前言一、Git 对文件名大小写不敏感方法1.使用git命令进行修改方法2.关闭git 忽略大小写配置 &#xff08;可以当前项目设置&#xff0c;也可以全局设置 --global&#xff09; 二、新的问题&#xff08;重复的目录&#xff09;原因分析解决方法 前言 Git是一个免费的、…

wpf prism 《4》 事件 发布订阅

PubSubEvent 继承 EventBase TEventType GetEvent() where TEventType : EventBase, new();