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 服务器 + 老驱动 → 上面的认证协议错误(最常见);
  • 老驱动 + 新版连接参数(useSSLserverTimezone 等)→ 各种奇怪的 "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 时区配置错误

相关推荐
用户3126874877201 小时前
ThreadLocal 到底会不会内存泄漏?源码级拆解 + 线程池陷阱
java
~木雨1 小时前
Java 并发编程架构全景:并发层的五域设计 —— 线程模型、线程池隔离、并发安全到问题治理(全体系汇总)
java·安全·架构·线程池·并发编程·高并发架构
极小狐1 小时前
从复制粘贴到可复用组件:极狐GitLab CI/CD 组件目录实战
java·ci/cd·gitlab·devops·组件化
麻瓜code1 小时前
【Agent】Spring AI RAG 实战:本地向量库 + 云端知识库
java·人工智能·spring
小刘在重生~2 小时前
Java 集合|Collection、List、ArrayList、LinkedList、泛型、Collections 工具类
java·数据结构·list
我不会起名字3222 小时前
一天一道算法题(29):单调栈
java·数据结构·python·算法·leetcode·golang·单调栈
XR1234567882 小时前
医院移动医护零漫游无线网络选型指南
java·后端·struts
干到60岁退休的码农2 小时前
13.构建登录接口响应数据
java·spring boot·mybatis
水巷石子2 小时前
学习langChain4j的第二天,体验springBoot中的starter
java·spring boot·学习·spring·langchain4j