MySQL--各版本DDL 操做总结

MySQL 5.5 DDL

在MySQL 5.5版本前,全部DDL操做都使用Copy Table的方式完成,操做过程当中原表数据库不容许写入,只能读取,在MySQL 5.5版本中引入FIC(Fast index creation)特性。html

FCI 操做流程:
(1)对表加共享S锁,容许其余会话读操做,但禁止写操做,
(2)根据当前表数据建立索引,
(3)新索引建立完成,解除S锁,容许读写。

FCI 优势:
(1)建立索引不须要拷贝整表数据,建立速度快,
(2)建立索引过程当中,能够快速停止。

FCI限制:
(1)FCI特新仅限于复制索引,不试用于汇集索引,
(2)索引建立期间,表只容许读不容许写。

在MySQL 5.6.7版本前,DDL操做主要有copy和inplace两种方式,两种方式全程都须要锁表禁止写操做,容许部分时间段的读操做,inplace方式仅支持添加和删除索引两种方式。mysql

copy方式:sql

(1)新建带索引的临时表
(2)锁原表,禁止DML,容许查询
(3)将原表数据拷贝到临时表(无排序,一行一行拷贝)
(4)进行rename,升级字典锁,禁止读写
(5)完成建立索引操做

inplace方式:数据库

(1)新建索引的数据字典
(2)锁表,禁止DML,容许查询
(3)读取汇集索引,构造新的索引项,排序并插入新索引
(4)等待打开当前表的全部只读事务提交
(5)建立索引结束

MySQL 5.6 DDL

在MySQL 5.6.7版本后,引入了row_log来记录DDL期间写操做所产生的日志,所以除DDL操做开始和结束的两小段时间须要对表持EXCLUSIVE-MDL锁禁止读写外,其他DDL操做阶段容许其余回话对表进行读写,所以可算做ONLINE DDL。缓存

对于ONLINE DDL操做,一样包含copy和inplace方式,而对于inplace方式,又能够细分为rebuild方式和no-rebuild方式,rebuild方式指须要从新组织记录的操做如添加删除列或交换列顺序等操做,而no-rebuild方式指不会致使记录格式发生变化的操做如删除和添加索引。并发

ONLINE DDL可分为三个阶段操做:app

Prepare阶段:
1.建立新的临时frm文件
2.持有EXCLUSIVE-MDL锁,禁止读写
3.根据alter类型,肯定执行方式(copy,online-rebuild,online-norebuild)
4.更新数据字典的内存对象
5.分配row_log对象记录增量
6.生成新的临时ibd文件

ddl执行阶段:
1.降级EXCLUSIVE-MDL锁,容许读写
2.扫描old_table的汇集索引每一条记录rec
3.遍历新表的汇集索引和二级索引,逐一处理
4.根据rec构造对应的索引项
6.将构造索引项插入sort_buffer块
6.将sort_buffer块插入新的索引
7.处理ddl执行过程当中产生的增量(仅rebuild类型须要)

commit阶段
1.升级到EXCLUSIVE-MDL锁,禁止读写
2.重作最后row_log中最后一部分增量
3.更新innodb的数据字典表
4.提交事务(刷事务的redo日志)
5.修改统计信息
6.rename临时idb文件,frm文件
7.变动完成  

Online DDL期间产生Row Log会按照Block来存放和处理,回放Row Log时按照Block来处理,一个Block回放完后处理下一个Block,只有到达最后一个Block时才会锁表,保证最后一个Block完成后新数据和老数据保持一致,所以Online DDL期间产生大量Row Log不会致使表被长时间锁定。

仅须要修改元数据的DDL操做:ide

(1)设置列默认值
(2)设置自增列的自增值
(3)删除索引

能够采用Online no-rebuild方式的DDL操做:工具

(1)添加索引

能够采用Online rebuild方式的DDL操做:性能

(1)添加列
(2)删除列
(3)交换列顺序
(4)修改列NULL-NOTNULL属性
(5)修改表ROW-FORMAT
(6)添加修改主键

只能采用Copy方式的DDL操做:

(1)修改列类型
(2)转换字符集
(3)Optimize table
(4)删除主键

 PS: 从MySQL 5.6.17版本后,Optimize table能够采用Inplace方式操做。

