MySQL&MariaDB-Online-DDL-参考指南

发表于 3年以前  | 总阅读数:548 次

图文无关

概述

在早期的 MySQL 版本中,DDL 操作(如创建索引等)通常都需要对数据表加锁,操作过程中 DML 操作都会被阻塞,影响正常业务。MySQL 5.6 和 MariaDB 10.0 开始支持 Online DDL,可以在执行 DDL 操作的同时,不影响 DML 的正常执行,线上直接执行 DDL 操作对用户基本无感知(部分操作对性能有影响)。

不同版本的数据库对各种 DDL 语句的支持存在一定的差异,本文将会针对 MySQL 和 MariaDB 对 Online DDL 的支持情况做一个汇总,在需要执行 DDL 操作时,可以参考本文的 Online DDL 支持情况 部分。

本文将会持续修正和更新,最新内容请参考我的 GITHUB 上的 程序猿成长计划 项目,欢迎 Star,更多精彩内容请 follow me

ALTER TABLE 语句中,支持通过 ALGORITHMLOCK 语句来实现 Online DDL:

  • ALGORITHM - 控制 DDL 操作如何执行,使用哪个算法
  • LOCK - 控制在执行 DDL 时允许对表加锁的级别
ALTER TABLE tab ADD COLUMN c varchar(50), ALGORITHM=INPLACE, LOCK=NONE;

ALGORITHM 支持的算法

ALGORITHM 说明
DEFAULT 默认算法,自动使用可用的最高效的算法
COPY 最原始的方式,所有的存储引擎都支持,不使用 Online DDL,操作时会创建临时表,执行全表拷贝和重建,过程中会写入 Redo Log 和大量的 Undo Log,需要添加读锁,非常低效
INPLACE 尽可能避免表拷贝和重建,更确切的名字应该是 ENGINE 算法,由存储引擎决定如何实现,有些操作是可以立即生效的(比如重命名列,改变列的默认值等),但有些操作依然需要全表或者部分表的拷贝和重建(比如添加删除列、添加主键、改变列为 NULL 等)
NOCOPY 该算法是 INPLACE 算法的子集,用于避免聚簇索引(主键索引)的重建造成全表重建,也就说用该算法会禁止任何引起聚簇索引重建的操作
INSTANT 用于避免 INPLACE 算法在需要修改数据文件时异常低效的问题,所有涉及到表拷贝和重建的操作都会被禁止

NOCOPY 算法支持:MariaDB 10.3.2+,MySQL 不支持该算法

INSTANT 算法支持:MariaDB 10.3.2+,MySQL 8.0.12+。

算法使用规则:

  • 如果用户指定的算法为 COPY,则 InnoDB 使用 COPY 算法。
  • 如果用户指定的是 COPY 之外的其它算法,则 InnoDB 会按照算法效率,选择最高效的算法,最差的情况下采用用户指定的算法。比如用户指定了 ALOGRITHM = NOCOPY,则 InnoDB 会从 (NOCOPY, INSTANT) 中选择支持的最高效的算法。

ALGORITHM 优劣

MySQL 服务主要为 Server 层存储引擎层 两部分组成,Server 层包含了 MySQL 大部分核心功能,所有的内置函数,跨存储引擎的功能如存储过程、触发器、视图等。存储引擎层负责数据的存储和读取,采用了插件式的架构模式。

COPY 算法 作用在 Server 层,其执行过程都是在 Server 层,因此所有存储引擎都支持使用该算法,执行过程如下图

COPY算法执行过程

INPLACE 算法 作用于存储引擎层,是 InnoDB 存储引擎特有的 DDL 算法,执行过程如下图所示

INPLACE 算法执行过程

LOCK 策略

默认情况下,MySQL/MariaDB 在执行 DDL 期间会使用尽可能少的锁,如果必要,可以通过 LOCK 子句控制在执行 DDL 时允许对表加锁的级别。如果指定的操作所要求的限制级别不满足(EXCLUSIVE > SHARED > NONE),则语句执行失败并报错。

