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

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

1.老革命遇到新问题

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

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

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

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

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

  1. Mysql ->: Authentication Plugin: mysql_native_password
  2. Client <-: Client Auth Plugin: caching_sha2_password
  3. Mysql ->: Auth Switch Request: Auth Method Name: mysql_native_password
  4. Client <-: Auth Switch Response
  5. Mysql ->: OK

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

3.开发起来,解决问题

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

3.1 确认二进制结构

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

3.2 代码开发

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

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

就是进行了密码认证插件的校验,如果不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. 【原创】Linux虚拟化KVM-Qemu分析(八)之virtio初探

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: KVM版本:5.9 ...

  2. linux设备

    设备初始化时同样要执行一个device_register函数,该函数传入一个struct device *类型的指针,因此要定义一个struct device类型的变量作为我们的设备. struct ...

  3. LocalDateTime去掉T

    最近在使用阿里巴巴的fastjson反序列化对象的时候,对象里面时间格式属性总是会多了一个T  2021-1-09T18:29:09.097 这个T是啥国际标准,但是我们的前端又不需要这个T,所以就要 ...

  4. Windows server 2008常用优化设置

    1. 如何取消开机按 CTRL+ALT+DEL登录? 控制面板→管理工具→本地安全策略→本地策略→安全选项→交互式登录:无须按CTRL+ALT+DEL→启用. 2. 如何取消关机时出现的关机理由选择项 ...

  5. jQuery 点击当前展开其他隐藏

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name ...

  6. Boyer-Moore 投票算法

    Boyer-Moore 投票算法 http://theory.stanford.edu/~trevisan/cs154-12/notestream.pdf 众数

  7. HTTP/2与HTTP/3的新特性

    解密HTTP/2与HTTP/3的新特性 - InfoQ https://www.infoq.cn/article/kU4OkqR8vH123a8dLCCJ

  8. SSL_ERROR_WANT_READ

    ``` 47757 2020/05/07 06:36:04 [debug] 19413#19413: *23421 event timer: 11, old: 15581551413, new: 15 ...

  9. OpenStack (云计算与openstck简介)

    云计算 什么是云计算 云计算是一种按使用量付费的模式,这种模式提供可用的,便捷的,按需的网络访问,通过互联网进入可配置的计算资源共享池(资源包括,计算,存储,应用软件和服务) 云计算的特征 易于管理: ...

  10. 【uva 534】Frogger(图论--最小瓶颈路 模版题)

    题意:平面上有N个石头,给出坐标.一只青蛙从1号石头跳到2号石头,使路径上的最长便最短.输出这个值.(2≤N≤200) 解法:最小瓶颈树.而由于这题N比较小便可以用2种方法:1.最短路径中提到过的Fl ...