携程:从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 能发挥更优越的表现。

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

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

相关文章

组件通信 Vue3

1.props 1.child <template><div class"child"><h3>子组件</h3><h4>玩具&#xff1a;{{ toy }}</h4><h4>父给的车&#xff1a;{{ car }}</h4><button click"sendToy(toy)">把玩具给父亲</butt…

通过visual studio进行dump文件调试和分析

0、前言 很多时候程序crash之后需要分析原因。对于C/C程序&#xff0c;一般最常见的场景和方法就是根据dump文件进行分析。 1、分析的前提条件 进行dump文件分析&#xff0c;需要以下文件&#xff1a; 进程crash时产生的dump文件程序源码进程对应的程序exe文件编译exe文件时产…

【赵渝强老师】MongoDB的存储引擎

存储引擎&#xff08;Storage Engine&#xff09;是MongoDB的核心组件&#xff0c;它负责管理数据如何存储在硬盘&#xff08;Disk&#xff09;和内存&#xff08;Memory&#xff09;上。从MongoDB 3.2 版本开始&#xff0c;MongoDB支持多种类型的数据存储引擎。 视频讲解如下&…

使用twilio向手机发短信做监控报警

最近遇到个需求&#xff0c;就是夜班HW希望有个监控系统指标&#xff0c;如果异常就向监控人手机打电话的需求。在考察以后&#xff0c;发现目前由于国内防电信诈骗的原因&#xff0c;所以想要使用云通讯功能必须由企业去申请&#xff0c;但作为一个个人的监控项目来说太大了。…

Python | Leetcode Python题解之第384题打乱数组

题目&#xff1a; 题解&#xff1a; class Solution:def __init__(self, nums: List[int]):self.nums numsself.original nums.copy()def reset(self) -> List[int]:self.nums self.original.copy()return self.numsdef shuffle(self) -> List[int]:for i in range(l…

极光推送(JPush)赋能登虹科技,打造智慧视觉云平台新体验

近日&#xff0c;中国领先的客户互动和营销科技服务商极光&#xff08;Aurora Mobile&#xff0c;纳斯达克股票代码&#xff1a;JG&#xff09;与杭州登虹科技有限公司&#xff08;以下简称“登虹科技&#xff08;Closeli&#xff09;”&#xff09;达成合作&#xff0c;借助极…

数分基础(03-3)客户特征分析--Tableau

文章目录 客户特征分析 - Tableau1. 说明2. 思路与步骤3. 数据准备和导入3.1 用EXCEL初步检查和处理数据3.1.1 打开3.1.2 初步检查&#xff08;1&#xff09;缺失值检查缺失值处理 &#xff08;2&#xff09;格式化日期字段&#xff08;3&#xff09;其他字段数据类型 &#xf…

【vscode】vscode+cmake+llvm+ninja开发环境的搭建(draft)

文章目录 前言1 软件、工具和插件安装1.1 vscode安装1.2 cmake安装1.3 安装LLVM1.4 安装Ninja1.5 vscode插件安装 2 工具链和CMakeLists2.1 工具链&#xff08;toolchain.cmake&#xff09;2.2 CMakeLists.txt2.3 基本语法注释 前言 本文是一个使用vscode的小白扫盲贴。 所谓工…

科讯档案管理系统存在SQL注入漏洞(0day)

漏洞描述 安徽科迅教育装备20年来来始终坚持智慧校园集成方案产品的开发和部署应用&#xff0c;我们有完善的智慧校园和数字校园建设方案&#xff0c;根据不同的学校不同的实际情况量身定做系统集成方案。产品主要是为了实现校园的智慧网络、智慧OA、智慧教学、智慧学习、数字医…

.NET Razor类库-热加载 就是运行时编译

1.新建3个项目 1.1 一个.NET Standard2.1项目 IX.Sdk.SvnCICD4NuGet 1.2 一个.NET Razor类库项目 IX.Sdk.SvnCICD4NuGet.RazorWeb 1.3 一个.NET6 Web项目 IX.Sdk.SvnCICD4NuGet.Web 这3个项目的引用关系 Web引用 Razor类库 和 .NET Standard2.1 Razor类库引用.NET Standard2.1…

