grant执行成功但权限不生效,主因是host匹配失败、网络配置错误(如bind-address=127.0.0.1)、认证插件不兼容(如caching_sha2_password)或账户被锁/密码过期。

GRANT 执行成功 ≠ 用户能访问数据库。权限没生效、匹配不上 host、网络不通、认证插件不兼容——这四类问题占了 90% 以上的“授权后连不上”。
用户登录后 SHOW DATABASES 只见 information_schema 和 performance_schema
这不是权限没给,而是权限没“对上号”:
-
GRANT SELECT ON mydb.* TO 'user'@'%'→ 用户只能看到mydb,其他库不可见;想看到所有库,得给SELECT权限到*.*(或至少mysql库的SELECT,否则连mysql都查不到) - 用户用
mysql -h 192.168.1.100 -u user -p登录,MySQL 实际匹配的是'user'@'192.168.1.100',不是'user'@'%'——%不会反向解析 IP 字面量(除非skip_name_resolve=ON且 DNS 失败) - 执行
SELECT User, Host FROM mysql.user WHERE User = 'user';,确认返回的Host值是否与登录时的 host 完全一致
bind-address 还是 127.0.0.1,远程授权就是摆设
即使 'user'@'%' 权限写得再全,只要 MySQL 只监听本地回环地址,外部 TCP 包根本进不来:
- 检查配置文件(如
/etc/mysql/mysql.conf.d/mysqld.cnf或/etc/my.cnf)中[mysqld]段的bind-address—— 若为127.0.0.1,必须注释掉或改为0.0.0.0 - 改完不重启服务,配置不会加载;验证是否生效:
ss -tln | grep :3306,输出里应含*:3306或0.0.0.0:3306,而非仅127.0.0.1:3306 - 云服务器上还要确认安全组放行 3306 入方向,不能只开系统防火墙(如
ufw)
caching_sha2_password 插件导致连接闪断或 Access denied
这不是权限问题,是握手阶段失败:
- 运行
SELECT User, Host, plugin FROM mysql.user WHERE User = 'user';,看plugin列是不是caching_sha2_password - PHP 7.4 以下、Navicat 12 以下、部分 JDBC 驱动默认不支持该插件;临时解决:
ALTER USER 'user'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd'; - 不建议全局改默认插件(影响所有新用户),只针对出问题的用户单独调整
用户被锁、密码过期,或 account_locked = 'Y'
权限和网络都通,但登录后立刻被踢,或者 SHOW GRANTS 返回空,大概率是账户状态异常:
- 执行
SELECT User, Host, account_locked, password_expired FROM mysql.user WHERE User = 'user'; - 若
account_locked = 'Y',用ALTER USER 'user'@'%' ACCOUNT UNLOCK;解锁 - 若
password_expired = 'Y',需重置密码:ALTER USER 'user'@'%' IDENTIFIED BY 'newpwd';
真正容易被忽略的,是 host 匹配的精确性——% 不等于“任意字符串”,它不参与 IP 地址字面量的反向匹配;而 bind-address 和 account_locked 这两个字段,往往在排查路径里被跳过。











