mysql oldaltertable_MySQL5.6 ALTER TABLE 分析和测试

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值