Online DDL是从mysql5.6版本后引入的新功能,可以实现在线DDL操作不锁表。但是MySQL5.6的Online DDL不是真正的Online DDL,针对部分操作还是有局限性。
5.6之前的DDL处理方式:
1、创建临时表
2、将原表加S锁(只能读,不能DML)
3、将原表数据导入临时表
3、删除原表
4、把临时表重命名成新表
这种情况会对表加一个S锁,其他用户只能访问,不能执行DML操作,如果数据量越大,锁时间越长,对业务影响也越长。
5.6之后的DDL处理方式:
innodb_online_alter_log_max_size参数,默认为128M,超出范围会报错,所以处理大表的情况下需要调整这个值。作用是将DML产生的日志先插入缓存中的最大允许大小。
old_alter_table参数,判断是通过INPLACE还是COPY的算法,默认为OFF,表示采用INPLACE的方式:
INPLACE 表示创建索引或删除索引操作不需要创建临时表;
COPY 表示按照MySQL 5.1版本之前的方法,即创建临时表。
1、将INSERT、UPDATE、DELETE这类DML操作日志写入到一个缓存中
2、是否在原表上修改,还是采用临时表跟具体操作有关,不是所有的操作都建临时表、也不是所有的操作都在原表修改(见如下表格说明)
3、在原表上修改或采用临时表也不一定会加S锁(见如下表格说明)
4、待完成后再将缓存中的数据应用到表上,以此达到数据的一致性
只有以下几类DDL操作不可以通过“Online”的方式进行:会影响其他DML操作
1、新加字符编码不同
2、更改列数据类型
3、删除主键
4、添加全文索引
所以5.6的Online DDL并不是真正的Online DDL,如果想保证尽量不锁表,可以使用oak-online-alter-table和pt-online-schema-change等工具。
原理:
1、首先会对表进行分析(数据量、外键等)
2、创建一个临时表
3、创建触发器(3个),用户跟踪插入、更新、删除的数据(原表有写入,通过触发器复制到临时表)
4、copy数据
5、更新外键关联的子表
6、数据一致后将原表rename成_old,将临时表rename成原表(瞬间)
7、删除_old表
8、删除触发器
https://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-overview.html#innodb-online-ddl-summary-grid