【MySQL】可以用localhost或者127.0.0.1 连接,但不能用IP连接的问题

本文介绍如何为MySQL数据库配置远程访问权限,包括创建新用户、分配权限及刷新权限等步骤。

MySQL数据库版本:5.7.20

MySQL 默认是没有开启这个权限的(只允许使用 host:localhost或者 host:127.0.0.1),如果想用host:192.168.1.* ,来访问MySQL,需要手动开启这个权限。

 

进入MySQL终端输入这个命令
 

 

1、打开 开始\MySQL\MySQL 5.7 Command Line Client。

2、输入密码后,执行以下命令分配新用户。

grant all privileges on *.* to '用户名'@'IP地址' identified by '密码';

命令返回:

Query OK, 0 rows affected, 1 warning (0.06 sec)

3、执行完上述命令后用下面的命令刷新权限。

flush privileges;

4、之后关闭mysql服务,然后启动mysql服务,大功告成。

 

<think>我们面对的现象是:连接 `localhost` 成功,但连接 `127.0.0.1` 失败,并出现 `SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known` 错误。这是一个非常特殊的情况,因为通常 `localhost` 和 `127.0.0.1` 都指向本地机器。下面我们逐步分析原因并给出解决方案。 ### 原因分析 1. **IPv4与IPv6解析差异**: - `localhost` 在大多数系统中被配置为同时指向 IPv4 地址 `127.0.0.1` 和 IPv6 地址 `::1`。 - 当使用 `localhost` 时,系统可能会优先尝试 IPv6 地址 `::1`(如果 IPv6 可用),而 `127.0.0.1` 是纯 IPv4 地址。 - 如果数据库服务只监听了 IPv6 地址(`::1`)而没有监听 IPv4 地址(`127.0.0.1`),那么连接 `localhost`(通过 IPv6)会成功,而连接 `127.0.0.1`(IPv4)就会失败。 2. **数据库服务监听配置**: - MySQL/MariaDB 默认配置可能只监听 IPv6 的 `::1` 地址,或者同时监听 IPv4 和 IPv6,但有时配置可能仅绑定IPv6。 - 检查数据库服务的绑定地址配置: - 在 MySQL 配置文件中(如 `/etc/mysql/my.cnf` 或 `/etc/mysql/mariadb.conf.d/50-server.cnf`): ``` [mysqld] bind-address = ::1 # 只监听IPv6 # bind-address = 127.0.0.1 # 只监听IPv4 # bind-address = 0.0.0.0 # 监听所有IPv4地址 ``` - 如果看到 `bind-address = ::1`,则说明数据库服务只监听 IPv6 地址。 3. **系统 hosts 文件配置**: - 检查 `/etc/hosts` 文件(Windows 为 `C:\Windows\System32\drivers\etc\hosts`): - 正常情况下应有: ``` 127.0.0.1 localhost ::1 localhost ``` - 如果 `127.0.0.1` 的映射被删除或注释,可能导致直接使用 `127.0.0.1` 时出现问题(但通常不会,因为这是系统保留地址)。 4. **防火墙设置**: - 虽然本地连接一般不经过防火墙,但仍需检查: - 是否防火墙阻止了 IPv4 本地回环(`127.0.0.1`)的数据库端口(3306),而允许 IPv6(`::1`)通过。 5. **PHP 网络配置**: - 某些 PHP 配置可能影响网络地址解析,例如: - 禁用了 IPv4 支持(极少见)。 - 存在特定主机名解析配置(如 `/etc/nsswitch.conf`)的问题。 ### 解决方案 #### 步骤1:验证数据库监听地址 1. 使用 `netstat` 或 `ss` 命令检查数据库监听的地址: ```bash sudo netstat -tulnp | grep mysql # 或 sudo ss -tulnp | grep mysql ``` 输出示例: ``` tcp LISTEN 0 70 127.0.0.1:3306 0.0.0.0:* users:(("mysqld",pid=123,fd=23)) tcp LISTEN 0 70 [::1]:3306 [::]:* users:(("mysqld",pid=123,fd=24)) ``` 如果只有 `[::1]:3306`(IPv6)而没有 `127.0.0.1:3306`(IPv4),则说明数据库未监听 IPv4 地址。 2. **修改数据库配置**: - 编辑 MySQL 配置文件(位置因系统而异): ```bash sudo vim /etc/mysql/mariadb.conf.d/50-server.cnf ``` - 修改 `bind-address` 为以下任意一种: - 同时监听 IPv4 和 IPv6:`bind-address = 0.0.0.0`(注意:这会让数据库监听所有网络接口,包括公网IP,需配合防火墙确保安全) - 或同时指定两个地址(某些版本支持):`bind-address = 127.0.0.1,::1` - 如果只需要本地访问,建议同时监听两个地址,或根据实际需求选择。 - 重启数据库服务: ```bash sudo systemctl restart mysql ``` #### 步骤2:检查系统 hosts 文件 确保 `/etc/hosts` 包含: ``` 127.0.0.1 localhost ::1 localhost ``` #### 步骤3:防火墙检查 尽管本地回环地址通常不受防火墙限制,但仍可检查: ```bash sudo iptables -L -n -v | grep 3306 sudo ip6tables -L -n -v | grep 3306 ``` 确保没有规则阻止 `127.0.0.1:3306` 的访问。 #### 步骤4:调整 PHP 连接方式 如果无法修改数据库配置,可在 PHP 中强制使用 IPv6 地址连接: - 使用 IPv6 的本地地址 `::1`(用方括号包裹): ```php // PDO 连接示例 $dsn = 'mysql:host=[::1];dbname=testdb;charset=utf8'; ``` 或在 ThinkPHP 配置中: ```php return array( 'DB_HOST' => '[::1]', // 使用 IPv6 ); ``` #### 步骤5:测试网络连通性 使用 `telnet` 分别测试 IPv4 和 IPv6 的数据库端口: ```bash telnet 127.0.0.1 3306 # 应该失败(如果未监听) telnet ::1 3306 # 应该成功(如果监听 IPv6) ``` ### 总结 当连接 `localhost` 成功而 `127.0.0.1` 失败时,核心原因是**数据库服务仅监听 IPv6 地址**。解决方案包括: 1. 修改数据库配置以同时监听 IPv4 地址(推荐)。 2. 在 PHP 中直接使用 IPv6 地址 `[::1]` 连接。 > **注意**:修改数据库配置后需重启服务。若使用云服务器,注意安全组规则仅开放给必要IP。[^1][^3] §§相关问题§§ 1. 如何查看 MySQL 服务的绑定地址? 2. 如何配置 MySQL 同时监听 IPv4 和 IPv6? 3. 在 PHP 中如何使用 IPv6 地址连接数据库? </think>### 连接 `localhost` 成功但 `127.0.0.1` 失败的原因及解决方案 #### 核心问题分析 当出现 `SQLSTATE[HY000] [2002]` 错误时,连接 `localhost` 成功但 `127.0.0.1` 失败,通常源于 **IPv4/IPv6 解析冲突**: 1. **IPv6 优先机制** - `localhost` 在支持 IPv6 的系统中默认解析到 `::1`(IPv6 地址)[^3] - `127.0.0.1` 是纯 IPv4 地址 - 若数据库服务仅监听 IPv6(如 MySQL 默认配置),则会拒绝 IPv4 连接 2. **服务监听配置问题** 通过命令验证监听状态: ```bash ss -tuln | grep 3306 # 检查数据库端口监听情况 ``` - 若输出含 `:::3306` 不含 `127.0.0.1:3306`,说明仅监听了 IPv6 3. **系统 hosts 配置异常** 检查 `/etc/hosts`: ```plaintext 127.0.0.1 localhost # 必须存在 ::1 localhost # IPv6映射 ``` --- ### 解决方案(逐步操作) #### 方法1:强制数据库监听 IPv4(推荐) 1. 修改 MySQL 配置: ```bash sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf ``` 2. 将 `bind-address` 改为: ```ini bind-address = 0.0.0.0 # 监听所有IP # 或 bind-address = 127.0.0.1 # 仅IPv4 ``` 3. 重启服务: ```bash sudo systemctl restart mysql ``` #### 方法2:PHP 中显式使用 IPv6 语法 在数据库配置中使用 IPv6 地址格式: ```php // ThinkPHP 示例 return [ 'DB_HOST' => '[::1]', // 方括号包裹 IPv6 地址 'DB_PORT' => '3306', //... ]; ``` > 此方法无需修改数据库配置[^3] #### 方法3:禁用 IPv6(临时方案) 1. 临时禁用 IPv6: ```bash sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1 sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1 ``` 2. 永久禁用需编辑 `/etc/sysctl.conf`: ```ini net.ipv6.conf.all.disable_ipv6=1 net.ipv6.conf.default.disable_ipv6=1 ``` --- ### 验证步骤 1. **测试端口连通性**: ```bash telnet 127.0.0.1 3306 # 检查IPv4 telnet ::1 3306 # 检查IPv6 ``` 2. **PHP 连接测试脚本**: ```php <?php try { $pdo = new PDO("mysql:host=127.0.0.1;port=3306", 'user', 'pass'); echo "Connected via IPv4!"; } catch (PDOException $e) { echo "IPv4 Failed: " . $e->getMessage(); } ``` 3. **监听状态复查**: ```bash sudo netstat -tulnp | grep mysql ``` > **注意**:云服务器需同时检查安全组规则是否放行 `127.0.0.1`[^1]
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值