☰
MySQL 8.0/8.4报错1524:mysql_native_password插件未加载的排查与解决
2026/10/9 6:22:12 网站建设 项目流程

1. 这个报错的本质:谁在找 mysql_native_password

直接说结论:ERROR 1524 (HY000) Plugin 'mysql_native_password' is not loaded 意思是——客户端或服务端的某个环节想用 mysql_native_password 这个认证插件来校验身份,但 MySQL 实例里压根没有加载这个插件。就像一个保安拿着对讲机喊“门禁卡系统出问题了”,结果你发现这个小区压根就没装那套门禁系统。

这个错误我前前后后踩过不下五次,每次场景都不一样,但核心逻辑都一样:MySQL 8.0 之后默认认证插件换成了 caching_sha2_password,mysql_native_password 不再是默认加载项。凡是显式配置、显式指定、或者老客户端隐式要求走 native 认证的地方,只要实例里没启用这个插件,就会抛出 1524。如果你正在做 MySQL 升级、数据库迁移、或者从老版本环境拷贝配置文件,碰到这个报错的概率极高。

先说清楚这个报错能解决什么问题:它基本锁定在“MySQL 8.0+ 的认证插件加载”这个技术点上,常见于三类操作——第一,my.cnf里写了default_authentication_plugin=mysql_native_password后重启实例;第二,执行ALTER USER 'xx'@'%' IDENTIFIED WITH mysql_native_password BY 'xxx'时插件缺失;第三,Navicat 旧版、PHP 5.x/7.x 老驱动、某些中间件连接池在握手阶段索要 native 认证,服务端回拒。

适用读者:DBA、后端开发、运维工程师,以及所有在自己笔记本上把 MySQL 8.0/8.4 当开发库使用、突然某天连不上库的人。这篇文章会把诊断思路、三种可行解法、隐藏的坑一次性讲透,你可以直接照着操作,不用再去搜一堆零散帖子。

2. 先搞清楚 mysql_native_password 是什么、为什么会被“卸载”

2.1 认证插件机制:MySQL 登录时的“门禁卡协议”

MySQL 的连接认证不是简单地比对用户名密码字符串,而是走了一套“认证插件”机制。服务端有一个全局插件列表,客户端发起连接时,服务端根据账号配置的 plugin 字段,决定用哪种算法来校验密码。

  • 在 MySQL 5.7 及更早版本,默认认证插件就是mysql_native_password,它基于 SHA1 算法做两次哈希后传给服务端比对,特点是简单、生态兼容极好。
  • 从 MySQL 8.0 开始,官方把默认插件换成了caching_sha2_password,基于 SHA256 的挑战-响应机制,安全性更高,密码不会以可逆形式出现在内存里。
  • 关键变化来了:8.0 安装包默认不再加载mysql_native_password这个插件,而是把它作为“可选组件”存在。如果你在配置里强制指定它,或者某些程序坚持要用它,而实例里没启用,那就直接 1524。

其实我更喜欢把这个机制理解成门禁卡协议:5.7 时代整个小区统一用 IC 卡开门,8.0 之后改为指纹+加密芯片的智能锁。智能锁默认不配 IC 卡读卡器,但你要是非得拿老 IC 卡去开门,系统直接回复“读卡器不存在”——就是 1524。

2.2 四种典型触发场景,对号入座

我不止一次在群里看到截图,每个人报错都一样,但成因完全不同。先列出最常见的四种,后面诊断步骤那里再教你准确区分:

场景 A:配置文件里显式启用了 native 插件,但组件未安装比如你在[mysqld]段写了:

default_authentication_plugin=mysql_native_password

MySQL 启动时会尝试加载并设置为默认认证插件,但 8.0 的二进制发行版把该插件做成了独立组件,如果你没执行过INSTALL COMPONENT,启动后所有新建用户都会默认走 native,接着在登录时直接炸 1524。

场景 B:执行 ALTER USER 指定认证插件时插件不存在

ALTER USER 'dev'@'%' IDENTIFIED WITH mysql_native_password BY '123456';

这条 SQL 的意思是“把 dev 账号的认证方式改成 native 插件”。如果实例的插件列表里没有 mysql_native_password,就会立刻返回 1524。这个场景在“从 8.0 回退兼容”或“老应用必须用老协议”时特别常见。

