首页 > 数据库 >你知道什么是 MySQL Online DDL 吗?

你知道什么是 MySQL Online DDL 吗?

时间:2024-05-06 15:56:40浏览次数:24  
标签:Online MDL DDL DML MySQL 操作

前言

MySQL 在进行 DDL 操作时,可能会产生表锁导致阻塞,影响用户的 DML 操作,而 Online DDL 指的是在 DDL 期间,允许用户进行 DML 操作。本文将详细讲解 MySQL 各版本的 Online DDL。


关于什么是 DDL 和 DML 操作,详细介绍见 MySQL 操作命令总结

1. 什么是 Online DDL

Online DDL 功能从 5.6 版本开始正式引入,可以支持 DDL 操作期间,允许 DML 操作同时进行,尽量避免 DDL 过程中对业务 SQL 产生的阻塞。8.0 版本对 DDL 的实现重新进行了设计,支持了原子特性。

那么为什么要引入 Online DDL?MySQL 5.5 版本及之前,在进行 DDL 操作的时候,整个表都会被阻塞,当用户或业务对表进行 DML 操作时就会被阻塞。如果在生产环境出现这种情况,导致整个服务的可用性降低,影响用户操作,这通常是不能被接受的。

引入 Online DDL 可以让 MySQL 在 DDL 操作期间,允许 DML 操作同时进行,减少表锁导致的业务阻塞,提高了服务的可用性、降低了业务风险

Online DDL 常用的几种操作:索引相关操作、主键相关操作、列相关操作、表相关操作。

2. Online DDL 算法

DDL 操作期间,无论哪种算法都会经历三个阶段:

  • 准备阶段(Prepare)
  • 执行阶段(DDL 语句)
  • 提交阶段(Commit)

2.1. Copy 算法

Copy 方式下 DDL 操作会生成临时新表,将原表数据逐行拷贝到新表中,在此期间会阻塞 DML,但允许查询。拷贝完成后的那一时刻原表禁止读写操作,因为在清理旧表结构和表定义缓存。

之后会在临时表上执行 DDL 语句,操作完成后原表会被删除,新表被重命名为原表名。该方式适用于需要做大量结构修改且表数据较少的情况。

COPY 方式下DDL 操作肯定不是 Online DDL。

执行流程如下图:

2.2. INPLACE 算法

INPLACE 方式下DDL 操作不会新建临时表,也无需拷贝全表数据到新表,优点是不需要额外的存储空间,但可能会产生较大的锁、阻塞和性能开销。分为两类:

  • rebuild:需要重建表,如,添加/删除主键。
  • no-rebuild:不需要重建表,如,修改列名、修改自增值等)。

对于rebuild方式,DDL 期间会缓存 DML,待完成之后,再进行 DML 操作。这种情况下,在 DDL 的初始准备和最后结束两个阶段时通常需要加 MDL 排他写锁,除此外,DDL 期间不会阻塞 DML。

即使使用 INPLACE 算法,虽然不会创建新表,但过程中可能会涉及到创建临时的数据文件进行辅助修改,所以都会需要额外的数据空间。

2.3. INSTANT 算法

INSTANT 方式是 8.0.12 引入的,只需修改数据字典中的元数据,无需拷贝数据也无需重建整表,同样,也无需加MDL 排他写锁,原表数据也不受影响。整个DDL过程几乎是瞬间完成的,也不会阻塞DML。

3. 各版本 Online DDL 总结

本文数据全部来自 MySQL 官方文档,由于 5.6 版本不在维护,本文仅整理目前常用的 5.7 和 8.0 版本。

3.1. MySQL 5.7

5.7版本

3.2. MySQL 8.0

3.3. 关于扩展 varchar 长度

根据官方文档描述,扩展 varchar 长度时使用的算法与该列所占用的字节数(不是字符)有关。具体逻辑如下:

  1. varchar 长度在 0-255 字节时,需要用 1 个字节编码值;
  2. varchar 长度在 256 以上字节时,需要用 2 个字节编码值;
  3. 如果扩展前后的大小均在 0-255 字节范围内或均大于 256 字节,则可以使用 INPLACE 算法,否则只能通过 COPY 算法进行 DDL;
  4. 如果进行减少 varchar 长度,则只能使用 COPY 算法。

3.4. Online DDL 会不会锁表

很多 MySQL 用户经常在表无法正常的进行 DML 时就觉得是锁表了,这种说法其实过于宽泛,实际上能够影响 DML 操作的锁主要有:

  • 元数据(MDL)锁
  • 表锁
  • 行锁
  • 间隙锁(GAP)锁

其中只有表锁和元数据锁可能进行锁表,关于锁的内容,详情见另一篇文章 MySQL 锁

一个 DDL 的基本过程是这样的:

  1. 准备阶段,需要拿到对应表的 MDL 排他写锁,然后进行一系列的准备工作;
  2. 执行阶段,将 MDL 排他写锁降级为 MDL 共享读锁,进行真正的 DDL 操作;
  3. 提交阶段,将 MDL 共享读锁升级为 MDL 排他写锁,完成 DDL 操作,释放 MDL 锁;

所以在真正执行 DDL 操作期间,确实是不会锁表的,但是如果在准备阶段和提交阶段为 MDL 排他写锁 期间是进行锁表的。

3.5. 版本总结

