![MySQL 无法通过“localhost”连接,只能通过 127.0.0.1](https://linux22.com/image/556934/MySQL%20%E6%97%A0%E6%B3%95%E9%80%9A%E8%BF%87%E2%80%9Clocalhost%E2%80%9D%E8%BF%9E%E6%8E%A5%EF%BC%8C%E5%8F%AA%E8%83%BD%E9%80%9A%E8%BF%87%20127.0.0.1.png)
这对我来说有点神秘。我连接 MySQL 的唯一方法是通过“127.0.0.1”调用它...例如,我的 PHP 连接脚本无法与 localhost 配合使用
我正在运行 Mac OS X Lion,内置 apache2、MySQL、PHP、phpMyAdmin
mysql管理员:
count 0
debug-check FALSE
debug-info TRUE
force FALSE
compress FALSE
character-sets-dir (No default value)
default-character-set auto
host (No default value)
no-beep FALSE
port 0
relative FALSE
socket (No default value)
sleep 0
ssl FALSE
ssl-ca (No default value)
ssl-capath (No default value)
ssl-cert (No default value)
ssl-cipher (No default value)
ssl-key (No default value)
ssl-verify-server-cert FALSE
user (No default value)
verbose FALSE
vertical FALSE
connect-timeout 43200
shutdown-timeout 3600
plugin-dir (No default value)
default-auth (No default value)
答案1
如果您告诉 MySQL 连接到“localhost”,它将尝试连接到 unix 套接字。如果您告诉它连接到 127.0.0.1,则强制它连接到网络套接字。因此,您可能已将 MySQL 配置为仅监听网络套接字,而不监听文件系统套接字。
很难说清楚你的 unix 套接字到底出了什么问题。但我建议你阅读这一页MySQL 参考指南。这应该对你有帮助。
更新:根据更新的问题:参数“socket”应该是这样的:“/var/lib/mysql/mysql.sock”。参考手册中的这一页还有更多信息。
这是我的 /etc/my.cnf 文件的开头:
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
您的文件应该类似。然后您的问题应该就解决了。在测试之前,不要忘记重新启动 MySQL 服务器。
答案2
您可能启用了 IPv6,很可能 localhost 解析为 ipv6 localhost,而这未在您的 msql 配置中定义。
我也遇到了一个问题,我必须将“localhost”添加到该用户允许的子网中而不是“127.0.0.1”,不明白为什么(我使用的是 ipv4,那是前一段时间了)但值得一试。
答案3
对我来说,OSX 的内置 php 配置为使用与 homebrew 的 mysql 不同的 unix-socket。因此它无法通过使用该套接字的 localhost 进行连接。
我通过将 php 配置的套接字路径符号链接到 mysql 实际使用的套接字路径来快速修复它。
sudo ln -s /tmp/mysql.sock /var/mysql/mysql.sock
以下诊断命令非常有用。
检查 php 和 mysql 使用的默认套接字路径:
php -i | fgrep 'mysql.default_socket'
mysql -e 'show variables where variable_name = "socket"'
使用指定的套接字连接:
php -r 'var_dump(mysql_connect("localhost:/tmp/mysql.sock", "user", "pass"));'
mysql --socket=/tmp/mysql.sock
确定 mysql 客户端使用哪种套接字进行连接:
lsof | egrep '^mysql .*(IPv|unix)'
答案4
我可以在我的测试箱上重现与您相同的症状,希望这会有所帮助。
在 MySQL 中,用户由两部分定义(名称和主机)。默认情况下,MySQL 将有 3 个 root 用户:
mysql> SELECT host,user,password FROM mysql.user WHERE user='root';
+-----------------------+------+-------------------------------------------+
| host | user | password |
+-----------------------+------+-------------------------------------------+
| localhost | root | |
| localhost.localdomain | root | |
| 127.0.0.1 | root | *PASSWORD_HASH_GOES_HERE |
+-----------------------+------+-------------------------------------------+
密码字段要么为空(无密码),要么存储哈希值。如果您为某个特定用户设置密码,则不会自动更新所有密码,因为 MySQL 会将他们视为不同的用户。
例如:
mysql> set password for 'root'@'127.0.0.1' = password('Password');
将更新 的密码'root'@'127.0.0.1'
,但不会'root'@'localhost'
或'root'@'localhost.localdomain'
看一下skip_name_resolve
变量:
mysql> show variables like 'skip_name_resolve';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| skip_name_resolve | ON |
+-------------------+-------+
1 row in set (0.00 sec)
默认情况下skip_name_resolve
为OFF
,并将尝试将所有 IP 地址解析为主机名。例如,如果您以 身份连接'root'@'127.0.0.1'
,MySQL 将更改为 以 身份连接您'root'@'localhost'
。
如果是ON
,MySQL 会将和视为不同的用户'root'@'127.0.0.1'
并进行连接'root'@'localhost'
。他们可能有不同的密码,具体取决于密码的设置方式。
因此首先,我要检查密码是否有差异:
mysql> SELECT host,user,password FROM mysql.user WHERE user='root';
如果有,您可以修复它们,或者继续调查。
然后我会检查skip_name_resolve
:
mysql> show variables like 'skip_name_resolve';
如果是ON
,我会找出它被设置的位置(例如/etc/my.cnf
)并将其删除,除非有需要。
希望这对你有帮助!