P11 · MySQL 驱动版本过旧:Client does not support authentication protocol

P11 · MySQL 驱动版本过旧:Client does not support authentication protocol

场景还原:项目一直用的老 MySQL 5.x,今天 DBA 把数据库升级到了 MySQL 8.0------代码一行没改,连接直接崩了:

MySQLNonTransientConnectionException: Client does not support authentication protocol requested by server; consider upgrading MySQL client

大白话:你手里的驱动是"老古董",服务器换了新的"验票方式",老驱动不认。

一、问题现象

(复现环境:驱动用老版本 mysql-connector-java-5.1.13,服务端是 MySQL 8.0.35)

复制代码
驱动加载成功,连接 MySQL 8 ...
>>>> 连接失败,看下面的异常信息:
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Client does not support authentication protocol requested by server; consider upgrading MySQL client
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3566)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3498)
	...

二、出错代码

java 复制代码
import java.sql.*;

public class OldDriverDemo {
    public static void main(String[] args) {
        try {
            // 5.x 老驱动的类名是 com.mysql.jdbc.Driver
            Class.forName("com.mysql.jdbc.Driver");
            Connection conn = DriverManager.getConnection(
                    "jdbc:mysql://127.0.0.1:3307/testdb", "root", "root123");
            System.out.println("连接成功: " + conn);
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

编译运行用的驱动:mysql-connector-java-5.1.13.jar(2011 年的老版本),服务端:MySQL 8.0。

三、为什么会这样

MySQL 8.0 把默认认证插件 从老的 mysql_native_password 换成了更安全的 caching_sha2_password。这相当于服务器换了新的"验票机":

  • 新版驱动(mysql-connector-j 8.x)认识新验票机,正常通过;
  • 老版驱动(5.x)只会老的 mysql_native_password 验票方式,看到新验票机直接懵了:"你这是什么验票方式?我不支持!" → 于是报 Client does not support authentication protocol requested by server。

类似的"驱动和服务器不匹配"还有这些表现:

  • MySQL 8 服务器 + 老驱动 → 上面的认证协议错误(最常见);
  • 老驱动 + 新版连接参数(useSSL、serverTimezone 等)→ 各种奇怪的 "Unknown system variable" / 参数解析错误;
  • 反过来:新驱动连老 MySQL 一般没事(向下兼容),但太老的 5.1 服务器也可能有新问题。

四、怎么解决

正解:把驱动升级到与 MySQL 8 匹配的新版 (mysql-connector-j 8.0.x),并且类名也要换成新的:

xml 复制代码
<!-- 用 8.x 驱动 -->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.0.33</version>
</dependency>
java 复制代码
// 类名也要用 8.x 的新写法(旧 com.mysql.jdbc.Driver 在新驱动里只是个兼容壳)
Class.forName("com.mysql.cj.jdbc.Driver");

Connection conn = DriverManager.getConnection(
    "jdbc:mysql://127.0.0.1:3307/testdb?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true",
    "root", "root123");

三个常见参数说明:useSSL=false(本地/内网测试关掉 SSL 省事)、serverTimezone=Asia/Shanghai(8.x 驱动要求明确时区,详见 P12)、allowPublicKeyRetrieval=true(caching_sha2_password 需要,本地测试常见)。

如果是老项目暂时没法升级驱动,应急方案是在数据库侧把该账号的认证方式改回老插件(不推荐长期用,仅应急):

sql 复制代码
-- 在 MySQL 里执行(DBA 操作):把某个账号降级为老认证方式
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root123';

怎么判断驱动版本? 看你的依赖/ jar 名就知道:

  • mysql-connector-java-5.1.x.jar / mysql-connector-java-8.0.x.jar → 老命名(8.0 早期)
  • mysql-connector-j-8.0.x.jar → 新命名(官方 8.0.31 后改的名)

五、防坑总结

  • 服务器 MySQL 8,驱动必须 8.x(mysql-connector-j),类名用 com.mysql.cj.jdbc.Driver;
  • 升级数据库后"连不上了"优先怀疑驱动版本,别先怀疑代码;
  • 看到 "Client does not support authentication protocol" = 驱动太老,升级驱动;
  • 老驱动能连老库,就别乱升级------先看服务器版本再选驱动版本;
  • 应急的 mysql_native_password 降级只是过渡,最终要升级驱动。

下一篇:P12 · JDBC 时区配置错误

相关推荐
user_admin_god11 小时前
第 10 篇:拼上下文与生成——预算、边界与防幻觉
java·人工智能·spring boot·语言模型
用户31268748772011 小时前
GC 算法与垃圾收集器演进:从 Serial 到 ZGC
java
天天被压力11 小时前
【别再到处找免费股票数据API了:官方204个接口,32篇一次讲透 #02】涨停跌停与特色股池:5类股池接口一次拉全
java·人工智能·python
斯维赤11 小时前
从 @Tool 到 Agent 流水线:LangChain4j 进阶教学,一个库打全套
java·后端
SimonKing11 小时前
SSE项目`nexus-sse`持续优化,不一样的视觉效果
java·后端·程序员
斑鸠喳喳11 小时前
读写锁模式 Read-Write Lock
java·后端
信誓旦旦的程序猿12 小时前
【Python 量化取数指南 #09】Python 拿港股通数据:港股通成交与港股财报实测
java·python·股票数据api·股票数据·股票数据api接口·股票api数据接口·股票量化数据api
小程序设计13 小时前
本科毕设避坑|大数据 / 单片机物联网 / 网络工程 / PLC / 机械设计选题与落地心得
java·hive·hadoop·单片机
卓怡学长13 小时前
w206基于SpringBoot的社区团购小程序设计与实现
java·spring boot·spring·intellij-idea
IT枫斗者枫哥18 小时前
MyBatis一对多分页:LIMIT 20,为什么凑不齐20个订单?
java·数据库