ERROR 1819 (HY000) 这个报错,只要是手动装过 MySQL、建过账号的人,十有八九都撞到过。明明 SQL 语句写得没问题,密码也按常规套路设置了一个看起来挺复杂的,结果 MySQL 直接甩回来一句:Your password does not satisfy the current policy requirements。我第一次遇到这个错误是在给测试环境搭库的时候,当时心里还嘀咕:这密码大小写、数字、特殊符号都齐了,哪条政策不满足啊?后来把 validate_password 那套机制彻底翻了一遍才发现,问题不在于“密码长得够不够复杂”,而在于“你的 MySQL 实例用哪套标准在衡量复杂度”。这个报错背后的策略、参数、适配规则,以及在不同版本、不同安装方式下的差异,值得单独拿出来讲透。
这篇文章不只是为了让你把这个报错消掉,而是把这套“密码校验机制”本身拆开来看:触发它的条件是什么、修改策略的正确姿势是什么、哪些参数在 MySQL 8.0 里改名了、在 Docker 容器里装 MySQL 和直接在 CentOS 上装 MySQL,遇到这个报错时的排查思路差在哪。同时也会覆盖 ERROR 2002、ERROR 1290、ERROR 1396 这几个在安装和账号操作过程中经常和 1819 一起出现的高频 MySQL 报错,该避的坑也一并列出来。
1. 这个报错到底是谁抛出来的:走进 validate_password 的历史和它干的事
1.1 MySQL 的密码复杂度校验不是天生就有的
如果你用的是很老的 MySQL 5.5 或者更早的版本,那你大概率没碰过 ERROR 1819。原因很简单:老版本压根没有内置的密码复杂度校验插件,你设密码哪怕只写一个 a,MySQL 也会照单全收。真正让这套机制开始进入大众视野,是 MySQL 5.6.6 版本之后把 validate_password 插件正式纳入。到了 MySQL 5.7,这个插件在很多发行版的默认安装中已经直接生效了,于是大批开发者和 DBA 就撞上了那个经典的 ERROR 1819 (HY000)。
MySQL 官方在 8.0 里又做了一个很重要的调整:插件统一改名为组件式管理,validate_password 变成了 validate_password 组件,但它的核心功能——检查密码长度、大小写字母、数字、特殊字符——并没有变,变的是一部分参数名和查看方式。
这里我建议你把“插件”和“组件”两个概念在脑子里分开理解。插件在 5.7 时代是独立的 .so 库,INSTALL PLUGIN 去启用;组件在 8.0 时代更强调安装和卸载的原子性,你用的是 INSTALL COMPONENT 来加载。从用户使用角度看,validate_password 提供的功能基本一致,但如果你拿着 5.7 的笔记在 8.0 上直接敲,很可能因为参数名不一样而对不上号。
1.2 一套复杂的规则,却只暴露了一句话:错误信息的提示谜题
很多第一次碰到 ERROR 1819 的人都会条件反射地问:“密码到底哪里不满足?”MySQL 抛出的这行错误只告诉你密码不符合当前策略要求,但不会告诉你具体是哪一项没过。也就是说,MySQL 没有给出类似“你缺了大写字母”或者“你密码太短了”这类精确反馈,这给新手排查增加了很多不必要的负担。
实际上,你只需要执行下面这条 SQL 就能看到这个“不近人情”的规则全貌:
sql复制SHOW VARIABLES LIKE 'validate_password%';
假如你是在 MySQL 8.0 里执行,输出大概长这样:
| 变量名 | 值 | 含义解释 |
|---|---|---|
| validate_password.changed_characters_percentage | 0 | 密码中必须更改的字符数占密码总长度的百分比,默认不限制 |
| validate_password.check_user_name | ON | 密码是否允许与用户名相同,默认不允许 |
| validate_password.dictionary_file | 空 | 字典文件的路径,用于阻止包含常用词或字典词的密码 |
| validate_password.length | 8 | 密码最短长度 |
| validate_password.mixed_case_count | 1 | 大写字母和小写字母各至少需要的个数 |
| validate_password.number_count | 1 | 数字至少需要的个数 |
| validate_password.policy | MEDIUM | 密码强度策略:0/LOW、1/MEDIUM、2/STRONG |
| validate_password.special_char_count | 1 | 特殊字符至少需要的个数 |
也就是说,ERROR 1819 背后的规则,力度几乎都集中在这 8 个参数上。不同 MySQL 版本的参数前缀不一样:
- MySQL 5.7 里直接用
validate_password_开头,下划线风格; - MySQL 8.0 里改成
validate_password.开头,点号风格。
如果你拿 5.7 的写法在 8.0 里执行 SHOW VARIABLES LIKE 'validate_password%',结果其实也能显示出来,因为 % 模糊匹配。但如果你用 5.7 的 SET 语法去动态修改 8.0 的变量,部分老写法会直接报错或没有生效,这也是为什么网上很多教程在 8.0 上会出现“照做了却没反应”的怪现象。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 一条通知如何拿到完整账号体系:得先看一个点:官方模板下执行的完整链路
2.1 什么时候最容易触发 1819:CREATE USER、ALTER USER 与 SET PASSWORD
这个报错绝不是只在某一个特定命令下出现。所有涉及“给账号设置密码”的操作,都有可能会被拦截:
sql复制CREATE USER 'demo'@'localhost' IDENTIFIED BY '123456';
ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';
SET PASSWORD FOR 'demo'@'localhost' = '123456';
为什么很少有人写 GRANT 触发它?因为 GRANT 通常是在账号已经创建的前提下授权,你不改密码就不会触发校验密码的逻辑。不过有一种情况可能会用到 GRANT ... IDENTIFIED BY,比如老版本里允许在授权的同时修
