iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >MySQL大表是怎么DDL变更的
  • 645
分享到

MySQL大表是怎么DDL变更的

2024-04-02 19:04:59 645人浏览 薄情痞子
摘要

本篇内容主要讲解“Mysql大表是怎么DDL变更的”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“mysql大表是怎么DDL变更的”吧!MySQL中的DDLDDL

本篇内容主要讲解“Mysql大表是怎么DDL变更的”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习mysql大表是怎么DDL变更的”吧!

MySQL中的DDL

DDL概述

Mysql中的DDL语句形式比较多,概括一下有以下几类:CREATE,ALTER,DROP,RENAME,TRUNCATE。

这些操作都是隐式提交且原子性,要么成功,要么失败,在MySQL 8.0之前DDL操作是不记录日志的。

今天就聊一下跟系统版本发布相关的数据库结构变更,主要就是ALTER TABLE变更了,DDL变更流程普通的DML变更是类似的,如下所示

MySQL大表是怎么DDL变更的

注:这里涉及MySQL基础知识,还不知道的朋友翻看下我MySQL基础章节即可。

在早期的MySQL版本,DDL变更都会导致全表被,阻塞表上的DML操作,影响业务正常运行,好的一点就是,随着MySQL版本的迭代,DDL的执行方式也在变化。

MetaData元数据

MySQL的元数据(MetaData)跟其他的RDBMS数据库一样的,描述的对象的结构信息,存储在infORMation_schema架构下,例如常见的TABLES、COLUMNS等,下面例子是创建一个表crm_users,MySQL会自动往Information_schema.tables和columns等相关数据字典表中插入数据,这些数据称为元数据,一般都是静态化,只有表上发生了DDL操作才会实时更新。

MySQL大表是怎么DDL变更的

MetaData Lock

MySQL利用MetaData  Lock来管理对象的访问,保证数据的一致性,对于一些核心业务表,表上DML操作比较频繁,这个时候添加字段可能会触发MetaData Lock。

MySQL大表是怎么DDL变更的

MySQL大表是怎么DDL变更的

可以看到Waiting for table metadata lock等待事件,thread 155正在执行alter table等待thread  154执行的select释放锁,因为DML在执行期间会持有SHARED_READ锁,要执行DDL时获取SHARED_UPGRADABLE(共享可升级锁,缩写为SU,允许并发更新和读同一个表)锁成功,但是获取EXCLUSIVE  MetaData Lock锁失败,处于暂挂PENDING状态。

DDL执行方式

从MySQL官方文档可以看到,ALTER TABLE的选项很多,跟性能相关的选项主要有ALGoRITHM和LOCK。

MySQL大表是怎么DDL变更的

ALGORITHM OPTIONDESCRIPTION
COPYMySQL早期的变更方式,需要创建修改后的临时表,然后按数据行拷贝原表数据到临时表,做rename重命名来完成创建,在此期间不允许并发DML操作,原表是可读的,不可写,同时需要额外一倍的磁盘空间。
INPLACE直接在原表上进行修改,不需创建临时表拷贝数据及重命名,原表会持有Exclusive Metadata  Lock,通常是允许并发DML操作。
INSTANTMySQL 5.8开始支持,只修改数据字典中的元数据,表数据不受影响,执行期间没有Exclusive Metadata  Lock,允许并发的DML操作。

从这张表可以看到,MySQL对于DDL执行方式一直在做优化,目的就是为了提高DDL执行效率,减少锁等待,不影响表数据,同时不影响正常的DML操作。

LOCK选项

LOCK OPTiONDESCRIPTION
DEFAULT默认模式:MySQL根据运行情况,在尽量不锁表的情况下自动选择LOCK模式。
NONE无锁:允许Online DDL期间进行并发读写操作,如果Online DDL操作不支持对表并发DML操作,则DDL操作失败,对表修改无效。
SHARED共享锁:Online DDL操作期间不影响读取,阻塞写入。
EXCLUSIVE排它锁:Online DDL操作期间不允许对锁表进行任何操作。

下面举例说明下这几种方式的执行过程,先创建测试表,制造一些数据。

MySQL大表是怎么DDL变更的

COPY

COPY方式的变更流程如下:

MySQL大表是怎么DDL变更的

根据业务需要,需要在crm_users添加一个字段user_type,采用COPY方式执行变更。

MySQL大表是怎么DDL变更的

MySQL大表是怎么DDL变更的

从执行过程及profile可以看出,通过COPY方式会创建临是表#sql-564_85,获取System  Lock,拷贝数据到临时表,最后做rename表名切换,释放Lock资源,在执行期间不支持并发DML操作。

INPLACE

INPLACE方式是在原表上直接修改,对于添加索引、添加/删除列、修改字段NULL/NOT  NULL属性等操作,需要修改MySQL内部的数据记录,需要重建表(Rebuild Table)。

MySQL大表是怎么DDL变更的

MySQL大表是怎么DDL变更的

MySQL大表是怎么DDL变更的

从执行过程可以看到,需要获取Exclusive Metadata Lock,修改表数据,释放Lock,在执行期间支持并发DML操作。

INSTANT

MySQL 5.8开始推出的方式,DDL只修改数据字典中的元数据,表数据不受影响,没有Exclusive Metadata  Lock,允许并发的DML操作,支持的DDL变更是有限制的,目前主要包括添加字段,添加/删除生成列,修改ENUM或SET列,改变索引类型以及重命名表。

MySQL大表是怎么DDL变更的

比对下这三种方式的执行效率

执行方式/项目数据量(w)执行时间(s)重建表修改MetaData修改Data允许并发DML
COPY65029.89YESNoYesNo
INPLACE65010.56YESNoYesYes
INSTANT6500.19NoYesNoYes

ONLINE DDL

截止MySQL 8.0,OnLine  DDL有三种方式COPY,INPLACE,INSTANT,MySQL会自动根据执行的DDL选择使用哪种方式,一般会优先选择INSTANT方式,如果不支持,就选择INPLANCE方式,再不支持就只能选择COPY方式了。

MySQL官方文档也给出了Online  DDL的支持矩阵,列下常用的DDL操作,对比项主要包括是否重建表,允许并发的DML操作以及只修改元数据,表数据不受影响。

OperationInstantIn PlaceCopyRebuilds TablePermits Concurrent DMLOnly Modifies Metadata
Adding a columnYesYes*YesNo*Yes*Yes
Dropping a columnNoYesYesYesYesNo
Renaming a columnNoYesYesNoYesYes
Setting a column default valueYesYesYesNoYesYes
Dropping the column default valueYesYesYesNoYesYes
Changing the auto-increment valueNoYesYesNoYesNo
Making a column NULLNoYesYesYes*YesNo
Making a column NOT NULLNoYesYesYes*YesNo
Adding a primary keyNoYes*YesYes*YesNo
Dropping a primary keyNoNoYesYesNoNo
Creating or adding a secondary indexNoYesYesNoYesNo
Dropping an indexNoYesYesNoYesYes
Renaming an indexNoYesYesNoNoNo
Adding a FULLTEXT indexNoYes*YesNo*NoNo

大表DDL方案在实际业务系统中,业务发展比较快,表的数据量比较大,业务层面又做了读写分离,同时会将MySQL数据实时同步到数据仓库(包括实时数仓和离线数仓),实际的数据库架构如下。

MySQL大表是怎么DDL变更的

假设这是一个交易系统数据库,订单表booking有8000w数据,且接入到了实时和离线仓库,根据业务需要,在订单表booking添加一个字段,在MySQL  5.7之前添加字段属于高危操作,需要充分考虑对业务的影响,主要存在于两个方面:

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. 在读写分离场景,主从同步延迟导致业务数据不一致

  3. 实时数仓ADB不允许源端MySQL表重命名,如果通过COPY方式或者pt-osc、gh-ost等工具都会rename表名,那么就需要从数仓删除该表,重新配置同步(全量  + 增量),会影响数仓业务

ONLINE DDL方式

对于MySQL 5.6到5.7的版本,可以使用OnLine  DDL的方式变更,对于大表来说,执行时间会很长,好处是在Master上DML操作不受影响,但是会导致主从延时。

假如Master上添加字段执行了20分钟,相应的Slave也要执行20分钟,在这期间Slave一直处于延迟状态,会造成业务数据不一致,比如用户在Master下单成功,由于Slave延迟查询不到订单信息,用户误以为网络原因没有下单成功,又下了一单,导致重复下单的情况。

