MySQL 5.7 DDL 与 GH-OST 对比分析

作者:来自 vivo 互联网存储研发团队- Xia Qianyong

本文首先介绍MySQL 5.7 DDL以及GH-OST的原理,然后从效率、空间占用、锁阻塞、binlog日志产生量、主备延时等方面,对比GH-OST和MySQL5.7 DDL的差异。

一、背景介绍

在 MySQL 数据库中,DDL(数据定义语言)操作包括对表结构、索引、触发器等进行修改、创建和删除等操作。由于 MySQL 自带的 DDL 操作可能会阻塞 DML(数据操作语言)写语句的执行,大表变更容易产生主备延时,DDL 变更的速度也不能控制,因此在进行表结构变更时需要非常谨慎。

为了解决这个问题,可以使用 GitHub 开源的工具 GH-OST。GH-OST 是一个可靠的在线表结构变更工具,可以实现零宕机、低延迟、自动化、可撤销的表结构变更。相比于 MySQL 自带的 DDL 操作,GH-OST 可以在不影响正常业务运行的情况下进行表结构变更,避免了 DDL 操作可能带来的风险和影响。

通过使用 GH-OST工具,可以对 MySQL 数据库中的表进行在线结构变更,而不会对业务造成太大的影响。同时,GH-OST 工具还提供了多种高级特性,如安全性检测、自动化流程等,可以帮助用户更加高效地进行表结构变更。

二、MySQL5.7几种DDL介绍

2.1 copy

  • server层触发创建临时表

  • server层对源表加MDL锁,阻塞DML写、不阻塞DML读

  • server层从源表中逐行读取数据,写入到临时表

  • 数据拷贝完成后,升级字典锁,禁止读写

  • 删除源表,把临时表重命名为源表

MySQL copy方式的DDL变更,数据表的重建(主键、二级索引重建),server层作为中转把从innodb读取数据表,在把数据写到innodb层临时表。简单示意图如下:

图片

2.2 inplace

(1)rebuild table

需要根据DDL语句创建新的表结构,根据源表的数据和变更期间增量日志,重建新表的主键索引和所有的二级索引。

Prepare阶段

  • 创建新的临时frm文件

  • 持有EXCLUSIVE-MDL锁,禁止读写

  • 根据alter类型,确定执行方式(copy,online-rebuild,online-norebuild)假如是Add Index,则选择online-norebuild

  • 更新数据字典的内存对象

  • 分配row_log对象记录增量

  • 生成新的临时ibd文件

ddl执行阶段 :

  • 降级EXCLUSIVE-MDL锁,允许读写

  • 扫描old_table的聚集索引每一条记录rec

  • 遍历新表的聚集索引和二级索引,逐一处理各个索引

  • 根据rec构造对应的索引项

  • 将构造索引项插入sort_buffer块排序

  • 将sort_buffer块更新到新表的索引上

  • 记录ddl执行过程中产生的增量(记录主键和索引字段)

  • 重放row_log中的操作到新表索引商

  • 重放row_log间产生dml操作append到row_log最后一个Block

commit阶段 :

  • 当前Block为row_log最后一个时,禁止读写,升级到EXCLUSIVE-MDL锁

  • 重做row_log中最后一部分增量

  • 更新innodb的数据字典表

  • rename临时idb文件,frm文件

  • 增量完成

MySQL rebuild table方式的DDL,数据不需要通过sever层中转,innodb层自己完成数据表的重建。简单示意图如下:

图片

(2)build-index

需要根据DDL语句创建新的表结构,根据源表的数据和变更期间增量日志,创建新的索引。

Prepare阶段 :

  • 持有EXCLUSIVE-MDL锁,禁止读写

  • 根据alter类型,确定执行方式(copy,online-rebuild,online-norebuild)

  • 假如是Add Index,则选择online-norebuild

  • 更新数据字典的内存对象

  • 分配row_log对象记录增量

