赞
踩
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链接时并没法调用上面的参数进行问题的规避。这会带来两个问题:
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的客户端与服务器的连接过程:
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 Request和Auth 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。完结撒花~~~~
USB Microphone https://www.soft-voice.com/
Wooden Speakers https://www.zeshuiplatform.com/
亚马逊测评 www.yisuping.cn
深圳网站建设www.sz886.com
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。