MySQL的localhost不等于127.0.0.1吗?

28
$ mysql -u root -h 127.0.0.1 -e 'show tables' created_from_host;
+-----------------------------+
| Tables_in_created_from_host |
+-----------------------------+
| test                        |
+-----------------------------+

$ mysql -u root -h localhost -e 'show tables' created_from_host;
ERROR 1049 (42000): Unknown database 'created_from_host'

$ cat /etc/hosts
127.0.0.1       localhost.localdomain localhost
127.0.0.1       localhost
::1     localhost6.localdomain6 localhost6

怎么可能呢?主要问题是 - 如何为root用户从所有主机授予所有数据库的所有特权?

更新:

$ mysql -u root -h 127.0.0.1 -pzenoss -e "show grants";
+----------------------------------------------------------------------------------------------------------------------------------------+
| Grants for root@localhost                                                                                                              |
+----------------------------------------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY PASSWORD '*3715D7F2B0C1D26D72357829DF94B81731174B8C' WITH GRANT OPTION |
| GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION                                                                           |
+----------------------------------------------------------------------------------------------------------------------------------------+
$ mysql -u root -h localhost -pzenoss -e "show grants";
+----------------------------------------------------------------------------------------------------------------------------------------+
| Grants for root@localhost                                                                                                              |
+----------------------------------------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY PASSWORD '*3715D7F2B0C1D26D72357829DF94B81731174B8C' WITH GRANT OPTION |
| GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION                                                                           |
+----------------------------------------------------------------------------------------------------------------------------------------+

更新2:

zends> SHOW GLOBAL VARIABLES LIKE 'skip_networking';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| skip_networking | OFF   |
+-----------------+-------+
1 row in set (0.00 sec)

zends> SELECT user,host FROM mysql.user WHERE user='root'; 
+------+-----------------------+
| user | host                  |
+------+-----------------------+
| root | 127.0.0.1             |
| root | ::1                   |
| root | localhost             |
| root | localhost.localdomain |
+------+-----------------------+
4 rows in set (0.00 sec)

你从 $ ping localhost 得到什么? - kery
@kery 来自localhost.localdomain (127.0.0.1)的64字节:icmp_seq=1 ttl=64 time=0.029毫秒 - Bunyk
1
如果出现这种情况,那么问题可能出在您的授权上。您需要授予'root'@'localhost'或类似用户权限。 - kery
我不确定你实际上在问什么,但是是的,mysql会将localhost和127.0.0.1区别对待。localhost适用于从本地主机通过IPC机制(例如Unix域套接字)进行的连接。127.0.0.1适用于来自本地主机的TCP/IP连接。当您运行mysql命令行工具时也会发生同样的情况,-h localhost使用Unix套接字连接,-h 127.0.0.1使用TCP/IP。这些可能会使您连接到不同的mysql服务器实例。 - nos
4个回答

14

我知道这个帖子很旧,但可能没有得到正确的答案。

默认情况下,mysql会进行名称解析,因此127.0.0.1和localhost将解析为同一个。但是,在my.cnf中可以关闭名称解析:

skip-name-resolve = 1

然后localhost和127.0.0.1将不再相同。因此,您要么保留名称解析,要么仅在授权中使用localhost或仅使用127.0.0.1 但是:如果选择后者,则还必须使用这些凭据访问我们的数据库。


1
实际上,我认为这个答案是错误的。Mysql和localhost vs. 127.0.0.1的问题在于mysql以不同的方式处理localhost,它使用unix套接字连接而不是tcp。这意味着,在GRANT中使用用户主机127.0.0.1和localhost并不会产生相同的结果。 - Bachi

14

正如您在这里所看到的,如果没有主机名或使用主机名localhost,UNIX mysqld将使用套接字。

因此,这使得它有所不同,在GRANT系统中,这种差异变得明显。


11

通过 127.0.0.1 登录并执行此语句:

SHOW GRANTS

你可能会看到类似下面的内容

GRANT ALL ... 'root'@'127.0.0.1'

我在本地安装中确认了一下,似乎MySQL无法自动解析主机名。你可以为 localhost 添加另一个授权,或者使用 127.0.0.1。


授权对于每个主机看起来都是一样的,但是本地主机和127.0.0.1可以访问的数据库是不同的。我更新了相关问题中的“屏幕截图”以说明这一点。 - Bunyk

1

这在MacOS上设置本地开发环境时会出现问题。

一些脚本函数,比如php中的mysqli_connect()可能使用localhost连接到MySQL:你不应该在每个脚本中都用127.0.0.1替换localhost

尝试通过在my.cnf文件中添加bind-address=localhostsocket=/var/mysql/mysql.socksocket=/tmp/mysql.sock等来修复此问题,但没有成功。

要解决此问题(在MacOS上),请注意/etc/php.ini文件中的mysql.default_socket设置指向/var/mysql/mysql.sock,而MySQL的default_socket是/tmp/mysql.sock

因此,要么编辑您的php.ini文件,要么创建一个软链接到MySQL的default_socket:

mkdir /var/mysql
ln -s /tmp/mysql.sock /var/mysql/mysql.sock

P.S - MySQL 将 127.0.0.1 视为 TCP 连接,将 localhost 视为 Unix 套接字连接:详细信息在此


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接