这种方式会导致主从延迟,但是不会影响实时数仓的业务,根据业务情况,只能选择在业务低峰期执行了。

pt-osc工具

为了解决DDL变更导致主从延时对业务的影响,会想到用大表变更利器pt-osc(pt-online-schema-change)或者gh-ost工具来做,这两个工具执行过程及原理大同小异,变更流程如下(不考虑外键,按照MySQL规范不允许使用外键):

MySQL大表是怎么DDL变更的

  • 创建一个新的表,表结构为修改后的数据表,用于从源数据表向新表中导入数据。

  • 在源表上创建触发器,用于记录从拷贝数据开始之后,对源数据表继续进行数据修改的操作记录下来,用于数据拷贝结束后,执行这些操作,保证数据不会丢失。

  • 拷贝数据,从源数据表中拷贝数据到新表中。

  • 修改外键相关的子表,根据修改后的数据,修改外键关联的子表。

  • rename源数据表为old表,把新表rename为源表名,并将old表删除。

  • 删除触发器。

执行pt-osc的时候也需要获取一个Exclusive Metadata  Lock,如果在此期间表上有DML操作正在进行,pt-osc操作会一直处于暂挂PENDING状态,这个时候表上正常DML操作都会被阻塞,MySQL活动连接数瞬间暴涨,CPU使用率100%,依赖的该表的接口都会报错,所以要选择在业务低峰期执行,同时做好MetaData  Lock锁的监控以便业务不受影响,来看一个例子:

MySQL大表是怎么DDL变更的

D=trade, t=booking:数据库trade,表名booking。

--chunk-size=1000:每次拷贝的数据行数。

--max-log = 1:确保从库延迟不超过1s,超过就停止拷贝数据。

--check-interval=2:表示等待2s之后继续拷贝数据。

--recursion-method="hosts":如果不是使用默认端口3306,那么使用hosts方式来查找从库更可靠。

一般MySQL  binlog格式都是ROW,pt-osc在拷贝数据的过程也会产生大量的binlog,也可能导致主从延时,需要控制好每次拷贝数据的大小和频率,在执行期间,也会降低DML的并发度。

MySQL 8.0变更方式

用过oracle的都知道,DDL变更都是修改元数据,上亿的表在Oracle中DDL变更都是瞬间完成。

令人激动的是,MySQL  8.0也推出了INSTANT方式,真正的只修改MetaData,不影响表数据,所以它的执行效率跟表大小几乎没有关系。建议新系统上线用MySQL的话尽量使用MySQL  8.0,老的数据库也可以升级到MySQL 8.0获取更好的性能。

官方文档对INSTANT的解释:

INSTANT: Operations only modify metadata in the data dictionary. No exclusive  metadata locks are taken on the table during preparation and execution, and  table data is unaffected, making operations instantaneous. Concurrent DML is  permitted. (Introduced in MySQL 8.0.12)

既要解决主从同步,又要解决rename数仓不同步的问题,目前只有INSTANT方式满足需求了。

监控DDL执行

进度在大表执行DDL变更的时候,非常关心它的执行进度,MySQL 5.7之前是没有好的工具去监控,基本只能坐等了。在MySQL  8.0可以通过开启performance_schema,打开events_stages_current事件进行监控。

MySQL大表是怎么DDL变更的

总结DDL在业务系统版本迭代的过程是必不可少的,如何在不影响业务以及外围系统的情况下,实现DDL的平滑变更,是需要综合个系统特性考虑的,评估出重要性和优先级,同时也要掌握不同MySQL版本DDL执行方式,以便我们做更好的选择。

例如上面提到了,目前我在大数据团队,我们的业务都做了读写分离,同时接入实时数仓,数仓不支持rename操作,这时就可以选择在业务低峰期使用ONLINE  DDL的方式执行,对业务系统影响最小,同时不影响数仓。

到此,相信大家对“MySQL大表是怎么DDL变更的”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

您可能感兴趣的文档:

--结束END--

本文标题: MySQL大表是怎么DDL变更的

