MySQL 8.4升级后ERROR 1524报错:原因与修复方案详解
刚升级完 MySQL 8.4 的第二天凌晨值班群就炸了。运维同事把一段报错甩进来ERROR 1524 (HY000): Plugin mysql_native_password is not loaded。配上一句所有用旧密码规则的账号全连不上了怎么办。我盯着这行报错看了三秒钟脑子里立刻浮现出过去一年里在好几个项目里都见过的同款场景——这根本不是一句重新装一下插件就能解决的问题背后是 MySQL 认证插件体系的一次大换血。这个报错看起来很短短到很多人会误判它的严重程度。但如果你不清楚 MySQL 8.0 以来认证插件的变化脉络、不知道自己当前版本对旧插件的支持情况很容易在错误的路线上浪费一两个小时。更麻烦的是处理不当还会把自己锁在数据库外面。这篇文章我尽量把话说透这个报错的真正含义、三条可落地的修复路径、以及我在实际运维中踩过的那些细节坑。1. 认识这条报错报错信息背后的真实逻辑1.1 报错发生的三种典型触发场景先明确一个容易混淆的事实ERROR 1524不是登录失败时报的错。它在绝大多数情况下是你主动执行了涉及认证插件的语句时服务端给出的拒绝响应。最容易触发它的三个场景分别是第一你执行了类似这样的ALTER USER语句想把某个账号的认证方式改回旧插件ALTER USER app_user% IDENTIFIED WITH mysql_native_password BY MyPass_2024;第二你在创建新账号时显式指定了旧插件CREATE USER legacy_app% IDENTIFIED WITH mysql_native_password BY Legacy_123;第三你在配置文件中写了default_authentication_pluginmysql_native_password然后新创建一个不指定认证插件的用户服务端按照默认插件去创建账号时同样会抛出这个错误。注意这三种场景的共性它们都是写入操作也就是你试图让某个账号使用mysql_native_password这个插件而服务端告诉你这个插件没加载我没法给你安排。还有一种情况容易被忽略——如果你的历史账号在mysql.user表里的plugin字段本来就写着mysql_native_password而插件未加载时这些账号登录会报另外的错误通常是ERROR 1525 (HY000): Authentication plugin mysql_native_password cannot be loaded。所以 1524 和 1525 经常成对出现一个在改账号配置时爆出来一个在登录时爆出来。后面做诊断时它们其实指向同一个根源。1.2 mysql_native_password 的前世今生为什么好好地说没就没了要理解这个报错得先搞清楚mysql_native_password在 MySQL 发展史中的位置。mysql_native_password是 MySQL 5.x 时代就存在的认证插件算法基于 SHA1 加一个加盐过程。它在当时是绝对的主流几乎百分之九十以上的应用连接 MySQL 时都在用它。但是 SHA1 算法这些年已经被认为不够安全存在已知的理论攻击和实际碰撞风险。所以从 MySQL 8.0 开始官方把默认认证插件换成了caching_sha2_password这玩意儿在安全性和性能之间做了更合理的取舍传输层面支持 RSA 公钥加密或 TLS 保护同时对高频重复认证做了内存缓存优化不用每次连接都走完整的加密流程。关键点来了MySQL 8.0 刚发布的时候虽然默认插件换成了新插件但mysql_native_password仍然是内置的、默认加载的。这就让很多人产生了一种错觉——这个插件永远都在。直到 MySQL 8.0.34 开始官方把它标记为废弃再到 2024 年的 MySQL 8.4 LTS 版本官方直接把它改成了默认不加载。你需要在启动参数或者配置文件里显式打开它才存在。到了 MySQL 9.0这个插件更是被彻底删除连打开的机会都没有了。所以当你看到is not loaded这个措辞时请翻译成更直白的版本不是这个插件文件丢了而是这个插件在我这个版本里默认不受欢迎了我故意不加载它。理解到这一层后面所有修复思路的出发点就清晰了——要么想办法让它重新加载要么干脆换个新插件用。1.3 服务端到底在检查什么从 MySQL 服务端的源码逻辑来说当ALTER USER ... IDENTIFIED WITH plugin_name执行时服务端的账号管理代码会去插件的注册表里查这个插件是否存在。这个注册表就是SHOW PLUGINS命令的输出如果目标插件不在这张表里就直接返回ERROR 1524。这里有一个很多人不理解的细节MySQL 8.0 里的mysql_native_password是编译进服务端二进制里的它不像早期版本那样需要通过INSTALL PLUGIN从.so文件里加载。所以你去执行INSTALL PLUGIN mysql_native_password SONAME mysql_native_password.so大概率会得到一个plugin already loaded或者找不到对应文件的提示——因为它根本不在插件库里它是二进制的内置部分。8.4 版本之所以不加载这个内置插件是通过一个开关变量实现的后面我会详细说。2. 动手修复前三个诊断步骤把局面看清楚接到这个报错先别急着敲命令。我自己吃过亏曾经在一台 MySQL 8.0.28 的环境上按 8.4 的修复思路去处理白白折腾了半天。不同版本、不同插件状态下正确解法完全不同。2.1 第一步确认当前 MySQL 版本版本决定了你的恢复路线版本mysql_native_password 状态是否能启用MySQL 8.0.0 ~ 8.0.33默认加载可用可直接使用MySQL 8.0.34 ~ 8.0.x默认加载但已标记废弃可直接使用MySQL 8.4 LTS默认不加载可通过配置启用MySQL 9.0已从内置中移除无法启用确认命令很简单只要你能以任何方式连进去执行SELECT VERSION();如果你已经因为别的原因连不进去了可以看数据目录下的data目录里有没有版本号文件或者直接看启动日志。日志里通常在初始化阶段会打一行Version: 8.4.0 socket: ...。2.2 第二步确认插件的加载状态如果还能连进 MySQL直接执行SHOW PLUGINS;输出里找mysql_native_password这一行重点看Status字段。如果是ACTIVE说明插件在那你面临的可能是别的权限或语法问题如果这一行根本不存在说明插件确实没加载。更精确的查询方式SELECT PLUGIN_NAME, PLUGIN_STATUS, PLUGIN_TYPE FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME mysql_native_password;这个查询的结果更直观返回空行就是不支持返回一行且状态是ACTIVE就是可用如果插件被禁用这里通常也查不到。2.3 第三步摸清受影响的账号范围无论走哪条修复路线你都要知道有多少账号依赖旧插件、有多少应用因为它们的认证方式变化会受影响。这一步的执行SELECT user, host, plugin FROM mysql.user WHERE plugin mysql_native_password;把查出来的结果导出一份后面无论是要批量改密码还是要跟应用团队对齐客户端兼容性这份清单都是最基础的依据。这里我额外提醒一句在 MySQL 8.0 的mysql.user表里plugin字段值是NULL的账号表示使用服务端当前默认认证插件。这类账号通常不受本次报错影响修复时不用慌着动它们。真正要处理的就是那些明确写着mysql_native_password的账号。3. 修复方案一让旧插件重新上岗如果你的 MySQL 版本是 8.4 LTS而业务短期内没法升级客户端驱动这是最常见的情况尤其是一些维护多年的老旧 Java/PHP 应用那最务实的做法就是把mysql_native_password这个内置插件重新启用。这个方案一劳永逸能让所有历史账号行为完全不变化但需要重启数据库实例。3.1 修改配置并重启实例在my.cnf的[mysqld]段下面增加一行[mysqld] mysql_native_passwordON在 MySQL 8.4 里mysql_native_password是一个布尔类型的系统变量默认值是OFF。把它打开之后服务端在启动阶段就会注册这个内置插件。改完配置执行一次平滑重启mysqladmin -u root -p shutdown # 或者 systemctl restart mysqld重启完成后再执行一次SHOW PLUGINS确认mysql_native_password已经出现并且状态是ACTIVE。到这一步之前报ERROR 1524的那些ALTER USER、CREATE USER语句就都能正常执行了。提示MySQL 8.4 还支持启动时用--mysql-native-passwordON参数临时开启适合你想临时确认效果、又不想改配置文件的场景。但生产环境建议走配置文件毕竟你不可能每次重启都手动加参数。3.2 不想重启试试在线加载的错误理解这里必须纠正一个很常见的误区。很多人会想这个插件不是内置的吗那我能不能在运行状态下直接加载它现实是MySQL 8.4 里mysql_native_password不通过插件库文件加载所以你在运行状态下执行INSTALL PLUGIN mysql_native_password SONAME mysql_native_password.so;你会得到一个找不到文件或者类似提示。这个插件没有对应的.so文件它已经内嵌在二进制里了启停由mysql_native_password系统变量控制。所以除非你重启否则没办法在运行中改变它的加载状态。类似的UNINSTALL PLUGIN也同样不可行。这就是我开头说很多人误判的意思——这个报错不像普通的缺插件问题它是一个版本策略问题你的修法必须顺着版本的脾气来。3.3 启用插件后如何给受影响账号重置认证方式插件加载回来后还得把账号的认证方式拨回正轨。分两种情况情况一你之前执行ALTER USER ... IDENTIFIED WITH mysql_native_password失败了账号实际还没改成旧插件。这种情况直接重新执行即可ALTER USER app_user% IDENTIFIED WITH mysql_native_password BY NewPass_2024;情况二你升级后发现已有账号的plugin字段本来就是mysql_native_password但这些账号登录时无法认证因为升级后插件还没启用。这种情况你只需要确认插件状态变为ACTIVE后这些账号就会自动恢复正常不需要额外操作。可以随便拿一个账号测一下登录。补充一个细节启用插件后如果你想顺带把服务端的默认认证插件也切回旧插件可以在[mysqld]段里写[mysqld] mysql_native_passwordON default_authentication_pluginmysql_native_password但说实话我不建议这么做除非你的旧客户端实在太多、短期真的切换不完。因为default_authentication_plugin在 MySQL 8.0 中已经废弃长期来看这个配置早晚要删越早切换到新插件你以后越省事。4. 修复方案二迁移到新认证插件推荐路线说句心里话启用旧插件只能算缓兵之计。MySQL 官方已经在 9.0 里彻底移除了mysql_native_password你用 8.4 只是借来的时间下次再升级还会遇到同样的问题而且到时候连启用这个选项都没有。所以如果你的客户端生态允许我更推荐直接迁移到caching_sha2_password。