MySQLDDL执行方式OnlineD

拉萨白癜风QQ交流群 http://liangssw.com/bozhu/12747.html

1引言

大家好,今天与大家一起分享一下mysqlDDL执行方式。一般来说MySQL分为DDL(定义)和DML(操作)。

DDL:DataDefinitionLanguage,即数据定义语言,那相关的定义操作就是DDL,包括:新建、修改、删除等;相关的命令有:CREATE,ALTER,DROP,TRUNCATE截断表内容(开发期,还是挺常用的),COMMENT为数据字典添加备注。

DML:DataManipulationLanguage,即数据操作语言,即处理数据库中数据的操作就是DML,包括:选取,插入,更新,删除等;相关的命令有:SELECT,INSERT,UPDATE,DELETE,还有LOCKTABLE,以及不常用的CALL–调用一个PL/SQL或Java子程序,EXPLAINPLAN–解析分析数据访问路径。

我们可以认为:

CREATE,ALTER,DROP,TRUNCATE,定义相关的命令就是DDL;

SELECT,INSERT,UPDATE,DELETE,操作处理数据的命令就是DML;

DDL、DML区别:

DML操作是可以手动控制事务的开启、提交和回滚的。

DDL操作是隐性提交的,不能rollback,一定要谨慎哦!

日常开发我们对一条DML语句较为熟悉,很多开发人员都了解sql的执行过程,比较熟悉,但是DDL是如何执行的呢,大部分开发人员可能不太关心,也认为没必要了解,都交给DBA吧。其实不然,了解一些能尽量避开一些ddl的坑,那么下面带大家一起了解一下DDL执行的方式,也算抛砖引玉吧。如有错误,还请各位大佬们指正。

2概述

在MySQL使用过程中,根据业务的需求对表结构进行变更是个普遍的运维操作,这些称为DDL操作。常见的DDL操作有在表上增加新列或给某个列添加索引。

我们常用的易维平台提供了两种方式可执行DDL,包括MySQL原生在线DDL(onlineDDL)以及一种第三方工具pt-osc。

下图是执行方式的性能对比及说明:

本文将对DDL的执行工具之OnlineDDL进行简要介绍及分析,pt-osc会专门再进行介绍。

3介绍

MySQLOnlineDDL功能从5.6版本开始正式引入,发展到现在的8.0版本,经历了多次的调整和完善。其实早在MySQL5.5版本中就加入了INPLACEDDL方式,但是因为实现的问题,依然会阻塞INSERT、UPDATE、DELETE操作,这也是MySQL早期版本长期被吐槽的原因之一。

在MySQL5.6版本以前,最昂贵的数据库操作之一就是执行DDL语句,特别是ALTER语句,因为在修改表时,MySQL会阻塞整个表的读写操作。例如,对表A进行DDL的具体过程如下:

按照表A的定义新建一个表B

对表A加写锁

在表B上执行DDL指定的操作

将A中的数据拷贝到B

释放A的写锁

删除表A

将表B重命名为A

在以上2-4的过程中,如果表A数据量比较大,拷贝到表B的过程会消耗大量时间,并占用额外的存储空间。此外,由于DDL操作占用了表A的写锁,所以表A上的DDL和DML都将阻塞无法提供服务。

如果遇到巨大的表,可能需要几个小时才能执行完成,势必会影响应用程序,因此需要对这些操作进行良好的规划,以避免在高峰时段执行这些更改。对于那些要提供全天候服务(24*7)或维护时间有限的人来说,在大表上执行DDL无疑是一场真正的噩梦。

因此,MySQL官方不断对DDL语句进行增强,自MySQL5.6起,开始支持更多的ALTERTABLE类型操作来避免数据拷贝,同时支持了在线上DDL的过程中不阻塞DML操作,真正意义上的实现了OnlineDDL,即在执行DDL期间允许在不中断数据库服务的情况下执行DML(insert、update、delete)。然而并不是所有的DDL操作都支持在线操作。到了MySQL5.7,在5.6的基础上又增加了一些新的特性,比如:增加了重命名索引支持,支持了数值类型长度的增大和减小,支持了VARCHAR类型的在线增大等。但是基本的实现逻辑和限制条件相比5.6并没有大的变化。