Online DDL操做相关参数:

(1)innodb_sort_buffer_size:用来存放Row log的Block大小由参数innodb_sort_buffer_size控制。
(2)innodb_online_alter_log_max_size:控制整个DDL期间产生Row log的文件上限值,当产生的Row Log超过该上限值,则DDL操做失败,并回滚该期间全部未提交的并发DML操做。
(3)innodb_sort_buffer_size:在DDL执行期间Row Log会写入到一个日志文件,该日志文件每次按照innodb_sort_buffer_size来扩展。
(4)old_alter_table,当该参数被启用后,全部Alter操做将使用COPY方式操做。

惟一索引的BUG:

(未找到该BUG出处)MySQL 在处理Row Log的时候存在BUG,会致使建立的惟一索引中可能存在不惟一KEY值的状况。

Duplicate entry问题:

在进行Online DDL操做过程当中,可能遇到Duplicate entry的报错,但数据和修改命令都正常,该问题解释:
When running an online DDL operation, the thread that runs the ALTER TABLE statement applies an “online log” of DML operations that were run concurrently on the same table from other connection threads. When the DML operations are applied, it is possible to encounter a duplicate key entry error (ERROR 1062 (23000): Duplicate entry), even if the duplicate entry is only temporary and would be reverted by a later entry in the “online log”. This is similar to the idea of a foreign key constraint check in InnoDB in which constraints must hold during a transaction.
链接:https://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-limitations.html

MySQL 5.7 DDL

在MySQL 5.7版本中,增长如下新功能:

  • 支持修改索引名操做

    操做语法:ALTER TABLE t1 RENAME INDEX idx1 to idx2;
    该操做仅须要修改元数据信息和刷新缓存,所以修改操做能快速完成。
  • 支持在线增长VARCHAR列的长度。

    在Innodb存储引擎中,字节长度小于255的列使用1个字节来标识列长,而对于字节长度超过255的列须要使用2个字节来标识列长。
    一、若是VARCHAR列长度仅在0-255或255-65535区间发生变化时,仅须要修改元数据信息而不须要对表进行Inplace操做,所以修改操做能快速完成。
        语法:alter table tb002 ALGORITHM=INPLACE, CHANGE COLUMN c4 c4 varchar(500);   
        或:  alter table tb002 ALGORITHM=INPLACE, modify c4 varchar(600);
    二、若是VARCHAR列长度从0-255区间变化到255-65535区间,则只能使用COPY方式,不容许并发DML。
    三、若是缩小VARCHAR列的长度,也只能使用COPY方式,不容许并发DML。
  • 支持使用INPLACE方式增长主键

    语法:ALTER TABLE tb002 ADD PRIMARY KEY(id),ALGORITHM=INPLACE;

MySQL DDL总结:

虽然MySQL 5.6和5.7版本提供了Online DDL操做,但Online DDL仍存在如下问题:

(1)主从复制延迟,只有主库上DDL执行成功才会写入到binlog中,而DDL操做在从库上不能并发执行,所以即便主库执行DDL时容许并发DML操做,对于大表操做,仍会引起严重的复制延迟。
(2)主库执行Online DDL时,不能根据负载暂停DDL操做。
(3)使用Inplace方式执行的DDL,发生错误或被KILL时,须要必定时间的回滚期,执行时间越长,回滚时间越长。
(4)使用Copy方式执行的DDL,须要记录过程当中的undo和redo日志,同时会消耗buffer pool的资源,效率较低,优势是能够快速中止。
(5)Online DDL并非全部时间段的Online,在特定时间段须要加元数据锁或其余锁。
(6)容许并发DML的DDL,可能会致使Duplicate entry问题。

DDL 建议:

一、对于并发操做较高的表,不管表数据量多少,不能在业务高峰期操做,
二、对于大表和较大表,若是对复制延迟和主库性能敏感,建议改成gh-ost或pt-osc工具,
三、对于包含惟一索引建立的DDL,不能使用gh-ost或pt-osc工具,
四、能业务低峰期操做的DDL,都尽可能安排在业务低峰期进行。
相关文章
相关标签/搜索