场景 C:老客户端/驱动强制索要 native 认证比如 PHP 5.6 的 mysqli、Navicat 11 之类的老工具连接 8.0 实例。客户端会在握手包中带上自己支持的插件列表,如果排第一的是mysql_native_password,但服务端实例没加载该插件,连接阶段就报 1524,而不是报密码错误。这里的迷惑性在于:即使密码完全正确,也进不去。

场景 D:通过 mysqld_safe --skip-grant-tables 进入后执行 FLUSH PRIVILEGES 或建用户网上很多找回 root 密码的教程会让你在 skip-grant-tables 模式下重启,然后ALTER USER 'root'@'localhost' IDENTIFIED BY 'newpass'。问题是:8.0 的 skip-grant-tables 模式同样受插件配置影响,如果当前实例本来就没加载 native 插件,而你执行的语句触发了对默认认证插件的读取,一样会报 1524。这种情况尤其隐蔽,因为很多人以为 skip-grant-tables 是万能的。

2.3 为什么 8.4 里更严重,存在的“卸载”陷阱

额外提醒一句:如果你用的是 MySQL 8.4(LTS 版本),mysql_native_password插件已经从默认安装集中彻底移除了。8.0 里你还能通过安装组件的方式把它加回来,8.4 官方文档直接声明该插件已被弃用且不再随着发行版提供。也就是说,在 8.4 环境里遇到这个报错,你不能指望“装回老插件”这条路,只能改客户端适配新认证方式,或者降到 8.0。这点务必在动手前确认版本,别照着 8.0 的教程折腾半天,最后发现 8.4 压根没有对应的 .so 文件。

3. 诊断第一:查出插件到底在不在、是谁在要

3.1 三步定位法:插件表、变量与错误日志

真正的排障不是上来就改配置,而是先回答三个问题:实例里有没有这个插件?当前默认认证插件是谁?到底是哪一步触发了对老插件的请求?

第一步,查插件列表:

SELECT PLUGIN_NAME, PLUGIN_STATUS, PLUGIN_TYPE FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE '%native%';

如果返回空行,说明插件根本没加载。如果返回一行PLUGIN_STATUS为ACTIVE,说明插件实际是存在的,那 1524 可能来自别的地方——比如配置里写死了default_authentication_plugin,但变量名在 8.0.27 之后已经改成了default_authentication_plugin已废弃,需要用--mysql-native-password=ON这种新参数,写法不对也会导致实际没启用。

第二步,看当前默认认证插件变量:

SHOW VARIABLES LIKE 'default_authentication_plugin'; SHOW VARIABLES LIKE 'mysql_native_password';

注意 8.0 的mysql_native_password变量默认是OFF,而 8.4 里这个变量直接不存在。如果查询结果显示mysql_native_password=OFF,说明即使插件安装了,也没有被启用为可用的认证方式。

第三步,翻错误日志。MySQL 的错误日志往往带着更详细的上下文:

tail -100 /var/log/mysql/error.log

如果里面有类似Plugin 'mysql_native_password' is not loaded的完整堆栈,注意看是哪个连接线程触发的,通常能看到Access denied for user 'xx'或者Authentication plugin 'mysql_native_password' cannot be loaded这样的线索,能直接帮你区分是客户端驱动问题还是配置问题。

3.2 8.0 与 8.4 的插件差异,别搞混

这里我整理一个速查表,方便你快速判断自己环境里到底该走哪条路:

版本mysql_native_password 是否内置默认认证插件是否还能启用老插件
MySQL 5.7是mysql_native_password本来就是默认,无此问题
MySQL 8.0.x作为可选组件附带caching_sha2_password可以,通过 INSTALL COMPONENT 或 INSTALL PLUGIN
MySQL 8.4已移除caching_sha2_password基本不行,建议升级客户端

所以诊断时第一件事是确认版本:

mysql --version

如果你发现 8.4 环境里插件列表为空,别再折腾安装组件了,直接跳到后面的“方案 C”,把客户端连接方式改成 caching_sha2_password,或者给老客户端换新驱动。

3.3 一条命令确认是谁在“索要”老插件

有时候你根本没法直接登录到 MySQL 里执行 SQL(因为 1524 就是在登录阶段爆出来的)。这种情况我建议用一条命令观察握手过程:

mysql -u root -p -h 127.0.0.1 --default-auth=mysql_native_password

这条命令让客户端显式指定用 native 插件去连。如果服务端没加载该插件,会立刻复现 1524;如果换用默认认证能连上,说明客户端侧默认在优先请求 native。反过来也可以:

