Kylin V10 安装 MySQL 8.0 后无法通过 127.0.0.1 连接

背景

Kylin V10 Desktop(arm64) 上通过二进制包 mysql-8.0.44-linux-glibc2.28-aarch64.tar.xz 部署 MySQL,后端应用(如 SQLAlchemy)使用 TCP 方式连接 127.0.0.1:3306 时,反复抛出 Lost connection to MySQL server during query 错误,而手动使用 mysql 客户端连接 localhost 却一切正常。本文记录该问题的排查过程、根因分析与最终解决方案。


问题现象

应用日志中报错如下:

复制代码
sqlalchemy/dialects/mysql/aiomysql.py", line 170, in connect
await_only(creator_fn(*arg, **kw)),
| | | -> {'host': '127.0.0.1', 'db': 'bisheng', 'user': 'root', 'password': '1234', 'port': 3306, 'charset': 'utf8mb4', 'client_flag': 2}
...
aiomysql/connection.py", line 661, in _read_bytes
raise OperationalError(CR.CR_SERVER_LOST, msg) from e
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2013, 'Lost connection to MySQL server during query')
...
RuntimeError: Error creating DB and tables
ERROR: Application startup failed. Exiting.

核心错误码为 2013 ,即 Lost connection to MySQL server during query,表明应用无法通过 TCP 连接访问数据库。其使用的连接参数为:

python 复制代码
{'host': '127.0.0.1', 'db': 'bisheng', 'user': 'root', 'password': '1234', 'port': 3306}

初步排查

1. MySQL 服务状态

bash 复制代码
systemctl status mysql

服务运行正常。

2. 手动测试连接

bash 复制代码
mysql -h 127.0.0.1 -P 3306 -u root -pxxx -e "SELECT 1;"

无法连接

bash 复制代码
mysql -h localhost -P 3306 -u root -pxxx -e "SELECT 1;"

连接成功

这一差异强烈暗示:MySQL 当前仅允许 Unix socket 连接,而 TCP 连接存在异常。localhost 默认走 socket,127.0.0.1 则强制 TCP。


深入定位:MySQL 监听情况

bash 复制代码
sudo netstat -nltp | grep 3306

输出:

复制代码
tcp6       0      0 :::33060                :::*                    LISTEN      76452/mysqld
tcp6       0      0 :::3306                 :::*                    LISTEN      76452/mysqld

结论:MySQL 只监听了 tcp6(IPv6 的 :: 通配地址),没有任何 IPv4 的 tcp 监听(如 0.0.0.0:3306)。

因此,当客户端使用 127.0.0.1(IPv4 地址)尝试连接时,系统找不到对应的 IPv4 监听端口,连接直接被拒绝或丢失。而 mysql -h localhost 能够成功是因为 MySQL 客户端默认使用 Unix socket,绕过了 TCP/IP 协议栈。


解决方案

强制 MySQL 监听 IPv4 地址。

  1. 编辑 MySQL 配置文件(不同系统的路径可能略有不同):

    bash 复制代码
    sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf

    (部分环境也可能是 /etc/my.cnf/etc/mysql/my.cnf,请根据实际情况选择。)

  2. [mysqld] 段中添加或修改:

    ini 复制代码
    [mysqld]
    bind-address = 0.0.0.0

    注意: 如果看到 skip-networking 行,请将其注释或删除(该选项会禁用所有 TCP/IP 连接)。

  3. 保存并重启 MySQL:

    bash 复制代码
    sudo systemctl restart mysql
  4. 再次检查监听端口:

    bash 复制代码
    sudo netstat -nltp | grep 3306

输出结果:

复制代码
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      76452/mysqld
tcp6       0      0 :::3306                 :::*                    LISTEN      76452/mysqld
  1. 验证 IPv4 连接:

    bash 复制代码
    mysql -h 127.0.0.1 -P 3306 -u root -p1234 -e "SELECT 1;"

    此时应能成功连接,应用启动异常也随之消失。


追问:为何 MySQL 安装后只监听了 IPv6?

从 MySQL 8.0.13 开始,当 bind_address 未显式设置时,其默认值为 *,表示 会分别创建 IPv4(0.0.0.0)和 IPv6(::)两个监听套接字 。也就是说,正常情况下使用 netstat 会同时看到 tcp 0.0.0.0:3306tcp6 :::3306

真凶:系统预置的配置文件

Kylin V10 Desktop 极有可能在以下路径之一 预置了 MySQL 或 MariaDB 的默认配置

  • /etc/my.cnf
  • /etc/mysql/my.cnf
  • /etc/mysql/mysql.conf.d/mysqld.cnf
  • /usr/etc/my.cnf
  • 编译时指定的 SYSCONFDIR 下的 my.cnf

这些预置文件中很可能包含了:

bind-address = ::1 或 bind-address = ::

当启动 mysqld 时,它会按照优先级顺序加载这些配置文件,从而覆盖了默认行为,最终 仅绑定了 IPv6 地址

netstat -tlnp 看到的便是仅有 tcp6 :::3306,而没有任何 IPv4 条目。

另一个小概率因素:net.ipv6.bindv6only

Linux 内核参数 net.ipv6.bindv6only 如果被设置为 1,即使 MySQL 监听了 IPv6 套接字,内核也会 禁止 IPv4 映射到 IPv6 。此时即使设置 bind-address = *,也可能无法通过 IPv4 连接,必须显式配置 0.0.0.0 创建独立的 IPv4 套接字。

不过从上述过程来看,添加 bind-address = 0.0.0.0 后问题立即解决,且没有报告其他内核异常,因此主因更大概率是配置文件覆盖,而非该内核参数。

显式设置 bind-address = 0.0.0.0 会让 MySQL 仅创建 IPv4 监听套接字AF_INET)。此时 netstat 会显示 tcp 0.0.0.0:3306,所有 IPv4 客户端(包括 127.0.0.1)就能顺利连接,问题解决。

当然,也可以设置为 0.0.0.0,::* 以同时支持 IPv4 和 IPv6,只是在本案例中快速恢复业务使用了最简单的方式。


愿你我都能在各自的领域里不断成长,勇敢追求梦想,同时也保持对世界的好奇与善意!

相关推荐
白露与泡影2 小时前
深入理解MySQL事务隔离级别:MVCC机制与Next-Key Lock如何解决幻读问题?
数据库·mysql
Gong-Yu2 小时前
MySQL数据库运维——性能优化进阶2️⃣
运维·数据库·mysql·性能优化
峥无2 小时前
MySQL 最全数据类型详解(数值/字符串/日期/枚举集合)
数据库·mysql
Amnesia0_03 小时前
MySQL的访问和数据流动
数据库·mysql
Arbori_262153 小时前
找回mysql root 密码
数据库·mysql
ejinxian5 小时前
PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, OceanBase, Sql Server等数据库
数据库·mysql·mongodb
大白要努力!12 小时前
MySQL 8.0 + Navicat 完整操作指南
数据库·mysql
云絮.13 小时前
数据库操作
数据库·mysql·算法·oracle
设计师小聂!15 小时前
宝塔 Linux 面板保姆级教程
linux·mysql·开源·运维开发