Doris开发手记1:解决蛋疼的MySQL 8.0连接问题

笔者作为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的二进制包是如何组成的。这里再次借助官方文档,确认了两个包的组成:

AuthSwitchRequest
AuthSwitchResponse
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源代码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,442评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,604评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,576评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,652评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,495评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,370评论 1 274
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,792评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,435评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,735评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,777评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,553评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,399评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,806评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,038评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,330评论 1 253
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,766评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,964评论 2 337

推荐阅读更多精彩内容