在MySQL5.5和之前版本,在运行的生产环境对大表(超过数百万纪录)执行Alter操作是一件很困难的事情。因为将重建表和锁表,影响用户者的使用。因此知道Alter操作何时结束对我们是非常重要的.甚至当执行Create index的时候.如果启用了 fast_index_creation,则不会重建表,但是仍然会锁表。fast_index_creation特性引进在MySQL5.5和更高版本里。在MySQL5.1中如果使用了innodb plugin则也可以使用该特性。
 
自从MySQL5.6开始,Online DDL特性被引进。他增强了很多种类的Alter Table操作避免拷贝表和锁表,在运行Alter操作的同时允许运行select,insert,update,delete语句。因此在最新版本,我们可以通过使用ALGORITHM和LOCK选项抑制文件拷贝和加锁。但是即使在MySQL5.6,仍然有一些Alter操作需要重建表,比如增加/删除列,增加/删除主键,改变数据类型等。
 
 
MySQL5.6 Online DDL在线状态概况如下(Yes*和No*表明结果依赖于其他一些附加条件):
执行操作 允许ALGORITHM=INPLACE    
是否拷贝表   
允许并发DML     
允许并发查询
备注和注意事项
create index
add index
Yes*
No*
Yes
Yes
对于全文索引,有一些限制,具体看下一行。目前,该操作不是在原地执行,需要拷贝表.
add fulltext index
Yes
No*
No
Yes
创建第一个全文索引涉及到拷贝表,除非有使用FTS_DOC_ID列。后面的全文索引则在原地执行。
drop index 
Yes
No
Yes
Yes
 
optimize table
Yes
Yes
Yes
Yes
在MySQL5.6.17里使用 ALGORITHM=INPLACE.

如果设置old_alter_table=1或使用mysqld --skip-new选项,则使用 ALGORITHM=COPY.

如果表使用了全文索引,则 ALGORITHM=INPLACE不适用
set default value for  column
Yes
No
Yes
Yes
修改.frm文件,不涉及数据文件
change auto-increment value
Yes
No
Yes
Yes
修改存储到内存的一个值,不修改数据文件
add  foreign key constraint
Yes*
No*
Yes
Yes
禁用foreign_key_checks,则可以避免拷贝表
drop  forgien key constraing
Yes
No
Yes
Yes
foreign_key_checks可以禁用或开启
rename  column
Yes*
No*
Yes*
Yes
允许并发DML,保持相同的数据类型,仅改变字段名
add  column
Yes
Yes
Yes*
Yes
增加auto-increment字段时不允许DML操作. 
虽然ALGORITHM=INPLACE可以允许, 
但是数据要重组,代价比较昂贵.
drop column
Yes
Yes
Yes
Yes
虽然ALGORITHM=INPLACE可以允许,
但是数据要重组,代价比较昂贵.
reorder columns
Yes
Yes
Yes
Yes
虽然ALGORITHM=INPLACE可以允许,
但是数据要重组,代价比较昂贵.
change ROW_FORMAT
property
Yes
Yes
Yes
Yes
虽然ALGORITHM=INPLACE可以允许,
但是数据要重组,代价比较昂贵.
change KEY_BLOCK_SIZE 
property
Yes
Yes
Yes
Yes
虽然ALGORITHM=INPLACE可以允许,
但是数据要重组,代价比较昂贵.
make column null 
Yes
Yes
Yes
Yes
虽然ALGORITHM=INPLACE可以允许,
但是数据要重组,代价比较昂贵.
make cplumn not null 
Yes*
Yes
Yes
Yes
当SQL_MODE为strict_all_tables,如果执行的列包含null,则会执行失败。

 
虽然ALGORITHM=INPLACE可以允许,
但是数据要重组,代价比较昂贵.
change data type 
of column
No
Yes
Yes
Yes
 
add primary key
Yes*
Yes
Yes
Yes
虽然ALGORITHM=INPLACE可以允许,
但是数据要重组,代价比较昂贵.
如果列必须转换为非空的条件下,
ALGORITHM=INPLACE是不允许的。
drop primary key 
and add other
Yes
Yes
Yes
Yes
当在同一个alter table新增主键时ALGORITHM=INPLACE是允许的.数据要重组,因此代价比较昂贵.
 
drop primary key
No
Yes
No
Yes
删除主键但是又不新增主键是被限制的
convert character set
No
Yes
No
Yes
如果新的字符编码不同将会重建表
specify character set
No
Yes
No
Yes
如果新的字符编码不同将会重建表
rebulid with 
force option
Yes
Yes
Yes
Yes
在MySQL5.6.17里使用 ALGORITHM=INPLACE.