mysql -u root -p -h 127.0.0.1 --default-auth=caching_sha2_password

能连上就说明服务端认证本身没问题,问题在“客户端为什么非要 native”。这招在区分“服务端插件缺失”和“客户端驱动老旧”时非常管用,我在排查好几个线上问题时都是靠它直接定性的。

4. 解法 A:加载 mysql_native_password 插件(8.0 适用)

4.1 通过 INSTALL COMPONENT 安装(8.0.11+ 推荐)

从 MySQL 8.0.11 开始官方推荐用组件方式管理认证插件。操作如下:

INSTALL COMPONENT 'file://component_mysql_native_password';

这条命令会把 native 认证组件加载进运行中的实例,并自动注册到mysql.component表里。执行完再查插件列表:

SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE '%native%';

如果返回mysql_native_password | ACTIVE,就说明已经加载。但请注意:这只是运行时加载。MySQL 重启后是否自动加载,取决于组件是否被持久化注册。用 INSTALL COMPONENT 的组件一般会持久化,但如果你不放心,可以在my.cnf里加上:

[mysqld] mysql_native_password=ON

这一项在 8.0 里是显式启用插件的开关。加上之后重启实例,插件必定加载。

4.2 通过 INSTALL PLUGIN 安装(老版本兼容)

如果你用的是较早的 MySQL 8.0 小版本,或者 INSTALL COMPONENT 报找不到文件,可以用传统方式:

INSTALL PLUGIN mysql_native_password SONAME 'mysql_native_password.so';

这条语句的前提是mysql_native_password.so文件存在于插件目录。先确认:

find /usr/lib/mysql/plugin/ -name '*native*'

在官方 8.0 发行版里,这个 .so 文件是随安装包附带的,一般在/usr/lib/mysql/plugin/或/usr/lib64/mysql/plugin/。如果文件不存在,说明你用的发行版把该插件裁剪掉了(某些云厂商 RDS 或精简版镜像常这样),那就没法用这条路,只能走方案 C 改客户端。

4.3 修改已有用户的认证方式

插件加载成功后,还需要把账号的认证方式改回 native,否则新老配置依然不匹配:

ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password'; FLUSH PRIVILEGES;

这里有个大坑:如果你原来用 caching_sha2_password 存的哈希值,改成 native 后密码必须原文重设,不能只改插件名不写密码,否则会导致哈希不可用。比如ALTER USER 'u'@'%' IDENTIFIED WITH mysql_native_password;这么写是不行的,必须带上BY '明文密码'。

4.4 修改全局默认认证插件(可选)

如果希望后续新建用户默认都走 native:

[mysqld] default_authentication_plugin=mysql_native_password

但 MySQL 8.0.27 开始,官方把default_authentication_plugin标记为废弃,并新增了default_authentication_plugin对应的替代方式。实测下来,8.0.34+ 里直接写这个旧变量有时会有告警,但不影响生效。如果你用的 8.0 版本比较新,建议改用:

[mysqld] mysql_native_password=ON
  • 同时确保客户端侧支持 caching_sha2_password 或者你显式把账号改成 native。这个全局配置生效后,新建用户会继承默认插件,避免后续每个用户都手动 ALTER。

5. 解法 B:不启用老插件,让客户端适配 caching_sha2_password

5.1 为什么要优先考虑这条路

说实话,如果你不是被老驱动卡死,我强烈建议走“改客户端”而不是“开老插件”。原因很直白:

  • mysql_native_password 的 SHA1 算法在 2023 年之后已被安全社区多次指出弱点,官方弃用是趋势。
  • 8.4 里你压根没有选择。
  • 开启老插件意味着所有后续账号都要兼容旧协议,等于把新版本的安全特性降级。

所以当你的客户端或驱动支持新认证时,最优解是把账号改成 caching_sha2_password。大部分情况下你甚至不用改账号——8.0 创建的用户默认就是新插件,出问题的往往是“从 5.7 迁移来的账号”或“显式指定过老插件的账号”。

5.2 把现有用户改回新认证方式

ALTER USER 'your_user'@'%' IDENTIFIED WITH caching_sha2_password BY 'your_password'; FLUSH PRIVILEGES;

执行完以后,确认一下:

SELECT USER, HOST, PLUGIN FROM mysql.user WHERE USER='your_user';

返回的plugin字段应该是caching_sha2_password。然后重启你的应用服务,或者重连一次,只要能连上就说明服务端已经没有 native 依赖了。

