MySQL5.6 ALTER TABLE 分析和测试
2015-12-14 16:51
615 查看
在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和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开始,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不适用 |
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>
相关文章推荐
- Solr 5.2.1 部署并索引Mysql数据库
- mysql 主从复制及相关故障说明
- MySql的字符串“=”查询优化
- MySQL存储过程及触发器
- Navicat 链接虚拟机MySQL失败(GRANT ALL PRIVILEGES)
- Liunx 导入MySQL数据库
- mysql时间加减
- 用hibernate连接mysql插入数据出错ConstraintViolationException
- MySQL性能优化的最佳20+条经验
- mysql表的死锁解决
- Mysql下的数据库备份
- mysql--windows忘记密码
- 找到一篇比较全面的解决mysql最大连接数Too many connections问题的帖子
- keepalived+Mysql主从配置实验
- MySQL Study之--mysqladmin工具应用
- MySQL Study之--mysqladmin工具应用
- mysql 服务安装 到windows服务 管理中
- MySQL优化大全
- MySql目录没有data文件夹怎么办
- Mysql 别名的使用方法