策略 说明
DEFAULT 使用当前操作支持的粒度最小的锁策略
NONE 不获取任何表锁,允许所有的 DML 操作
SHARED 对表添加共享锁(读锁),只允许只读的 DML 操作
EXCLUSIVE 对表添加排它锁(写锁),不允许任何 DML 操作

为了避免执行 DDL 时,由于锁表导致生产服务不可用,在执行表结构变更语句时,可以添加 LOCK=NONE 子句,如果语句需要获取共享锁或者排它锁,则会直接报错,这样就可以避免意外锁表,造成线上服务不可用了。

Online DDL 执行过程

Online DDL 操作主要分为三个阶段:

Online DDL 执行过程

  • 阶段 1:初始化

    在初始化阶段,服务器会根据存储引擎的能力,操作的语句和用户指定的 ALGORITHMLOCK 选项来决定允许多大程度的并发。在这个阶段会创建一个 可升级的元数据共享锁(SU)来保护表定义。

  • 阶段 2:执行

    这个阶段会 准备执行 DDL 语句,根据 阶段 1 评估的结果来决定是否将元数据锁升级为 排它锁 (X),如果需要升级为排它锁,则只在 DDL 的 准备阶段 短暂的添加排它锁。

  • 阶段 3:提交表定义

    在表定义的提交阶段,元数据锁会升级为排它锁来更新表的定义。独占排它锁的持续时间非常短。

元数据锁(MDL,Metadata Lock)主要用于 DDL 和 DML 操作之间的并发访问控制,保护表结构(表定义)的一致,保证读写的正确性。MDL 不需要显式的使用,在访问表时会自动加上。

MDL

由于上面三个阶段中对元数据锁的独占, Online DDL 过程必须等待已经持有元数据锁的并发事务提交或者回滚才能继续执行。

注意:当 Online DDL 操作正在等待元数据锁时,该元数据锁会处于挂起状态,后续的所有事务都会被阻塞。在 MariaDB 10.3 之后,可以通过添加 NO WAIT 或者 WAIT n 来控制等待所得超时时间,超时立即失败。

ALTER TABLE tbl_name [WAIT n|NOWAIT] ...
CREATE ... INDEX ON tbl_name (index_col_name, ...) [WAIT n|NOWAIT] ...
DROP INDEX ... [WAIT n|NOWAIT]
DROP TABLE tbl_name [WAIT n|NOWAIT] ...
LOCK TABLE ... [WAIT n|NOWAIT]
OPTIMIZE TABLE tbl_name [WAIT n|NOWAIT]
RENAME TABLE tbl_name [WAIT n|NOWAIT] ...
SELECT ... FOR UPDATE [WAIT n|NOWAIT]
SELECT ... LOCK IN SHARE MODE [WAIT n|NOWAIT]
TRUNCATE TABLE tbl_name [WAIT n|NOWAIT]

评估 Online DDL 操作的性能

Online DDL 操作的性能取决于是否发生了表的重建。在对大表执行 DDL 操作之前,为了避免影响正常业务操作,最好是先评估一下 DDL 语句的性能再选择如何操作。

  1. 复制表结构,创建一个新的表
  2. 在新创建的表中插入少量数据
  3. 在新表上面执行 DDL 操作
  4. 检查执行操作后返回的 rows affected 是否是 0。如果该值非 0,则意味着需要拷贝表数据,此时对 DDL 的上线需要慎重考虑,周密计划

比如

  • 修改某一列的默认值(快速,不会影响到表数据)

      Query OK, 0 rows affected (0.07 sec)
  • 添加索引(需要花费一些时间,但是 0 rows affected 说明没有发生表拷贝)

      Query OK, 0 rows affected (21.42 sec)
  • 修改列的数据类型(需要花费很长时间,并且重建表)

      Query OK, 1671168 rows affected (1 min 35.54 sec)

