mysql事故复盘: 单行字节最大阈值65535字节(原创)

背景

记得还在银行做开发,投产上线时,项目发版前,要提DDL的sql工单,mysql加1个字段,因为这张表为下游数据入湖入仓用的,长度较大。在测试库加字段没问题,但生产库字段加不上。

先说结论

投产前,开发同学测试库和生产库,没对比出字段长度不一致,在 MySQL 中,每行的最大大小限制通常是 65535 字节(即 64KB 减去一些开销),当新增字段时,超了这个阈值,导致新字段加不上。

前置知识

在 MySQL 中,每行的最大大小限制通常是 65535 字节(即 64KB 减去一些开销),这个限制适用于所有列的总和,不仅仅是 VARCHAR 列。当你说"每行 VARCHAR 阈值最小是 65535"时,这个表述可能有些误导。实际上,65535 字节是整行的最大大小限制,而不是 VARCHAR 列的最小或最大阈值。

VARCHAR 列本身有一个最大长度限制,这个限制取决于 MySQL 的版本和配置。在大多数情况下,单个 VARCHAR 列的最大长度可以达到 65535 字节,但这实际上是不现实的,因为还需要考虑行中的其他列以及存储引擎所需的元数据。实际上,单个 VARCHAR 列的长度很少会接近这个数值,因为还需要考虑其他列和行的总大小限制。

更常见的情况是,你会遇到由于整行大小超过限制而导致的错误。当定义表时,你需要确保所有列的总和(包括 VARCHAR、TEXT、BLOB 和其他类型)不会接近或超过这个限制。如果接近或超过限制,你可能需要调整列的数据类型、大小或使用其他策略来减少行的大小。

请注意,TEXT 和 BLOB 类型的列在存储时不会计入每行的 65535 字节限制,因为它们的值存储在表的外部,只在表中保留一个指针。因此,如果你需要存储大量数据,考虑使用这些类型而不是增加 VARCHAR 列的大小。

总结起来,每行的最大大小限制是 65535 字节,而不是 VARCHAR 列的最小或最大阈值。在设计表结构时,需要确保所有列的总大小不会接近或超过这个限制。

场景复现

本地环境复现

mysql版本8.0.33

数据库字符集utf8mb4

比如有张t_user表,表结构如下:

sql 复制代码
CREATE TABLE `t_user` (
  `name` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '姓名',
  `address` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '住址',
  `dept` varchar(10000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '部门',
  `position` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '职务',
  `work` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '工作'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

现打算加个salary字段

执行如下sql

sql 复制代码
ALTER TABLE t_user
ADD salary VARCHAR(500);

发现新字段添加失败,报错:1118 - Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs

分析

在 utf8mb4 字符集情况下(这是为了支持所有的 Unicode 字符,包括表情符号),1个字符可能需要最多 4 个字节。因此,在 utf8mb4 字符集中,VARCHAR(10) 字段可能最多占用 40 个字节。

上述t_user表单行数字节总数=(1000+2000+10000+1000+2000+500)*4=66000 > 65535最大阈值, 所以salary字段自然加不上。

警示

当设计表和新增字段时,一定用合理的字段长度,注意单行最大字节阈值65535,生产提交DDL工单加字段前,比较好测试库和生产库是否一致。

相关推荐
计算机毕设VX:Fegn08952 小时前
计算机毕业设计|基于springboot + vue医院设备管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
Mr__Miss2 小时前
保持redis和数据库一致性(双写一致性)
数据库·redis·spring
Knight_AL3 小时前
Spring 事务传播行为 + 事务失效原因 + 传播行为为什么不用其他模式
数据库·sql·spring
倔强的石头_3 小时前
时序数据时代的“存储与分析困局”解析及金仓解决方案
数据库
计算机毕设VX:Fegn08953 小时前
计算机毕业设计|基于springboot + vue小型房屋租赁系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
倔强的石头_4 小时前
场景化落地指南——金仓时序数据库在关键行业的应用实践
数据库
SelectDB4 小时前
驾驭 CPU 与编译器:Apache Doris 实现极致性能的底层逻辑
运维·数据库·apache
刀法如飞5 小时前
开箱即用的 DDD(领域驱动设计)工程脚手架,基于 Spring Boot 4.0.1 和 Java 21
java·spring boot·mysql·spring·设计模式·intellij-idea
zbguolei5 小时前
MySQL根据身份证号码计算出生日期和年龄
数据库·mysql
马克学长5 小时前
SSM校园图书借阅服务系统jd2z8(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·图书管理系统·ssm 框架·ssm 校园图书借阅系统