一震网

一震网

Mysql Online DDL之VARCHAR字段扩容探索

admin
Mysql Online DDL之VARCHAR字段扩容探索-第1张-游戏资讯-一震网

前言:

现时小伙伴们对“魔兽世界85级数据库”大致比较关注,看官们都需要学习一些“魔兽世界85级数据库”的相关文章。那么小编也在网上网罗了一些关于“魔兽世界85级数据库””的相关资讯,希望大家能喜欢,你们快快来了解一下吧!

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

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

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

mysql> select count(*) from sbtest1;+----------+| count(*) |+----------+| 10000000 |+----------+1 row in set (2.44 sec)

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

mysql>  alter table sbtest1 modify c3 varchar(11) not null default '';Query OK, 0 rows affected (0.32 sec)Records: 0  Duplicates: 0  Warnings: 0

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

mysql>  alter table sbtest1 modify c3 varchar(100) not null default '';Query OK, 10000000 rows affected (9 min 41.85 sec)Records: 10000000  Duplicates: 0  Warnings: 0

为什么会这样呢,同一个表,从长度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算法去做字段长度扩容了。

[mysql@localhost sbtest]$ du -sm *1       db.opt1       sbtest1.frm2944    sbtest1.ibd1       #sql-9212_6.frm2648    #sql-9212_6.ibd

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

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

Error:1799SQLSTATE:HY000(ER_INNODB_ONLINE_LOG_TOO_BIG)Message: Creating index 'idx_aaa' required more than 'innodb_online_alter_log_max_size' bytes of modification log. Please try again.

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

标签 魔兽世界85级数据库