由于在执行 Online DDL 过程中需要记录并发执行的 DML 操作发生的变更,然后在执行完 DDL 操作之后再应用这些变更,因此使用 Online DDL 操作花费的时间比不使用 Online 模式执行要更长一些。

Online DDL 支持情况

INSTANT 算法支持:MariaDB 10.3.2+,MySQL 8.0.12+。NOCOPY 只支持 MariaDB 10.3.2 以上版本,不支持 MySQL,这里就暂且忽略了。

重点关注是否 重建表支持并发 DML:不需要重建表,支持并发 DML 最佳。

Online DDL Select Path

二级索引

操作 INSTANT INPLACE 重建表 并发 DML 只修改元数据
创建或者添加二级索引
删除索引
重命名索引 (⚠️MySQL 5.7+,MariaDB 10.5.2+)
添加 FULLTEXT 索引 ✅ ① ❌ ①
添加 SPATIAL 索引(⚠️MySQL 5.7+,MariaDB 10.2.2+)
修改索引类型

说明:

  • ① 第一次添加全文索引字段时需要重建表,之后就不需要了

主键

操作 INSTANT INPLACE 重建表 并发 DML 只修改元数据
添加主键 ✅ ② ✅ ②
删除主键
删除一个主键同时添加一个新的

说明:

  • 重建聚簇索引总是需要拷贝表数据(InnoDB 是“索引组织表”),所以最好是在创建表的时候就定义好主键
  • 如果创建表是没有指定主键,InnoDB 会选择第一个 NOT NULLUNIQUE 索引作为主键,或者使用系统生成的 KEY
  • ② 对聚簇索引来说,使用 INPLACE 模式比 COPY 模式要高效一些:不会产生 undo logredo log,二级索引是有序的,所以可以按顺序加载,不需要使用变更缓冲区

普通列

操作 INSTANT INPLACE 重建表 并发 DML 只修改元数据
列添加 ✅ ③ ❌ ③ ✅ ③
列删除 ❌ ④
列重命名 ✅ ⑤
改变列的顺序 ❌ ⑫
设置默认值
修改数据类型
扩展 VARCHAR 长度(⚠️MySQL 5.7+, MariaDB 10.2.2+) ❌ ⑬ ❌ ⑥
删除列的默认值
改变自增值 ❌ ⑦
设置列为 NULL ✅ ⑧
设置列为 NOT NULL ✅ ⑨ ✅ ⑨
修改 ENUMSET 列的定义 ❌ ⑩

说明:

  • ③ 并发 DML:当插入一个自增列时,不支持并发的 DML 操作,添加自增列时,大量的数据会被重新组织,代价高昂

  • ③ 重建表:添加列时,MySQL 5.7及之前版本需要重建表,MySQL 8.0 当 ALGORITHM=INPLACE 时,需要重建表,ALGORITHM=INSTANT 时不需要重建

  • ③ INSTANT算法:添加列时,使用 INSTANT 算法有下面这些限制

    • 添加列操作不能和其它不支持 INSTANT 算法的操作合并为一条 ALTER TABLE 语句
    • 新增的列只能添加到表的最后,不能放到其它列的前面,在 MariaDB 10.4 之后,支持在任意位置添加
    • 不能将列添加到 ROW_FORMAT=COMPRESSED 的表中
    • 不能将列添加到包含 FULLTEXT 的表中
    • 不能将列添加到临时表中,临时表只支持 ALGORITHM=COPY
    • 不能将列添加到驻留在数据字典表空间中的表中
    • 在添加列的时候不会计算行的大小限制,该限制在执行 DML 操作插入或者更新表时才会被检查
  • ④ 删除列时,大量的数据需要被重新组织,代价高昂,在 MariaDB 10.4 之后,删除列支持 INSTANT 算法

  • ⑤ 重命名列时,确保只改变列名,不改变数据类型,这样才能支持并发的 DML 操作

  • ⑥ 扩展 VARCHAR 长度时,INPLACE 是有条件的,必须保证用于标识字符串长度的长度字节不变(这里说的都是字节,不是 VARCHAR 的字符长度,字节占用与采用的字符集有关,utf8 字符集下,一个字符占 3 个字节, utf8mb4 则 4 个字节)

    • 当 VARCHAR 列长度在 0-255 个字节时,长度标识占用一个字节
    • 当 VARCHAR 列长度大于 255 个字节时,长度标识占用两个字节

    因此,INPLACE 只支持 0-255 个字节之间或者 256 个字节到更大的长度之间的变更。VARCHAR 列长度减小是不支持 INPLACE 的。

  • ⑦ 自增列值变更是修改的内存中的值,不是数据文件

  • ⑧ ⑨ 设置列为 [NOT] NULL 时,大量的数据被重新组织,代价高昂

  • ⑩ 修改 ENUMSET 类型的列定义时,是否需要表拷贝取决于已有元素的个数和插入成员的位置

  • ⑫ 在 MariaDB 10.4 之后,列排序支持 INSTANT 算法

  • ⑬ 在 MariaDB 10.4.3 之后,InnoDB 支持使用 INSTANT 算法增加列的长度,但是也有一些限制,具体参考 Changing the Data Type of a Column

