DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

MySQL 虚拟机 127.0.0.1 能连,localhost 报 2002:显式选择 TCP

Unix 宿主机通过端口转发连接虚拟机 MySQL,127.0.0.1 正常而 localhost 报 socket 2002 时,显式选择 TCP,核对宿主机端口与实际客户端配置。

MySQL 放在 VirtualBox 等虚拟机内,宿主机已把数据库端口转发到本机。mysql -h 127.0.0.1 可以登录,换成 mysql -h localhost 却报下面这类错误:

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

这是错误形式示例,socket 路径随客户端安装方式而变。对 Linux、macOS 等 Unix 环境中的 mysql 命令行客户端,localhost 默认选择 Unix socket。它不会因为 localhost 能解析为 127.0.0.1,就自动使用已配置的 TCP 端口转发。

报错里出现 socket,先确认连接方式

虚拟机内 MySQL 的 socket 文件位于虚拟机自己的文件系统。宿主机上的 mysql 客户端查找 /tmp/mysql.sock,找不到它,并不能证明虚拟机数据库没有启动。宿主机与虚拟机也不是同一个操作系统内核,仅把两边配置成相同路径无法共享 Unix socket。

如果明确的 127.0.0.1 连接已经成功,就先保留这条可用连接,核对失败命令是否改用了 socket。给 -h localhost 增加 -P 3306 在默认 socket 连接下也没有作用:TCP 端口参数不会把 socket 连接变成 TCP。

这条规则限定于相关 Unix 客户端行为。Windows 的本地连接还可能涉及共享内存或命名管道,其他语言驱动也可能采用不同规则,应按实际客户端判断。

通过端口转发连接,就显式选择 TCP

以下是供读者使用的连接示例。13306 是假设的宿主机转发端口,app_user 和 app_db 应换成已获授权的账户和数据库;-p 会提示输入密码:

mysql --protocol=TCP -h 127.0.0.1 -P 13306 -u app_user -p app_db

转发关系可能是宿主机 13306 到虚拟机 3306。这里填写宿主机入口端口,不是看到服务端监听 3306 就照填。若保留 -h localhost,也可用 --protocol=TCP 显式指定传输方式;仍需确认 localhost 解析出的地址与转发监听地址一致。

命令成功后,在 mysql 客户端内查看连接状态,确认 Connection 字段显示 TCP/IP:

status

再确认连接到预期实例和数据库,避免本机另一个 MySQL 恰好占用了同一个端口。连接成功只是传输与认证已经通过,实际业务仍须用原应用配置验证。

改了虚拟机配置,宿主机客户端不会自动读取

虚拟机 /etc/mysql/my.cnf 中的 [mysqld] 决定那里的服务端行为,[client] 只影响能够读取该文件的客户端。宿主机上的 mysql 不会自动使用虚拟机内的 [client] socket=...。

如果需要持久化 TCP 选项,应修改实际运行 mysql 的那台机器上生效的客户端配置,先备份原文件。不要为了这条报错更改服务端数据目录或删除 socket 文件,也不要把虚拟机所有网卡端口开放到公网。

若强制 TCP 后变成连接拒绝或超时,再查宿主机转发入口、虚拟机目标端口和监听地址。若变成 Access denied,说明已进入认证阶段,应核对连接来源匹配的账号与权限,不能继续按 socket 文件缺失处理。

如果原本就是要访问宿主机上的本地数据库,而不是虚拟机,则应核对该本地服务实际使用的 socket 路径,并选择正确的 --socket。只有确认目标就在本机且 socket 可访问时,这条分支才适用。

修复标准是:原工作流程使用明确的连接参数,状态显示预期的传输方式,实际实例与数据库正确,应用所需查询能够完成。仅将 localhost 改为 IP 后能登录,还要把这组参数同步到真正失败的脚本或客户端;配置调整出现问题时恢复先前备份和已确认可用的连接参数。