MySQL添加索引是否会锁表呢?(Mysql Online DDL)
MySQL Online DDL(Data Definition Language,数据定义语言)是MySQL数据库提供的一项功能,允许在不中断数据库服务的情况下执行DDL操作。
定义与特点
定义:MySQL Online DDL指的是在执行DDL操作(如表结构的修改)的同时,允许对表进行正常的DML(Data Manipulation Language,数据操纵语言)操作(如INSERT、UPDATE、DELETE等),从而不阻塞表的读写操作。
特点:
- 提高数据库的可用性和响应效率,减少DDL操作对业务的影响。
- 适用于大数据量的表格,避免传统DDL操作锁定整个表导致无法读写的问题。
发展历程
- MySQL 5.5及之前的版本:在进行DDL操作时,整个表都会被阻塞,无法进行DML操作,这在生产环境中通常是不能接受的。
- MySQL 5.6版本:正式引入了Online DDL功能,支持DDL操作期间允许DML操作同时进行,尽量避免DDL过程中对业务SQL产生的阻塞。
- MySQL 8.0版本:对DDL的实现重新进行了设计,支持了原子特性,并引入了INSTANT算法,使得某些DDL操作几乎瞬间完成,且不阻塞DML。
执行Online DDL时经历的阶段
在执行Online DDL时,无论采用哪种算法,一般都会经历以下三个阶段:
-
准备阶段(Prepare):
- 在此阶段,服务器会根据存储引擎的能力、语句中指定的操作以及用户指定的ALGORITHM和LOCK选项来确定操作期间允许的并发量。
- 使用共享的元数据锁(MDL)来保护当前表定义,根据DDL的类型和指定的算法,可能会创建新的临时文件或进行其他准备工作。
-
执行阶段(DDL 语句执行):
- 在这一阶段,实际的DDL操作被执行。对于Online DDL,重要的是在此期间允许DML操作(如INSERT、UPDATE、DELETE)并发执行。
- 根据采用的算法不同,执行阶段的具体逻辑也会有所不同。例如,Inplace算法可能会在原表上直接修改结构,而Copy算法则可能会将数据复制到新表中。
-
提交阶段(Commit):
- 在DDL操作完成后,进入提交阶段。此时,可能会将元数据锁升级为排他锁,以完成表定义的更新。
- 对于涉及数据复制的算法(如Copy算法),在此阶段会完成数据的最终同步和旧表的清理工作。
实现原理
MySQL Online DDL通过不同的算法和策略来实现在线修改数据库结构的目标,主要包括Copy算法、Inplace算法和Instant算法(MySQL 8.0.12引入):
-
Copy算法:
- 大体逻辑:按照原表定义创建一个新的临时表,对原表加写锁(禁止DML,允许SELECT),将原表中的数据逐行拷贝到新表中,然后在原表上执行DDL操作,最后将新表替换为原表名。
- 特点:Copy算法在执行期间会阻塞DML操作,因此通常不是纯粹的Online DDL。它适用于需要大量结构修改且表数据较少的情况。
-
Inplace算法:
- 大体逻辑:在原表上直接执行DDL操作,无需创建临时表或拷贝全表数据。根据DDL操作的具体类型,Inplace算法可能会分为rebuild和no-rebuild两种方式。Rebuild方式需要重建表(如添加索引、添加/删除列等),而no-rebuild方式则只需修改表的元数据(如删除索引、修改列名等)。
- 特点:Inplace算法减少了额外的存储空间和IO开销,但DDL操作期间可能会产生较大的锁、阻塞和性能开销。在Inplace算法的某些阶段(如准备和提交阶段),仍然可能需要加锁以保证数据的一致性。
-
Instant算法:
- 大体逻辑:MySQL 8.0.12引入的新算法,只需修改数据字典中的元数据,无需拷贝数据也无需重建整表。整个DDL过程几乎是瞬间完成的,也不会阻塞DML操作。
- 特点:Instant算法极大地提高了DDL操作的效率和对业务的影响,但当前支持的操作范围较为有限,主要包括修改二级索引类型、新增/删除/重命名列、修改列默认值等。
是否锁表
Online DDL(在线数据定义语言)在MySQL中的行为是否会导致锁表,取决于多个因素,包括具体的DDL操作类型、MySQL的版本、以及是否使用了特定的算法(如INPLACE或COPY)。
INPLACE算法
- 不锁表或短暂锁表:在大多数情况下,使用INPLACE算法的DDL操作不会显著影响对表的并发访问。MySQL会尽量减少锁的使用,以便在DDL操作期间允许DML操作继续进行。然而,在某些准备阶段或提交阶段,可能需要短暂地获取元数据锁(MDL),这可能会导致短暂的锁表现象。
- 锁的类型:在Online DDL过程中,主要使用的锁是元数据锁(MDL)。MDL锁分为共享锁(允许并发读取)和排他锁(阻止其他读写操作)。DDL操作通常需要排他MDL锁来修改表结构,但在执行阶段,这个锁可能会被降级为共享锁,以便允许DML操作。
COPY算法
- 会锁表:使用COPY算法的DDL操作会创建一个新表,将原表的数据复制到新表中,然后在新表上执行DDL操作。在这个过程中,原表通常会被锁定,以防止数据不一致。因此,这种操作会导致显著的锁表现象,影响对表的并发访问。
MySQL版本差异
- 不同版本的MySQL在Online DDL的支持和锁表行为上可能存在差异。例如,MySQL 5.6引入了Online DDL功能,但在某些操作上可能仍然需要锁表。而MySQL 8.0及更高版本则提供了更完善的Online DDL支持,包括INSTANT算法,该算法在某些情况下可以几乎瞬间完成DDL操作,无需锁表或拷贝数据。
常用操作
MySQL Online DDL支持多种类型的DDL操作,包括但不限于:
- 索引相关操作:新建索引、删除索引等。
- 主键相关操作:增加主键、删除主键(注意,重建聚集索引通常需要Copy算法)。
- 列相关操作:新增列、删除列、重命名列、设置/删除列的缺省值、修改列类型等。
- 表相关操作:改变表的字符集、优化表(optimize table)等。
注意事项
- 即使在执行Online DDL操作期间,某些阶段(如准备阶段和提交阶段)仍然可能需要加锁,因此可能会对DML操作产生短暂影响。
- 对于大表的DDL操作,应评估其对主从复制延迟的影响,并考虑在低峰时段执行。
- 在执行Online DDL操作之前,最好查阅MySQL的官方文档以了解具体的支持情况和限制。
- 在高并发场景下,考虑在低峰时段执行DDL操作,以减少对业务的影响。
Online DDL Support
Mysql 5.7
Table 14.10 Online DDL Support for Index Operations
Operation | In Place | Rebuilds Table | Permits Concurrent DML | Only Modifies Metadata |
---|---|---|---|---|
Creating or adding a secondary index | Yes | No | Yes | No |
Dropping an index | Yes | No | Yes | Yes |
Renaming an index | Yes | No | Yes | Yes |
Adding a FULLTEXT index | Yes* | No* | No | No |
Adding a SPATIAL index | Yes | No | No | No |
Changing the index type | Yes | No | Yes | Yes |
Table 14.11 Online DDL Support for Primary Key Operations
Operation | In Place | Rebuilds Table | Permits Concurrent DML | Only Modifies Metadata |
---|---|---|---|---|
Adding a primary key | Yes* | Yes* | Yes | No |
Dropping a primary key | No | Yes | No | No |
Dropping a primary key and adding another | Yes | Yes | Yes | No |
其他更多操作参见Mysql 5.7 Online DDL
Mysql 8.0
Table 17.16 Online DDL Support for Index Operations
Operation | Instant | In Place | Rebuilds Table | Permits Concurrent DML | Only Modifies Metadata |
---|---|---|---|---|---|
Creating or adding a secondary index | No | Yes | No | Yes | No |
Dropping an index | No | Yes | No | Yes | Yes |
Renaming an index | No | Yes | No | Yes | Yes |
Adding a FULLTEXT index | No | Yes* | No* | No | No |
Adding a SPATIAL index | No | Yes | No | No | No |
Changing the index type | Yes | Yes | No | Yes | Yes |
Table 17.17 Online DDL Support for Primary Key Operations
Operation | Instant | In Place | Rebuilds Table | Permits Concurrent DML | Only Modifies Metadata |
---|---|---|---|---|---|
Adding a primary key | No | Yes* | Yes* | Yes | No |
Dropping a primary key | No | No | Yes | No | No |
Dropping a primary key and adding another | No | Yes | Yes | Yes | No |
其他更多操作参见Mysql 8.0 Online DDL