你真的认识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的策略,我们可以通过显示增加以下两个参数来进行控制,分别是ALGORITHM
与LOCK
使用方式如下,将这两个关键字放在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:初始化
在初始化阶段,服务器会根据存储引擎能力、语句中指定的操作以及用户指定
ALGORITHM
和LOCK
选项来确定操作期间允许的并发量 。在此阶段,使用共享的可升级元数据锁来保护当前表定义。 -
阶段 2:执行
在这个阶段中,语句准备和执行,根据初始化阶段的预判考虑是否使用排他锁。
-
阶段 3:提交表定义
在提交表定义阶段,元数据锁升级为独占锁,然后进行新旧表的元数据信息替换。元数据独占锁占用的时间会比较少。
六、评估DDL消耗的性能
在MySQL官网上有一个表格记录不同的DDL支持的算法与锁策略这里作者不再摘录https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl-operations.html
这里专门用一个小节来说这个点,是因为每条DDL的操作运用的算法和加锁都不是相同的.即上面的#四 的配置不一定适配每一条DDL语句,所以我们准备执行DDL的时候可以先查查表,看下是否支持对应的算法和锁策略,还要留意下会不会导致表复制,消耗资源情况等,都可以在上面的表中得到信息.另外官网也提供了一个评估的依据,他建议的评估DDL的操作建议是这样的:
- 复制一个表的结构
- 用少了的数据填充复制表
- 在复制表上面执行DDL语句
- 通过观察响应结果,分析当前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数据存入,我们要关注以下两个点:
-
磁盘空间.这个不再累述,如果磁盘空间不够那肯定会有问题.尽量的留存有10%(作者评估)的磁盘空间
-
内存空间.通过可以通过参数
innodb_sort_buffer_size
和innodb_online_alter_log_max_size
两个参数控制,如果并发量很多,可以控制好这两个参数的大小,防止日志爆了写不进去.
七、总结
总结,当我们需要执行Online DDL的时候我们可以根据以下步骤来评估该操作对生产环境的影响:
- 准备好DDL语句
- 根据DDL语句查阅算法表,看下当前的DDL语句是否支持
INPLACE
还有操作的过程 - 在测试环境做好测试,观察结果
- 评估内存空间与磁盘空间是否不足
- 执行操作,并观察业务情况
参考文档:https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl.html
以上是关于你真的认识InnoDB OnlineDDL吗?的主要内容,如果未能解决你的问题,请参考以下文章
你真的懂并发吗?谈谈对JUC线程池ThreadPoolExecutor的认识吧