CREATE USER必须指定host,默认'localhost'导致远程无法连接;MySQL 8.0默认认证插件为caching_sha2_password,旧客户端需显式指定mysql_native_password;GRANT后无需FLUSH PRIVILEGES。

CREATE USER 语句必须指定 host,否则默认为 'localhost',远程连不上
MySQL 用户是 user@host 组合,不是单看用户名。只写 CREATE USER 'alice' 等价于 CREATE USER 'alice'@'localhost',这个用户只能从本机连——哪怕你用的是 Docker 或云服务器,只要客户端 IP 不是 127.0.0.1 或 ::1,就会报 Access denied for user 'alice'@'xxx.xxx.xxx.xxx'。
实操建议:
- 明确指定 host:
CREATE USER 'alice'@'%'(允许任意 IP),或更安全的'alice'@'192.168.1.%'、'alice'@'app-server.example.com' - 避免用
'%'开放生产库,尤其不要搭配GRANT ALL PRIVILEGES - 如果用 MySQL 8.0+,密码策略默认启用,需满足长度和复杂度要求,否则报
Failed to set password for 'alice'@'%'
GRANT 后必须执行 FLUSH PRIVILEGES 吗?不,通常不用
GRANT 语句本身会自动重载权限表,FLUSH PRIVILEGES 是手动触发重载,仅在直接修改 mysql.user 等系统表后才需要。误加这句不会报错,但多一次无谓操作,还可能掩盖权限未生效的真实原因(比如没指定正确 host)。
常见错误现象:
- 执行
GRANT SELECT ON mydb.* TO 'alice'@'%'后仍连不上 → 实际是CREATE USER时用了'alice'@'localhost',而连接时走的是远程 IP - 执行
GRANT后查不到新权限 → 忘了IDENTIFIED BY或密码过期,应检查SELECT user, host, account_locked, password_expired FROM mysql.user WHERE user = 'alice'
MySQL 8.0 的默认认证插件变了,老应用可能连不上
MySQL 8.0 默认用 caching_sha2_password 插件,而很多旧客户端(如某些 PHP 7.2 扩展、老旧 JDBC 驱动)只支持 mysql_native_password。创建用户时不显式指定,就容易出现 Client does not support authentication protocol requested by server。
实操建议:
- 兼容旧客户端:创建时加
IDENTIFIED WITH mysql_native_password BY 'p@ssw0rd' - 用新插件但升级客户端:确认驱动版本支持(如 MySQL Connector/J 8.0.15+)
- 临时改全局默认(不推荐):
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'xxx',只改必要账号
授予权限时,ON 子句的数据库名不能用通配符 * 匹配模式,只能是字面量或 *
GRANT SELECT ON `myapp_%`.* TO 'alice'@'%' 是无效语法,MySQL 不支持库名通配(不像 SHOW DATABASES LIKE)。想批量授权多个库,只能逐个写,或用脚本生成 SQL。
使用场景与替代方案:
- 微服务多租户库(
tenant_a,tenant_b…):用mysqldump --all-databases备份时也得注意权限是否覆盖全库 - 想限制只读:用
GRANT SELECT, SHOW VIEW ON `mydb`.* TO 'reporter'@'%',别漏掉SHOW VIEW(否则查视图报错) - 最小权限原则:避免
GRANT ALL PRIVILEGES ON *.*,尤其是给非 DBA 账号;DROP和FILE权限风险极高
真正容易被忽略的是 host 粒度和认证插件的组合影响——同一用户名、不同 host 的记录在 mysql.user 表里是独立行,权限互不影响;而插件类型一旦设错,连登录都卡在握手阶段,根本进不了权限校验环节。