通过 3.1 和 3.2 的表格的整理可以得到一下几个结论:

1. 即使使用 INPLACE 算法,执行的 DDL 也不一定是 Online DDL

2. INSTANT 方式 是 MySQL 8.0 引入的新功能,当前支持的范围较小,仅包括:

  • 修改二级索引类型
  • 新增/删除/重命名列
  • 修改列默认值
  • 修改列 ENUM 值
  • 重命名表

3. 我们常说的 Online DDL,其实是从 DML 操作的角度描述的,如果 DDL 操作不阻塞 DML 操作,那么这个 DDL 就是 Online 的。当前非 Online DDL 其实已经比较少了,主要有:

  • 新增全文索引
  • 新增空间索引
  • 删除主键
  • 修改列数据类型
  • 指定表字符集
  • 修改表字符集

4. 在执行 DDL 操作时,用户可以通过ALGORITHM=COPY主动指定算法,若未指定,则优先选择 INPLACE,若不支持 INPLACE 则选择 COPY,当前不支持 INPLACE 的操作主要有:

  • 删除主键
  • 修改列数据类型
  • 修改表字符集

4. 第三方工具实现 Online DDL

除了支持 INSTANT 算法的 DDL 操作,其余的建议采用gh-osc/pt-osc工具进行 DDL 操作。

4.1. gh-ost

推荐文章:MySQL 最佳实践:gh-ost 工具使用详解-腾讯云开发者社区-腾讯云

4.2. pt-osc

推荐文章:PT-OSC在线DDL变更工具使用攻略-腾讯云开发者社区-腾讯云


参考:
[1] 周杰伦的稻香. 你知道 Online DDL 吗.
[2] 翊云. 白话 Online DDL.

标签:Online,MDL,DDL,DML,MySQL,操作
From: https://www.cnblogs.com/fuxing/p/18175135

相关文章

  • mysql 的常用批量更新
    批量更新inupdatetableNamesetcolumnName=valuewherecolumnNamein(value1,value2,value3);有局限性,限制了更新的属性值必须一致。如果不一致,需要分开写多个update语句。insertinto...onduplicatekeyupdateinsertintotableName(columnName1,columnName2)......
  • MySQL Connection not available问题解决方案
    在后端开发过程中,连接mysql数据库,过几个小时第一次使用会出现MySQLConnectionnotavailable报错这是因为MySql数据库存在一个连接池的回收时间,超过这个时间会导致资源无法正常释放,无法连接到MySql数据库1)在相关引用页面,进行定时刷新功能,这样尽管是同一个连接,但是相当于一个新......
  • MySQL DBA 面试问题
    1、MySQL适用的场景是什么?数据量建议单实例T级或以内,不依赖存储过程、函数、触发器的传统oltp场景都适用,因为是一个相对轻量级的数据库灾备使用MySQL各类的高可用方案即可,比如主从、mha、mgr等。2、MySQL巡检应该怎么做?优先关注哪些参数?可以从以下几个方面去做:服务器配置操......
  • mysql忘记密码
      mysql修改用户密码的方法及命令 方法1:用SETPASSWORD命令 首先登录MySQL。 格式:mysql>setpasswordfor用户名@localhost=password('新密码'); 例子:mysql>setpasswordforroot@localhost=password('123'); 方法2:用mysqladmin 格式:mysqladmin-u用户名......
  • Mysql权限管理,备份与三大范式
    mysql访问权限系统表mysql的权限由四个表来控制权限,分别是user表,db表,tables_priv表,columns_priv表表名作用user存放用户账号、密码、主机信息和全局权限db数据库级别的权限表tables_priv表级别的权限表columns_priv列级权限表procs_priv函数/存储过......
  • Mysql索引
    索引是对数据库表中一列或多列的值进行排序的一种结构。MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。索引的优缺点:优点:所有的MySql列类型(字段类型)都可以被索引,也就是可以给任意字段设置索引。大大加快数据的查询速度。缺点:......
  • mysql执行update语句流程
    客户端发送更新命令到MySQL服务器,经过处理连接、解析优化等步骤;Server层向InnoDB存储引擎要id=1的这条记录;存储引擎先从bufferpoll中查找这条记录,有的话直接返回,没有则从磁盘加载到bufferpoll中然后返回;Server层执行器修改这条记录的name字段值;存储引擎更新修改到内存中;存储......
  • Mysql中的事务
    事务的四大特性:特性解释原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么全部成功,要么全部失败。一致性(Consistency)事务发生前后,数据的完整性要保持一致。隔离性(Isolation)隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的......
  • 解析mysql奇葩语句
    首先看看完整的表如下图那么看看一个比较奇葩的语句select*fromuserswherename='aa'='bb'这个语句为啥能执行成功以及为什么打印出了除了两个aa之外的所有行数据呢。我们来解释一下原理。当我们使用where语句的时候,where是会一行一行的匹配的,同时where的执......
  • 如何选择配置 MySQL innodb_log_file_size
    配置InnoDB的redo空间大小是写密集型工作负载最重要的配置选项之一。不过,这需要权衡利弊。配置的redo空间越大,InnoDB就能更好地优化写IO。不过,增加redo空间也意味着在系统断电或因其他原因崩溃时需要更长的恢复时间。 对于特定的innodb_log_file_size值,要预测系统......