MySQL扩展varchar字段长度能否Online DDL

news/2024/11/21 18:23:53/

目录

问题场景

DDL%20%E7%AE%80%E4%BB%8B-toc" style="margin-left:0px;">Online DDL 简介

场景复现

DBdoctor%E5%BF%AB%E9%80%9F%E8%AF%86%E5%88%AB%20Online%20DDL-toc" style="margin-left:0px;">DBdoctor快速识别 Online DDL

总结


问题场景

在MySQL数据库中,DDL变更可以通过两种算法实现:Copy算法和In-Place算法。Copy算法会复制整个表,这可能导致长时间的写入阻塞,从而严重影响业务运行。相比之下,In-Place算法直接在现有表上进行结构修改,通常锁定时间较短,因此对业务的干扰也较小。由于In-Place算法几乎不需要锁定表,它通常被称为Online DDL。判断哪些SQL不支持Online DDL,成为DBA 面临的一大挑战。

大家看下面这条SQL在大表DDL变更时,会不会长时间阻塞写入?

alter table test_tb modify name varchar(128) default '' not null comment '创建人';

表test_tb 的charset为utf8mb4,字段name原类型为varchar(32)。官方文档中扩展varchar长度是支持Online DDL的,但是最近开发同学却遇到了问题。

某个版本上线一段时间后,发现一个表的两个varchar字段的长度不够用,开发紧急上线数据库脚本扩展字段长度,而在执行过程中,修改第一个字段很快就执行完了,修改第二个字段时执行时间较长,执行时间段内业务有告警写入失败,对应功能界面全部转圈,收到用户投诉。

数据库版本为MySQL 5.7,表结构如下:

create table k8s_auth_server.paas_role_list(id              bigint                         not null primary key,creator         varchar(16) default ''        not null comment '创建人',role_name       varchar(32)                    not null comment '角色英文名称',...)comment '平台角色表' collate = utf8mb4_general_ci;

扩展字段长度SQL如下:

alter table k8s_auth_server.paas_role_list modify creator varchar(32) default '' not null
comment '创建人';
alter table k8s_auth_server.paas_role_list modify role_name varchar(128) not null comment'角色英文名称';

同样是修改字段长度,为什么修改字段creator很快,而修改字段role_name 特别慢呢?

DDL%20%E7%AE%80%E4%BB%8B">Online DDL 简介

在MySQL 5.6 版本之前,所有的DDL变更都需要锁表,导致大量线程处于“Waiting for meta data lock”的状态,5.6版本引入Online DDL新特性,部分DDL 变更不需要锁表,引入算法In-Place和Copy(8.0增加Instant),其中 Instant,In-Place可以实现无锁变更。

  • Copy:建一张新表,并将表数据逐行从原始表复制到新表,复制阶段全程不允许并发DML。

  • In-Place:尽量避免复制表数据,但可能会在原地重建表。在操作的准备和执行阶段,可以短暂地对表进行独占元数据锁定。通常支持并发DML(全文索引和空间索引例外)。

  • Instant:操作仅修改数据字典中的元数据。在操作的执行阶段,可以短暂地对表进行独占元数据锁定。表数据不受影响,允许并发DML。

Copy算法和In-Place算法各阶段加锁情况对比如下,可以看到In-Place算法仅在开始和结束时短时间阻塞写入,而Copy算法在变更阶段全程阻塞写入。

图片

Online DDL的变更原理这里不再详细描述,在MySQL 5.7 官方文档中,对于字段相关的Online DDL支持如下:

图片

可以看到扩展varchar字段长度支持In-Place算法,但实际表现为什么和官方文档中不一致呢?

继续往下看,文档中对扩展varchar字段长度有额外说明:

  • The number of length bytes required by a VARCHAR column must remain the same. For VARCHAR columns of 0 to 255 bytes in size, one length byte is required to encode the value. For VARCHAR columns of 256 bytes in size or more, two length bytes are required. As a result, in-place ALTER TABLE only supports increasing VARCHAR column size from 0 to 255 bytes, or from 256 bytes to a greater size. In-place ALTER TABLE does not support increasing the size of a VARCHAR column from less than 256 bytes to a size equal to or greater than 256 bytes. In this case, the number of required length bytes changes from 1 to 2, which is only supported by a table copy (ALGORITHM=COPY)

翻译下就是只有256 字节内的变更才支持In-Place算法,超过这个长度只能使用Copy算法,换言之需要锁表。

文档中有提示:

  • The byte length of a VARCHAR column is dependant on the byte length of the character set

也就是使用In-Place算法扩展varchar类型的长度限制,和字段的字符集有关。

mysql> show charset where Charset in ('latin1', 'utf8', 'utf8mb4');+---------+----------------------+--------------------+--------+| Charset | Description          | Default collation  | Maxlen |+---------+----------------------+--------------------+--------+| latin1  | cp1252 West European | latin1_swedish_ci  |      1 || utf8    | UTF-8 Unicode        | utf8_general_ci    |      3 || utf8mb4 | UTF-8 Unicode        | utf8mb4_general_ci |      4 |+---------+----------------------+--------------------+--------+3 rows in set (0.00 sec)

常见的字符集utf8一个字符需要3个字节,utf8mb4需要4个字节,即 utf8 的varchar(86)及以上,utf8mb4 的varchar(64)及以上不支持In-Place算法,不支持 Online DDL

场景复现

一张utf8mb4的测试表

