localhost连接失败本质是unix socket路径不匹配:mysql对localhost强制走socket文件通信,127.0.0.1才走tcp/ip;需同步配置my.cnf中[mysqld]、[client]、[mysql]三段socket路径,并确保php.ini中mysqli.default_socket等对应项一致,最后重启服务。

localhost 连不上但 127.0.0.1 能连,基本就是 Unix socket 路径不一致,不是权限、端口或服务没启的问题。
为什么 localhost 和 127.0.0.1 行为完全不同
MySQL 对 localhost 是硬编码走 Unix socket 文件通信,完全绕过 TCP/IP;而 127.0.0.1 被当成普通 IPv4 地址,走的是 3306 端口。所以两者根本不在同一套链路上——连通性互不相关。
典型错误是:ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock'。括号里那个路径,就是客户端“以为”该找的位置,但它很可能压根不存在,或者服务端根本没写到那儿。
- 先确认服务端实际 socket 路径:
mysqld --verbose --help 2>/dev/null | grep "socket" - 再检查客户端是否真在用这个路径——
mysql --socket=/var/lib/mysql/mysql.sock -u root -p手动指定试试 - 别信“我改过 my.cnf”,很多教程只改
[mysqld]段,漏了客户端段,等于白改
my.cnf 必须同步配置三个 section 的 socket
MySQL 客户端程序(包括命令行 mysql、PHP 的 mysqli、Python 的 pymysql)启动时,会按顺序读取配置段:[client] → [mysql] → [mysqld]。前两者没配,就 fallback 到编译默认值(比如 /tmp/mysql.sock),而服务端可能在 /var/lib/mysql/mysql.sock 写文件——自然报错。
必须确保三处路径完全一致:
[mysqld] socket=/var/lib/mysql/mysql.sock <p>[client] socket=/var/lib/mysql/mysql.sock</p><p>[mysql] socket=/var/lib/mysql/mysql.sock</p>
- 路径必须和
mysqld --verbose --help输出的一致,大小写、斜杠方向都不能错 - 配置文件里不能有中文标点、全角空格、不可见 Unicode 字符——MySQL 会静默跳过整行,且不报错
- 改完必须重启服务:
systemctl restart mysqld,不重启配置不生效
PHP 应用连不上 localhost?别指望 my.cnf,得看 php.ini
PHP 的 MySQL 扩展(mysqli、PDO_mysql)不读 my.cnf,而是依赖 php.ini 中的独立配置项。即使 my.cnf 全配对了,PHP 还是可能连不上。
检查并修改以下三项(路径需和服务端一致):
mysqli.default_socket = /var/lib/mysql/mysql.sockPDO_mysql.default_socket = /var/lib/mysql/mysql.sock-
mysql.default_socket = /var/lib/mysql/mysql.sock(仅 PHP 5.x 旧版)
改完记得重启 Web 服务:systemctl restart php-fpm 或 systemctl restart apache2,否则 PHP 不会加载新配置。
IPv6 环境下 localhost 解析成 ::1 导致失败
某些系统(如 macOS、新版 Linux)的 /etc/hosts 里,localhost 默认同时映射 127.0.0.1 和 ::1。MySQL 如果只授权了 'root'@'127.0.0.1',没给 'root'@'::1' 权限,用 localhost 就可能因解析成 IPv6 地址而被拒绝。
验证方式:ping localhost 看返回的是 IPv4 还是 IPv6 地址;或者直接试:mysql -h ::1 -u root -p。
- 如果
::1能连,说明是授权问题:进 MySQL 执行CREATE USER 'root'@'::1' IDENTIFIED BY 'xxx'; GRANT ALL ON *.* TO 'root'@'::1'; FLUSH PRIVILEGES; - 更简单粗暴的临时方案:在连接字符串里显式指定
-h 127.0.0.1,绕过解析
真正容易被忽略的点在于:socket 路径不一致 + 客户端配置段遗漏 + PHP 单独一套配置体系,三者叠加,排查时很容易只盯一个环节就放弃。











