mysql 扩容_Mysql Online DDL之VARCHAR字段扩容探索

从mysql5.6开始以后的版本,支持Online DDL,这个功能是mysql梦寐以求的功能,要知道在mysql5.6以前的版本,做DDL变更,可是会锁表,业务无法做DML操作,只能查询,其中痛苦,只有经历过的同学才会知道。

7f08fedf5a44e2aafae753b1670985ab.png

本文只探索Mysql5.7版本的 Online DDL之VARCHAR字段扩容操作,以前在生产做VARCHAR字段扩容时,发现有时候扩容操作非常快,基本在秒级就返回了,有时候扩容,要好几十秒,甚至好几分钟才返回,当时以为是业务表数据量导致的,后来注意到2个数据量差不多的表,做VARCHAR字段扩容操作,执行时间相差好几十倍时,才发现原来不仅仅是数据量的原因。

下面就来验证一下,首先用sysbench模拟出一张10000000条记录的表,sysbench安装很简单,这里就不做介绍了,不会的同学,可以在网上搜索一下

a651e15579d6442b6cadd257808040a2.png

首先,修改字段c3从varchar(10)变成varchar(11),如下所示

14b232a5f42e4534fd13096c2481655b.png

可以看到耗时320毫秒,秒级返回的。再看看将字段c3从varchar(11)变成varchar(100),如下所示

2b58e596c6ffbbcf85284fd8dc10aef4.png

为什么会这样呢,同一个表,从长度10到11,秒级返回,变成100时,执行时间竟然变成9分41秒,这时间也差得太多了。

于是去看了一下官方文档,看看是什么原因,原来varchar的字段,如果所占用的字节小于256时,用一个字节记录占用字段长度,并且修改字段长度时,默认的算法是inplace,允许并发DML,此时只需要修改表的元数据信息,即可完成字段长度变更。

在这里需要注意,如果你的表的字符集是utf8,那么varchar(1)是占用3个字节长度,utf8mb4,那么varchar(1)是占用4个字节长度,也即是说当数据库字符集为uft8时,列定义少于85,数据库字符集为uft8mb4时,列定义少于63,字段长度扩容时,算法是inplace,此时只需要修改表的元数据信息,秒级完成字段扩容。

可是当字段占用字节数超过255时,mysql会采用两个字节记录占用字段长度,这个时候,页内头部存储信息发生改变了,就只能采取copy算法去做字段长度扩容了。

c20c1b648e0686d89cee7ea324e7a66e.png

采用copy算法,可以看到生成了一个临时表(#sql-9212_6.ibd),因为要将原来老表的所有数据全部拷贝到新表中,所以时间会非常长。

在这里再多说一句,Mysql Online DDL是如何做到并发DML的,原来在做DDL期间,mysql会记录所有在此表上所有的DML操作,并将日志写到一个内存区域里,这个内存区域大小由innodb_online_alter_log_max_size控制,其默认大小为128M,如果产生的日志超出该容量大小,则会抛出类似如下的异常提示:

0b0120c4ceb3ef515b86dcfad2d2f3a1.png

导致你的DDL语句执行失败,如果想继续执行DDL语句,则需要调整innodb_online_alter_log_max_size参数,比较繁忙的数据库,此参数建议调整为512M。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值