如果设置old_alter_table=1或使用mysqld --skip-new选项,则使用 ALGORITHM=COPY.

如果表使用了全文索引,则 ALGORITHM=INPLACE不适用

rebulid with 
"null"
 
alter table ...
engine=innodb
Yes
Yes
Yes
Yes
在MySQL5.6.17里使用 ALGORITHM=INPLACE.

如果设置old_alter_table=1或使用mysqld --skip-new选项,则使用 ALGORITHM=COPY.

如果表使用了全文索引,则 ALGORITHM=INPLACE不适用

 
下面做测试,通过ALGORITHM=INPLACE和ALGORITHM=COPY两种不同算法下下分别删除和新增一个字段,ALGORITHM=INPLACE(online ddl)下删除和增加字段时可以进行DML操作,但是由于数据要重组,Alter时间比较长。而在ALGORITHM=COPY下因为要拷贝表和锁表,所以在执行过程中DML操作都会等待metadata lock,但是执行Alter时间要比ALGORITHM=INPLACE短很多。
 
1.ALGORITHM=INPLACE模式删除字段测试:
 
session 1:
13:55:11 pe> alter table product_2 ALGORITHM=INPLACE,drop column ext_1;
Query OK, 0 rows affected (42.18 sec)
Records: 0 Duplicates: 0 Warnings: 0
 
13:56:20 pe> 
 
session 2:
13:55:43 pe> update product_2 set category_id=5312 where id=621;
 
Query OK, 1 row affected (2.16 sec)
Rows matched: 1 Changed: 1 Warnings: 0
 
13:55:45 pe> insert into product_2(id,product_code,product_cname,product_ename,category_id) values(2000001,'000222222','cname','ename',100);
Query OK, 1 row affected (0.19 sec)
 
13:55:45 pe> delete from product_2 where id=2000001;
Query OK, 1 row affected (2.57 sec)
 
 
2.ALGORITHM=INPLACE模式添加字段测试:
 
session 1:
13:59:05 pe> alter table product_2 ALGORITHM=INPLACE,add column ext_1 char(10);
Query OK, 0 rows affected (42.98 sec)
Records: 0 Duplicates: 0 Warnings: 0
 
13:59:51 pe> 
 
session 2:
13:59:28 pe> update product_2 set category_id=5312 where id=621;
 
Query OK, 0 rows affected (2.37 sec)
Rows matched: 1 Changed: 0 Warnings: 0
 
13:59:30 pe> insert into product_2(id,product_code,product_cname,product_ename,category_id) values(2000001,'000222222','cname','ename',100);
Query OK, 1 row affected (0.00 sec)
 
13:59:30 pe> delete from product_2 where id=2000001;
Query OK, 1 row affected (2.50 sec)
 
13:59:32 pe> 
 
 
 
3.ALGORITHM=COPY模式删除字段测试:
session1:
13:59:32 pe> alter table product_2 ALGORITHM=COPY,drop column ext_1;
Query OK, 1999999 rows affected (20.91 sec)
Records: 1999999 Duplicates: 0 Warnings: 0
 
session2:
14:03:15 pe> update product_2 set category_id=5312 where id=621;
 
Query OK, 0 rows affected (16.80 sec)
Rows matched: 1 Changed: 0 Warnings: 0
 
14:03:32 pe> insert into product_2(id,product_code,product_cname,product_ename,category_id) values(2000001,'000222222','cname','ename',100);
Query OK, 1 row affected (0.00 sec)
 
14:03:32 pe> delete from product_2 where id=2000001;
Query OK, 1 row affected (1.61 sec)
 
14:03:33 pe> 
 
4.ALGORITHM=COPY模式添加字段测试:
session1:
14:06:40 pe> alter table product_2 ALGORITHM=COPY,add column ext_1 char(10);
Query OK, 1999999 rows affected (21.77 sec)
Records: 1999999 Duplicates: 0 Warnings: 0
 
session2:
 
14:03:33 pe> update product_2 set category_id=5312 where id=621;
 
Query OK, 0 rows affected (11.90 sec)
Rows matched: 1 Changed: 0 Warnings: 0
 
14:07:28 pe> insert into product_2(id,product_code,product_cname,product_ename,category_id) values(2000001,'000222222','cname','ename',100);
Query OK, 1 row affected (0.00 sec)
 