create table testmb4(id              bigint                         not null primary key,creator         varchar(16) default ''        not null comment '创建人',role_name       varchar(32)                    not null comment '角色英文名称') charset = utf8mb4 collate = utf8mb4_general_ci;

变更字段 creator

mysql> alter table testmb4 modify creator varchar(32) default '' not null comment '创建人', ALGORITHM = INPLACE;
Query OK, 0 rows affected (0.10 sec)
Records: 0  Duplicates: 0  Warnings: 0

变更字段 role_name

mysql> alter table testmb4 modify role_name varchar(128) default '' not null comment '角色英文名称', ALGORITHM = INPLACE;
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY.

果然,utf8mb4的字段将varchar(32)变至varchar(128)不再支持In-Place算法。

测试支持In-Place算法的边界:


mysql> alter table testmb4 modify role_name varchar(64) default '' not null comment '角色英文名称', ALGORITHM = INPLACE;
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY.
mysql> alter table testmb4 modify role_name varchar(63) default '' not null comment '角色英文名称', ALGORITHM = INPLACE;
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0

经验证,utf8mb4的varchar类型字段,变更长度大于等于64时,不再支持In-Place算法。

DBdoctor%E5%BF%AB%E9%80%9F%E8%AF%86%E5%88%AB%20Online%20DDL">DBdoctor快速识别 Online DDL

Online DDL包含表、字段、索引等多个场景,DBA也很难全部识别。线上DDL变更更是个挑战。但是DBdoctor提供的免费SQL审核工具可以简化这一过程。只需将多条DDL变更的SQL放入审核窗口内,就可快速识别不支持Online DDL的SQL语句。

上传SQL

图片

点击审核

图片

审核详情中出现:DDL语句不支持Online DDL

图片

总结

扩展varchar字段长度虽然支持In-Place算法,但是有一定限制,长度若大于等于256 byte则不支持Online DDL,utf8对应varchar(86),utf8mb4对应varchar(64)。面对Online DDL的众多场景,DBdoctor免费的SQL审核功能可以快速识别Online DDL,支撑线上DDL变更,有效预防锁表问题,欢迎小伙伴们下载体验!

*************************************************************************************************************

免*费下载,一键部署:DBdoctor-数据库性能诊断


http://www.ppmy.cn/news/1548820.html

相关文章

WPF下 DataGrid加入序号列

先上代码&#xff1a; <DataGrid Name"DGV" AutoGenerateColumns"False" Grid.Row"0" Grid.Column"0" HorizontalGridLinesBrush"RoyalBlue" VerticalGridLinesBrush"Tomato" CanUserAddRows"False&qu…

第十种Prompt 框架-MASTER

俺滴个娘嘞&#xff0c;咋能有九种Prompt框架捏&#xff1f;-CSDN博客啥是prompt? 往低说是说人话在于沟通目标和结果&#xff0c; 往高了居然有点哲学味道&#xff08;要不怎么叫spell&#xff09;&#xff0c;so 居然有九种Prompt框架....俺滴个娘嘞&#xff0c;咋能有九种P…

ImportError: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.29‘ not found

3.一、编译安装make 以make4.2 2.2.1为例 1.下载make wget https://ftp.gnu.org/gnu/make/make-4.2.tar.gz 2.解压make4.2安装包 tar -zxvf make-4.2.tar.gz && cd make-4.2 3.编译安装make-4.2 ./configure --prefix/usr/local/make4.2 make && make …

go channel select 语句使用

在 Go 语言中&#xff0c;select 语句用于在多个通道操作中进行选择。它的工作机制类似于 switch 语句&#xff0c;但专门用于处理通道操作。select 语句可以同时等待多个通道操作&#xff0c;并在其中一个通道准备好时执行相应的分支。 select 的基本用法 以下是 select 的基…

Adobe Illustrator(Ai)修图软件入门操作参考,收集查过的各个细节用法

到现在&#xff0c;对于Ai的使用也是一半一半&#xff0c;基本上都是用到啥就查啥。因为用得也不是很频繁&#xff0c;脑子也记不住很多操作&#xff0c;所以有时候靠肌肉记忆&#xff0c;很多时候&#xff0c;得再百度一遍…… 所以 我在这再备份一下&#xff0c;做个搬运工 …

Flutter:key的作用原理(LocalKey ,GlobalKey)

第一段代码实现的内容&#xff1a;创建了3个块&#xff0c;随机3个颜色&#xff0c;每次点击按钮时&#xff0c;把第一个块删除 import dart:math; import package:flutter/material.dart; import package:flutter_one/demo.dart;void main() {runApp(const App()); }class App…

第二十六章 TCP 客户端 服务器通信 - $ZB 和 READ 命令

文章目录 第二十六章 TCP 客户端 服务器通信 - $ZB 和 READ 命令$ZB 和 READ 命令 TCP 设备的 WRITE 命令WRITE如何工作WRITE 修改 $X 和 $YWRITE命令错误WRITE控制命令 第二十六章 TCP 客户端 服务器通信 - $ZB 和 READ 命令 $ZB 和 READ 命令 $ZB 保存终止读取的字符。该字…

AIGC ---探索AI生成内容的未来市场

文章目录 一、AIGC的市场现状与挑战1. 快速发展的生成模型 二、AIGC在内容生成中的应用场景1. 文本生成的实际案例2. 图像生成的多样化探索3. 跨模态内容生成的实现 三、AIGC市场的技术挑战与解决方案1. 数据质量问题2. 模型偏差问题3. 内容真实性问题 四、AIGC的未来趋势1. 多…