MySQL 表新增字段时报丢失连接错误
2025-01-04 10:21 阅读(183)

1. 问题描述

有一张MySQL数据库表,业务变动,需要新增一个业务字段,于是直接用下面的SQL语句进行字段新增:

ALTER TABLE table_name ADD `add_field` tinyint(1) DEFAULT NULL COMMENT '新增字段';

使用Navicat for MySQL执行该语句会报一个错误,如下图所示:

2013 - Lost connection to MySQL server during query,翻译过来就是在查询过程中,MySQL服务器失去连接。

该问题是大约一年前遇到的(2020年我写的文章),最近整理笔记看到了,趁有时间做一些整理记录。但是当时的具体环境已经无法复现了。

2. 官方文档

MySQL 官方文档的附录中有一篇是讲 MySQL 服务器连接断开。下面是我翻译的内容:

此错误消息有三个可能的原因。

通常它表示网络连接有问题,如果这个错误经常发生,你应该检查一下你的网络状况。如果提示的错误消息包含"during query"字符,那么您遇到的情况可能就是这种原因。

有时,当几百万行作为一个或多个查询的一部分被发送时,就会发生"during query"表单。如果您知道发生了这种情况,那么您应该尝试将net_read_timeout从默认的30秒增加到60秒或足以完成数据传输的更长时间。

更少见的情况是,当客户端试图初始化连接到服务器时,会发生这种情况。在这种情况下,如果connect_timeout值被设置为几秒,那么您可以通过将其增加到10秒来解决问题,如果您的连接距离很长或速度较慢,那么时间可能会更长。你可以通过查询Aborted_connects来确定你是否正在经历这种更不常见的原因。服务器每中止一个初始连接尝试,它的值就会增加1。如果错误消息包括"reading authorization packet",表明这正是您所需要的解决方案。

SHOW GLOBAL STATUS LIKE 'Aborted_connects'

如果原因不是以上所述的,你可能遇到了BLOB值大于max_allowed_packet的问题,这可能导致某些客户端出现此错误。有时你可能还会看到一个ER_NET_PACKET_TOO_LARGE错误,可以确定是需要提高max_allowed_packet值了。

SHOW VARIABLES LIKE '%max_allowed_packet%';

3. 解决办法

通过查阅官方文档,不难看出其实比较符合第一条解释。结合当时那家公司的网络,确实经常的时断时续的,网络环境比较差。

MySQL的这个错误除了官方说的几种情况,还需要针对自己的业务场景进行适当探索和甄别,具体情况具体分析。这里再记录一下另一种可能,因为ALTER TABLE操作是比较耗时的,所以也很有可能是因为超时原因报的错误。查询关于超时时间的系统变量:

sql 代码解读复制代码

SHOW VARIABLES LIKE '%timeout%';

高性能MySQL这本书的第四章Schema与数据优化提到了以下内容:


MySQL的ALTER TABLE操作的性能对大表来说是个问题。MySQL执行大部分修改表结构操作的方法是用新的结构创建一个空表,从旧表中查出所有数据插入新表,然后删除旧表。这样操作可能需要花费很长时间,如果内存不足表又很大,而且还有很多索引的情况下尤其如此。



一般而言,大部分ALTER TABLE操作将导致MySQL服务中断。对于常见场景,能使用的技巧只有两种:一种是先在一台不提供服务的机器上执行ALTER TABLE操作,然后和提供服务的主库进行切换;另一种技巧是影子拷贝,就是用要求的表结构创建一张与源表无关的新表,然后通过重命名和删表操作交换两张表。



ALTER TABLE允许使用ALTER COLUMN、MODIFY COLUMN、CHANGE COLUMN三种语句修改列。这三种操作都是不一样的。


可以结合MySQL错误日志,找到需要修改的系统变量,进行相应修改即可。


作者:一线大码

链接:https://juejin.cn