GRANT命令中host参数必须显式指定,不可省略或留空;须写成'username'@'host'格式,否则报错;授权后需执行FLUSH PRIVILEGES生效,MySQL 8.0+建议先CREATE USER再GRANT,并注意认证插件兼容性。

GRANT 命令中 host 参数必须显式指定,不能省略或留空
MySQL 的 GRANT 语句要求明确声明用户可从哪些主机连接,host 字段不是可选的默认值。如果你只写 GRANT ... TO 'user',会报错 ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement 或更常见的 ERROR 1133 (42000): Can't find any matching row in the user table——因为没带 @'xxx',MySQL 不知道你要操作哪个用户实体。
常见错误写法:
GRANT ALL ON *.* TO 'admin'; -- ❌ 缺少 @host,语法错误
正确写法必须包含 @ 和 host 值:
-
GRANT ALL ON *.* TO 'admin'@'localhost':仅本机可连 -
GRANT ALL ON *.* TO 'admin'@'%':任意 IP(注意防火墙和 bind-address 限制) -
GRANT SELECT ON sales.* TO 'reporter'@'192.168.5.100':仅来自该 IP 的只读访问 -
GRANT INSERT ON logs.* TO 'writer'@'192.168.5.%':匹配整个 C 段子网
% 和 _ 在 host 中的通配行为与 LIKE 不同,不支持混合使用
MySQL 的 host 字段在权限匹配时用的是「字符串前缀匹配」,不是 SQL 的 LIKE 模式。这意味着:
-
'%'表示「任意长度字符串」,但只允许出现在开头或结尾,不能中间出现(如'192.168.%.10'是非法 host 值) -
'_'在host中无通配含义,就是字面下划线字符,不会被解释为单字符占位符 -
'%.example.com'合法,表示所有子域名;'db_.prod'合法,但只匹配字面含db_.prod的主机名,不是通配
所以别指望 '192.168._.10' 能匹配 192.168.5.10——它只会当普通字符串查,找不到对应记录。
授权后必须执行 FLUSH PRIVILEGES,否则新权限不生效
MySQL 把权限缓存在内存里,GRANT 只是修改了 mysql.user 表,不会自动重载到运行时权限系统。跳过这步是远程连不上最常被忽略的原因之一。
执行顺序不能颠倒:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 先
GRANT(或CREATE USER+GRANT) - 再
FLUSH PRIVILEGES
注意:如果用的是 MySQL 8.0+,且之前用户不存在,推荐分两步操作更稳妥:
CREATE USER 'api'@'%' IDENTIFIED BY 'secret123';<br>GRANT SELECT, INSERT ON app_db.* TO 'api'@'%';<br>FLUSH PRIVILEGES;
直接 GRANT ... IDENTIFIED BY 在 8.0+ 中虽支持,但若用户已存在,密码不会被更新(除非加 ALTER USER),容易误以为授权成功实则密码没变。
MySQL 8.0+ 连不上?大概率是 plugin 认证插件不兼容
执行 SELECT host, user, plugin FROM mysql.user,如果看到 root 或你的用户 plugin 是 caching_sha2_password,而客户端(如 Navicat、旧版 JDBC 驱动、某些 Python MySQL 库)不支持,就会报 ERROR 2059 (HY000)。
临时解法(开发/测试环境可用):
- 改回兼容模式:
ALTER USER 'api'@'%' IDENTIFIED WITH mysql_native_password BY 'secret123'; - 立即生效:
FLUSH PRIVILEGES;
生产环境建议升级客户端驱动,而不是降级服务端认证方式——caching_sha2_password 更安全,且多数主流工具 2022 年后版本均已支持。
另外确认 bind-address 没被锁死为 127.0.0.1,以及系统防火墙(如 ufw、iptables)放行了 3306 端口——这两点不在 SQL 层,但常和 GRANT 问题一起出现,排查时容易漏掉。










