iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >mysql修改字段的长度是否会锁表
  • 781
分享到

mysql修改字段的长度是否会锁表

mysql数据库java 2023-09-17 05:09:27 781人浏览 独家记忆
摘要

结论: 缩小字段长度不能使用inpalce,会锁表。放大字段长度:取决于变化前和变化后是否跨越255这个长度。以UTF8编码为例,一个字符占3个字节。字段变化1:varchar(50)--》varch

结论:

缩小字段长度不能使用inpalce,会锁表。放大字段长度:取决于变化前和变化后是否跨越255这个长度。以UTF8编码为例,一个字符占3个字节。字段变化1:varchar(50)--》varchar(80),不锁表。字段变化2:varchar(100)->varcahr(130),不表。字段变化3:varchar(50)--》vachar(130),会锁表;50*3=150个字节,130*3=390字节,这个变化跨越了255长度,会锁表。

缩小字段长度示例

本文实验的Mysql版本是5.7
本文操作的t_customer_copy1表的数据量有1000w+。
缩小phone字段的长度由varchar(512)修改长度至varchar(256).
alter table t_customer_copy1 modify column phone varchar(256), alGorithm=copy;
改小字段的长度algorithm不能选择inplace。
进行上述操作后,耗时情况:1047.06s,大概18分钟
在这里插入图片描述

在这个操作的过程中,不能对表里的数据进行修改,查询不受影响。在这里插入图片描述

大数据库字段长度示例

使用t_customer_copy1表,数据量有1000万。
将字段phone varchar(256)扩大到varchar(512)
alter table t_customer_copy1 modify column phone varchar(512);
耗时0.73s。
将字段 relate_id varchar(64)扩大到varchar(90),耗时1044s,17min。
大家可能印象中有256的概念,这个256并不是指定义的字符串的长度,而是这个字段存储占的字节个数.
字段的长度是以字节为单位存储,utf8一个字符需要三个字节。0~255字节以内的长度可以使用一个byte存储。
大于255个字节的长度则需要使用2个byte存储。大家可能印象中有256的概念,这个256并不是指varchar(256).

**online ddl **
algorithm={copy|inplace}
LOCK={NONE|SHARED|DEFAULT|EXCLUSIVE} 表的锁定方式
NONE:允许并发查询和DML(数据库操作语言,INSERT、UPDATE、DELETE)操作;
SHARED:允许并发查询;
DEFAULT:允许尽可能的并发查询和DML操作;
EXCLUSIVE:不允许并发查询和DML操作。
COPY方式:
这是InnoDB最早期支持的方式,主要实现步骤:

  1. 创建与原表结构定义一致的临时表;
  2. 对原表加锁,不允许执行DML,但允许查询;
  3. 在临时表上执行DDL语句;
  4. 逐行拷贝原表数据到临时表;
  5. 原表与临时表进行RENAME操作,此时会升级原表上的锁,不允许读写,直至完成DDL操作;

in-place方式:
只支持字段的字节长度变化在0~255和256到更大值这两个区间内变化。扩大字段长度跨越上述这个区间,就会使用copy。
执行alter table t_customer_copy1 modify column phone varchar(512), algorithm=inplace,LOCK=NONE;不支持inplace,执行语句会提示不支持。
缩小字段长度不支持inplace.

MDL

所有方式做 DDL 均会产生 MDL(metadata lock)。除了 copy 模式会有持续性的锁(DDL 的整个过程期间无法向该表写入任何数据)之外,其他方式的 MDL 均为短暂的锁。

除了 copy 模式之外的所有模式,MDL 如下:

在 DDL 的开始阶段,申请该表的 EXCLUSIVE-MDL 锁,禁止读写
降级 EXCLUSIVE-MDL 锁,允许读写
在 DDL 的最终 COMMIT 阶段,升级 EXCLUSIVE-MDL 锁,禁止读写
其中的阶段一和阶段三,其 MDL 的持续时间都是非常短暂的,也就是申请到了 MDL 锁之后会在很快的时间(一般小于一秒)处理完成相关操作并释放锁,一般情况下是不会影响业务的。只有阶段二是真正在处理数据,持续时间一般较长。

但是,有可能出现在阶段一和阶段三,无法申请到 MDL 的情况。这是因为 MDL 和所有的读写语句都可能会产生冲突,如果是在申请 MDL 的时候,之前有读写的事务一直没有执行完成(或者执行完成之后一直没有 COMMIT),MDL 就会无法立刻申请到,这个时候,DDL 语句,以及所有在该 DDL 语句之后的读写事务,都会阻塞并等待之前的读写事务完成,导致整个实例处于不可用状态。这个时候 SHOW PROCESSLIST 看到的语句状态为 waiting for metadata lock。

由于目前所有的 DDL 语句都会产生 MDL,无法避免,因此,在执行 DDL 操作期间,尽可能确保不要有未执行完成的长事务。如果发生了 warting for metadata lock 导致的阻塞,一般有以下三种处理方法:

耐心等待之前的事务全部执行完成
将之前未执行完成的事务全部 kill 掉
kill 掉 DDL 语句

参考博客:https://www.cnblogs.com/zmc60/p/14533123.html

来源地址:https://blog.csdn.net/yuanlairuci1992/article/details/126886422

您可能感兴趣的文档:

--结束END--

本文标题: mysql修改字段的长度是否会锁表

本文链接: https://www.lsjlt.com/news/410496.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作