mysql 8.0中create user失败主因是validate_password插件拦截弱密码、caching_sha2_password认证插件不兼容旧客户端,以及host未显式指定;需先show variables like 'validate_password%'查策略,再set global validate_password.policy=low等调低要求,并显式指定identified with mysql_native_password方可成功建户。

MySQL 8.0 中 CREATE USER 不是“输完就完事”,必须处理密码策略、认证插件和 host 匹配三件事,否则连建都建不成功。
CREATE USER 报 ERROR 1819:密码不满足策略要求
这是最常见卡点——不是语法错,是 MySQL 8.0 默认启用了 validate_password 插件,密码太短、缺大小写或特殊字符就会直接拒绝。错误信息形如:ERROR 1819 (HY000): Your password does not satisfy the current policy requirements。
实操建议:
- 先查当前策略:
SHOW VARIABLES LIKE 'validate_password%';,重点关注validate_password.policy(0=LOW,1=MEDIUM,2=STRONG) - 测试环境可临时降级:
SET GLOBAL validate_password.policy = LOW;(注意:仅会话级生效,重启失效) - 生产环境别关策略,改用合规密码:至少 8 位,含大小写字母 + 数字 + 特殊字符,例如
'MyDB@2026!' - 空密码在 MySQL 8.0+ 完全禁止,
IDENTIFIED BY ''会报错
客户端连不上:caching_sha2_password 插件不兼容
用户能建成功,但 Python、PHP 或老版 Navicat 死活连不上,报错类似:Client does not support authentication protocol——大概率是默认的 caching_sha2_password 插件惹的祸。
实操建议:
- 旧客户端(如 MySQL Connector/J 5.x、PyMySQL CREATE USER 'app'@'%' IDENTIFIED WITH mysql_native_password BY 'MyDB@2026!';
- 确认插件是否生效:
SELECT plugin FROM mysql.user WHERE User = 'app' AND Host = '%';,结果应为mysql_native_password - 新项目且客户端明确支持 SHA2(如 MySQL Shell、Connector/J 8.0+),可保留默认:
CREATE USER 'api'@'localhost' IDENTIFIED BY 'MyDB@2026!';
host 写成 '%' 却连不了本地?localhost 和 127.0.0.1 是两个账号
执行了 CREATE USER 'dev'@'%',命令行用 mysql -u dev -p 能连,但程序用 127.0.0.1 就报 Access denied——因为 MySQL 把 'dev'@'localhost' 和 'dev'@'%' 当作完全独立的账号,而 Unix socket 连接(无 host 指定时)默认走 localhost,TCP 连接走 127.0.0.1 或 %。
实操建议:
- 若需本机 TCP 连接(比如 Docker 容器内连宿主机),必须显式创建
'dev'@'127.0.0.1'或'dev'@'localhost'(后者只接受 socket) - 想统一覆盖本地所有方式?建两个:
CREATE USER 'dev'@'localhost' ...和CREATE USER 'dev'@'127.0.0.1' ... - 生产环境禁用
'user'@'%',改用具体网段如'app'@'192.168.10.%',避免暴露到公网
CREATE USER 后权限仍不生效:GRANT 和 FLUSH PRIVILEGES 的关系
CREATE USER 只建账号,不带任何权限;GRANT 才真正赋权。但很多人授完权还连不上,是因为没理清权限层级或忽略刷新动作。
实操建议:
-
GRANT SELECT ON mydb.* TO 'dev'@'localhost';允许查mydb下所有表,但USE mydb;仍可能失败——因为USAGE权限(连接能力)虽隐式存在,但数据库级操作(如USE)依赖SELECT等对象权限是否覆盖当前库 - 最小权限起步:不要用
GRANT ALL PRIVILEGES ON *.*,限定到具体库甚至表:GRANT SELECT, INSERT ON app.orders TO 'app'@'192.168.10.%'; - MySQL 8.0+ 中
GRANT会自动重载权限表,FLUSH PRIVILEGES;非必需;但如果你手动改过mysql.user表,就必须执行它 - 验证权限是否到位:
SHOW GRANTS FOR 'dev'@'localhost';
最容易被忽略的是 host 匹配的精确性——MySQL 查权限时按 User@Host 字符串逐字匹配,'user'@'localhost' 和 'user'@'127.0.0.1' 完全不互通,连错 host 就等于连错账号。











