这里有一篇译文,对5.6在线DDL的操作做了介绍,5.6里对在线DDL做了很多的优化,从译文里的表5.9可以看到,很多操作不需要做copying data操作。
下面这段话很有启发作用:
对于DDL操作一个基本的想法:它的变化是就地执行还是执行表拷贝, 在命令结束之后看看显示“rows affected “的值。例如,这里您可能会看到在做不同类型的DDL操作: 修改列默认值(超级快,不影响表的所有数据): Query OK, 0 rows affected (0.07 sec) 添加索引 (需要时间, 但0 rows affected 表明表没有被复制): Query OK, 0 rows affected (21.42 sec) 改变列的数据类型(需要大量的时间和需要重建表中的所有行): Query OK, 1671168 rows affected (1 min 35.54 sec) 例如, 在一个大表运行一个DDL操作之前,你可能会检查操作是将快还是慢,如下所示: 克隆表结构。 用少量数据填充克隆的表。 在克隆的表运行DDL操作。 检查 “行受影响”的值是否为零或不是。一个非零值意味着操作需要重建整个表,这可能需要特殊的规划。例如,你可能在计划停机期间做DDL操作,或在复制每个从服务器。
主要的意思就是说,在做DDL操作的时候,可以通过检查rows affected是否为0来判断是否做了copying data操作。在5.1built in,5.5,5.6下分别做了几个测试。
#5.1 built in innodb
mysql> alter table t2 add index idx_title(title); Query OK, 1 row affected (0.01 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> alter table t2 alter title set default 'brce'; Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> alter table t2 change title3 title4 varchar(30);
Query OK, 1 row affected (0.01 sec) Records: 1 Duplicates: 0 Warnings: 0
mysql> alter table t2 add column title5 varchar(30);
Query OK, 1 row affected (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 0
#5.5
mysql> alter table bus add index idx_name(name); Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> alter table bus add column(title varchar(30)); Query OK, 785 rows affected (0.14 sec) Records: 785 Duplicates: 0 Warnings: 0 mysql> alter table bus alter name set default 'brce'; Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> alter table bus change title title_new varchar(40); Query OK, 785 rows affected (0.13 sec) Records: 785 Duplicates: 0 Warnings: 0
#5.6
mysql> alter table t1 add index idx_a(a); Query OK, 0 rows affected (0.43 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> alter table t1 change a a_new int; Query OK, 0 rows affected (0.20 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> alter table t1 add column b int; Query OK, 0 rows affected (0.84 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> alter table t1 alter b set default 1; Query OK, 0 rows affected (0.08 sec) Records: 0 Duplicates: 0 Warnings: 0
从上面简单测试可以看到,在线DDL的“宽容度”越来越高,buitin<plugin<5.6.
在对大表做DDL操作的时候,或许不知道此操作是否会发生copying data操作,此时可以先建一个同结构的表tmp,导入少量数据然后对tmp做DDL,操作,查看rows affected返回值,如果确认会copying data,那就需要酌情考虑别的方法了。
pt出品的在线DDL工具有些人在用,淘宝也有相应的开源工具,在非关键业务下可以尝试。