在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>

mysql oldaltertable_MySQL5.6 ALTER TABLE 分析和测试相关推荐

  1. MySQL中的alter table操作之add/modify/drop列

    alter table的操作有增加列.删除列和修改列的长度等 create table t1 (c1 int primary key) engine = innodb; // 增加一个列c2 alte ...

  2. MySQL基础知识——ALTER TABLE

    点击关注上方"SQL数据库开发", 设为"置顶或星标",第一时间送达干货 ALTER TABLE的作用 ALTER TABLE命令用于添加.删除或者更改现有数据 ...

  3. MySQL修改数据表(ALTER TABLE语句)

    为实现数据库中表规范化设计的目的,有时候需要对之前已经创建的表进行结构修改或者调整. 在 MySQL 中可以使用 ALTER TABLE 语句来改变原有表的结构,例如增加或删减列.创建或取消索引.更改 ...

  4. 【转】【MySql】Waiting for table metadata lock原因分析

    MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景.而且,一旦alter table TableA的操作停滞在Wa ...

  5. alter table add column多个字段_SQL对表中字段的操作 alter

    ALTER TABLE 语句用于在现有表中添加.删除或修改列. 注意不同的数据库的语句有所不一样 增加和删除都基本一致. 进行修改表中字段的时候注意: 本文主要介绍 sqlserver/mysql/o ...

  6. 2、ALTER TABLE:修改数据表

    修改数据表的前提是数据库中已经存在该表.修改表指的是修改数据库中已经存在的数据表的结构.修改数据表的操作也是数据库管理中必不可少的,就像画素描一样,画多了可以用橡皮擦掉,画少了可以用笔加上. 不了解如 ...

  7. MySQL出现Waiting for table metadata lock的原因以及解决方法

    MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景.而且,一旦alter table TableA的操作停滞在Wa ...

  8. 【MySQL】MySQL出现Waiting for table metadata lock的原因、解决方法

    Waiting for table metadata lock MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景 ...

  9. MySQL ALTER TABLE报错Duplicate entry 'xxx' for key 'PRIMARY'解决方法

    在MySQL中执行加字段等操作时可能会报Duplicate entry 'xxx' for key 'PRIMARY'的错,例如: mysql> alter table test add aa ...

  10. MySQL 新增字段(alter table add column),报错:Duplicate entry

    问题 执行一个增加字段的DDL语句脚本时,报错,错误如下: Error 1062: Duplicate entry 'c51d3db8-59a5 2022-06-28 17:59:59' for ke ...

最新文章

  1. QNX Hypervisor管理程序
  2. mvvm模式和mvc的区别_mvvm 和 mvc 区别?
  3. No operations allowed after connection closed--转
  4. SpringBoot中操作spring redis的工具类
  5. Vue——全局element-resize-detector监听DOM元素
  6. linux stm32 ide,一文教你如何在ubuntu上快速搭建STM32 CubeIDE环境(图文超详细+文末有附件)...
  7. go语言mysql框架_超级详细:Go语言框架Gin和Gorm实现一个完整的待办事项微服务...
  8. Storm,Spark和Samza
  9. 【AD】如何将喜欢的图案导出成为丝印层和PCB形状
  10. 使用RIP协议处理不连续的子网和VLSM(一)
  11. 多通道卷积的参数数量计算
  12. 什么是低信噪比图像及处理方法
  13. c语言系统编程项目实训,《C语言程序设计》项目实训指导书.doc
  14. 一篇关于蜿蜒型河流的介绍
  15. cocos2d-x初步
  16. chan算法 matlab,TDOA定位的Chan算法MATLAB源代码
  17. 编程吸金榜:你排第几?网友神回应了 !
  18. 相机对焦和调焦距的区别是什么 ?
  19. CAD中如何布置火灾探测器?消防探测器范围计算
  20. latex:ieee摘要两端对齐

热门文章

  1. 用c#创建支持多语言的WinForm应用程序 .
  2. Linux中用st_mode判断文件类型
  3. tomcat的comet事件解释
  4. 关于Decorator模式
  5. vector 实现二维数组
  6. 【MyBatis】动态SQL中的参数判空
  7. layui option 动态添加_layui select如何动态添加option
  8. mysql 循环 索引值,mysql:循环遍历表和alter table添加索引
  9. erp系统原理和实施第五版pdf_ERP系统实施费用!
  10. python存数据到impala_0039-如何使用Python Impyla客户端连接Hive和Impala