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,表示独占锁。不支持并发读写
![](https://img2022.cnblogs.com/blog/1335795/202209/1335795-20220923172147571-426501200.png)