Mysql5.6版本之前

更新步骤
  • 对原始表加写锁
  • 按照原始表和执行语句的定义,重新定义一个空的临时表。
  • 对临时表进行添加索引(如果有)。
  • 再将原始表中的数据逐条Copy到临时表中。
  • 当原始表中的所有记录都被Copy临时表后,将原始表进行删除。再将临时表命名为原始表表名。
这样的话整个DDL过程的就是全程锁表的。

Mysql5.6版本之后

更新步骤
  • 对原始表加写锁
  • 按照原始表和执行语句的定义,重新定义一个空的临时表。并申请rowlog的空间。
  • 拷贝原表数据到临时表,此时的表数据修改操作(增删改)都会存放在rowlog中。此时该表客户端可以进行操作的。
  • 原始表数据全部拷贝完成后,会将rowlog中的改动全部同步到临时表,这个过程客户端是不能操作的。
  • 当原始表中的所有记录都被Copy临时表,并且Copy期间客户端的所有增删改操作都同步到临时表。再将临时表命名为原始表表名。

此时只有第四步是锁表的,其他时间可以正常进行DML

ALTER TABLE 默认操作

根据操作过程中是否需要表拷贝,online ddl可分为下面两大类:
以下都是支持INPLACE操作,只是区别为是否需要重建表
1.需要表拷贝的 ddl 操作:
增加、删除、字段。
修改字段长度(modify)
增加、删除主键。
改变表的 ROW_FORMAT 或 KEY_BLOCK_SIZE属性。
改变的字段的null状态。
执行OPTIMIZE TABLE,优化表。
使用 FORCE 选项重建表。
使用ALTER TABLE ... ENGINE=INNODB 语句。
首次创建全文索引。
 
2.不需要表拷贝的 ddl 操作:
创建、增加、删除普通索引。
创建第二个及后续的全文索引。
为字段设置默认值。
改变auto-increment值。
删除外键约束。
添加外键约束( 只有在foreign_key_checks=off时)
仅仅改变列的名称(rename)
设置表的持续统计选项(STATS_PERSISTENT, STATS_AUTO_RECALC STATS_SAMPLE_PAGES)
 
3: 如果ALGORITHM是被省略的。如果存储引擎支持,mysql则会选择ALGORITHM=INPLACE。否则选择ALGORITHM=COPY
 
4:LOCK表示并发的读写控制。默认是DEFAULT。存储引擎支持,则选择NONE表示同时可读可写。
    不支持则选择SHARED,支持并发读,不支持写。最终才会选择EXCLUSIVE,表示独占锁。不支持并发读写