
# MySQL原生的DDL工具
#### Copy算法
1. 按照原表定义创建一个新的临时表。
2. 对原表加写锁（禁止DML）。
3. 在[1]建立的临时表执行DDL。
4. 将原表中的数据copy到临时表。
5. 释放原表的写锁。
6. 将原表删除，并将临时表重命名为原表。
采用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时添加外键约束。
- 不支持对表进行分区，优化分区，删除分区。
 
