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,比如老版本里允许在授权的同时修改密码,但 8.0 已经把这个写法移除了。
从工程经验来看,最容易在初始化安装之后的第一个建号动作上踩坑。很多人在安装 MySQL 5.7 时,安装脚本会自动生成一个临时密码,写到了 /var/log/mysqld.log 里。你用临时密码登录后,第一件事就是想把密码改成自己常用的弱口令,此时必然弹出 1819;你已经知道密码规则了,绕过去即可。
除了手动建号和改密码,mysqld --initialize 之后那个临时密码因为是自动生成的一串强密码,所以不会触发 1819——那串临时密码本身已经满足所有复杂度要求,你通常要做的反而是把它改成符合自己习惯的密码。
2.2 从 MySQL 5.7 到 8.0 的账号体系差异
这条报错能在网络上常驻成热搜词,还有一个重要原因是 MySQL 8.0 默认认证插件改了。MySQL 5.7 默认用 mysql_native_password,而 MySQL 8.0 默认使用 caching_sha2_password。很多在新版本里执行创建用户命令时,如果只复制了网上的老代码,可能会同时遇到两个问题:一个是 ERROR 1819 密码策略不满足,另一个是程序连不上数据库,报错 Authentication plugin 'caching_sha2_password' cannot be loaded。
在排查 1819 的时候,不少人把认证插件和密码策略混在一起,改了好半天密码策略,最后还是连不上,其实那已经不是密码强度的问题了,而是驱动不支持新认证插件。区分起来很简单:如果创建用户或改密码时直接报 1819,那就查密码策略;如果工具能连接但连不上,并能看到明显的 authentication 相关提示,再考虑兼容性。
2.3 首次安装后的典型复现流程:你大概率会在这一步被卡住
为了方便下文理解,我把一段最标准的“遭遇战”流程复现出来:
-
启动 MySQL 服务,找到初始化生成的临时密码:
bash复制grep 'temporary password' /var/log/mysqld.log -
用临时密码登录:
bash复制
mysql -uroot -p -
输入一个自己熟悉的业务密码,比如
123456:sql复制ALTER USER 'root'@'localhost' IDENTIFIED BY '123456'; -
此时得到刺眼的报错:
code复制ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
整个过程不超过一分钟,新手就在这里愣住。接下来你可能会去搜索引擎找各种解决方案,大部分人的第一反应是把密码改得更长更长,比如搞个 MyPassword@123456,完了发现居然能过。这时候你以为是自己密码写得不够复杂,其实是 MEDIUM 策略下只需要长度 8、大小写各 1、数字 1、特殊字符 1 就基本能满足,很多看起来“复杂”的密码其实已经达到要求。
3. 三种排雷法:临时放行、合理降级、永久自定义策略
3.1 临时修改全局策略:适合开发环境快速跑通
如果你是在本地开发环境或者一次性测试环境里遇到 ERROR 1819,核心诉求就是要快速让弱密码生效。最简单的做法是把密码策略调低到 LOW,同时对长度下限也改小:
sql复制-- MySQL 5.7
SET GLOBAL validate_password_policy = LOW;
SET GLOBAL validate_password_length = 6;
-- MySQL 8.0
SET GLOBAL validate_password.policy = LOW;
SET GLOBAL validate_password.length = 6;
设置完成后,你的 6 位简单密码就能通过。但必须提醒一句:SET GLOBAL 是运行时修改,重启 MySQL 后会恢复默认值。所以这种方式适合“临时救火”,不适合作为长期策略。
还有一种更狠的临时方案,直接把校验组件卸载掉,但我不太推荐 5.7 用户这么干,因为卸载后忘了装回去,后面所有建号操作都会绕过强度校验:
sql复制-- 5.7 卸载插件
UNINSTALL PLUGIN validate_password;
-- 8.0 卸载组件
UNINSTALL COMPONENT 'file://component_validate_password';
卸载组件类操作,在生产环境改动太大,适合个人电脑上纯玩玩的场景。
3.2 固定写入配置文件:让自定义规则永久生效
假如你希望这个实例长期保持一个较低的密码强度要求,比如公司内部测试库的账号统一使用统一格式,那应该把配置写进 MySQL 的配置文件,而不是每次重启后再敲一遍 SET GLOBAL。
先确认你的配置文件在哪,不同安装方式的路径有区别:
- 通过二进制包或源码包安装在
/etc/my.cnf; - 通过 yum 安装在
/etc/my.cnf或/etc/my.cnf.d/下的子文件; - 通过 Docker 挂载方式,则需要把配置写进宿主机挂载路径下的自定义
.cnf文件。
下面是 MySQL 5.7 的一段配置示例:
ini复制[mysqld]
validate_password_policy=LOW
validate_password_length=6
validate_password_mixed_case_count=0
validate_password_number_count=0
validate_password_special_char_count=0
如果配置后没有生效,请检查两件事:
- 是不是放错了
[mysqld]段,放进[client]或其他段是不会有作用的; - 是否修改后重启了服务,配置类的变更必须等实例重新加载配置才会生效:
bash复制
systemctl restart mysqld
MySQL 8.0 的配置文件写法保持点号,示例如下:
ini复制[mysqld]
validate_password.policy=LOW
validate_password.length=6
validate_password.mixed_case_count=0
validate_password.number_count=0
validate_password.special_char_count=0
3.3 更精细的 STRONG 策略:字典文件到底什么用
先解释一下 LOW、MEDIUM、STRONG 三档的含义:
| Policy 取值 | 数值 | 校验内容 |
|---|---|---|
| LOW | 0 | 只校验密码长度是否满足 validate_password_length |
| MEDIUM | 1 | 在 LOW 基础上,增加大小写字母、数字、特殊字符数量校验 |
| STRONG | 2 | 在 MEDIUM 基础上,增加字典文件匹配,密码不能包含字典里的单词,且长度不能低于 4 的规则在部分逻辑里会更严格 |
LOW 不代表没有长度限制。如果你只把 validate_password_policy 改成 LOW,而 validate_password_length 依然是默认的 8,那么你写 123456 这类六位短密码依然会报 ERROR 1819。所以别忘了一条链路:改策略还得看长度,长度才是第一个门槛。
STRONG 档需要使用 dictionary_file 指定一个字典文件,格式是一行一个单词。假如你在开发服务器上设置了 STRONG,就会体验到什么叫“想个密码想破头”,因为一旦密码里包含了名字、公司名、admin、password 这类词,都会被挡在外面。互联网企业一般不会在生产库上开 STRONG 档,更多是银行、政务类项目里才会因为合规要求开到这档。
3.4 查看当前密码策略正确姿势:SHOW VARIABLES 输出辨析
无论你选择临时改还是永久配置,改完都要验证,验证建议直接用一条模糊匹配看全部参数:
sql复制SHOW VARIABLES LIKE 'validate_password%';
如果你改了配置并重启,但这里看到的默认值纹丝不动,那就别继续调参数了,优先排查配置文件的路径和段名。我自己踩过的坑是,CentOS 上通过 yum 安装的 MySQL 5.7 会在 /etc/my.cnf 里使用 !includedir /etc/my.cnf.d/ 这种写法,某些 .cnf 文件里的配置因为文件名不以 .cnf 结尾而被忽略,或者配置写在 [mysql] 段,导致一直不生效。
4. 从 1819 延伸出去:ERROR 2002、ERROR 1290、ERROR 1396 的高频关联问题
4.1 ERROR 2002:socket 找不到的三种处境
在 MySQL 安装和配置的搜索语境里,ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' 几乎是和 1819 同一批出现的高频错误。为什么呢?因为装完 MySQL、调完密码策略后的下一步,就是让程序或命令行工具去连接数据库,而 socket 连接失败会把你挡在第一步。
触发这个报错的原因通常有三个:
- MySQL 服务没启动:先确认进程到底有没有起来。
ps -ef | grep mysqld或systemctl status mysqld,没启动就先启动,不然后面一切免谈。 - socket 路径不一致:客户端默认去
/tmp/mysql.sock查找,而服务端实际把 socket 文件写到了/var/lib/mysql/mysql.sock。解决方式有两种,一种是指定连接时使用:bash复制
另一种是在客户端配置文件里加上 socket 路径。mysql -uroot -p -S /var/lib/mysql/mysql.sock - socket 目录权限不对:这种情况相对少见,但当你使用专用系统用户运行 mysqld,而 socket 目录对
mysql用户没有写权限时,就会出现服务起来了却无法生成 socket 文件的诡异现象。
当年排查一个 CentOS 环境时,最让我头疼的其实是日志已经明确告诉我们 socket 文件路径,但客户端工具就是连不上。后来发现是因为 /tmp 目录有特殊的清理机制,把 socket 文件清掉了,但 mysqld 还在运行。此时重启一次 MySQL 让 socket 重新生成就恢复了,这种情况在 Ubuntu 上尤其常见。
4.2 ERROR 1290:--skip-grant-tables 模式下的一个隐藏约束
不少人调密码强度时,因为忘了 root 密码,直接往配置里加了 skip-grant-tables 来免密登录,结果在跳过授权表的状态下执行 ALTER USER 想重置密码,会碰到另一个经典报错:
code复制ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement
翻译过来就是:现在服务处于跳过授权表模式,全局变量都认定你不需要登录验证,但与此同时你也不能执行需要操作授权表的语句。想修改密码、创建用户、授权等语句,会被直接拒绝。这也是很多搜索词里 ERROR 1290 和 ERROR 1 819 同时出现的原因——同样的使用场景是“忘了 root 密码,想要重置密码”,过程中会遇到多个报错。
正确操作顺序应该是:
- 在配置文件中加
skip-grant-tables后重启服务; - 用如下方式免密进入 MySQL:
bash复制
mysql -uroot - 先刷新权限让内存中的授权表重新加载:
sql复制
此时才能执行FLUSH PRIVILEGES;ALTER USER修改密码,但要注意:在 skip-grant-tables 模式下修改密码可能仍然失败,更稳妥的做法是退出后先移除配置项、正常重启再修改密码。如果确实想一条命令在跳过模式下完成改密,语法是:sql复制前提是你已经先执行过ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'YourNewPass@123';FLUSH PRIVILEGES;。
这里想额外说一句:skip-grant-tables 是应急方案,不是常规运维手段。一旦处理完密码问题,务必从配置文件里把这个参数删除或注释掉再重启服务。如果遗忘,数据库等同不设防,任何人都能免密登录,这在公网环境容易出现安全事故。
4.3 ERROR 1396:ALTER USER 操作不存在的或名称冲突的账号
ERROR 1396 (HY000): Operation ALTER USER failed for 'root'@'localhost' 是在你试图修改不存在的用户时出现的。通常发生在两个场景:
- 你并不确定账号是否存在,直接执行了 ALTER USER;
- 账号的实际 Host 跟命令里写的不匹配,比如实际是
'root'@'%',你写成了'root'@'localhost'。
查账号的正确姿势是:
sql复制SELECT user, host FROM mysql.user;
把输出里的 User 和 Host 拼出来,再执行你的操作。有些新手用户会在这里卡很久,是因为 root 账号可能同时存在多条记录,有的 host 是 localhost,有的是 127.0.0.1,有的是 %,它们其实是三个不同账号,需要分别处理。
4.4 Docker 环境中 MySQL 的密码策略与启动参数差异
Docker 部署 MySQL 已经成了很多开发者的默认姿势,但它和本机安装有一个非常大的区别:容器内运行的 mysqld 启动参数和初始化动作,很多是官方镜像脚本控制的。
如果在 Docker 容器里要临时修改密码策略,可以直接进入容器执行:
bash复制docker exec -it mysql-container mysql -uroot -p
然后在 MySQL 里执行 SET GLOBAL 修改策略。但如果你希望容器每次重建后都保持自定义密码策略,最佳方案是用配置挂载方式,而不是每次启动后手动执行:
yaml复制services:
mysql:
image: mysql:8.0
container_name: mysql-demo
environment:
MYSQL_ROOT_PASSWORD: "Root@123456"
MYSQL_DATABASE: demo
MYSQL_USER: demo
MYSQL_PASSWORD: "Demo@123456"
ports:
- "3306:3306"
volumes:
- ./mysql-conf.d:/etc/mysql/conf.d
- mysql-data:/var/lib/mysql
然后在宿主机 ./mysql-conf.d 目录下放一个自定义配置文件,比如 my-custom.cnf,内容写上:
ini复制[mysqld]
validate_password.policy=LOW
validate_password.length=6
有一个非常隐蔽的坑是:镜像首次启动时会通过环境变量 MYSQL_ROOT_PASSWORD 去初始化数据库。如果这个密码不满足 MySQL 默认的密码策略,镜像的初始化脚本可能会失败,或者你会看到日志中不断提示 1819。所以即使你在 Docker 里通过配置文件把策略调低了,首次初始化时环境变量里的密码也务必给一个复合复杂度的密码,让启动过程别在初始化阶段就炸掉。
另一个常见问题:在 MySQL 8.0 官方镜像中使用 mysql_native_password 插件建立的账号,如果代码里的数据库驱动版本太低无法支持 caching_sha2_password,会出现连接报错。通常建议创建账号时显式指定认证插件:
sql复制CREATE USER 'demo'@'%' IDENTIFIED WITH mysql_native_password BY 'Demo@123456';
这既能绕开部分驱动兼容问题,也能保证密码固定格式。
5. 一个异常现象复盘:密码满足所有参数为什么还是 1819
5.1 check_user_name 参数的隐形拦路虎
有一种情况特别诡异:你精心构造了一个密码,比如 Abcd#123,按规则算长度 8、大写 1、小写 3、数字 3、特殊字符 1,完全满足 MEDIUM 默认条件,但它还是弹了 1819。问题可能出在 validate_password.check_user_name 这个参数上。
这个参数的默认值是 ON,含义是“密码不允许和用户名相同或包含用户名”。当你建立一个用户 'abcd'@'localhost',然后设密码为 'Abcd#123' 时,因为密码里包含子串 abcd,触发了用户名校验,直接拒绝。此时你无论怎么增加密码长度,只要还包含 abcd,都会被拒绝。
解决方式:
- 改密码,把用户名相关的字符去掉;
- 或者把
check_user_name改成 OFF。
但要注意:check_user_name 并不是所有版本的 MySQL 都提供,它是 8.0 才加的参数。在 5.7 中如果想规避同样的问题,只能绕开用户名字段来设计密码,因为没有对应的参数可以关闭。
5.2 大小写敏感与特殊字符集解析差异
还有一个案例来自我熟悉的团队内部:某次在 MySQL 里设密码,用了一个全角特殊字符 @ 代替半角 @,结果被 1819 拦下。原因是校验规则里数的是半角特殊字符,全角字符可能被归到其他字符集或者不计入 special_char_count。类似情况还有中文特殊符号,比如中文输入法下的 #、!,看起来样子差不多,实际 ASCII 码不同。
所以如果你觉得密码复杂度已经满足但是还报错,先检查输入法状态,确认是半角字符。稳妥的做法是只用英文键盘能直接敲出的特殊字符,例如:
!@#$%^&*()-_=+[]{}
这些一般是能明确被识别为特殊字符的。
5.3 从 5.7 升级到 8.0 后老配置到底去哪个了
有些项目原来跑在 MySQL 5.7 上,密码策略是通过 install plugin validate_password soname 'validate_password.so' 方式启用的,后来原地升级到 8.0,发现策略竟然消失了。原因是 8.0 的 validate_password 改成了组件形式,默认安装的是组件的 .so,而老插件名不会自动迁移成组件模式。碰到这种情况,你需要重新安装组件:
sql复制INSTALL COMPONENT 'file://component_validate_password';
安装完后再次查看 SHOW VARIABLES LIKE 'validate_password%',如果能看到一堆点号风格的变量,那说明组件已生效。如果执行 SELECT * FROM mysql.component 查到了对应记录,说明安装成功。
升级场景里的另一个坑是:5.7 的配置文件中写的是下划线风格参数名,比如 validate_password_policy=LOW,8.0 的 MySQL 在启动时不认识这种老命名,可能会告警或直接忽略。所以升级到 8.0 后最好把配置块整体改成点号风格;否则可能发生一种奇怪现象:策略看起来是 LOW,实际行为还是默认 MEDIUM,或者配置文件里有一段完全没被加载。
6. 一键解决 1819 的思路:常规步骤和实测验证
6.1 标准处理流程(建号前先确认策略,改号后立刻验证)
我在实际处理这个问题时,总结了一个相对固定的“五步法”,适合开发环境、测试环境甚至小规模生产环境。你也可以把它固化到自己的初始化脚本里。
第一步:登录 MySQL,先查询当前策略。
sql复制SHOW VARIABLES LIKE 'validate_password%';
这一步的意义是搞清楚现状,不要盲目执行修改。
第二步:决定是否需要调整策略。
如果你能接受把密码改成强密码,那就不需要动策略,直接把密码设计成 大小写字母 + 数字 + 特殊字符 + 长度不少于 8 即可。如果你的需求和“业务系统约定俗成的弱密码”绑定,那可以按前面的方式降级。
第三步:选择合适的修改持久化方式。
- 只影响当前会话重启失效 →
SET GLOBAL; - 影响范围永久 → 配置文件中调整。
第四步:执行建号或改密操作,例如:
sql复制CREATE USER 'app_user'@'%' IDENTIFIED BY 'App_User@2025';
GRANT ALL PRIVILEGES ON app_db.* TO 'app_user'@'%';
FLUSH PRIVILEGES;
第五步:重新模拟弱密码操作进行验证。比如同样的场景想确认弱密码确实弹 1819,可临时用 123456 再试一次,观察到预期报错后,再改回正常流程建号,这样能让你的处理结论非常清晰。
6.2 用一条 SQL 看穿目标用户当前认证信息
很多人在处理完密码后还想再复核一下账号状态,可用下方 SQL:
sql复制SELECT user, host, plugin, password_lifetime, account_locked
FROM mysql.user
WHERE user = 'app_user';
观察 plugin 字段,能确认账号到底用的是 caching_sha2_password 还是 mysql_native_password。如果你创建账号时指定了 mysql_native_password,但程序驱动是较新版本,也可以正常连接;如果是老驱动连 caching_sha2_password,有可能会在握手阶段失败。
再补充一点:如果你已经开启了二进制日志,账号相关 DDL 也会记录日志,避免在高权限环境下反复切换密码策略,否则会在同步或恢复环境中产生策略不一致问题。
6.3 弱密码策略会在什么时候带来真正的风险:我的看法
讲了这么多修改方法,我的立场反而要给降级策略泼点冷水。如果不是必要场景,不要在生产环境把 validate_password.policy 降到 LOW,更不要顺手把 length 降到 8 以下。我见过不止一个团队为了图省事把密码策略关掉,结果半年后等来了暴力破解日志里的密密麻麻尝试记录。密码强度校验是最后一道相对容易的前置防御线,为一个常规业务账号去牺牲整个实例的密码安全感,不划算。
需要弱密码的场景通常有这些替代方式:
- 仅内部网络可达的测试库,可以考虑限制来源 IP + 单独设置专用账号;
- 本地开发环境,可以接受降级;
- 数据价值不高的沙箱环境,可以随意。
但如果你面对的是生产库,我强烈建议保留 MEDIUM 作为底线,甚至可以顺手把 check_user_name 保持默认开启状态,避免业务账号的用户名出现在密码里。
7. 最后的实操总结与经验备注
7.1 逐版本对照处理建议
| MySQL 版本 | 查看方式 | 修改运行时 | 修改持久化 |
|---|---|---|---|
| 5.6 / 5.7 | SHOW VARIABLES LIKE 'validate_password%' | SET GLOBAL validate_password_policy = LOW; | my.cnf [mysqld] validate_password_policy=LOW |
| 8.0 | SHOW VARIABLES LIKE 'validate_password%' | SET GLOBAL validate_password.policy = LOW; | my.cnf [mysqld] validate_password.policy=LOW |
| 8.0 组件未安装时 | SHOW VARIABLES LIKE 'validate_password%' 无结果 | INSTALL COMPONENT 'file://component_validate_password' | 安装后如需配置再加 |
7.2 生产环境中遇到 1819 的先问自己三句话
第一句:这个密码是给谁用的?如果是 root 或 DBA 的高权限账号,别降级策略,直接生成强密码更明智。如果是应用账号,可以考虑在应用层配置中心里统一保存密码,而不是登录时手敲一个弱密码。
第二句:这个环境是几版 MySQL?5.7 和 8.0 的变量名风格完全不同,别把网络教程里的老代码无脑复制到 8.0 里执行。
第三句:改完策略后重启服务会不会丢配置?记得区分运行时与持久化配置的关系,否则下次机器重启,1819 又会重新回来找你。
我个人在实际操作中最常用的一句话是:不要只盯着密码长度这个单一维度。每次看到 1819,我都先把 SHOW VARIABLES 的结果打印出来,逐项看哪项为 0、哪项为 1、默认长度是多少;然后再分析自己设置的密码离每一档规则还差几个条件。这套“先看规则,再设计密码”的思路,远比在网上搜索形形色色的“绕过姿势”要可靠。如果你把 validate_password 的机制理解透了,ERROR 1819 这个吓人的编码,后面对你而言不过是一个“再检查一下大小写、数字、特殊字符和长度”的善意的提醒而已。
