ddl是什么意思(MySQL DDL Online)

35小吃技术网 推荐阅读 2023年06月26日13时56分59秒 155 0

什么是DDLOnline为什么要OnlineDDLOnline的方法官方自带DDLOnlinept-online-schema-change工具gh-ost工具总结什么是DDLOnlineDDLOnline:在线执行DDL语句,也就是在线修改表结构。所谓在线的意思就是保证在执行DDL语句的过程中,表

  • 什么是DDL Online

  • 为什么要Online

  • DDL Online的方法

    • 官方自带DDL

    • Onlinept-online-schema-change工具

    • gh-ost工具

  • 总结

什么是DDL Online

DDL Online:在线执行DDL语句,也就是在线修改表结构。所谓在线的意思就是保证在执行DDL语句的过程中,表仍然可以提供正常的读写服务,不会中断。

这就像飞机在不降落的情况下,在空中给飞机加油的操作。

ddl是什么意思(MySQL DDL Online)-第1张图片


你可能会想我执行一个DDL语句很快的呀,不会导致表不能正常读写吧?那是因为你操作的表是一个数据量比较小的表,或者不是一个被频繁访问的业务表,对于这些表,执行DDL语句确实很快,不会对业务造成很大的影响。但是,你如果对一个几百万、甚至上千万的大表进行DDL语句的修改,这个DDL语句执行的过程,可能会持续几十秒、甚至几分钟,此时的网这个过程不会像操作小表那么快。


为什么要Online

我们在生产环境中,难免要遇到对表结构的修改。而此时线上的表正在为后端提供各种请求访问的服务,如果此时我们直接进行对表结构的更改,可能导致后端的SQL请求被阻塞,不能正常访问,进而导致服务异常或不可用。所以,在我们对在线的表进行DDL操作的时候,要格外的注意。要选择合适的方式、合适的时间进行,尽量避免这些问题的发生。

那么为什么增加给表增加一个字段会导致锁表呢?

当我们对表增加字段的时候,我们就要获取这个表的MDL元数据锁(meta data lock)写锁(写锁又称为X锁,读锁又称为S锁),只有获取的这个MDL的X锁之后,我们才可以对这个表的结构进行修改,否则不能修改会被阻塞。


DDL Online的方法

目前为止,MySQL的DDL Online的方式主要有以下几种。

  • MySQL官方自带的DDL Online功能

  • percona提供的Percona Toolkit

  • Github开源的gh-ost工具

  • 主从切换的方式

  • Facebook的OSC

  • LHM

下面我们分别针对其中的几种方式来一一归纳总结一下。


官方自带DDL Online

MySQL从5.6之后的版本已经支持了DDL的Online操作。在使用的时候,就是在我们的DDL语句中,显示去指定关键字ALGORITHM和LOCK的参数值。示例如下:


/*推荐该参数组合*/alter table t add column col varchar(32), ALGORITHM=INPLACE, LOCK=NONE;alter table t add column col varchar(32), ALGORITHM=INPLACE, LOCK=SHARED;alter table t add column col varchar(32), ALGORITHM=INPLACE, LOCK=DEFAULT;alter table t add column col varchar(32), ALGORITHM=INPLACE, LOCK=EXCLUSIVE;

其中的ALGORITHM=INPLACE, LOCK=NONE是关键的地方,这里需要分别为ALGORITHM和LOCK这两个参数指定值。

  • ALGORITHM该参数的值可以为INPLACE、COPY、DEFAULT。INPLACE:它的原理是基于原来的表直接进行DDL的操作,此时原表可以支持DML操作。COPY:它的原理是复制出一张和原表的结构一样的表,然后基于这个新复制出来的表进行DDL操作。然后再用这个复制出来的新表替换掉原表。在执行DDL期间,原表不支持DML的操作,因为数据已经复制了一个新表中,在原表中如果仍然执行DML操作,将不能把这些操作同步到复制的新表中。DEFAULT:默认值,根据DDL语句的类型,自动的选择使用INPLACE或者COPY选项,能使用INPLACE的不使用COPY。注意:这个COPY的操作,要求磁盘的空间要充足,因为它会复制出一张和原表一样的表,会再次占用和原表一样的磁盘空间,同时会增加IO的负载。所以,一般情况下我们都是使用INPLACE作为ALGORITHM参数的值,只有当某些DDL语句,不支持ALGORITHM=INPLACE参数的时候,才选择ALGORITHM=COPY的选项。

  • LOCK参数的取值范围可以有NONE、SHARED、DEFAULT、EXCLUSIVE四种。NONE:表示不加锁,在DDL语句执行的过程中,表仍然可以进行select和DML的操作,这也正是我们DDL Online的真正所希望实现的效果。SHARED:可以执行select操作,但是不能执行DML操作。DEFAULT:根据不同的DDL语句,采用所需要的最小的锁。EXCLUSIVE:在DDL语句执行的过程中,既不能执行select操作,也不能执行DML操作。整个表完全不可以读写,被锁住。

