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

2024-04-24 15:20

本文主要是介绍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表,表结构如下:

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

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工单加字段前,比较好测试库和生产库是否一致。

这篇关于mysql事故复盘: 单行字节最大阈值65535字节(原创)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/932102

相关文章

SQL中的外键约束

外键约束用于表示两张表中的指标连接关系。外键约束的作用主要有以下三点: 1.确保子表中的某个字段(外键)只能引用父表中的有效记录2.主表中的列被删除时,子表中的关联列也会被删除3.主表中的列更新时,子表中的关联元素也会被更新 子表中的元素指向主表 以下是一个外键约束的实例展示

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

如何去写一手好SQL

MySQL性能 最大数据量 抛开数据量和并发数,谈性能都是耍流氓。MySQL没有限制单表最大记录数,它取决于操作系统对文件大小的限制。 《阿里巴巴Java开发手册》提出单表行数超过500万行或者单表容量超过2GB,才推荐分库分表。性能由综合因素决定,抛开业务复杂度,影响程度依次是硬件配置、MySQL配置、数据表设计、索引优化。500万这个值仅供参考,并非铁律。 博主曾经操作过超过4亿行数据

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

MySQL数据库宕机,启动不起来,教你一招搞定!

作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG、Mongodb数据库运维(如安装迁移,性能优化、故障应急处理等)公众号:老苏畅谈运维欢迎关注本人公众号,更多精彩与您分享。 MySQL数据库宕机,数据页损坏问题,启动不起来,该如何排查和解决,本文将为你说明具体的排查过程。 查看MySQL error日志 查看 MySQL error日志,排查哪个表(表空间

MySQL高性能优化规范

前言:      笔者最近上班途中突然想丰富下自己的数据库优化技能。于是在查阅了多篇文章后,总结出了这篇! 数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意,并且最后不要超过32个字符 临时库表必须以tmp_为前缀并以日期为后缀,备份

[MySQL表的增删改查-进阶]

🌈个人主页:努力学编程’ ⛅个人推荐: c语言从初阶到进阶 JavaEE详解 数据结构 ⚡学好数据结构,刷题刻不容缓:点击一起刷题 🌙心灵鸡汤:总有人要赢,为什么不能是我呢 💻💻💻数据库约束 🔭🔭🔭约束类型 not null: 指示某列不能存储 NULL 值unique: 保证某列的每行必须有唯一的值default: 规定没有给列赋值时的默认值.primary key:

poj 3723 kruscal,反边取最大生成树。

题意: 需要征募女兵N人,男兵M人。 每征募一个人需要花费10000美元,但是如果已经招募的人中有一些关系亲密的人,那么可以少花一些钱。 给出若干的男女之间的1~9999之间的亲密关系度,征募某个人的费用是10000 - (已经征募的人中和自己的亲密度的最大值)。 要求通过适当的招募顺序使得征募所有人的费用最小。 解析: 先设想无向图,在征募某个人a时,如果使用了a和b之间的关系

poj 3258 二分最小值最大

题意: 有一些石头排成一条线,第一个和最后一个不能去掉。 其余的共可以去掉m块,要使去掉后石头间距的最小值最大。 解析: 二分石头,最小值最大。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <c