你真的认识InnoDB OnlineDDL吗?

Posted hello_读书就是赚钱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了你真的认识InnoDB OnlineDDL吗?相关的知识,希望对你有一定的参考价值。

最近在给一个大表增加字段的时候用到了Online DDL,在操作时有些疑问,带着这些问题查阅了官方文档并做一些总结,方便后面可以对DDL操作做好安全风险评估.

一、定义

先说说几个名词的定义

DDL:数据定义或数据描述语言.比如使用如下语句去修改表的结构信息,类似的语句成为DDL语句

ALTER TABLE abcmouse_qq_ugc.t_upload_audio ADD COLUMN file_score_detail  varchar(500) default '',ALGORITHM=INPLACE, LOCK=NONE`

data definition or data description language

DML:数据操控语言.指的是对普通数据的操作,比如我们常见的增删改查

select * form a;

data manipulation language

Online DDL:即支持在线DDL操作,支持并发DML.可以理解为就是不锁表的DDL操作

二、mysql怎么开启Online DDL

通常,无需执行任何特殊操作即可启用在线Online DDL.默认情况下,MySQL在允许的情况下会执行可并发的DDL操作,并尽可能少加锁.

比如说,你想给一个表增加字段,那么直接使用以下语句,那么InnoDB将自动开启Online DDL.(因为加字段的这个DDL是支持Online DDL的)

ALTER TABLE abcmouse_qq_ugc.t_upload_audio ADD COLUMN file_score_detail  varchar(500) default '';

注意一下这个点,应该很多人都跟作者一样,以为DDL操作一定会导致数据库锁表.其实MySQL5.7已经帮我们考虑好这个问题.如果当前执行的DDL语句支持不锁表DDL,那么会优先使用该种模式,注意一定要具体情况具体分析、下面会细说.

三、使用Online DDL的好处

Online DDL具有以下好处

  • 提高响应性与可用性,减少锁等待
  • 减少磁盘I/O与CPU负载
  • 减少了缓冲池的使用

好处就不用再次强调,在生产环境中,可能是不能锁表来DDL.但,锁表也有锁表的好处,无竞争会更快嘛.

四、显示指定DDL时的算法与锁

上面咱们说MySQL默认情况下会选择最优让DDL支持无锁操作.但如果我们需要细粒度的控制DDL的策略,我们可以通过显示增加以下两个参数来进行控制,分别是ALGORITHMLOCK使用方式如下,将这两个关键字放在SQL语句的末尾,并用逗号隔开:

ALTER TABLE tbl_name ADD PRIMARY KEY (column), ALGORITHM=INPLACE, LOCK=NONE;

下面具体说说这两个参数的作用:

LOCK:指定DDL操作时,所用的锁级别

默认情况下,MySQL 在 DDL 操作期间使用尽可能少的锁定.但是我们可以通过LOCK字段来精确控制DDL的锁级别.注意,如果当前DDL操作需要的锁级别达不到要求,那么将无法执行,比如有什么恶心的操作一定要锁表的,这个key提供的几个value如下所示:

  • NONE:允许并发查询和DML.但是要注意,作者在分布式数据库中使用这个NONE会导致数据错乱问题,最后导致后面DML失败.

  • SHARED:只允许并发查询.

  • DEFAULT:尽量可能多的并发,这是这个key的缺省参数.如果确认DDL的操作不会对业务造成影响的时候会使用这个参数.

  • EXCLUSIVE:阻塞并发查询和DML.使用这个选项相等于就是锁表更新了,这样会使DDL操作起来会更快.

ALGORITHM:是用来调整DDL时的算法.这是key,他的value有如下几个选择:

COPY:通过复制源表来实现的,就是说DDL是新建一个新表,然后再迁移旧数据,注意这种情况是不支持并发的一定要留意

INPLACE:这种操作会避免复制源表,但是可能会在原地重建表.在"准备阶段"和"执行阶段"(执行阶段下面会继续说)会申请元数据锁.通常在这种情况下可以支持并发的DML操作,注意在部分情况下还是不能支持并发的,具体要看DDL内容进行分析.

DEFAULT: 根据DDL语句的默认支持策略选取一个适用的模式,如果能支持INPLACE,那么就会优先使用.

注意以上的参数搭配如果支持的话那么DDL就直接运行了,如果不支持的话那么会响应失败.

五、DDL执行的三个阶段

DDL执行的三个阶段,了解这些原理可以让我们更好的理解DDL是怎么执行的:

  • 阶段 1:初始化

    在初始化阶段,服务器会根据存储引擎能力、语句中指定的操作以及用户指定ALGORITHMLOCK 选项来确定操作期间允许的并发量 。在此阶段,使用共享的可升级元数据锁来保护当前表定义。

  • 阶段 2:执行

    在这个阶段中,语句准备和执行,根据初始化阶段的预判考虑是否使用排他锁。

  • 阶段 3:提交表定义

    在提交表定义阶段,元数据锁升级为独占锁,然后进行新旧表的元数据信息替换。元数据独占锁占用的时间会比较少。

六、评估DDL消耗的性能

在MySQL官网上有一个表格记录不同的DDL支持的算法与锁策略这里作者不再摘录https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl-operations.html

这里专门用一个小节来说这个点,是因为每条DDL的操作运用的算法和加锁都不是相同的.即上面的#四 的配置不一定适配每一条DDL语句,所以我们准备执行DDL的时候可以先查查表,看下是否支持对应的算法和锁策略,还要留意下会不会导致表复制,消耗资源情况等,都可以在上面的表中得到信息.另外官网也提供了一个评估的依据,他建议的评估DDL的操作建议是这样的:

  1. 复制一个表的结构
  2. 用少了的数据填充复制表
  3. 在复制表上面执行DDL语句
  4. 通过观察响应结果,分析当前DDL语句是否使用的是INPLACE算法

如果是COPY结果如下:

Query OK, 1671168 rows affected (1 min 35.54 sec)-- 可以看到行数很多

如果是INPLACE结果如下:

Query OK, 0 rows affected (21.42 sec) -- 可以看到虽然消耗了一定的时间,但是影响的行数为0

另外,当并发DML的时候,是会暂时把DML的数据写到临时文件中,所以还需要评估一下磁盘空间与配置的参数大小是否能支持DDL期间的DML数据存入,我们要关注以下两个点:

  1. 磁盘空间.这个不再累述,如果磁盘空间不够那肯定会有问题.尽量的留存有10%(作者评估)的磁盘空间

  2. 内存空间.通过可以通过参数innodb_sort_buffer_sizeinnodb_online_alter_log_max_size两个参数控制,如果并发量很多,可以控制好这两个参数的大小,防止日志爆了写不进去.

七、总结

总结,当我们需要执行Online DDL的时候我们可以根据以下步骤来评估该操作对生产环境的影响:

  1. 准备好DDL语句
  2. 根据DDL语句查阅算法表,看下当前的DDL语句是否支持INPLACE还有操作的过程
  3. 在测试环境做好测试,观察结果
  4. 评估内存空间与磁盘空间是否不足
  5. 执行操作,并观察业务情况

参考文档:https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl.html

以上是关于你真的认识InnoDB OnlineDDL吗?的主要内容,如果未能解决你的问题,请参考以下文章

你真的懂并发吗?谈谈对JUC线程池ThreadPoolExecutor的认识吧

你真的懂ThreadPoolExecutor线程池技术吗?看了源码你会有全新的认识

你真的了解IP地址吗?

你真的了解爬虫吗?看完你会对网络爬虫有更深更全面的认识

你真的了解爬虫吗?看完你会对网络爬虫有更深更全面的认识

MySQL InnoDB Online DDL学习