MySQL问题收集

文章目录

  • MySQL问题收集
    • [1、Host is not allowed to connect to this MySQL server解决方法](#1、Host is not allowed to connect to this MySQL server解决方法)
    • 2、10060错误
    • 3、1130错误
    • [4、错误126 - Incorrect key file for table](#4、错误126 - Incorrect key file for table)
    • 5、版本问题导致无法连接MySQL服务
    • 6、未授权导致无法连接MySQL服务
    • 7、10061错误
    • 8、1045(28000)
    • [9、Too many connections(连接数过多,导致连接不上数据库,业务无法正常进行)](#9、Too many connections(连接数过多,导致连接不上数据库,业务无法正常进行))
    • 10、数据库密码忘记的问题
    • 11、Mysql乱码问题
    • [12、MySQL 数据库连接超时的报错](#12、MySQL 数据库连接超时的报错)
    • 13、MySql设置InnoDb级别和密码
    • [14、忘记密码或无法登录------重置 root 密码](#14、忘记密码或无法登录——重置 root 密码)
    • [15、ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)](#15、ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES))
    • [16、MySQL Workbench中的权限设置不生效](#16、MySQL Workbench中的权限设置不生效)
      • 🖼️现象:
      • [🔑 为什么一个全局权限会导致看到所有数据库?](#🔑 为什么一个全局权限会导致看到所有数据库?)
      • [🕵️‍♂️ 排查问题:test 账号拥有哪些权限?](#🕵️‍♂️ 排查问题:test 账号拥有哪些权限?)
      • [🔧 解决方案:如何限制用户只能看到授权的数据库?](#🔧 解决方案:如何限制用户只能看到授权的数据库?)
        • [1. 方案一:移除 `SHOW DATABASES` 权限(推荐)](#1. 方案一:移除 SHOW DATABASES 权限(推荐))
        • [2. 方案二:检查并回收不必要的全局权限](#2. 方案二:检查并回收不必要的全局权限)
        • [3. 验证结果](#3. 验证结果)
      • [💎 核心总结](#💎 核心总结)

MySQL问题收集

1、Host is not allowed to connect to this MySQL server解决方法

今天在Linux上面装完MySQL,却发现在本地登录可以,但是远程登录却报错Host is not allowed to connect to this MySQL server,找了半天试了网上的一些方法都没有解决,最终在一篇文章里找到了解决方法,特意记录一下。

先说说这个错误,其实就是我们的MySQL不允许远程登录,所以远程登录失败了,解决方法如下:

  1. 在装有MySQL的机器上登录MySQL mysql -u root -p密码

  2. 执行use mysql;

  3. 执行update user set host = '%' where user = 'root';这一句执行完可能会报错,不用管它。

  4. 执行FLUSH PRIVILEGES;

    经过上面4步,就可以解决这个问题了。
    注: 第四步是刷新MySQL的权限相关表,一定不要忘了,我第一次的时候没有执行第四步,结果一直不成功,最后才找到这个原因。

2、10060错误

解决方法:

1)检查是否开启防火墙,限制了连接请求。设置防火墙入站规则:






2)监听地址错误导致无法远程连接MySQL服务

MySQL服务对127.0.0.1地址进行监听,导致外部无法远程连接。

然后保存,重启mysql:

bash 复制代码
/etc/init.d/mysql restart #重启

3)检查MySQL数据库是否有访问权限。可通过如下命令进行添加

bash 复制代码
use mysql;
Grant all privileges on *.* to 'root'@'%' identified by '[$Password]' with grant option;
flush privileges;

4)在my.ini配置文件添加skip-name-resolve参数。

5)修改hosts.allow配置文件,增加如下配置。

复制代码
mysqld-max : ALL :ALLOW

3、1130错误

百度查询mysql的1130错误是远程连接的用户无远程权限问题导致。解决方案:在本机登入mysql后,更改 "mysql" 数据库里的 "user"表里的 "host" 项,从"localhost"改称'%'

mysql 复制代码
mysql -u root -p
mysql>use mysql;
mysql>select 'host' from user where user='root';
mysql>update user set host = '%' where user ='root';
mysql>flush privileges;
mysql>select 'host' from user where user='root';
#第一句是以权限用户root登录
#第二句:选择mysql库
#第三句:查看mysql库中的user表的host值(即可进行连接访问的主机/IP名称)
#第四句:修改host值(以通配符%的内容增加主机/IP地址),当然也可以直接增加IP地址
#第五句:刷新MySQL的系统权限相关表
#第六句:再重新查看user表时,有修改。

4、错误126 - Incorrect key file for table

清空表格时发生如下错误:

说明表格损害了,需要

mysql 复制代码
REPAIR table `table_name`;

5、版本问题导致无法连接MySQL服务

问题现象:

自建的MySQL服务器版本为5.6,远程连接时提示如下错误。

复制代码
ERROR 2049 (HY000): Connection using old (pre-4.1.1) authentication protocol refused (client option 'secure_auth' enabled)

问题原因:

由于服务器端的密码管理协议陈旧,使用的是旧有的用户密码格式存储,但客户端升级之后采用了新的密码格式 。MySQL 5.6版本遇到这种不一致的情况就会拒绝连接 。

解决方案:

连接时添加--secure-auth参数,连接命令如下所示。详细的表述可以参考MySQL手册

复制代码
mysql -h [$Host] -u [$Username] --secure-auth -p

注:[ H o s t ] 为 E C S 实例域名或 I P , [ Host]为ECS实例域名或IP,[ Host]为ECS实例域名或IP,[Username]为数据库用户名。

6、未授权导致无法连接MySQL服务

问题现象

在ECS实例内部连接MySQL服务正常,远程连接则会出现如下错误 。

复制代码
EHost 'XX.XX.XX.XX' is not allowed to connect to this MySQL serverConnection closed by foreign host.

系统显示类似如下。

解决方案
  1. 确认MySQL服务监听的是0.0.0.0地址。
  2. 检查实例是否开启防火墙,建议先关闭防火墙进行测试。
  3. 确认MySQL服务是否开启远程登录,可通过如下方法开启。
    • 登录数据库,选择MySQL数据库。将user表中的host项,从localhost改为'%'
    • 登录数据库,创建一个远程连接的用户。

7、10061错误

navicat报错界面:

Workbench报错界面:

解决方法:

bash 复制代码
# 检查 MySQL 绑定地址
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
#修改后,ctrl+s保存,ctrl+x退出

找到 bind-address 行:

  • 如果只允许本地连接:bind-address = 127.0.0.1
  • 如果允许远程连接:bind-address = 0.0.0.0 或注释掉这行

修改后重启 MySQL:

bash 复制代码
sudo systemctl restart mysql

8、1045(28000)

常见原因:

  1. 输入的 root 密码不正确
  2. root 用户没有从当前主机访问的权限
  3. MySQL 的 root 用户被限制只能通过特定方式登录
  4. MySQL 用户权限表出现问题

我的原因是密码键盘输入就是会报错,而复制好密码再右键黏贴进去就能登陆。

9、Too many connections(连接数过多,导致连接不上数据库,业务无法正常进行)

问题还原:

sql 复制代码
mysql> show variables like '%max_connection%';
| Variable_name   | Value |
| max_connections | 151   |

mysql> set global max_connections=1;Query OK, 0  rows affected (0.00 sec)

[root@node4 ~]# mysql -uzs -p123456 -h 192.168.56.132
ERROR 1040 (00000): Too many connections

解决问题的思路:

  1. 首先先要考虑在我们 MySQL 数据库参数文件里面,对应的max_connections 这个参数值是不是设置的太小了,导致客户端连接数超过了数据库所承受的最大值。
    ● 该值默认大小是151,我们可以根据实际情况进行调整。
    ● 对应解决办法:set global max_connections=500
    但这样调整会有隐患,因为我们无法确认数据库是否可以承担这么大的连接压力,就好比原来一个人只能吃一个馒头,但现在却非要让他吃 10 个,他肯定接受不了。反应到服务器上面,就有可能会出现宕机的可能。
    所以这又反应出了,我们在新上线一个业务系统的时候,要做好压力测试。保证后期对数据库进行优化调整。
  2. 其次可以限制Innodb 的并发处理数量,如果 innodb_thread_concurrency = 0(这种代表不受限制) 可以先改成 16或是64 看服务器压力。如果非常大,可以先改的小一点让服务器的压力下来之后,然后再慢慢增大,根据自己的业务而定。个人建议可以先调整为 16 即可。
    MySQL 随着连接数的增加性能是会下降的,可以让开发配合设置 thread pool,连接复用。在MySQL商业版中加入了thread pool这项功能,另外对于有的监控程序会读取 information_schema 下面的表,可以考虑关闭下面的参数
sql 复制代码
innodb_stats_on_metadata=0set global innodb_stats_on_metadata=0

1.2 法二

查看从这次 mysql 服务启动到现在,同一时刻并行连接数的最大值:
show status like 'Max_used_connections';

更改最大连接数只能从表面上解决问题,随着我们开发人员的增多,Sleep 连接也会更多,到时候万一又达到了 1000 的上限,难道我们又得改成 10000 吗?这显然是非常不可取的。所以杀掉多余的 Sleep 连接。

杀掉Sleep连接

我们可以通过 show processlist 命令来查看当前的所有连接状态。

Mysql 数据库有一个属性 wait_timeout 就是 sleep 连接最大存活时间,默认是 28800 s,换算成小时就是 8 小时。

执行命令:

sql 复制代码
show global variables like '%wait_timeout';

将他修改成一个合适的值,这里我改成了 250s。当然也可以在配置文件中修改,添加 wait_timeout = 250。这个值可以根据项目的需要进行修改,以 s 为单位。我在这里结合 navicat 的超时请求机制配置了 240s。

执行命令:

sql 复制代码
set global wait_timeout=250;

这样,就能从根本上解决 Too Many Connections 的问题了

10、数据库密码忘记的问题

sql 复制代码
[root@zs ~]# mysql -uroot -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
[root@zs ~]# mysql -uroot -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

我们有可能刚刚接手别人的 MySQL 数据库,而且没有完善的交接文档。root 密码可以丢失或者忘记了。

解决思路:

目前是进入不了数据库的情况,所以我们要考虑是不是可以跳过权限。因为在数据库中,mysql数据库中user表记录着我们用户的信息。

解决方法:

启动 MySQL 数据库的过程中,可以这样执行:

shell 复制代码
/usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf  --skip-grant-tables &

这样启动,就可以不用输入密码,直接进入 mysql 数据库了。然后在修改你自己想要改的root密码即可。

sql 复制代码
update mysql.user set password=password('root123') where user='root';

11、Mysql乱码问题

3.1 Mysql乱码问题

博客园:StrongerW:MySQL乱码问题(为什么?追根溯源)

win下my.ini、Linux下my.cnf:

xml 复制代码
# Win下 my.ini 有的默认被注释掉,只需要去掉注释就可以
#在[client]下追加:
default-character-set=utf8
#在[mysqld]下追加:
character-set-server=utf8
#在[mysql]下追加:
default-character-set=utf8

# Linux下,这里就有所不同,每个人当初安装MySQL的方式,添加的my.cnf
#是否是用的官网模板还是网上复制的内容填充的,但是方式要添加的内容和win
#大同小异,如果当初指定了相应的默认字符集就无需指定字符集。

#【注】无论是my.ini还是my.cnf里面的mysql相关的配置项一定要在所属的组下面,
比如default-character-set就只能放在[mysql]/[client],不能放在[mysqld]下,
不然会导致mysql服务启动失败,可能如下:
#[Error]start Starting MySQL ..  The server quit without updating PID file
# 所以说mysql服务起不来了,可能是配置文件出现了问题

最关键的一项是[mysqld] character-set-server=utf8,其它两项,对于my.cnf只需要追加[mysql] character-set-server=utf8就可以改变 character_set_client、character_set_connection、character_set_results这三项的值.

character_set_client/connection/results变量

3.2 数据库总会出现中文乱码的情况

解决思路:

对于中文乱码的情况,记住老师告诉你的三个统一就可以。还要知道在目前的mysql数据库中字符集编码都是默认的UTF8

处理办法:

  1. 数据终端,也就是我们连接数据库的工具设置为 utf8
  2. 操作系统层面;可以通过 cat /etc/sysconfig/i18n 查看;也要设置为 utf8
  3. 数据库层面;在参数文件中的 mysqld 下,加入 character-set-server=utf8。
    Emoji 表情符号录入 mysql 数据库中报错。
java 复制代码
Caused by: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x97\xF0\x9F...' for column 'CONTENT' at row 1
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2734)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1379)

解决思路:针对表情插入的问题,一定还是字符集的问题。

处理方法:我们可以直接在参数文件中,加入

shell 复制代码
vim /etc/my.cnf
[mysqld]
init-connect='SET NAMES utf8mb4'
character-set-server=utf8mb4

注:utf8mb4 是 utf8 的超集。

12、MySQL 数据库连接超时的报错

java 复制代码
org.hibernate.util.JDBCExceptionReporter - SQL Error:0, SQLState: 08S01
org.hibernate.util.JDBCExceptionReporter - The last packet successfully received from the server was43200 milliseconds ago.The last packet sent successfully to the server was 43200 milliseconds ago, which is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection 'autoReconnect=true' to avoid this problem.
org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
org.hibernate.exception.JDBCConnectionException: Could not execute JDBC batch update
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Connection.close() has already been called. Invalid operation in this state.
org.hibernate.util.JDBCExceptionReporter - SQL Error:0, SQLState: 08003
org.hibernate.util.JDBCExceptionReporter - No operations allowed after connection closed. Connection was implicitly closed due to underlying exception/error:
** BEGIN NESTED EXCEPTION **

大多数做 DBA 的同学,可能都会被开发人员告知,你们的数据库报了这个错误了。赶紧看看是哪里的问题。

这个问题是由两个参数影响的,wait_timeout 和 interactive_timeout。数据默认的配置时间是28800(8小时)意味着,超过这个时间之后,MySQL 数据库为了节省资源,就会在数据库端断开这个连接,Mysql服务器端将其断开了,但是我们的程序再次使用这个连接时没有做任何判断,所以就挂了。

解决思路:

先要了解这两个参数的特性;这两个参数必须同时设置,而且必须要保证值一致才可以。

我们可以适当加大这个值,8小时太长了,不适用于生产环境。因为一个连接长时间不工作,还占用我们的连接数,会消耗我们的系统资源。

解决方法:

可以适当在程序中做判断;强烈建议在操作结束时更改应用程序逻辑以正确关闭连接;然后设置一个比较合理的timeout的值(根据业务情况来判断)

13、MySql设置InnoDb级别和密码

yaml 复制代码
[mysqld]
# Mysql innodb级别
innodb_force_recovery = 6
# 设置免密登录
skip-grant-tables

14、忘记密码或无法登录------重置 root 密码

如果完全忘记密码或无法登录------重置 root 密码(通用方法)

对于 MySQL 8.0 / 5.7(推荐方法):

  1. 停止 MySQL 服务

    bash 复制代码
    sudo systemctl stop mysql      # Linux (systemd)
    # 或者
    sudo service mysql stop

    Windows:以管理员身份运行 net stop MySQL

  2. 跳过权限表启动 MySQL

    bash 复制代码
    sudo mysqld_safe --skip-grant-tables &

    注意:如果 mysqld_safe 不可用,可以直接运行:
    sudo mysqld --skip-grant-tables --skip-networking &

  3. 无密码登录

    bash 复制代码
    mysql -u root
  4. 清空 root 密码(先清空再重新设置)

    bash 复制代码
    FLUSH PRIVILEGES;
    ALTER USER 'root'@'localhost' IDENTIFIED BY '';
  5. 退出并正常重启 MySQL

    bash 复制代码
    sudo systemctl restart mysql
  6. 无密码登录后重新设置新密码

    bash 复制代码
    mysql -u root -p   # 直接回车,密码为空
    bash 复制代码
    ALTER USER 'root'@'localhost' IDENTIFIED BY '你的新密码';
    FLUSH PRIVILEGES;

4️⃣ 检查 root 账号的主机权限

登录成功后(无论是通过 127.0.0.1 还是重置密码后),执行:

bash 复制代码
SELECT host, user, authentication_string, plugin FROM mysql.user WHERE user='root';
  • 如果 host 列只有 % 而没有 localhost,说明 root 不允许从 localhost 登录,你需要添加一个 localhost 的 root:

    bash 复制代码
    CREATE USER 'root'@'localhost' IDENTIFIED BY '你的密码';
    GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;
    FLUSH PRIVILEGES;
  • 如果 plugin 列显示 caching_sha2_password,而你的客户端很老(比如 MySQL 5.x 客户端),可以改为 mysql_native_password

    bash 复制代码
    ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';
    FLUSH PRIVILEGES;

🧪 最后验证

完成上述修复后,尝试:

bash 复制代码
mysql -u root -p -h localhost

输入你设置的正确密码,应该就能登录了。之后你就可以继续去检查和修改 yftest 账号的权限了。

15、ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

可能原因:

  1. 密码错误 (最常见)------ 你输入的密码与 MySQL 中 root@localhost 的密码不一致。
  2. root 账号没有 localhost 的访问权限 ------ 比如 root 只允许从 %(任意主机)或 127.0.0.1 登录,但禁用了 localhost

🛠️ 解决步骤

1️⃣ 确认密码是否正确

  • 如果你记得安装时设置的 root 密码,尝试重新输入,注意大小写和特殊字符。
  • 检查键盘布局、Caps Lock。

2️⃣ 尝试用 TCP/IP 方式登录(绕过 socket 问题)

有时候 localhost 会使用 Unix socket,而密码或权限配置可能有问题。尝试通过 127.0.0.1 连接:

复制代码
mysql -u root -p -h 127.0.0.1

如果这个能成功,说明 root@localhost 的密码或权限确实有问题,但你可以先通过 127.0.0.1 登录来修复。

16、MySQL Workbench中的权限设置不生效

🖼️现象:

这个test账号我只给了两个数据库权限,为什么它连接还是能看到其他数据库。下图是这个账号的设置。

test 账号能看到其他数据库,很可能是因为它拥有了某个"全局级别"的权限,比如 SHOW DATABASES。只要用户有任意一个全局权限,MySQL 就会允许他查看服务器上所有数据库的名字,这可能会造成一些安全风险。

🔑 为什么一个全局权限会导致看到所有数据库?

在 MySQL 中,权限的授予范围是分层级的。其中,"全局权限"(*.*)是所有权限里最高的一级。根据 MySQL 的官方设计,只要用户拥有了任何一个全局权限,系统在执行 SHOW DATABASES 命令时,就会向其展示服务器上所有数据库的名称

🕵️‍♂️ 排查问题:test 账号拥有哪些权限?

按照下面的步骤来检查 test 账号的具体权限,应该就能找到是哪个全局权限导致了问题。

  1. 登录数据库 :用 root 或其他有管理权限的账号登录 MySQL。

    bash 复制代码
    mysql -u root -p
  2. 查看用户权限:在 MySQL 命令行中,执行以下 SQL 命令:

    bash 复制代码
    SHOW GRANTS FOR 'test'@'%';

    请注意 :账号由用户名 (test) 和主机名 (%) 共同组成。

  3. 分析返回结果 :重点检查输出中是否包含 GRANT ... ON \*.\* TO ... 这样的语句。这类语句就代表了全局权限。

🔧 解决方案:如何限制用户只能看到授权的数据库?

想解决这个问题,核心思路就是移除用户多余的全局权限。

1. 方案一:移除 SHOW DATABASES 权限(推荐)

如果你只希望用户看不到其他数据库,但无需回收他的其他权限,可以只撤销 SHOW DATABASES 权限。在命令行中执行:

bash 复制代码
REVOKE SHOW DATABASES ON *.* FROM 'test'@'%';
2. 方案二:检查并回收不必要的全局权限

你也可以选择移除所有不必要的全局权限,仅保留数据库级别的授权。操作前请先查询并评估,再执行撤销:

bash 复制代码
-- 1. 查询当前权限以评估
SHOW GRANTS FOR 'test'@'%';
-- 2. 移除不必要的全局权限,例如:
REVOKE SELECT ON *.* FROM 'test'@'%';
3. 验证结果

执行权限回收后,可以让 test 重新登录并运行 SHOW DATABASES; 命令,检查数据库列表是否已符合预期。

💎 核心总结

理解权限层级是关键,MySQL 的这种设计是为了兼顾安全性可用性

  • 安全性优先 :默认行为是"最小权限原则",即用户只能看到自己有权限访问的数据。这有效防止了低权限用户通过 SHOW DATABASES 来探测服务器上的所有数据库名称,降低了信息泄露的风险。
  • 全局权限的双刃剑:作为最高层级的权限,全局权限能极大地方便管理员操作,但也会产生"看到所有数据库"的副作用。因此,在给普通业务账号授予任何全局权限时,都需格外谨慎。
相关推荐
小王毕业啦3 分钟前
2006-2023年 省级-建成区绿化覆盖率数据(xlsx)
大数据·人工智能·数据挖掘·数据分析·社科数据·实证分析·经管数据
十有八七3 分钟前
OpenHarness 架构说明文档
人工智能·架构
一 乐4 分钟前
校园线上招聘|基于springboot + vue校园线上招聘系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·校园线上招聘系统
Bruce1235 分钟前
openclaw学习日常(一)openclaw在WSL中搭建
人工智能·node.js
liliangcsdn5 分钟前
如何基于sentence_transformers构建向量计算工具
数据库·人工智能·全文检索
西海天际蔚蓝8 分钟前
AI配合写的第一个demo系统页面
java·人工智能
贵慜_Derek9 分钟前
Managed Agents 里,Harness 到底升级了什么?
人工智能·算法·架构
Tadas-Gao12 分钟前
从“驯马”到“驭队”:Harness Engineering 如何重构 AI 产品化的底层逻辑
人工智能·语言模型·架构·大模型·llm·harness
Thomas.Sir16 分钟前
重构诊疗效率与精准度之【AI 赋能临床诊断与辅助决策从理论到实战】
人工智能·python·ai·医疗·诊断
weixin_66818 分钟前
OCR 模型深度对比分析报告 - AI分析
人工智能·ocr