数据同步大冒险:PostgreSQL到MySQL的奇妙之旅

引言&#xff1a;一场跨数据库的浪漫邂逅 &#x1f491; 在数据的世界里&#xff0c;不同数据库系统就像是来自不同星球的恋人&#xff0c;它们各自拥有独特的魅力&#xff0c;但偶尔也会渴望一场跨越界限的亲密接触。今天&#xff0c;我们就来见证一场PostgreSQL与MySQL之间的…

基于RK3588+MCU智能清洁车应用解决方案

智能清洁车应用解决方案 在智慧城市建设发展的过程中&#xff0c;智慧环卫是打造智慧城市的重要组成部分&#xff0c;智能清洁车作为实现环卫智能化、提升作业效率和服务质量的关键工具&#xff0c;发挥着不可或缺的作用。 智能清洁车集成了激光雷达、双目视觉、多重传感器以及…

无线通信频率分配

首先看看无线电信号的频谱如何划分&#xff1a; 一、5G NR 3GPP已指定5G NR 支持的频段列表&#xff0c;5G NR频谱范围可达100GHz&#xff0c;指定了两大频率范围&#xff1a; ① Frequency range 1 &#xff08;FR1&#xff09;&#xff1a;就是我们通常讲的6GHz以下频段 频率…

uniapp uni-popup底部弹框留白 底部颜色修改 滚动穿刺

做底部弹框的时候&#xff0c;可能出现以下场景需要处理。 一、出现底部留白不是白色&#xff0c;需要修改颜色的时候&#xff1a; 1、如果弹框不需要圆角效果&#xff0c;则在uni-popup加上背景色就行&#xff0c;弹框是个直角样式&#xff1a; 2、如果需要圆角效果&#xff0…

CSS3页面布局-三栏-中栏流动布局

三栏-中栏流动布局 用负外边距实现 实现三栏布局且中栏内容区不固定的核心问题就是处理右栏的定位&#xff0c; 并在中栏内容区大小改变时控制右栏与布局的关系。 控制两个外包装容器的外边距&#xff0c;一个包围三栏&#xff0c;一个包围左栏和中栏。 <!DOCTYPE html&…

【vue、Electron】搭建一个Electron vue项目过程、将前端页面打包成exe 桌面应用

文章目录 前言使用 electron-vue 创建项目1. 安装 vue-cli&#xff08;如果未安装&#xff09;2. 使用 electron-vue 模板创建项目3. 安装和配置 electron-builder4. 运行Electron项目5. 打包应用 可能遇到的问题解决Electron vue首次启动巨慢无法加载执行npm run electron:bui…

grid布局实现移动端H5响应式排列正方形格子布局

grid布局实现移动端H5响应式排列正方形区域 grid布局&#xff1a;CSS Grid 网格布局教程在 CSS 中&#xff0c;padding-top 的百分比值是相对于元素自身的宽度&#xff0c;而不是高度。这是 CSS 规范中的一个特性&#xff0c;所有的 padding 和 margin 的百分比值都是相对于元…

客服系统简易版

整体架构解读 客服端和商城端都通过websocket连接到客服系统, 并定期维持心跳当客户接入客服系统时, 先根据策略选择在线客服, 然后再发送消息给客服 websocket实现 用netty实现websocket协议, 增加心跳处理的handler, 详见chat-server模块 客服路由规则 暂时仅支持轮询的…

上新!Matlab实现基于QRGRU-Attention分位数回归门控循环单元注意力机制的时间序列区间预测模型

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现基于QRGRU-Attention分位数回归门控循环单元注意力机制的时间序列区间预测模型&#xff1b; 2.多图输出、多指标输出(MAE、RMSE、MSE、R2)&#xff0c;多输入单输出&#xff0c;含不同置信区间图、概率…

出现Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are requiredProperty报错

目录&#xff1a; bug Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are requiredProperty报错解决方法 bug Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are requiredProperty 报错 在一个springboot demo启动的时候出现以下错误 &#xff0c;…