这里要注意:caching_sha2_password 在首次连接时,如果走 TCP/IP 且没有 SSL,客户端需要支持 RSA 公钥传输。8.0 客户端自动处理,但某些老驱动(比如 PHP 7.2 之前的 mysqli)不支持,那就得在连接串里显式加上ssl-mode=DISABLED并且allowPublicKeyRetrieval=true(JDBC 场景)或类似参数。如果驱动连新插件都不支持,那只能回到方案 A。

5.3 客户端选型建议

根据我实际踩坑经验,给你一份“能用新认证”的连接组件清单:

客户端/驱动是否支持 caching_sha2_password备注
MySQL 8.0 自带 mysql CLI支持无需额外配置
MySQL Shell支持推荐
Connector/J 8.0.9+支持JDBC 需要加 allowPublicKeyRetrieval=true
Connector/Python 8.0+支持无特殊设置
PHP mysqli (PHP 7.4+)支持7.4 后通过 mysqlnd 支持
PHP PDO (PHP 7.4+)支持同上
Navicat 16+支持16 以后版本
Navicat 11/12不支持只能配老插件或升级
DBeaver 最新版支持自动协商
Python PyMySQL 1.0+支持1.0.2 后

如果你的客户端在“不支持”或“不确定”列,又没法升级,那就只能走方案 A 开启老插件。这个取舍没有完美的,安全性和兼容性总得让一头。

6. 解法 C:直击 8.4 版本,彻底放弃 mysql_native_password

6.1 8.4 下不能加载,那报错怎么处理

8.4 用户看到 1524 时,先不要浪费时间找 .so 文件。官方在 8.4 的 release note 里写得很明确:mysql_native_password插件被移除,连 .so 文件都不再打包。所以任何INSTALL PLUGIN或INSTALL COMPONENT都会报错。唯一的正道是:所有账号统一使用 caching_sha2_password,并且所有连接方都升级到支持新插件的驱动。

操作上分几步走:

  1. 检查当前所有账号的认证插件类型:
SELECT USER, HOST, PLUGIN FROM mysql.user;
  1. 如果有残留的 native 账号(一般是迁移环境带过来的),先把它改成新插件:
ALTER USER 'user'@'host' IDENTIFIED WITH caching_sha2_password BY 'your_password';
  1. 检查连接配置(应用连接串、配置文件、中间件),把驱动升级到支持新插件的版本。

6.2 迁移场景下的特殊处理:先改 schema 再升级

如果你是从 8.0 往 8.4 做数据迁移,切记顺序不能反。8.0 导出数据时,mysql.user 表里可能还带着 native 插件的账号记录。你可以先做一次“账号清洗”,在源库把所有账号改成 caching_sha2_password,再执行导出:

-- 源库执行 SELECT CONCAT('ALTER USER ''', user, '''@''', host, ''' IDENTIFIED WITH caching_sha2_password BY ''temp_pass_123'';') FROM mysql.user WHERE plugin = 'mysql_native_password';

把生成的 SQL 批量执行一遍,然后把客户端连接串里的密码同步改掉,最后再做迁移。这样目标库 8.4 里就不会残留不支持的插件记录,启动后也不会出现 1524。

迁移后如果还有账号验证失败,可以通过mysql_upgrade或手动检查mysql.user表确保所有 plugin 字段都指向caching_sha2_password。

7. 实操记录:一个从 5.7 升 8.0 的完整排查过程

7.1 现场描述

一个朋友的项目从 MySQL 5.7 升到 8.0.36,数据导入完成后,他用 root 登录执行:

ALTER USER 'app_user'@'%' IDENTIFIED BY 'newpass';

结果直接报:

ERROR 1524 (HY000): Plugin 'mysql_native_password' is not loaded

他觉得莫名其妙:明明密码没改错,账号也存在,怎么会扯到插件上。

7.2 排查步骤与关键决策

我先让他执行诊断 SQL 查插件:

SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'mysql_native_password';

发现PLUGIN_STATUS是ACTIVE,插件明明存在。那为什么会报错?接着查:

SHOW VARIABLES LIKE 'mysql_native_password';

返回OFF。到这里原因就清晰了:插件虽然安装了,但被参数mysql_native_password=OFF禁用了。ALTER USER 要切换认证方式时,服务端检测到该插件当前状态不可用,于是抛出 1524。

7.3 最终修复方案

确认该环境所有客户端都支持新认证后,我们决定彻底切换成 caching_sha2_password,避免以后每个账号都踩一遍坑:

ALTER USER 'app_user'@'%' IDENTIFIED WITH caching_sha2_password BY 'newpass';

然后把应用连接串里的 JDBC 参数补上:

jdbc:mysql://127.0.0.1:3306/app?useSSL=false&allowPublicKeyRetrieval=true

重启应用后连接正常。整个过程耗时不到二十分钟,核心其实就三步:确认插件状态→决定安全路线→同步调整客户端。

8. 常见问题与排查技巧实录

8.1 报错速查对照表

这里把你可能遇到的各种“像 1524 但不完全是”的情况汇总一下,方便一眼定位:

现象可能原因处理方法
ERROR 1524 (HY000) 登录时发生服务端未加载 mysql_native_password 插件INSTALL COMPONENT/ PLUGIN 或改客户端
执行 ALTER USER 时 1524目标账号要切换成 native 但插件被禁用启用插件或用 caching_sha2_password
连接时报 Access denied 但密码确定没错客户端索要 native、服务端只支持 sha2升级驱动或开启老插件
8.4 版本 INSTALL PLUGIN 报文件不存在8.4 已彻底移除该插件放弃老插件,升级客户端
开启 skip-grant-tables 后 ALTER USER 报 1524实例未加载 native,但修改操作触发了插件引用先 INSTALL PLUGIN 再操作,或者直接改 caching_sha2_password
修改 my.cnf 增加 mysql_native_password=ON 后启动失败参数位置写错或版本不支持8.0.27+ 确认放在 [mysqld] 段并使用合法变量名
插件显示 ACTIVE 但连接仍报 1524插件被参数禁用或账号 plugin 字段与全局变量冲突检查 mysql.user 表 plugin 字段,检查 mysql_native_password 变量

8.2 三个我亲自踩过的坑

坑一:改错密码导致哈希失效,然后无法登录

我早期在 8.0 上执行过:

ALTER USER 'user'@'%' IDENTIFIED WITH mysql_native_password;

以为只改插件名不重置密码就行,结果密码哈希直接作废,用户彻底连不上,还得再走一次忘记密码流程。现在我的习惯是:任何涉及认证插件的 ALTER USER,一律带上BY '明文密码'。虽然多次输入明文麻烦,但不会把账号搞坏。

坑二:在 skip-grant-tables 模式下操作插件,引发更多连锁问题

某次为了找回 root 密码,我在 skip-grant-tables 模式下执行 ALTER USER,结果 8.0 实例不支持 native 插件,命令失败。我一度以为系统坏了,后来冷静下来分析:skip-grant-tables 模式依然遵守认证插件规则。解决办法是先启动时加上--mysql-native-password=ON参数临时启用老插件,再执行 ALTER USER,最后去恢复配置文件。这个场景下,如果你本来就用新插件,完全可以不用处理插件,直接ALTER USER 'root'@'localhost' IDENTIFIED BY 'newpass'就行,因为 caching_sha2_password 不需要额外插件组件。

坑三:云数据库环境根本没有插件文件

有一次在云厂商的 MySQL 8.0 托管实例上,执行 INSTALL PLUGIN 提示无法加载共享库,原因就是云实例压根没打包这个 .so 文件,用户也没有文件系统权限去补。这时候无论怎么折腾都开不了老插件,唯一的出路就是把应用驱动全部升级,以后只用 caching_sha2_password。所以,遇到 1524 先确认你用的是自建库还是托管库,托管库的操作路径非常有限。

8.3 最终排障口诀

把整个排查逻辑浓缩成一句口诀:先查版本,再查插件,三看变量,最后决定启老还是改新。版本决定你能不能走老插件路线;插件列表告诉你装了没;mysql_native_password变量告诉你是装而禁用还是根本没装;最后一步是决定兼容方案。

我个人在实际操作中的体会是,能走新认证就千万别恋战老插件。mysql_native_password 终归是要进博物馆的东西,今天你把它加回来解决了一个老客户端的连接问题,明天可能又有一个老组件冒出来要它,倒不如趁着一次报错,把客户端和相关配置一次升级到位,后面一劳永逸。如果你确实被老驱动卡得死死的,必须开老插件,也请记住:这只是过渡方案,之后只要有机会,还是要把账号切回 caching_sha2_password,毕竟数据库认证这层是安全底线,不能一直为了兼容性兜底。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询