本文链接: https://www.lsjlt.com/news/61939.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • MySQL大表是怎么DDL变更的
    本篇内容主要讲解“MySQL大表是怎么DDL变更的”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MySQL大表是怎么DDL变更的”吧!MySQL中的DDLDDL...
    99+
    2024-04-02
  • MySQL日常大表的DDL操作介绍
    这篇文章主要讲解了“MySQL日常大表的DDL操作介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“MySQL日常大表的DDL操作介绍”吧!大多数的alte...
    99+
    2024-04-02
  • MySQL表结构怎样变更Metadata Lock
    本篇文章为大家展示了MySQL表结构怎样变更Metadata Lock,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。想必玩过mysql的人对Waiting for ...
    99+
    2024-04-02
  • mysql ddl指的是什么意思
    小编给大家分享一下mysql ddl指的是什么意思,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨吧!mysql ddl是数据定于语言的缩写,简单来说,就是对数据库内部的对象进行创建、删除、修改等操...
    99+
    2024-04-02
  • MySQL DDL操作实践是怎样的
    本篇文章给大家分享的是有关MySQL DDL操作实践是怎样的,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。根据网上的DDL 树状图,自己cop...
    99+
    2024-04-02
  • MySQL分库分表后总存储变大了的原因是什么
    本篇内容介绍了“MySQL分库分表后总存储变大了的原因是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!...
    99+
    2024-04-02
  • MySQL中的DML、DDL、DCL是什么意思
    小编给大家分享一下MySQL中的DML、DDL、DCL是什么意思,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!引言一直以来,很多...
    99+
    2024-04-02
  • Mysql 5.7中mysql.gtid_executed表及其他变量更改时机是什么
    本篇内容介绍了“Mysql 5.7中mysql.gtid_executed表及其他变量更改时机是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些...
    99+
    2024-04-02
  • mysql多表更新的方法是什么
    在 MySQL 中,可以使用 JOIN 子句来进行多表更新操作。下面是一个示例: 假设有两个表:table1 和 table2,它们...
    99+
    2024-03-07
    mysql
  • mysql中大表是什么意思
    这篇文章主要介绍mysql中大表是什么意思,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!前言相对来说,什么情况下的数据库表能够称为“大表”呢?当一个表的数据超过千万行的时候,就会对数...
    99+
    2024-04-02
  • Angular变更检测是怎么引起的
    本篇内容介绍了“Angular变更检测是怎么引起的”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!什么是变更检测?简单来说,变更检测就是Ang...
    99+
    2023-07-04
  • 怎么查看mysql表大小
    要查看MySQL表的大小,可以使用以下几种方法: 使用MySQL命令行工具:在命令行中输入以下命令可以查看数据库中每个表的大小: ...
    99+
    2024-04-09
    mysql
  • Mysql中怎么删除大表
    本篇文章给大家分享的是有关Mysql中怎么删除大表,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。    【解决办...
    99+
    2024-04-02
  • MySQL怎么查看表大小
    本篇内容主要讲解“MySQL怎么查看表大小”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MySQL怎么查看表大小”吧! selec&...
    99+
    2024-04-02
  • MySQL怎么更改表格结构
    要更改表格结构,可以使用ALTER TABLE语句。以下是一些常用的修改表格结构的操作: 添加新列: ALTER TABLE ta...
    99+
    2024-03-06
    MySQL
  • mysql跨表更新怎么实现
    本篇内容介绍了“mysql跨表更新怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 背景项...
    99+
    2024-04-02
  • mysql大表数据去重的方法是什么
    在MySQL中,可以使用以下方法来去除大表数据中的重复记录: 使用DISTINCT关键字:通过在SELECT语句中使用DI...
    99+
    2024-04-09
    mysql
  • Mysql怎么处理大数据表
    这篇文章主要介绍“Mysql怎么处理大数据表”,在日常操作中,相信很多人在Mysql怎么处理大数据表问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Mysql怎么处理大数据表”...
    99+
    2023-03-19
    mysql
  • angular的变更机制是什么
    本篇内容主要讲解“angular的变更机制是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“angular的变更机制是什么”吧!一、什么是变更检测概括: 一种...
    99+
    2024-04-02
  • mysql怎么设置单表大小
    这篇文章给大家分享的是有关mysql怎么设置单表大小的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。mysql设置单表大小的方法:1、创建表时的修改方法;2、修改已存在表的方法,代...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作