validate_password插件未生效需先验证是否加载:执行SHOW VARIABLES LIKE 'validate_password%';,若无返回则插件未加载;检查plugin_dir路径下文件存在性,并在配置文件中正确配置plugin_load_add = validate_password。

validate_password 插件没生效?先确认它真被加载了
MySQL 启动后插件未必自动启用,validate_password 就是典型——装了不等于在用。最直接的验证方式是查系统变量:SHOW VARIABLES LIKE 'validate_password%';。如果返回空,说明插件压根没加载。
常见错误现象:改了配置、重启了 MySQL,但依然能设 123456 这种密码,CREATE USER 或 ALTER USER 完全不报错。
- Linux 下检查插件路径是否正确:
plugin_dir值(用SELECT @@plugin_dir;查),确保validate_password.so(或.dll)文件真实存在 - 配置文件中必须写
plugin_load_add = validate_password(MySQL 8.0.19+ 推荐用install_plugin命令,但配置文件方式更稳定) - MySQL 5.7 默认不启用,8.0 默认启用但可能被配置覆盖;别信“装完就生效”,一定要手动验证
密码策略等级(validate_password.policy)怎么选才不翻车
validate_password.policy 控制校验严格程度,取值 0(LOW)、1(MEDIUM)、2(STRONG)。但它的实际行为严重依赖其他参数,不是调高数字就万事大吉。
使用场景:开发环境常设为 1,生产环境建议至少 1,但设成 2 前务必确认客户端兼容性——比如旧版 JDBC 驱动或某些运维脚本会因密码生成失败直接中断。
- 设为 2(STRONG)时,
validate_password.dictionary_file必须指定且文件可读,否则插件初始化失败,MySQL 可能拒绝启动 - 即使设为 1(MEDIUM),若
validate_password.length设为 12,而应用代码里硬编码了 8 位密码逻辑,就会在ALTER USER时突然报错ERROR 1819 (HY000): Your password does not satisfy the current policy requirements -
validate_password.number_count、validate_password.uppercase_count等参数默认是 1,但如果你关掉了大小写校验(设为 0),那policy=1实际效果可能退化到接近 0
MySQL 8.0 中 validate_password 和 caching_sha2_password 的冲突
MySQL 8.0 默认认证插件是 caching_sha2_password,而 validate_password 对密码哈希前的明文做校验——这本身没问题。但问题出在部分客户端连接时,会跳过密码强度检查。
常见错误现象:用 mysql -u root -p 命令行能设弱密码,但在应用程序里执行 CREATE USER ... IDENTIFIED BY '123' 却报错;或者反过来。
- 根本原因是:命令行客户端默认走 socket 连接(本地),而某些版本的 MySQL 对本地连接会绕过部分安全插件校验;网络连接则严格校验
- 解决方法不是关插件,而是统一连接方式:测试时用
mysql -h 127.0.0.1 -u root -p强制走 TCP,才能复现真实生产行为 - 如果应用用的是老版本 Connector/J(caching_sha2_password 支持不完整,再叠加密码策略,容易在握手阶段就断连,错误信息可能是
Public Key Retrieval is not allowed,和密码强度无关但常被误判
卸载或临时禁用 validate_password 的安全代价
别为了“快速通过 CI 测试”就运行 UNINSTALL PLUGIN validate_password;。一旦卸载,所有策略参数(validate_password.length 等)立刻失效,且 MySQL 不会警告你——下次重启后你以为策略还在,其实已裸奔。
真正需要临时放宽时,只该调低策略等级,而不是移除插件:
- 临时改策略:
SET GLOBAL validate_password.policy = 0;,但注意这仅对新连接生效,已有连接不受影响 - 想彻底关闭校验?不行。MySQL 不提供“全局停用”开关,
validate_password.length = 0是非法值,会报错ERROR 1231 (42000) - 最隐蔽的坑:Docker 环境里如果用
my.cnf挂载配置,但容器启动时 MySQL 已提前读取了旧配置并加载插件,挂载的新配置可能被忽略——得进容器执行SET PERSIST才真正持久化
密码策略不是挡箭牌,是最后一道提醒。真正危险的从来不是“设不了弱密码”,而是“以为设了强密码,结果策略根本没跑”。



