MySQL自带的DDL Online的参数大纲如下:

ddl是什么意思(MySQL DDL Online)-第2张图片


图片来源参考:https:网//blog.csdn.net/finalkof1983/article/details/88355314

MySQL官方虽然已经支持了DDL的Online操作,但是,这个操作比较有局限性,并不是所有的DDL语句都可以真正的Online的去执行。有些DDL语句,虽然我们显示的执行要让其使用online的方式去执行,但是当MySQL真正的去执行的时候,如果它发现不能online的时候,会给出错误提示,让我们修改对应的显示参数去改为offline的方式去执行。这里不同的DDL语句范围很广,例如:修改字段类型、增加主键、删除主键、增加索引、删除索引、更改索引名称、增加字段、删除字段、修改字段长度等等。根据不同类型的DDL语句,参数ALGORITHM和LOCK的取值范围并不是都可以随意组合使用的,这个要视情况而定,具体场景具体分析。具体参考如下图片:

ddl是什么意思(MySQL DDL Online)-第3张图片


图片来源参考:https://blog.csdn.net/finalkof1983/article/details/88355314

另外,在针对有主从架构的场景时,使用官方自带的这种DDL Online语句,即便是在master主节点可以online的去执行,但是会在从库上会执行同样的DDL语句期间,从库中对应的这个执行DDL语句的表会出现DML语句被阻塞的情况,从而出现主从延迟的现象。大致过程如下:

  1. 在master节点上某个表执行DDL语句,此时对表的DML仍然可以支持并行的执行。

  2. 在这个DDL语句没有执行完成之前,这个操作是不会通过binlog同步到slave节点上去的。只有当这个DDL语句在master节点执行完成后,才会同步到slave节点去执行。

  3. 当slave开始执行从master同步过来的DDL的过程中,从master节点同步过来的,对该表的DML语句不能同时执行,需要等待slave上面的DDL语句执行完成后,才可以执行同步过来的DML语句。

  4. 此时,在slave上就出现了延迟的现象。

所以,官方自带的这个在线的DDL方式比较有局限性网。我们基本上都不使用这种方式,而是采用第三方的工具来实现在线修改表结构的需求。


pt-online-schema-change工具

pt-online-schema-change是Percona公司提供的众多工具集中的一个,它是工具包Percona Toolkit里面的其中一个命令。而这个工具箱的安装也比较简单,有各种安装方式。如果不想编译安装,可以下载一个编译好的二进制压缩包,开箱即用,解压后进入bin目录既可以使用。下载地址为:https://www.percona.com/downloads/percona-toolkit/LATEST/

pt-online-schema-change可以实现在线的DDL语句。它的原理是基于触发器来实现在线更改表结构。它的实现过程大概如下:

  1. 先创建一个临时表,这个临时表的表结构比原表的表结构不同之处就在于它已经应用了我们的DDL语句。

  2. 把原表中的数据慢慢的导入到这个临时表中。

  3. 在执行第2步导入操作的时候,如果仍然有对原表的DML语句,这些操作也要记录下来,然后同步到临时表中。

  4. 在确保临时表中的数据和原表中的数据完全同步之后,用临时表替换原表。

其中的第3步,在pt-osc工具中的实现方式是在原表上创建insert、update、delete触发器,通过这些触发器,把在导入数据到临时表的过程中在对原表的DML操作同步到临时表中去。这种做法比较大的问题就是增加了原表的压力,对原表的一些事物的操作会因为触发器操作临时表的加入而导致事物变长。