生成列

操作 INSTANT INPLACE 重建表 并发 DML 只修改元数据
添加 STORED
修改 STORED 列的排序
删除 STORED
添加 VIRTUAL
修改 VIRTUAL 列的排序
删除 VIRTUAL

外键

操作 INSTANT INPLACE 重建表 并发 DML 只修改元数据
添加外键约束 ✅ ⑭
删除外键约束

说明:

  • ⑭ 添加外键时,只有当 foreign_key_checks 选项被禁用的时候才支持 INPLACE 算法

操作 INSTANT INPLACE 重建表 并发 DML 只修改元数据
修改 ROW_FORMAT
修改 KEY_BLOCK_SIZE
设置持久表统计信息
指定字符集 ✅ ⑮
转换字符集 ✅ ⑯
优化表 ✅ ⑰
使用 FORCE 选项重建表 ✅ ⑱
执行空的重建 ✅ ⑲
重命名表

说明:

  • ⑮⑯ 当字符集不同时,需要重建表
  • ⑰⑱⑲ 如果表中包含 FULLTEXT 的字段,则不支持 INPLACE

表空间

操作 INSTANT INPLACE 重建表 并发 DML 只修改元数据
重命名常规表空间
启用或者禁用常规表空间加密
启用或者禁用 file-per-table 表空间加密

限制

  • 在临时表 TEMPORARY TABLE 上创建索引时会发生表拷贝
  • 如果表上有 ON...CASCADE 或者 ON...SET NULL 约束,则 ALERT TABLE 不支持字句 LOCK=NONE
  • 在 Onlne DDL 操作完成之前,它必须等待相关表已经持有元数据锁的事务提交或者回滚,在这个过程中,相关表的新事务会被阻塞,无法执行
  • 当在大表上执行涉及到表重建的 DDL 时,会存在以下限制
    • 没有任何机制可以暂停 Online DDL操作或限制 Online DDL 操作的 I/O 或CPU使用率
    • 如果操作失败,则回滚 Online DDL操作的代价非常高昂
    • 长时间运行的 Online DDL 可能会导致复制延迟。 Online DDL 操作必须在 Master 上执行完成后才能在 Slave 上执行,在这个过程中, 并发处理的 DML 在 Slave 上面必须等待 DDL 操作完成后才会执行。

写在最后

本文将会持续修正和更新,最新内容请参考我的 GITHUB 上的 程序猿成长计划 项目,欢迎 Star,更多精彩内容请 follow me

参考

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 5年以前  |  237231次阅读
vscode超好用的代码书签插件Bookmarks 2年以前  |  8065次阅读
 目录