ddl执行阶段 :

  • 降级EXCLUSIVE-MDL锁,允许读写

  • 扫描old_table的聚集索引每一条记录rec

  • 遍历新表的聚集索引,根据rec构造新的索引数据

  • 将构造索引项插入sort_buffer块排序

  • 将sort_buffer块更新到新表的索引上

  • 记录ddl执行过程中产生的增量(仅记录主键和新索引字段)

  • 重放row_log中的操作到新表索引上

  • 重放row_log间产生dml操作append到row_log最后一个Block

commit阶段 :

  • 当前Block为row_log最后一个时,禁止读写,升级到EXCLUSIVE-MDL锁

  • 重做row_log中最后一部分增量

  • 更新innodb的数据字典表

  • 增量完成

MySQL rebuild index方式的DDL,数据不需要通过sever层中转,innodb层只需要完成变更二级索引的创建。简单示意图如下:

图片

(3)only modify metadata

只修改元数据(.frm文件和数据字典),不需要拷贝表的数据。

图片

三、GH-OST

在GH-OST端,根据DDL语句创建新的表结构,根据源表的数据和增量期间增量日志,重建新表的主键索引和所有的二级索引,最终完成DDL增量。

主要流程如下:

  • 根据DDL语句和源表创建新的表结构

  • 根据唯一索引(主键索引或者其它唯一索引)

- 优先应用新增量的binlog到新的表中,需要经过GH-OST把binlog日志转换为sql,然后回放到影子表

- 其次拷贝源表中的数据到新的表中,表数据拷贝通过sql语句 insert ignore into (select .. from)直接在MySQL实例上执行,无需经过GH-OST中转

  • 数据拷贝完成并应用完binlog后,通过lock table write 锁住源表

  • 应用数据完成-获取到锁期间产生的增量binlog

  • delete源表,rename影子表为源表,完成数据增量

GH-OST 进行DDL变更,GH-OST服务通知server层,server层作为中转把从innodb读取数据表,在把数据写到innodb层影子表。并且GH-OST作为中转读取DDL变更期间增量binlog解析成SQL写语句回放到影子表。简单示意图如下:

图片

四、对比分析

DDL变更执行时长、对磁盘的额外占用(临时数据表+binlog)、锁阻塞时长、主备延时都是执行DDL变更人员比较关心的问题,本章将从从执行效率、占用表空间、锁阻塞、产生binlog日志量、主备延时等方面对MySQL原生的DDL和GH-OST进行对比分析。

4.1 执行效率

(1)only modify metadata(正常小于1S)

(2)build-index: 数据条目越多、新索引字段越大耗时越多

  • 增量日志超过innodb_online_alter_log_max_size造成DDL失败

(3)rebuild table: 数据条目越多、所有索引字段之和越大耗时越多

  • 增量日志超过innodb_online_alter_log_max_size造成DDL失败

(4)copy:数据条目越多,所有索引字段之和越大耗时越多,相对于rebuild table,数据需要从server层中转,所以比rebuild table耗时多

(5)GH-OST :数据条目越多,所有索引字段之和越大耗时越多,

  • 相对于copy,增量日志数据需要从GH-OST中转,所以比copy耗时多

  • 有各种限流,(主备延时,threads超限延时…),增加耗时

  • 增量期间应用binlog速度如果跟不上业务产生binlog日志的速度,将无法完成增量

  • critical 参数还会导致主动退出,例如thread_running

耗时:only modify metadata < build-index < build < copy < GH-OST

4.2 占用表空间

  • 【only modify metadata】:忽略

  • 【build-index】:额外需要,新增索引字段占用的空间

  • 【rebuild-table】:额外需要约两倍的表空间

  • 【copy】:额外需要约两倍的表空间

  • 【GH-OST】 :临时表占用约两倍的表空间,另外生成影子表会产生大量的binlog日志会占用表空间

占用表空间: only modify metadata < build-index < build = copy < GH-OST

4.3 锁阻塞