14:07:28 pe> delete from product_2 where id=2000001;
Query OK, 1 row affected (1.71 sec)
 
14:07:29 pe> 
 
processlist:
987835 root localhost pe Query 7 Waiting for table metadata lock update product_2 set category_id=5312 where id=621
 
 
MySQL 5.6 Alter Table 常用场景测试:
 
MySQL 5.6的Alter Table有ALGORITHM=INPLACE和ALGORITHM=COPY两种不同算法。使用ALGORITHM=INPLACE可以允许在执行AlterDe时候并发执行DML语句。但是耗费的代价也比较大,在这种模式下Alter时间约是ALGORITHM=COPY算法的2倍左右。
如下测试:在5.6中,Alter Table首选使用ALGORITHM=INPLACE算法。其中加字段,加索引,加主键,字段设置默认值都允许在Alter的同时进行DML操作,而更改字段类型则要锁表。
 
1.加字段
 
session1:
17:03:40 pe> alter table product_2 add column ext_1 char(10);
Query OK, 0 rows affected (42.52 sec)
Records: 0 Duplicates: 0 Warnings: 0
 
17:04:31 pe> 
 
session2:
17:03:50 pe> update product_2 set category_id=5312 where id=621;
 
Query OK, 0 rows affected (2.09 sec)
Rows matched: 1 Changed: 0 Warnings: 0
 
17:03:54 pe> insert into product_2(id,product_code,product_cname,product_ename,category_id) values(2000001,'000222222','cname','ename',100);
Query OK, 1 row affected (0.15 sec)
 
17:03:54 pe> delete from product_2 where id=2000001;
Query OK, 1 row affected (1.69 sec)
 
17:03:56 pe> 
 
 
2.加索引
 
session1:
17:12:34 pe> alter table product add index idx_1(category_id);
Query OK, 0 rows affected (49.38 sec)
Records: 0 Duplicates: 0 Warnings: 0
 
17:13:38 pe> 
 
session2:
17:12:51 pe> update product set category_id=5312 where id=621;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
 
17:12:52 pe> insert into product(id,product_code,product_cname,product_ename,category_id) values(20000001,'000222222','cname','ename',100);
Query OK, 1 row affected (0.01 sec)
 
17:12:52 pe> delete from product where id=2000001;
Query OK, 1 row affected (0.05 sec)
 
17:12:53 pe> 
 
3.加主键
 
session1:
17:38:15 pe> alter table product_2 add primary key(id);
Query OK, 0 rows affected (47.42 sec)
Records: 0 Duplicates: 0 Warnings: 0
 
17:39:48 pe>
 
session2:
17:39:03 pe> update product_2 set category_id=5312 where id=621;
 
Query OK, 0 rows affected (2.07 sec)
Rows matched: 1 Changed: 0 Warnings: 0
 
17:39:07 pe> insert into product_2(id,product_code,product_cname,product_ename,category_id) values(20000001,'000222222','cname','ename',100);
Query OK, 1 row affected (0.00 sec)
 
17:39:07 pe> delete from product_2 where id=2000001;
Query OK, 0 rows affected (1.66 sec)
 
17:39:09 pe> 
 
 
4.设置默认值,只改变.frm文件,很快
17:20:48 pe> alter table product_2 modify ext_1 char(10) default 'test';
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
 
 
5.更改字段类型,会锁表
session1:
17:22:22 pe> alter table product_2 modify ext_1 datetime;
Query OK, 1999999 rows affected (24.90 sec)
Records: 1999999 Duplicates: 0 Warnings: 0
 
17:28:34 pe> 
 
session2:
17:28:12 pe> update product_2 set category_id=5312 where id=621;
Query OK, 0 rows affected (22.97 sec)
Rows matched: 1 Changed: 0 Warnings: 0
 
17:28:37 pe> 

