上周把一个老项目从 MySQL 8.0 升到 8.4,mysqld --initialize 阶段直接失败,翻 error log 末尾看到一行:Plugin 'mysql_native_password' is not loaded。当时第一反应是某个初始化脚本里写了 IDENTIFIED WITH mysql_native_password,可我把项目翻了个底朝天也没找到这样的语句。真正的问题出在 my.cnf 里一条从 5.7 时代一直抄下来的配置:default_authentication_plugin=mysql_native_password。
从 MySQL 8.0 开始,官方默认认证插件就换成了 caching_sha2_password,到 8.4 时 mysql_native_password 默认不再加载,配置里再让服务端拿它当默认认证,自然就炸了。那这个报错到底怎么解?是退回老版本,还是把项目里所有账号改一遍,或者干脆让 8.4 把旧插件打开?我花了一晚上把几条路都试了一遍,下面按实际排查顺序写清楚,希望能让同样被这个报错卡住的人少走点弯路。如果你是从 8.0 之后就没再关注过认证插件变化的老开发,这篇也值得花五分钟看完。
1. 我踩到的现场:同一句报错,三种不同姿势
1.1 启动即挂的场景
先说第一种。升级后第一次执行初始化或者直接启动 mysqld,服务起不来,error log 里能看到 Plugin 'mysql_native_password' is not loaded。这种场景一般不是代码在显式创建旧认证账号,而是 my.cnf 或启动参数里带着一句类似 default_authentication_plugin=mysql_native_password 的配置。
这句配置在 5.7 升 8.0 的早期确实有效。当时大量用了多年的老驱动不支持 caching_sha2_password,DBA 只能靠它把新建用户的默认认证方式拉回旧协议。可到了 8.4,插件默认不加载,服务启动时尝试把这个插件设成默认认证,直接报错退出。
这种场景下,一开始最容易被误导。我见过有人把配置删掉,服务起来了,可一查 mysql.user 发现所有存量账号的 plugin 字段还是 mysql_native_password,后面一连接又炸第二次。
1.2 应用连不上:报错和实际根因隔着一层
第二种场景更隐蔽。服务端运行正常,是某个老应用连不上了。数据库 error log 里能看到 Plugin 'mysql_native_password' is not loaded 或者 authentication plugin ... cannot be loaded;应用端的报错则五花八门,常见的是 Access denied for user,甚至会提示密码错误。很多人的第一反应是去重置密码,其实问题根本不在这。
为什么会有这种隔层现象?因为服务端验证握手的顺序是:先按 mysql.user 找到账号对应的 plugin,发现这个 plugin 没加载,直接就按认证失败处理了。客户端看到的是 Access denied,服务端日志才暴露真正原因——不是密码不对,是账号指定的认证插件不存在。
如果你正好遇到“密码明明对,但就是连不上”,不要急着改密。先去看服务端 error log,再查询确认账号的 plugin 字段。
1.3 建账号时被拦下,ERROR 1524
第三种最直白。DBA 在 8.4 上执行:
sql复制CREATE USER 'app'@'%' IDENTIFIED WITH mysql_native_password BY 'YourPass123';
MySQL 直接返回:
code复制ERROR 1524 (HY000): Plugin 'mysql_native_password' is not loaded
这个错码 1524 的意图很明确:不是语法错误,是你指定的插件当前在服务端不可用。类似情况还有执行 ALTER USER ... IDENTIFIED WITH mysql_native_password 把存量账号改回去时会遇到。
这时候就别折腾 SQL 了,先去解决“服务端没加载这个插件”这个前置条件。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 从 5.7 用到 8.4 的老配置,为什么突然成了雷
2.1 mysql_native_password 的版本沉浮
MySQL 8.0 发布时,默认认证插件从 mysql_native_password 换成了 caching_sha2_password。那会儿最大的争议就是它带来大量兼容性问题——PHP 老版本、JDBC 老驱动、部分客户端工具全被卡住。许多项目为了平稳过渡,都把 default_authentication_plugin=mysql_native_password 写死在了配置里,于是 8.0 虽然跑着新版本,实际密码校验走的还是五六年以前的逻辑。
mysql_native_password 本身并没有立刻消失。8.0 时代它还在服务端内置,只是不再是默认项,所以老配置一直没出问题。到了 8.4 LTS,官方把它默认禁用;到了 9.0,直接把它从发行版里移除。也就是说,你在 8.4 上还能找到把它重新打开的入口,到 9.0 基本上没有回头路了。
如果你的服务是 9.x,又刚好听到“加一行配置就能解决”的言论,建议先确认对方说的版本是不是 8.4,别在 9.x
