当前位置:首页 > 问答 > 正文

MySQL报错MY-010317,老密码被忽略导致认证失败,远程帮你修复问题

(引用来源:MySQL官方文档“MySQL 8.0升级指南”章节)我们需要理解这个错误的背景,MySQL报错MY-010317,其完整描述通常是“[Warning] [MY-010317] [Server] Plugin mysql_native_password reported: ''mysql_native_password' is deprecated and will be removed in a future release. Please use caching_sha2_password instead'”,但更关键的是伴随而来的连接失败信息,例如客户端会收到“Access denied for user 'username'@'host'”或者服务器日志里可能有更详细的认证协议失败记录,这个问题的核心并非单一警告,而是由MySQL版本升级带来的认证插件变更所引发的一系列连锁反应。

(引用来源:MySQL官方博客关于认证插件的说明)这个问题几乎总是发生在将MySQL从5.7版本升级到8.0或更高版本之后,在MySQL 5.7及更早版本中,默认的身份认证插件是mysql_native_password,它使用一种相对简单的密码哈希算法,而从MySQL 8.0开始,为了提升安全性,默认的认证插件改为了caching_sha2_password,这个新的插件提供了更强大的密码加密方式,当服务器升级后,原有的用户账户如果是在5.7时代创建的,其认证插件信息仍然记录为mysql_native_password,问题在于,如果用户在升级后,出于某些原因(比如使用mysql_upgrade命令或在某些管理操作中)更改了密码,而更改密码时没有显式指定认证插件,MySQL可能会自动将该用户的认证插件切换为新的默认插件caching_sha2_password

MySQL报错MY-010317,老密码被忽略导致认证失败,远程帮你修复问题

(引用来源:Percona数据库专家博客关于连接故障排除的案例)这就导致了“老密码被忽略”的现象,想象一下这个场景:一个用户'myapp'@'%'在MySQL 5.7中有一个密码是'old_password_123',认证插件是mysql_native_password,升级到MySQL 8.0后,管理员执行了ALTER USER 'myapp'@'%' IDENTIFIED BY 'new_password_456';这样的语句来更新密码,如果服务器变量default_authentication_plugincaching_sha2_password,那么这条语句不仅改变了密码,还 silently(静默地)将'myapp'@'%'的认证插件改为了caching_sha2_password,当你的应用程序(例如一个用旧版本MySQL连接器编写的程序)尝试连接时,它可能仍然期望使用mysql_native_password插件进行握手认证,但服务器现在却要求使用caching_sha2_password协议,客户端如果不支持新协议,认证就会失败,从客户端的角度看就是“密码错误”,而服务器日志则可能记录认证不匹配的错误,这就是所谓的“老密码被忽略”的实质——不是密码本身被忽略,而是整个基于老插件的认证机制被服务器的新期望所拒绝。

(引用来源:MySQL社区论坛用户问题汇总)如何远程修复这个问题呢?既然是远程协助,我们无法直接接触服务器桌面,只能通过命令行或数据库管理工具进行操作,修复的核心思路是统一客户端和服务器认可的认证插件,有以下几种常见方案。

MySQL报错MY-010317,老密码被忽略导致认证失败,远程帮你修复问题

第一种方案,也是最一劳永逸的方案,是升级客户端库,确保你的应用程序所使用的MySQL连接器(如PHP的mysqli、Java的JDBC驱动、Python的MySQLdb或PyMySQL等)是支持MySQL 8.0和caching_sha2_password插件的最新版本,这是官方推荐的做法,因为它能享受到最新的安全特性,但对于一些遗留系统,升级客户端可能比较困难。

第二种方案,是将特定用户的认证插件改回mysql_native_password,这种方法可以让你在不修改应用程序代码和客户端库的情况下快速恢复连接,具体操作步骤如下:你需要一个能成功连接到MySQL 8.0服务器的管理账户(比如root账户),通过MySQL命令行客户端或类似工具登录,执行如下SQL命令:

ALTER USER '你的用户名'@'连接主机' IDENTIFIED WITH mysql_native_password BY '你的密码';

ALTER USER 'myapp'@'%' IDENTIFIED WITH mysql_native_password BY 'new_password_456'; 这条命令的关键在于WITH mysql_native_password,它明确指定了认证插件,执行成功后,该用户的认证方式就固定回了旧模式,应用程序使用原有的连接方式就能正常登录了。

第三种方案,是改变整个服务器的默认认证插件(不推荐在生产环境随意使用),如果有很多用户都遇到同样问题,可以临时修改MySQL的配置文件my.cnf(通常是/etc/my.cnf或/etc/mysql/my.cnf),在[mysqld]段落下添加一行:default_authentication_plugin=mysql_native_password,然后重启MySQL服务,这样之后,新创建的用户或修改密码时未指定插件的用户都会默认使用旧插件,但需要注意的是,这降低了系统的安全基线,并且重启数据库服务会影响线上业务,因此务必在维护窗口进行并评估风险。

(引用来源:Stack Overflow上DBA的实践经验分享)在远程协助过程中,还需要注意几点,要准确识别问题,确认连接失败确实是由认证插件不匹配引起的,而不是简单的密码输入错误、网络问题或权限问题,可以查看服务器的错误日志(error log),里面通常会有更详细的线索,在执行任何修改命令后,最好使用SELECT user, host, plugin FROM mysql.user WHERE user = '你的用户名';来验证用户的认证插件是否已经按预期更改,沟通至关重要,作为协助者,需要向对方清晰地解释问题根源和解决方案的利弊,让对方理解为什么会出现这个问题以及每种修复方法的影响,从而共同做出最合适的决定,整个修复过程,如果方法得当,通常只需要几分钟的数据库操作时间,就能解决因MySQL版本升级带来的这个典型兼容性问题。

MySQL报错MY-010317,老密码被忽略导致认证失败,远程帮你修复问题