Kylin V10 安装 MySQL 8.0 后无法通过 127.0.0.1 连接
背景在Kylin V10 Desktoparm64上通过二进制包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 连接访问数据库。其使用的连接参数为{host:127.0.0.1,db:bisheng,user:root,password:1234,port:3306}初步排查1. MySQL 服务状态systemctl status mysql服务运行正常。2. 手动测试连接mysql-h127.0.0.1-P3306-uroot-pxxx-eSELECT 1;无法连接。mysql-hlocalhost-P3306-uroot-pxxx-eSELECT 1;连接成功。这一差异强烈暗示MySQL 当前仅允许 Unix socket 连接而 TCP 连接存在异常。localhost默认走 socket127.0.0.1则强制 TCP。深入定位MySQL 监听情况sudonetstat-nltp|grep3306输出tcp6 0 0 :::33060 :::* LISTEN 76452/mysqld tcp6 0 0 :::3306 :::* LISTEN 76452/mysqld结论MySQL 只监听了tcp6IPv6 的::通配地址没有任何 IPv4 的tcp监听如0.0.0.0:3306。因此当客户端使用127.0.0.1IPv4 地址尝试连接时系统找不到对应的 IPv4 监听端口连接直接被拒绝或丢失。而mysql -h localhost能够成功是因为 MySQL 客户端默认使用 Unix socket绕过了 TCP/IP 协议栈。解决方案强制 MySQL 监听 IPv4 地址。编辑 MySQL 配置文件不同系统的路径可能略有不同sudovi/etc/mysql/mysql.conf.d/mysqld.cnf部分环境也可能是/etc/my.cnf或/etc/mysql/my.cnf请根据实际情况选择。在[mysqld]段中添加或修改[mysqld] bind-address 0.0.0.0注意如果看到skip-networking行请将其注释或删除该选项会禁用所有 TCP/IP 连接。保存并重启 MySQLsudosystemctl restart mysql再次检查监听端口sudonetstat-nltp|grep3306输出结果tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 76452/mysqld tcp6 0 0 :::3306 :::* LISTEN 76452/mysqld验证 IPv4 连接mysql-h127.0.0.1-P3306-uroot-p1234-eSELECT 1;此时应能成功连接应用启动异常也随之消失。追问为何 MySQL 安装后只监听了 IPv6从 MySQL 8.0.13 开始当bind_address未显式设置时其默认值为*表示会分别创建 IPv40.0.0.0和 IPv6::两个监听套接字。也就是说正常情况下使用netstat会同时看到tcp 0.0.0.0:3306和tcp6 :::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.bindv6onlyLinux 内核参数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只是在本案例中快速恢复业务使用了最简单的方式。愿你我都能在各自的领域里不断成长勇敢追求梦想同时也保持对世界的好奇与善意!