(1)only modify metadata

  • DDL prepare阶段短暂的MDL排他锁,阻塞读写

(2)build-index table

  • DDL prepare阶段短暂的MDL排他锁,阻塞读写

  • 执行阶段(主要耗时阶段),MDL SHARED_UPGRADABLE锁,不阻塞读写

  • 执行阶段的最后会回放增量日志row_log,两个block间隙和最后block,持有源表索引的数据结构锁,会阻塞写

  • 提交阶段,MDL锁升级为排他锁

  • 回放剩余的row_log(执行完成致MDL锁升级期间新增的row_log,持有源表索引的数据结构锁,阻塞读写)

(3)rebuild-table: 和build-index table一致

(4)copy

  • DDL prepare阶段短暂的MDL排他锁,阻塞读写

  • 执行阶段(主要耗时阶段),阻塞写,不阻塞读

(5)GH-OST

  • 等待锁的时间也会阻塞业务

  • 进入rename到拿表写锁的间隙有少量的新增binlog,后续需要持锁回放这部分日志

  • rename表本身的耗时通常1s以内左右

锁阻塞时间:

only modify metadata=GH-OST < build-index table = rebuild-table  < copy(整个DDL期间都会阻塞业务的写)

锁阻塞分析:

MySQL DDL在获取MDL排它锁和GH-OST获取表的的写锁,在获取锁的等待期间都会阻塞业务的读写

  • MySQL等待锁的超时时间为MySQL参数innodb_lock_wait_timeout。等待超时则失败

  • GH-OST等待锁的时间,等待超时时间可配(默认6秒),等待超时次数可配

4.4 产生binlog日志量

【MySQL5.7 DDL】: 在DDL执行结束时仅向binlog中写入一条DDL语句,日志量较小。

【GH-OST】: 影子表在全量数据拷贝和增量数据应用过程中产生大量的binlog日志(row模式),对于大表日志量非常大。

产生binlog日志量:MySQL5.7 DDL < GH-OST

4.5 主备延时分析

(1)MySQL5.7 DDL:MySQL集群主备环境

  • Master上DDL执行完成,binlog提交后,slave才开始进行DDL。

  • slave串行复制、group复制模式,需要等前面的DDL回放完成后才会进行后续binlog回放,主备延时至少是DDL回放的时间。

图片

(2)GH-OST:主备复制延时基本可以忽略

  • GH-OST在master上创建一个影子表,在执行数据拷贝和binlog应用阶段,GHO表的binlog会实时同步到备。

  • 影子表(_GHO表)应用完成后,通过rename实现新表切换,这个rename动作也会通过binlog传到salve执行完成DDL。

图片

延时时间:GH-OST < MySQL DDL

备库执行DDL期间主库异常,主备切换。备库升级为主过程中,要回放完relaylog中的DDL和dml,才能对外服务,否则会出现数据丢失,这将造成业务较长时间的阻塞。

4.6 总结

图片

GH-OST 工具和 MySQL 原生 DDL 工具的适用场景不同,具体使用哪种工具需要根据实际需求进行选择。

  • 变更人员无法判断本次DDL是否会造成DML阻塞、锁阻塞等,建议使用GH-OST工具。

  • 如果需要进行在线表结构变更,并且需要减少锁阻塞时间、减少主备延时等问题,建议使用 GH-OST 工具。

  • 变更只涉及到元数据的修改,建议使用mysql原生DDL。

  • 如果表结构变更较小,对锁阻塞时间和主备延时要求不高,建议使用 MySQL 原生 DDL 工具。

参考资料:

  • online DDL Operations

  • MySQL · 源码阅读 · 白话Online DDL

  • 【腾讯云CDB】源码分析·MySQL online ddl日志回放解析 

  • GH-OST一些使用限制

  • mysql mdl锁类型

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

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

相关文章

MyBatis--XML映射文件