4用法

ALTERTABLEtbl_nameADDPRIMARYKEY(column),ALGORITHM=INPLACE,LOCK=NONE;

ALTER语句中可以指定参数ALGORITHM和LOCK分别指定DDL执行的算法模式和DDL期间DML的锁控制模式。

ALGORITHM=INPLACE表示执行DDL的过程中不发生表拷贝,过程中允许并发执行DML(INPLACE不需要像COPY一样占用大量的磁盘I/O和CPU,减少了数据库负载。同时减少了bufferpool的使用,避免bufferpool中原有的查询缓存被大量删除而导致的性能问题)。

如果设置ALGORITHM=COPY,DDL就会按MySQL5.6之前的方式,采用表拷贝的方式进行,过程中会阻塞所有的DML。另外也可以设置ALGORITHEM=DAFAULT,让MySQL以尽量保证DML并发操作的原则选择执行方式。

LOCK=NONE表示对DML操作不加锁,DDL过程中允许所有的DML操作。此外还有EXCLUSIVE(持有排它锁,阻塞所有的请求,适用于需要尽快完成DDL或者服务库空闲的场景)、SHARED(允许SELECT,但是阻塞INSERTUPDATEDELETE,适用于数据仓库等可以允许数据写入延迟的场景)和DEFAULT(根据DDL的类型,在保证最大并发的原则下来选择LOCK的取值)。

5两种算法

第一种Copy:

按照原表定义创建一个新的临时表;

对原表加写锁(禁止DML,允许select);

在步骤1建立的临时表执行DDL;

将原表中的数据copy到临时表;

释放原表的写锁;

将原表删除,并将临时表重命名为原表。

从上可见,采用copy方式期间需要锁表,禁止DML,因此是非Online的。比如:删除主键、修改列类型、修改字符集,这些操作会导致行记录格式发生变化(无法通过全量+增量实现Online)。

第二种Inplace:

在原表上进行更改,不需要生成临时表,不需要进行数据copy的过程。根据是否行记录格式,又可分为两类:

rebuild:需要重建表(重新组织聚簇索引)。比如optimizetable、添加索引、添加/删除列、修改列NULL/NOTNULL属性等;

no-rebuild:不需要重建表,只需要修改表的元数据,比如删除索引、修改列名、修改列默认值、修改列自增值等。

对于rebuild方式实现Online是通过缓存DDL期间的DML,待DDL完成之后,将DML应用到表上来实现的。例如,执行一个altertableAengine=InnoDB;重建表的DDL其大致流程如下:

建立一个临时文件,扫描表A主键的所有数据页;

用数据页中表A的记录生成B+树,存储到临时文件中;

生成临时文件的过程中,将所有对A的操作记录在一个日志文件(rowlog)中;

临时文件生成后,将日志文件中的操作应用到临时文件,得到一个逻辑数据上与表A相同的数据文件;

用临时文件替换表A的数据文件。

说明:

在copy数据到新表期间,在原表上是加的MDL读锁(允许DML,禁止DDL);

在应用增量期间对原表加MDL写锁(禁止DML和DDL);

根据表A重建出来的数据是放在tmp_file里的,这个临时文件是InnoDB在内部创建出来的,整个DDL过程都在InnoDB内部完成。对于server层来说,没有把数据挪动到临时表,是一个原地操作,这就是”inplace”名称的来源。

使用Inplace方式执行的DDL,发生错误或被kill时,需要一定时间的回滚期,执行时间越长,回滚时间越长。使用Copy方式执行的DDL,需要记录过程中的undo和redo日志,同时会消耗bufferpool的资源,效率较低,优点是可以快速停止。不过并不是所有的DDL操作都能用INPLACE的方式执行,具体的支持情况可以在(在线DDL操作)中查看。

以下是常见DDL操作:




转载请注明:http://www.aierlanlan.com/grrz/3094.html