MySQL5.7小版本升级遇到 [Note] Bad handshake错误

2024年 4月 26日 70.7k 0

适用范围

   Linux X86平台下的 MySQL 5.7 社区版 小版本升级(5.7.34 -> 5.7.44)。

问题概述

   升级后有部分连接无法连接成功,MySQL错误日志连续报 [Note] Bad handshake 相关提示信息。
   整个升级过程很简单,简单描述如下:

  1. 系统架构
  2. 升级过程:
       MySQL主从架构中,建议先升级从库,再升级主库。
       a. 关闭从库

[root@phe-dev-mysql01 local]# mysql -uroot -p’password’

mysql > show global variables like ‘%read_only%’;

# 确保从库只读,如果没有只读,需要临时设置为只读!
mysql > set global read_only=1;

mysql > stop slave;

mysql > set global innodb_fast_shutdown=0;
说明:关闭mysql时会做清除脏页和插入缓冲区的合并操作,也会将脏页全部刷新到磁盘,确保数据完整性。

mysql > shutdown;

mysql > exit;

# 确认mysqld进程消失
[root@phe-dev-mysql01 local]# ps -ef|grep mysqld

# 确认mysql实例关闭(日志中会有shutdown关键字)
[root@phe-dev-mysql01 local]# tail -20 /var/log/mysqld.log

   b. 备份(从库冷备)

确保mysql数据目录位置(如果涉及到日志目录也需要对日志目录进行备份)进行对数据的冷备
[root@phe-dev-mysql01 local]# cat /etc/my.cnf|grep datadir
datadir=/var/lib/mysql

[root@phe-dev-mysql01 local]# cp -rp /var/lib/mysql /var/lib/mysql_bak
[root@phe-dev-mysql01 local]# cp /etc/my.cnf /etc/my.cnf_bak

   c. 新版本软件启动并执行升级

# 编辑配置文件,在[mysqld]下面加入basedir=/usr/local/mysql (新版本软件的绝对路径)
[root@phe-dev-mysql01 local]# vi /etc/my.cnf
basedir=/usr/local/mysql
pid-file=/var/lib/mysql/mysql.pid
说明:修改pid文件路径为/var/lib/mysql/mysql.pid

# 使用新版本mysql软件启动数据库:
[root@phe-dev-mysql01 local]# /usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf --user=mysql &

# 确认mysql进程已经启动
[root@phe-dev-mysql01 local]# ps -ef|grep mysqld

#若启动失败,查看错误日志,进行排查
[root@phe-dev-mysql01 local]# tail -20 /var/log/mysqld.log

# 执行升级命令,并观察输出信息:
[root@phe-dev-mysql01 local]# /usr/local/mysql/bin/mysql_upgrade -uroot -p’k#6y*pR7LkPUl2iWyC0p’ -S /var/lib/mysql/mysql.sock

# 查询版本
[root@phe-dev-mysql01 local]# /usr/local/mysql/bin/mysql -uroot -p’k#6y*pR7LkPUl2iWyC0p’ -S /var/lib/mysql/mysql.sock
mysql > select version();

# 关闭数据库并用新版本软件正常启动MySQL:
[root@phe-dev-mysql01 local]# /usr/local/mysql/bin/mysqladmin -uroot -p’k#6y*pR7LkPUl2iWyC0p’ -S /var/lib/mysql/mysql.sock shutdown

[root@phe-dev-mysql01 local]# /usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf --user=mysql &

   d. 确认从库状态

[root@phe-dev-mysql01 local]# /usr/local/mysql/bin/mysql -uroot -p’k#6y*pR7LkPUl2iWyC0p’

mysql > select version();
+-----------+
| version() |
+-----------+
| 5.7.44 |
+-----------+
1 row in set (0.00 sec)

mysql > start slave;

mysql > show slave statusG

说明:至此从库状态正常,升级成功

  1. 出现问题:
      观察错误日志,马上出现异常如下:

    错误日志中频繁出现 [Note] Bad handshake 信息,部分业务人员表示无法连通数据库。

问题分析

  与应用业务人员沟通,发现连接MySQL数据库的应用有10几个,有些是正常的,有些出现异常,故进行进一步排查:
  在排查之前我们先了解一下这个 Bad handshake 的含义:
  通常MySQL客户端通过IP地址,端口号,用户名/密码等必要的连接串参数进行对数据库的远程访问,走网络,走TCP/IP协议, 这里的handshake就是指通过网络TCP/IP协议进行客户端服务器端之间的三次握手,这里显示 Bad handshake 坏的握手,表明我们在建立连接的过程中失败了,没有成功,连接阶段产生的错误,我们借用一下网络上关于MySQL握手的截图如下:

  粗略流程为:
     1: 客户端向DB发起TCP握手。
     2: 三次握手成功。与通常流程不同的是,由DB发送HandShake信息。这个Packet里面包含了MySQL的一些必要的认证信息。
     3: 客户端根据HandShake包里面的信息对MySQL登录密码进行摘要后,构造Auth认证包发送给DB。
     4: DB接收到客户端发过来的Auth包后会对密码摘要进行比对,从而确认是否能够登录。如果能,则发送Okay包返回。
     5: 客户端与DB的连接至此完毕。

问题原因

  我们出现错误的原因是上面的流程出现了问题,导致无法连接成功,经过对数据库端进行的参数排查,从MySQL5.7.34升级到5.7.44发现并没有参数上的改变,一个最为敏感的参数have_ssl参数默认都是YES既打开状态,由于应用端涉及到的应用有10多个,他们采用连接的方式各有不同,有的是通过python连的,有的是通过java 的驱动连的,还有是通过 spring集成框架连接的,并且使用的MySQL java-connector驱动版本也比较老,当时建议他们升级一下驱动版本jar包,因为早期版本的java-connector里面对默认使用ssl参数有不同的值。有的默认是建立ssl,有的低版本驱动是不建立ssl连接,当时有一个应用端就报如下错误:

  MySQL 5.5.45+, 5.6.26+和5.7.6+的要求,如果没有设置显式选项,则必须默认建立SSL连接。为了符合不使用SSL的现有应用程序,将verifyServerCertificate属性设置为“false”。
  还有一个应用程序连接串配置了useSSL=true 参数,如果使用ssl那么连接的时候就要有相关的安全验证,一般通过证书或者令牌之类相关文件才可以。
  MySQL5.7 版本后默认是使用SSL连接的,5.7之前的版本默认是不使用ssl(useSSL 默认值为false useSSL=false就是通过账号密码进行连接),一般情况下都是使用useSSL=false。

解决方案

  针对当前的问题,解决方案可以有两个:
    1. 应用端连接串修改JDBC的连接串改为 useSSL=false
    2. 修改MySQL服务器端参数,在my.cnf文件中 [mysqld] 下面添加skip_ssl
  由于应用比较多,改应用的配置文件代码和时间比较长,故采取修改数据库参数方式来解决,修改完参数后,对数据库进行重启生效,应用端连接正常,错误消失。

参考文档

https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::HandshakeResponse
https://dev.mysql.com/doc/dev/mysql-server/latest/
https://stackoverflow.com/questions/48477121/wireshark-password-capture-of-mysql-traffic

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论