MyBatis–XML映射文件 lombok工具包 为了解决声明实体类的get()和set()函数臃肿的问题&#xff0c;我们使用lombok工具包。 我们看一下lombok工具包为我们提供的注解&#xff1a; XML映射文件 我们需要遵守下面的规则&#xff1a; 首先XML映射文件和Mapper接口包应该在同…

wps怎么找回未保存的文件?分享三个文件恢复方法

在编辑WPS文档时&#xff0c;偶尔会遇到未保存就意外关闭的情况&#xff0c;这不仅令人沮丧&#xff0c;还可能导致重要信息的丢失。但幸运的是&#xff0c;WPS提供了多种途径来帮助用户找回这些未保存的宝贵文件。从利用WPS的自动备份与恢复功能&#xff0c;到检查最近文档列表…

树形结构查找(B树、B+树)

平衡树结构的树高为 O(logn) &#xff0c;平衡树结构包括两种平衡二叉树结构&#xff08;分别为 AVL 树和 RBT&#xff09;以及一种树结构&#xff08;B-Tree&#xff0c;又称 B 树&#xff0c;它的度大于 2 &#xff09;。AVL 树和 RBT 适合内部存储的应用&#xff0c;而 B 树…

堆(数据结构)

堆的概念与结构 堆的底层逻辑是一个完全二叉树&#xff08;或满二叉树&#xff09;。 堆的分类 大根堆和小根堆 大根堆 所谓大根堆就是每一个父节点都要大于等于子结点 小根堆 所谓小根堆就是每一个父节点都要小于等于子结点 堆的实现 (未完待续 待续......)

力扣高频SQL 50题(基础版)第四十四题之626. 换座位

文章目录 力扣高频SQL 50题&#xff08;基础版&#xff09;第四十四题之626. 换座位626. 换座位题目说明思路分析实现过程准备数据实现方式结果截图 力扣高频SQL 50题&#xff08;基础版&#xff09;第四十四题之626. 换座位 626. 换座位 题目说明 表: Seat --------------…

【网络】IP-VPN技术概述

目录 引言 核心协议 封装与加密 工作流程 IP-VPN的应用场景 MPLS-VPN 个人主页&#xff1a;东洛的克莱斯韦克-CSDN博客 引言 IP-VPN&#xff08;Internet Protocol - Virtual Private Network&#xff09;是一种通过公共网络实现私密、安全通信的技术。它主要依赖于互联网…

力扣系统刷题-树(一)

放松了一周,也一周都没写题了,接下来,我做题的方式可能会更趋向于成体系的学习,今天就先从树的章节开始学起,主要参考的学习资料还是博客,知乎等网上较为系统的教材,涉及到的参考内容我都会进行标注,并以力扣题目作为导向来学习. 一.树 1. 什么是树 根据维基百科的定义:在计…

InfluxDB Studio 下载,时序数据库Windows图形界面操作

下载地址&#xff1a; https://github.com/CymaticLabs/InfluxDBStudio/releases解压缩后&#xff0c;双击 InfluxDBStudio.exe 运行。 参考 windows下 influxDB 操作工具 InfluxDBStudio 吐槽 现在 CSDN 太恶心了&#xff0c;动不动就让订阅或者积分下载资源。诚然&#…

主机组装笔记

参考资源&#xff1a;B站【装机教程】全网最好的装机教程&#xff0c;没有之一&#xff0c;仅供探讨学习 9大部件一览 其中得到固态和机械&#xff0c;是硬盘&#xff0c;存储空间&#xff0c;可以只选固态 CPU&#xff0c;主要有 AMD 和 Intel (AMD&#xff0c;基板的背面布…

nvm的下载和使用(Windows)

NVM&#xff08;Node Version Manager&#xff09;是一个用于管理多个Node.js版本的工具&#xff0c;它允许用户在同一台机器上安装和使用多个Node.js版本。 一、NVM的基本功能 多版本支持&#xff1a;NVM允许用户在同一台机器上安装多个Node.js版本&#xff0c;方便处理不同…

docker:在官方停止国内服务的情况下安装使用docker

