MySQL原生的DDL工具
Copy算法
- 按照原表定义创建一个新的临时表。
- 对原表加写锁(禁止DML)。
- 在1建立的临时表执行DDL。
- 将原表中的数据copy到临时表。
- 释放原表的写锁。
- 将原表删除,并将临时表重命名为原表。
采用copy方式期间需要锁表,禁止DML写操作。当Lock = Shared时允许读操作,不允许写操作;当Lock = Exclusive时,读写操作都被禁止,因此不能实现Online。但这种方法可以应用在几乎全部DDL场景下。
Inplace算法
Inplace采用在原表上进行更改的方法,不需要生成临时表,不需要进行数据copy的过程。可分为两类:
- rebuild:需要重建表(重新组织聚簇索引)。比如optimize table、添加索引、添加/删除列、修改列NULL/NOT NULL属性等。
- no-rebuild:不需要重建表,只需要修改表的元数据,比如删除索引、修改列名、修改列默认值、修改列自增值等。
对于rebuild方式实现Online是通过缓存DDL期间的DML,待DDL完成之后,将DML应用到表上来实现的。由于MDL写锁在拷贝数据期间降为MDL读锁,DML操作在DDL执行期间几乎不会被阻塞。
Inplace算法使用限制
Inplace算法支持大部分DDL操作,只有少数场景下只能利用Copy算法。
- 不支持删除主键,但不同时添加另外一个主键。
- 不支持更改字段的数据类型。
- 不支持扩展varchar列的长度从小于256位到大于256位,因为占用的空间从1个字节会变更到2个字节。不支持减少varchar类型列的长度。
- 不支持修改virtual column和stored column的顺序。
- 不支持在参数foreign_key_checks = 1时添加外键约束。
- 不支持对表进行分区,优化分区,删除分区。