字段长度扩容大冒险:MySQL的Inplace与Copy之辩

字段增肥

今天,我们来讨论一个看似简单,但实际上令无数MySQL管理员和开发者头疼不已的话题—— 修改VARCHAR字段长度!是的,这听起来就像是在搬家时决定要不要把那箱旧杂志也一起扛着走那么无聊。但别被它的外表所迷惑,因为这个小小的操作,往往会引发一场内部的“战争”!

想象一下,MySQL内部的两支阵营正在就"字段长度变更"这个问题激烈地争论着。一方是Inplace军团,他们坚持现行的做法,就地修改字段长度,免去了数据挪移的麻烦。而另一方则是Copy特遣队 ,他们则认为这种做法太过简单粗暴,复制整张表数据才是王道。

双方各执一词,你来我往,争论不休。有时候连MySQL自己也搞不清它到底应该选择哪一种方案!这就好比你在家里重新布置客厅,究竟是把现有的家具挪一挪,还是直接扔了重买?

无论最终MySQL如何抉择,都免不了遭到一方的指责和谩骂。有时它会暗自担心:”我到底做错了什么?“但无论如何,每次字段长度变更都必将上演一场令人哭笑不得的闹剧。面对这出falvour comedy,我们不如就暂且坐下来,好好品味一番其中的讽刺和荒诞吧!(咳咳😆,整点废话凑篇幅,让我们进入今天的话题吧!)

数据小实验

假如我们数据库中存在表t_0322

create table t_0322
(
  id bigint primary key,
  a varchar(30),
  b varchar(64)
);

|id |a  |b  |
|---|---|---|
|1  |abc|def|
|2  |iop|jkl|
|3  |hjl|dfg|

有一天,开发同学急匆匆找上门,说字段a长度不够用了,需要你帮忙扩充到60,此时你会怎么做了?是直接修改还是使用其他DDL变更工具?是立马修改还是等到业务低峰期再扩容?

答案是直接改。但是为什么呢?不会重建表吗?不会影响业务吗?带着疑问,我们进入今天的实验环节。

为了更直观地观察表空间文件的变化,我们首先开启一个文件变化监控进程,监控当前数据库amias的数据目录。

![[Pasted image 20240322154337.png]]

然后,我们生成上述示例表和数据,可以看到,文件变化情况如下:
![[Pasted image 20240322154535.png]]

接着,我们来执行字段长度变更脚本,修改字段avarchar(60)

alter table t_0322 modify a varchar(60);

字段很快便修改好了,而且可以看到文件并没有发生变化。其实此时MySQL在修改字段长度时使用了inplace算法。
![[Pasted image 20240322154922.png]]

但这时开发同学的需求又变了,是将字段a修改为varchar(80)。这时,你想到刚才将字段长度扩充到60的时候并没有新建表,要不还是直接改吧?

alter table t_0322 modify a varchar(80);

细心的你发现,这次修改花的时间久了一些。刚开始创建了#sql-200e21_629.ibd ,最后又删了。其实这时MySQL在修改字段长度时使用了copy算法,也就是创建临时表,把数据copy过去,最后交换名字,删除旧表。如果要修改的表是张大表的话,肯定要花费很久的时间,虽然MDL加锁时间很短,并不会影响该表正常读写,但是如果涉及主从架构的话,产生主从延迟是不可避免的了。

![[Pasted image 20240322161402.png]]

这时候,糟糕的开发同学又急匆匆地跑来了,说刚才字段长度说错了,其实计划修改为varchar(200),那这时候你该怎么办呢?

答案是直接改。

alter table t_0322 modify a varchar(200);

你发现这次并没有新建表,也是用了inplace
![[Pasted image 20240322162958.png]]

其实,varchar这种变长类型在255个字节内需要额外一个字节编码长度,超过255则需要2个字节,所以在utf8mb4下:

  • 在(0, 63]区间内,增加字段长度,可以inplace,不需要新建表。
  • 在[64, 16383] 区间内,增加长度,也可以inplace,不需要新建表。
  • 但是如果跨这两个区间,增加长度,则只能copy,需要创建临时表。

但是如果是缩短字段长度呢?

只要是缩短字段长度,只能copy,所以需要新建表。

alter table t_0322 modify a varchar(188);

![[Pasted image 20240322164054.png]]

结束语

就这样,通过一系列的小实验,我们揭开了MySQL在修改VARCHAR字段长度时,内部算法选择的神秘面纱。

我们需要因地制宜,审慎评估每一次字段变更操作可能带来的影响,并制定相应的变更策略和预案。

毕竟在这个数据决定一切的时代,一个小小的字段变更,都可能引发连锁反应,影响无垠。所以,让我们在运维管理工作中精雕细琢,避免踩坑,争取在性能和可用性之间寻求平衡。

这条修行之路虽然漫长,但对于数据库从业者来说,一定是充满乐趣和挑战的。

  • 30
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值