前言 很烦,前段时间docker官方已经全面停止国内网络访问了,但业务又依赖docker,所以这里只能通过科学的方案来处理这件事: 系统:ubuntu 22.04 desktop 目的:在官方停止国内服务的情况下,安装使用docker 关键技术:科学工具(小猫猫) 安装科学工具 没有安装包的,可以自…

Re常见简单密码

Re常见简单密码 起码没有Crypto专项那么柜物。。。 文章目录 Re常见简单密码1. RC4算法2. TEA算法3. XTEA算法4. XXTEA算法5. DASCTF strangeprograme参考 C语言stdint.h提供如下类型 int8_t 八位有符号整数 uint8_t 八位无符号整数 int16_t int32_t int64_t 64为有符号整数c…

定时器介绍

定时器介绍 STM32F103C8T6微控制器内部集成了多种类型的定时器&#xff0c;这些定时器在嵌入式系统中扮演着重要角色&#xff0c;用 于计时、延时、事件触发以及PWM波形生成、脉冲捕获等应用。下面是对STM32F103C8T6中几个定时器的 简单介绍&#xff1a;TIM1&#xff1a;这是一…

细数那些令人瞩目的内网穿透工具

在日常工作场景中&#xff0c;我们时常面临需要将本地网络中的特定端口&#xff08;如80、3306等&#xff09;对外开放&#xff0c;以便让远程用户或设备跨越局域网界限进行访问的需求。为实现这一目标&#xff0c;端口映射&#xff08;又称内网穿透&#xff09;技术显得尤为重…

Qt项目【上位机十字屏开发】

效果图 说明 重写 QWidget 中的 paintEvent() 处理绘图事件&#xff0c;废话不多说&#xff0c;上代码 源码 #ifndef MYWIDGETFORM_H #define MYWIDGETFORM_H#include <QWidget>namespace Ui { class myWidgetForm; }enum MYTYPE{SIZEWIDTH,SIZEHEIGHT,TOPWIDTH,TOPHE…

Spring 循环依赖解决方案

文章目录 1. 循环依赖的产生2. 循环依赖的解决模型3. 基于setter/Autowired 的循环依赖1_编写测试代码2_初始化 Cat3_初始化 Person4_ 回到 Cat 的创建流程5_小结 4. 基于构造方法的循环依赖5. 基于原型 Bean 的循环依赖6. 引人AOP的额外设计7. 总结 IOC 容器初始化bean对象的逻…

Java并发类的主要API方法-CountDownLatch和CyclicBarrier

1.概念介绍 CountDownLatch 是一个计数器&#xff0c;计数器的初始值由创建它时指定。每次调用 countDown() 方法时&#xff0c;计数器会减1&#xff0c;直到计数器值变为0时&#xff0c;所有调用 await() 的线程都会被唤醒继续执行。 CyclicBarrier 是 Java 中另一个常用的同…

渗透率超50%,新能源汽车已成中国制造新名片

近日&#xff0c;乘联会公布了最新一期全国乘用车市场分析报告。报告显示&#xff0c;今年7月&#xff0c;中国乘用车市场零售销量173.2万辆&#xff0c;批发销量195.6万辆&#xff1b;同期&#xff0c;新能源乘用车零售销量87.8万辆&#xff0c;批发销量94.5万辆。按此计算&am…

DC-4靶机渗透测试

一、靶机下载地址 https://www.vulnhub.com/entry/dc-4,313/ 二、信息收集 1、主机发现 # 使用命令 nmap 192.168.145.0/24 -sn | grep -B 2 "00:0C:29:43:49:A5" 2、端口扫描 # 使用命令 nmap 192.168.145.217 -p- -sV 3、指纹识别 # 使用命令 whatweb "…

顺序表各种接口的实现(C)

线性表 线性表是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串…线性表在逻辑上是线性结构&#xff0c;也就说是连续的一条直线。在物理结构上并不一定是连续的&#xff0c;线性表在物…