DDL工具简介
MySQL 5.6之前数据库中对大表的表结构修改的DDL操作通常会引发DML语句阻塞,复制延迟升高等问题,导致数据库对外呈现出一种“异常”的状态。本文介绍了MySQL原生的数据库DDL方式Copy和Inplace算法、开源工具gh-ost以及MySQL 8.0新增的Instant秒级加列的算法的原理,使用限制,适用场景等。
- MySQL原生的Copy算法由于在拷贝数据的过程中对源表加MDL写锁,导致DML语句被长时间阻塞,已经不推荐使用。
- Inplace算法相比Copy算法有很大的改进,采用在原表上进行更改的方法,不需要生成临时表,占用的额外空间小。同时Inplace操作只需要短暂的持有MDL写锁,不会造成DML操作被长时间阻塞。但是对大表的表结构修改,依然要消耗大量的时间,导致备机在回放DDL语句时产生较大的复制延迟。
- 开源gh-ost将一个DDL操作拆分成多个小操作,减少单次操作的时间来降低复制延迟。同时只有在最后rename镜像表和原表的过程中才会短暂阻塞读写操作。gh-ost基于Binlog回放增量数据,同时额外维护了额外的心跳表来记录DDL执行过程,支持临时暂停DDL过程。这些机制导致gh-ost的执行时间比原生的DDL算法略长。
- MySQL 8.0之后提出的instant秒级加列算法,不再需要rebuild整个表,只需要在表的metadata中记录新增列的基本信息即可。这种方式将大表的加列操作降低到了秒级。但是目前这种方式的应用场景只局限在添加列,设置列默认值,删除列默认值,修改ENUM/SET列的定义等少量DDL场景。
根据每种算法和工具的特点,建议在可以使用instant算法的DDL场景和版本下,尽可能使用instant算法来减少DDL对整个业务的影响。此外的其他情况,如果客户是主备或含有只读实例的场景,且对复制延迟带来的影响容忍较低的情况下,使用gh-ost工具来进行DDL操作。如果客户需要快速变更表结构,可以容忍短时间的主备不一致的问题,用Inplace算法可以满足需求。Copy算法由于会长时间阻塞DML操作,占用大量磁盘空间,且执行时间较长,目前在可以应用其他算法和工具的场景下不推荐使用。
方法 |
MySQL Copy |
MySQL Inplace |
gh-ost |
instant |
---|---|---|---|---|
DDL过程中读取数据 |
允许 |
允许 |
允许 |
允许 |
DDL过程中写入数据 |
不允许 |
允许(短暂时间不允许) |
允许(短暂时间不允许) |
允许 |
额外空间占用 |
大 |
小(需要rebuild会略高) |
大 |
小 |
执行时间 |
非常长 |
长 |
非常长 |
短 |
复制延迟 |
大 |
大 |
小 |
小 |