MySQL5.6 ALTER TABLE 分析和测试的更多相关文章

  1. MySQL--当mysqldump --single-transaction遇到alter table(2)

    在上篇<MySQL--当mysqldump --single-transaction遇到alter table>中测试发现,在MySQL 5.6版本中,如果在mysqldump期间修改表, ...

  2. 【SQL篇章】【SQL语句梳理 :--基于MySQL5.6】【已梳理:ALTER TABLE解析】

    ALTER TABLE 解析实例: SQL: 1.增加列 2.增加列,调整列顺序 3.增加索引 4.增加约束 5.增加全文索引FULL-TEXT 6.改变列的默认值 7.改变列名字(类型,顺序) 8. ...

  3. MySQL ALTER TABLE语法

    先看一下定义(密密麻麻) ALTER TABLE tbl_name [alter_specification [, alter_specification] ...] [partition_optio ...

  4. MySQL alter table时执行innobackupex全备再看Seconds_Behind_Master

    1.场景描述 早上7:25 接到Report中心同学告警,昨天业务报表数据没有完整跑出来,缺少500位业务员的数据,并且很快定位到,缺少的是huabei_order库上的数据.Report中心的数据是 ...

  5. 【转载】alter table move 和 alter table shrink space的区别

    move 和shrink 的共同点1.收缩段2.消除部分行迁移3.消除空间碎片4.使数据更紧密 shrink 语法:  alter table TABLE_NAME shrink space [com ...

  6. [每日一题] OCP1z0-047 :2013-07-26 alter table set unused之后各种情况处理

    有疑问可以去itpub讨论:http://www.itpub.net/thread-1804872-1-1.html 对于alter table setunused的用法,查官方文档: alter_t ...

  7. MySQL--当mysqldump --single-transaction遇到alter table

    部分生产环境采用mysqldump --single-transaction的方式在夜间进行数据库备份,而同事恰好在备份期间执行了alter table操作,操作部分成功部分失败,为啥呢? 在mysq ...

  8. MySQL--当mysqldump --single-transaction遇到alter table(1)

    部分生产环境采用mysqldump --single-transaction的方式在夜间进行数据库备份,而同事恰好在备份期间执行了alter table操作,操作部分成功部分失败,为啥呢? ##=== ...

  9. 曲演杂坛--使用ALTER TABLE修改字段类型的吐血教训

    --===================================================================== 事件起因:开发发现有表插入数据失败,查看后发现INT类型 ...

随机推荐

  1. POJ 2265 Bee Maja (找规律)

    题目链接 题意 : 给你两个蜂巢的编号,给你一个的编号让你输出在另外一个蜂巢中对应的编号. 思路 : 先将蜂巢分层,第一层一个数,第二层6个数,第三层12个数…………然后用公式表示出第n层的最后一个数 ...

  2. 2014多校第一场 E 题 || HDU 4865 Peter's Hobby (DP)

    题目链接 题意 : 给你两个表格,第一个表格是三种天气下出现四种湿度的可能性.第二个表格是,昨天出现的三种天气下,今天出现三种天气的可能性.然后给你这几天的湿度,告诉你第一天出现三种天气的可能性,让你 ...

  3. listview优化 汇总

    1,listview加载性能优化ViewHolder 转自: http://blog.csdn.net/jacman/article/details/7087995 在android开发中Listvi ...

  4. JAVA容器

    JAVA容器 一.容器体系结构 java.util 二.迭代器Iterator<E> 迭代器是一种设计模式,可以遍历并选择序列中的对象,而开发人员并不需要了解该序列的底层结构.迭代器通常被 ...

  5. AngularJS学习笔记1——什么是AngularJS?

    Angular JS是一个由Google维护的开源的Javascript框架,主要作者为: Misko Hevery(angular JS之父, Sr. Computer Scientist at G ...

  6. CentOS7区域设置

    区域设置的配置文件在/etc/locale.conf,通过localectl命令进行设置: systemd服务在启动的时候读取区域配置文件,完成系统的设置. 命令的几个常用方法如下: 1 查看当前配置 ...

  7. 8天学通MongoDB

    随笔分类 - MongoDB 双十一来了,别让你的mongodb宕机了 摘要: 好久没过来吹牛了,前段时间一直赶项目,没有时间来更新博客,项目也终于赶完了,接下来就要面临双十一这场惊心动魄的处女秀考验 ...

  8. Oracle ->> ENABLE VALIDATE & DISABLE VALIDATE

    这里找到一篇博文对这两个用法的解释:http://www.cnblogs.com/rootq/archive/2008/09/23/1297400.html 启用约束: enable( validat ...

  9. [c/c++]指针数组 pk 数组指针

    首先强调 指针数组归根结底是个数组:数组指针归根结底是个指针. 数组指针 以int (*int)[10]为例 ()的优先级大于[],因此首先它是一个指针,它指向一个数组,数组的维数是10.因此数组指针 ...

  10. linux系统的 suid/guid简单介绍 linux suid guid

    我们在前面曾经提到过s u i d和g u i d.这种权限位近年来成为一个棘手的问题.很多系统供应商不允许实现这一位,或者即使它被置位,也完全忽略它的存在,因为它会带来安全性风险.那么人们为何如此大 ...