error 1819 是因 mysql 8.0+ 默认启用 validate_password 插件,在 create user 或 alter user 语句解析阶段即拦截 identified by 后的密码,按当前策略(如 length、mixed_case_count 等)实时校验,不满足则终止执行、不写入用户表;需用 set global 正确顺序设置 policy=0 及各依赖参数,并常配合指定 mysql_native_password 插件方可解决。

因为 MySQL 8.0 默认加载了 validate_password 插件,且策略设为 MEDIUM,任何 CREATE USER 或 ALTER USER 操作在执行前就会被拦截校验——不满足长度、大小写、数字、特殊字符要求,直接报 ERROR 1819,根本不会走到密码赋值那步。
validate_password 插件如何在语句执行前就拦截?
它不是“改完密码再检查”,而是在 SQL 解析阶段就介入:只要语句里带 IDENTIFIED BY,插件立刻读取当前策略参数(如 validate_password.length),拿你写的密码去比对。不达标就终止执行,连用户记录都不会写入 mysql.user 表。
- 即使你用
UPDATE mysql.user SET authentication_string = ...绕过语法校验,MySQL 8.0 也会在下次登录时拒绝认证(因caching_sha2_password对弱哈希敏感) -
SHOW VARIABLES LIKE 'validate_password%'返回非空结果,说明插件已生效;返回空行则插件未加载,此时ERROR 1819不会出现 - 插件状态与 MySQL 启动时是否加载
plugin-load-add=validate_password.dll(Windows)或validate_password.so(Linux)强相关
为什么 SET GLOBAL validate_password.policy=0 有时仍失败?
常见原因是参数名写错或顺序不对。MySQL 8.0+ 的变量名带英文点号,不是下划线;且 policy 必须先设,其他参数才生效。
- 错:
SET GLOBAL validate_password_policy = 0→ 报Unknown system variable - 对:
SET GLOBAL validate_password.policy = 0 - 必须同步清零依赖项:
SET GLOBAL validate_password.length = 4、SET GLOBAL validate_password.mixed_case_count = 0、SET GLOBAL validate_password.number_count = 0、SET GLOBAL validate_password.special_char_count = 0 - 仅改
policy不改length,密码仍需 ≥8 位;仅改length不降policy,大小写/数字/特殊字符仍被强制要求
为什么指定 mysql_native_password 有时是必需的?
caching_sha2_password 是 MySQL 8.0 默认认证方式,它内部对密码哈希处理更严格,即使 validate_password 策略已放宽,仍可能因密码太短导致哈希生成失败,最终登录报错。
- 安全但兼容性差:旧客户端(如某些 PHP 扩展、DataGrip 旧驱动)不支持该插件
- 显式指定更可靠:
CREATE USER 'test'@'localhost' IDENTIFIED WITH mysql_native_password BY '123' - 若已有用户,先改认证方式再改密码:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123';
真正容易被忽略的是:插件参数修改后,只影响后续新建/修改操作,对已存在的弱密码用户无影响;而 caching_sha2_password 和 validate_password 是两层独立校验,漏掉任一层都可能卡住。











