背景介绍:
服务器 252G/40C SSD盘
mysql版本是5.6.25
表大小:CISXX_DATA_XXX 110908162 rows
第一次尝试直接加索引
mysql> alter table CISXX_DATA_XXX add column `RESERVED1` varchar(20) NOT NULL DEFAULT '' COMMENT '预留字段1',
-> add column `RESERVED2` varchar(20) NOT NULL DEFAULT '' COMMENT '预留字段2',
-> add column `RESERVED3` varchar(20) NOT NULL DEFAULT '' COMMENT '预留字段3';
ERROR 1878 (HY000): Temporary file write failure.
由于表太大,产生的临时表已经超出了 /目录下的磁盘限制。
第二次尝试新建表
修改新表结构,然后通过insert….select….方式导入数据
create table tmp_CISXX_DATA_XXX_20160620 (……);
insert into tmp_CISXX_DATA_XXX_20160620(….)select … from CISXX_DATA_XXX;
在数据导入的过程中,新开一个会话。测试本次建表过程对cis_data_tag表加的是什么锁。测试结果如下图:
由此可知,通过这种方式给cis_data_tag加的是一个共享锁。
在数据导入的过程中
服务器的负载如下:
磁盘读写压力情况:
在导数过程中发现/目录下的磁盘空间还是报警了
于是kill掉导数进程,执行kill掉操作后,发现服务器上的内存和磁盘使用率还是在不断上涨。于是再次尝试kill。
再次尝试还是失败。如果系统资源一直这么消耗小去,可能会导致服务器挂机。但后来发现,磁盘空间到达100%时,该导数进程就被服务器给终止掉了,内存和磁盘空间资源开始释放。
第三次尝试修改
因为要操作的表实在太大。而/的磁盘空间又实在太小,为了避免影响产线业务,在第二次修改的基础上,更改mysql临时空间的设置。于是整理了如下的解决方案
检查修改前中
内存的使用率一直在上涨,增长了72G
临时目录所在磁盘目录一直在上涨,增长了72G
磁盘的读写率达到了589836.00 wsec/s 172812.00 rsec/s
该表所占的物理文件大小也就48G
在建索引的过程中,发现mysql居然支持在线DDL操作,即不会堵塞其它请求。请看:
这真的是个非常非常伟大的发现,mysql果然进步了。但是听说mysql只有部分表结构的修改是支持在线的,真是遗憾。
翻阅官方文档,可以了解更详细的信息:
修改一张2千万的表添加字段和加索引所需的时间参考:
修改一张一亿的表添加字段和加索引所需的时间参考: