笔者作为Apache Doris的开发者,平时感觉相关Doris的文章写的很少。主要是很多时候不知道应该去记录一些怎么样的问题,感觉写的不好就会很慌张。新的一年,希望记录自己在Doris开发过程之中所遇到一些有意思的事情。(只希望能坚持下来,别打脸~~

言归正传,回到本篇想聊的问一个问题,笔者在开发ODBC of Doris的工作之中,发现通过MySQL 8.0的Driver连接Doris总是提示密码验证失败。但是由于开发工作繁忙,一直没有腾出手解决这个问题。最近重新抽时间梳理了一下这个问题,这个问题本身不难解决,但是解决问题的思路我觉得值得与大家分享,献丑了啊,各位~~

1.老革命遇到新问题

使用MySQL 8.0的客户端连接Doris时,如果不添加如下参数--default-auth=mysql_native_password的话,总会出现如下提示的密码认证错误:

ERROR 1045 (28000): Access denied for user 'default_cluster:test' (using password: YES)

同样的密码认证问题也会同时出现在了使用ODBC的MySQL 8.0以上的Driver连接Doris时。更令人蛋疼的是,使用ODBC链接时并没法调用上面的参数进行问题的规避。这会带来两个问题:

    1. Doris本身的ODBC外表无法通过MySQL 8.0以上的Driver连接Doris
  • 2.许多流行的BI分析工具如Tableau等:也无法通过ODBC的方式连接Doris

之前通过5.x的客户端和Driver可以顺利的连接Doris,而现在真是老革命遇上新问题了。

默认的密码认证插件的变更

其实新问题的引入很简单,就是MySQL的客户端从8.0的版本开始,将原先客户端的默认的密码认证插件由mysql_native_password改为了caching_sha2_password,两种密码认证方式不同。而Doris当前只支持mysql_native_password的密码认证插件,所以就导致了连接时密码认证失败了。而关于密码认证插件的变更,更为详细的内容,可以参考MySQL的官方文档

2.问题的分析与梳理

好的,确认了问题,就开始研究解决方案。从直觉上说,Doris支持新的caching_sha2_password密码认证插件肯定是最直接的解决思路。这种做法肯定是一劳永逸的解决问题的,但是这就得重构整个Doris的密码管理系统,开发和支持起来的代价实在是有些太大了。

那既然我们否定了这种方式,就得另外想办法解决了。首先,使用MySQL 8.0的客户端连接Doris时,添加如下参数--default-auth=mysql_native_password便可以认证成功。 所以问题就回到了如何让ODBC的连接能够支持上述参数,笔者经历了下面的分析历程:

2.1 ODBC连接文档

ODBC是通过连接串的方式传参给MySQL的连接Driver的,如果能够像使用MySQL客户端的方式添加参数便可以解决,那么自然无代码的Coding是成本最低的解决方案。

笔者首先尝试查看了MySQL官方的ODBC连接参数文档,遗憾的是,并没有找到ODBC关于认证方式的任何内容,这也就意为着:此路不通

2.2 新旧版本的兼容性

既然MySQL从8.0开始切换了默认的密码认证插件,那么新的客户端是否可以连接老的MySQL服务器呢?MySQL本身是如何解决新老客户端的兼容问题的呢?

于是笔者尝试使用MySQL 8.0的客户端连接了MySQL的5.x的服务器,发现了下面的线索:新客户端并不需要像连接Doris一样,修改默认的密码认证插件。那也就意味着,MySQL的客户端和服务器可以在连接过程之中通过某种方式交换确认一种服务器支持的密码认证方式。

既然如此,笔者开始了Google之旅,但是并没有搜索到什么有价值的信息。没办法,源码面前,了无秘密。于是笔者决定尝试阅读一下MySQL Client端的代码,看看是否能发现上述的交互逻辑。

经过一番"痛苦"的源码搜索和阅读,笔者在找到了如下的注释,完整的阐述了MySQL的客户端与服务器的连接过程:

  1. The client connects to the server
2. The server sends @ref page_protocol_connection_phase_packets_protocol_handshake
3. The client respons with
@ref page_protocol_connection_phase_packets_protocol_handshake_response
4. The server sends the
@ref page_protocol_connection_phase_packets_protocol_auth_switch_request to tell
the client that it needs to switch to a new authentication method.
5. Client and server possibly exchange further packets as required by the server
authentication method for the user account the client is trying to authenticate
against.
6. The server responds with an @ref page_protocol_basic_ok_packet or rejects
with @ref page_protocol_basic_err_packet

把上述的注释读懂之后,笔者又回头查阅了一下Doris之中处理MySQL客户端连接的代码。总算是整明白了为啥新的客户端连接Doris会失败了,这个是新客户端连接Doris的流程:

Drois  ->: Authentication Plugin: mysql_native_password
Client <-: Client Auth Plugin: caching_sha2_password
Doris ->: MySQL Error 2012 (HY000): Password check failed.

而新客户端连接老的MySQL的流程如下:

Mysql  ->: Authentication Plugin: mysql_native_password
Client <-: Client Auth Plugin: caching_sha2_password
Mysql ->: Auth Switch Request: Auth Method Name: mysql_native_password
Client <-: Auth Switch Response
Mysql ->: OK

MySQL的服务器支持了Auth Switch Request的网络请求来告知客户端自己支持的认证的密码插件,而客户端会进行密码插件的支持检查,而客户端则将密码插件加密的结果返回。

3.开发起来,解决问题

通过上一小节的分析,问题已经水落石出了。接下来就是如何在Doris上支持Auth Switch Request的网络请求。

3.1 确认二进制结构

所以这里就需要研究这两个Auth Switch RequestAuth Switch Response的二进制包是如何组成的。这里再次借助官方文档,确认了两个包的组成:

3.2 代码开发

其实到这里的工作已经很简单了,直接上笔者修改Doris的代码吧:

if (!handshakePacket.checkAuthPluginSameAsDoris(authPacket.getPluginName())) {
// 1. clear the serializer
serializer.reset();
// 2. build the auth switch request and send to the client
handshakePacket.buildAuthSwitchRequest(serializer);
channel.sendAndFlush(serializer.toByteBuffer());
// Server receive auth switch response packet from client.
ByteBuffer authSwitchResponse = channel.fetchOnePacket();
if (authSwitchResponse == null) {
// receive response failed.
return false;
}
// 3. the client use default password plugin of Doris to dispose
// password
authPacket.setAuthResponse(readEofString(authSwitchResponse));
}

就是进行了密码认证插件的校验,如果不Match Doris默认的密码认证插件的话,则构造AuthSwitchRequest发送给客户端。(笔者这里只列出了部分代码,完整的代码修改请参考如下的pr .

Coding完成之后,编译部署,进行测试,问题解决,提出issue,把解决问题的代码贡献给Doris的官方代码仓库提pr。完结撒花~~~~

4.小结

Bingo! 到此为止,问题顺利解决了,希望通过和大家分享一个问题的解决流程,帮助大家梳理数据库开发之中的解决问题的思路。我们有着最大的三个帮手

  • 搜索引擎
  • 官方文档
  • 源代码

而如果你遇到的是Doris的问题,那你就有第四个帮手了:百度Doris团队。(加星重点)

当然,这里也留下一个TODO的问题:支持MySQL 8.0默认的caching_sha2_password的认证方式。相较原先的mysql_native_password的认证方式,它有一定的安全性优势,但是这样可能需要重构整个Doris的密码体系了。

最后,也希望大家多多支持Apache Doris,多多给Doris贡献代码,感恩~~

5.参考资料

MySQL官方文档

MySQL源代码

Apache Doris源代码

Doris开发手记1:解决蛋疼的MySQL 8.0连接问题的更多相关文章

  1. mysql(8.0连接navicat发生的错误解决方法)

    关于mysql(8.0连接navicat发生的错误解决方法)数据库安装图形化界面无法更改加密的方式导致无法连接问题为解决; Alter user 'root'@'localhost' identifi ...

  2. Doris开发手记4:倍速性能提升,向量化导入的性能调优实践

    最近居家中,对自己之前做的一些工作进行总结.正好有Doris社区的小伙伴吐槽向量化的导入性能表现并不是很理想,就借这个机会对之前开发的向量化导入的工作进行了性能调优,取得了不错的优化效果.借用本篇手记 ...

  3. 解决win10下MySQL 8.0登录Access denied for user 'root'@'localhost' (using password: YES)的问题

        近些时间在开始学MySQL,安装挺顺利的,按照网上现成的教程就能安装成功.     但是,在输入 mysql -uroot -p     再输入密码时,遇到了这个情况 Access denie ...

  4. Doris开发手记2:用SIMD指令优化存储层的热点代码

    最近一直在进行Doris的向量化计算引擎的开发工作,在进行CPU热点排查时,发现了存储层上出现的CPU热点问题.于是尝试通过SIMD的指令优化了这部分的CPU热点代码,取得了较好的性能优化效果.借用本 ...

  5. Doris开发手记3:利用CoreDump文件快速定位Doris的查询问题

    Apache Doris的BE部分是由C++编写,当出现一些内存越界,非法访问的问题时会导致BE进程的Crash.这部分的问题常常较难排查,同时也很难快速定位到对应的触发SQL,给使用者带来较大的困扰 ...

  6. mysql jdbc8.0连接mysql

  7. MySQL 8.0.x for Windows 解压缩版配置安装

    一.官网下载MySQL8.0.16 直达官网下载Community版:https://dev.mysql.com/downloads/mysql/ 然后拉倒下方点击对应版本位数下载 二.创建my.in ...

  8. MySQL 8.0有什么新功能

    https://mysqlserverteam.com/whats-new-in-mysql-8-0-generally-available/ 我们自豪地宣布MySQL 8.0的一般可用性. 现在下载 ...

  9. DataGrip 2019.1 连接mysql 8.0.16

    # 下载mysql Connector/J驱动包 https://dev.mysql.com/downloads/connector/j/ 然后解压到一个目录 # 新建mysql 8.0连接驱动 打开 ...

随机推荐

  1. SQLSERVER 修改数据实例的排序规则

    SQL Server服务器修改排序规则的方法 操作及验证步骤: 1 登录数据库后,查看当前安装数据库默认排序规则的两种方式 方式一.使用SQL Server 2014 Management Studi ...

  2. 性能测试WAS内存使用的探索和分析

    性能测试中,CPU和内存是关注最多的两个性能指标.以我行应用最多的系统架构(WAS+Oracle)来说,CPU使用率高的问题多发生于数据库,比如索引不当引发的表扫描.绑定变量使用不当引发的硬解析.连接 ...

  3. top命令详解-性能分析

    top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,常用于服务端性能分析. top命令说明 [www.linuxidc.com@linuxidc-t-tomcat-1 ...

  4. QQ好友状态,QQ群友状态,究竟是推还是拉? 网页端收消息,究竟是推还是拉?

    https://mp.weixin.qq.com/s/KB1zdKcsh4PXXuJh4xb_Zw 网页端收消息,究竟是推还是拉? 原创 58沈剑 架构师之路 2020-12-28   https:/ ...

  5. 览器全面禁用三方 Cookie 全栈前端精选 4月16日

    览器全面禁用三方 Cookie 全栈前端精选 4月16日

  6. Building a Robust Live Reloader with WebSockets and Go — Brandur Leach https://brandur.org/live-reload

    Building a Robust Live Reloader with WebSockets and Go - Brandur Leach https://brandur.org/live-relo ...

  7. Spring听课笔记(专题二下)

    第4章 Spring Bean基于注解的装配 4.1 Bean的定义及作用域的注解实现 1. Bean定义的注解 -- @Component是一个通用注解,可用于任何bean -- @Reposito ...

  8. 十六:SpringBoot-自定义启动页,项目打包和指定运行环境

    SpringBoot-自定义启动页,项目打包和指定运行环境 1.自定义启动页 2.打包配置 2.1 打包pom配置 2.2 多环境配置 3.环境测试接口 4.打包执行 4.1 指定模块打包 4.2 运 ...

  9. 使用Docker部署监控系统,Prometheus,Grafana,监控服务器信息及Mysql

    使用Docker部署监控系统,Prometheus,Grafana,监控服务器信息及Mysql 一.docker部署prometheus监控系统 1.1 配置安装环境 1.1.1 安装promethe ...

  10. spark SQL (四)数据源 Data Source----Parquet 文件的读取与加载

    spark SQL Parquet 文件的读取与加载 是由许多其他数据处理系统支持的柱状格式.Spark SQL支持阅读和编写自动保留原始数据模式的Parquet文件.在编写Parquet文件时,出于 ...