MySQL 错误剖析

每个 MySQL 错误都由标识错误的以下部分组成:

ERROR NUMBER 是标识每个错误的唯一编号。
SQLSTATE 是标识 SQL 错误情况的代码。
ERROR MESSAGE 以人类可读的格式描述错误。
下面是一个 MySQL 错误示例:

1
ERROR 1146 (42S02): Table 'test.no_such_table' doesn't exist

在上面的示例中:

  • 1146 是错误号
  • 42S02 是 SQLSTATE
  • 表 ‘test.no_such_table’ 不存在是错误消息

用户 ‘root‘@’localhost’ 的访问被拒绝(使用密码:YES)

1
ERROR 1045: Access denied for user 'root'@'localhost'

任何使用 MySQL 的人都可能至少遇到过一次。
此错误可能有多种原因,例如用户名和/或密码错误,或缺少对数据库的权限。

此错误表示 MySQL 服务器在尝试使用提供的密码从 ‘localhost’ 服务器进行连接时拒绝了对 ‘root’ 用户的访问。

💡要解决此问题,请仔细检查密码并确保用户具有必要的权限。
您可以重置密码或授予解决此问题所需的权限。

Lost connection to MySQL server during query

1
ERROR 2013: Lost connection to MySQL server during query

当您的 MySQL 客户端和数据库服务器之间的连接超时时,会发生此错误。
从本质上讲,查询返回数据花费的时间太长,因此连接被断开。
这可能是由于各种原因造成的,例如网络问题或服务器超时。

💡 要解决此问题,请考虑调整 MySQL 服务器配置以增加连接超时值或调查网络稳定性。

Too many connections

1
ERROR 1040: Too many connections

当 MySQL 服务器达到其允许的最大连接数限制时,会出现此错误。

💡 要解决此问题,您可以增加 MySQL 配置文件中的 max_connections 设置,或者优化应用程序以使用更少的连接。

MySQL server has gone away

1
ERROR 2006 (HY000): MySQL server has gone away

此错误表示 MySQL 服务器意外终止了连接。
这可能是由于各种原因造成的,包括长时间运行的查询或服务器超时。

💡 要防止这种情况,您可以在 MySQL 配置中调整 wait_timeout 和 interactive_timeout 设置。

MySQL client ran out of memory

1
ERROR 2008: MySQL client ran out of memory

当 MySQL 客户端消耗的内存超过可用内存时,会发生此错误。

💡 要解决此问题,您可能需要优化查询、限制结果集或为 MySQL 客户端分配更多内存。

The table is full

1
ERROR 1114 (HY000): The table is full

如果发生 table-full 错误,则可能是磁盘已满或表已达到其最大大小。
MySQL 数据库的有效最大表大小通常由操作系统对文件大小的限制决定,而不是由 MySQL 内部限制决定。

💡 要解决此问题,您可以:

  • 增加 MEMORY 表允许的最大大小
1
2
3
[mysqld]
max_heap_table_size = 2G
tmp_table_size = 2G
  • 切换到 InnoDB 存储引擎
  • 检查磁盘空间并增加可用空间:

You have an error in your SQL syntax

1
ERROR 1064 (42000): You have an error in your SQL syntax

这意味着 MySQL 由于语法问题而无法理解您的查询。通常,问题的原因是忘记将某些文本或值括在反引号或引号中。例如,而不是在 MySQL 查询中使用数据库名称,因为它应该是 。my-databasemy-database

错误消息甚至会更进一步,并指出语法开始无效的位置,您可以将其用作寻找问题的起点。

💡 仔细检查您的查询,确保所有 SQL 语句的格式正确并遵循 MySQL 的语法规则。

Packet too large

1
ERROR: Packet too large

当 MySQL 客户端或 mysqld 服务器获取的数据包大于max_allowed_packet字节,它会发出 Packet too large 错误并关闭连接。

1 GB 数据包大小是可以传输到 MySQL 服务器或客户端或从 MySQL 服务器或客户端传输的最大数据包大小。如果 MySQL 服务器或客户端收到大于 max_allowed_packet 字节的数据包,则发出 ER_NET_PACKET_TOO_LARGE 错误并关闭连接。

💡 您可以通过调整 MySQL 配置文件中的 max_allowed_packet 设置来解决此问题。

Communication Errors and Aborted Connections

1
ERROR: Communication Errors and Aborted Connections

如果您在错误日志中发现如下错误。

1
010301 14:38:23  Aborted connection 854 to db: 'users' user: 'simplebackups'

这意味着发生了以下情况:

  • 客户端程序未调用mysql_close()before 退出。
  • 客户睡得超过wait_timeout或interactive_timeout无需执行任何请求。
  • 客户端程序在传输过程中突然结束。

Can’t create/write to file

1
ERROR: Can’t create/write to file

当 MySQL 无法创建或写入文件时,通常会发生此错误,通常是由于权限不足或磁盘空间不足。
💡 确保 MySQL 用户具有必要的文件权限,并检查可用磁盘空间以解决此问题。

Commands out of sync

1
ERROR: Commands out of sync

如果您在客户端代码中收到此错误,则表示您以错误的顺序调用客户端函数。
例如,如果您正在使用mysql_use_result()并尝试在调用mysql_free_result().

💡 确保您的应用程序遵循正确的执行和获取查询结果的顺序,以避免此错误。

Packet for query is too large错误

1
2
在mysql安装目录中找到my.ini配置文件
在最后添加 max_allowed_packet=10485760

数值可以 MB为单位,16M

索引失效

eg:假设age是整数类型,但是却使用字符串类型

1
SELECT * FROM user WHERE age = '20';

MySQL 需要在查询时转换 ‘20’ 为整数类型,可能会导致索引无法使用。 某个电商平台就有这么一个类似的bug,导致下单超时崩盘30分钟。

MySql 5.7 解决GROUP BY出现的问题

报错如下:

1
2
1055 - Expression #1 of SElECT list is not in GRoUp BY clause and contains nonaggregated column 'projhigh.project node.i whicn is not functionally dependent on columns in GROup BY clause; this is incompatible with sql mode=only_full_group_by

引起的原因是:这个错误一般发生在mysql 5.7以及 5.7以上的版本中,其原因是mysql的默认配置中,sql_mode=”ONLY_FULL_GROUP_BY” 这个配置严格执行了 ‘SQL92标准’,所以很高网站维护人员在升级mysql版本时,都会修改 sql_mode 的配置,使其能兼容。

解决方法1,重启mysql后会失效:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- 查看ONLY_FULL_GROUP_BY 校验规则是否开启
SELECT @@GLOBAL.sql_mode;
SELECT @@SESSION.sql_mode;


-- 第一个sql语句的结果,使用自己查询的结果
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

-- 第二个sql语句的结果
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION


-- 关闭only_full_group_by的规则校验
set @@GLOBAL.sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
set @@SESSION.sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

解决方法2:
修改配置文件 my.ini

1
2
在 [mysqld] 下面添加代码:
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

重启mysql服务。

注意:

1、不同的系统,mysql 的配置文件名以及路径不同

2、Mac或Linux文件 /etc/my.cnf

3、windows 在数据库安装目录下的 my.ini

Lock wait timeout exceeded; try restarting transaction

这是 MySQL 数据库中的一个常见错误,通常发生在使用 InnoDB 存储引擎的事务中。它的含义是:某个事务在尝试获取锁资源时,等待时间超过了数据库配置的阈值(innodb_lock_wait_timeout,默认 50 秒),因此被强制终止

参考

https://simplebackups.com/blog/extensive-mysql-common-errors-list/#the-anatomy-of-mysql-errors