当前位置: 首页 > news >正文

【GaussDB】使用MySQL客户端连接到GaussDB的M-Compatibility数据库

【GaussDB】使用MySQL客户端连接到GaussDB的M-Compatibility数据库

概述

GaussDB 从内核 505.1 版本(2024年4月发布)起,新增了一种新的兼容模式 M-Compatibility,这是一种整体上比之前的B模式对MySQL兼容性更高的模式。这种M模式在建库时会自动使用模板库 templatem

之所以需要再新增一种M模式,我猜测是因为GaussDB发现有些MySQL兼容性已经完全违背了内核的SQL及存储逻辑,无法通过参数调整进行兼容,为了不影响原有B模式的用户,必须新增一种兼容模式来隔离之前的逻辑。

新的这个M兼容模式,可以用MySQL客户端进行连接,但是实际使用过程中,可能会有一些坑在文档中并未详细说明,本文就来介绍一下"使用MySQL客户端连接到GaussDB的M-Compatibility数据库"的正确姿势。

测试环境:本文使用的GaussDB内核版本为 506.0 SPC0100


建库操作

指定M兼容模式建库:

CREATE DATABASE mysql DBCOMPATIBILITY='M';

修改参数

参考文档

  • 《基于MySQL JDBC开发-开发步骤-环境准备》

添加客户端IP到数据库白名单

将客户端IP添加到数据库白名单,具体操作请联系管理员处理。

设置兼容性参数

请参见《管理员指南》中的"配置运行参数"章节,配置相关GUC参数并重启数据库。

参数配置:

  1. 配置协议监听的TCP端口号,设置GUC参数 plat_compat_server_port 为合理端口
  2. 如果使用到RSA,需要设置GUC参数 plat_compat_allow_public_key_retrievalon
  3. 将GUC参数 m_format_dev_version 设置为 "s2"

执行命令:

gs_guc reload -I all -N all -c "plat_compat_server_port=3306"
gs_guc reload -I all -N all -c "plat_compat_allow_public_key_retrieval=on"
gs_guc reload -I all -N all -c "m_format_dev_version='s2'"

创建连接用户(可选)

CREATE USER mysql_user PASSWORD 'Gaussdb@123' SYSADMIN MONADMIN;

连接测试

初始连接问题

image-grwl.png
使用MySQL客户端连接时出现报错:

错误信息: plat_compat_b_conn_handshake, handshake error.

Java代码连接测试

尝试手写一段Java代码进行连接:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;public class MySQLCreateTable {public static void main(String[] args) {String url = "jdbc:mysql://192.168.163.119:3306/mysql";String user = "mysql_user";String password = "Gaussdb@123";try (Connection conn = DriverManager.getConnection(url, user, password);Statement stmt = conn.createStatement()) {String sql = "CREATE TABLE IF NOT EXISTS users2 (" +"id INT PRIMARY KEY AUTO_INCREMENT," +"name VARCHAR(100) NOT NULL," +"email VARCHAR(100) NOT NULL UNIQUE" +")";stmt.executeUpdate(sql);System.out.println("Table created successfully.");} catch (Exception e) {e.printStackTrace();}}
}

运行结果: 也报错了

com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failureThe last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174)at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64)at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:827)at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:447)at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:237)at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:199)at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:681)at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:229)at MySQLCreateTable.main(MySQLCreateTable.java:11)
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failureThe last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151)at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167)at com.mysql.cj.protocol.a.NativeProtocol.negotiateSSLConnection(NativeProtocol.java:340)at com.mysql.cj.protocol.a.NativeAuthenticationProvider.negotiateSSLConnection(NativeAuthenticationProvider.java:777)at com.mysql.cj.protocol.a.NativeAuthenticationProvider.proceedHandshakeWithPluggableAuthentication(NativeAuthenticationProvider.java:486)at com.mysql.cj.protocol.a.NativeAuthenticationProvider.connect(NativeAuthenticationProvider.java:202)at com.mysql.cj.protocol.a.NativeProtocol.connect(NativeProtocol.java:1348)at com.mysql.cj.NativeSession.connect(NativeSession.java:163)at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:947)at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:817)... 6 more
Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)at java.base/sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:172)at java.base/sun.security.ssl.ClientHandshakeContext.<init>(ClientHandshakeContext.java:103)at java.base/sun.security.ssl.TransportContext.kickstart(TransportContext.java:240)at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:448)at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:426)at com.mysql.cj.protocol.ExportControlled.performTlsHandshake(ExportControlled.java:316)at com.mysql.cj.protocol.StandardSocketFactory.performTlsHandshake(StandardSocketFactory.java:188)at com.mysql.cj.protocol.a.NativeSocketConnection.performTlsHandshake(NativeSocketConnection.java:99)at com.mysql.cj.protocol.a.NativeProtocol.negotiateSSLConnection(NativeProtocol.java:331)... 13 more

解决方案

查看官方文档《基于MySQL JDBC开发-开发步骤-连接数据库-以常规方式连接》,发现文档中的连接串是:

String sourceURL = "jdbc:mysql://$ip:$port/database?useSSL=false&allowPublicKeyRetrieval=true";

多了两个参数,逐步测试:

步骤1:添加 useSSL=false

先加一个 useSSL=false 参数测试。
image-kjpz.png
结果: 出现了和mogeaver一样的报错。

步骤2:添加 allowPublicKeyRetrieval=true

再把另一个参数也加上去 allowPublicKeyRetrieval=true
image-mrai.png
结果: ✅ 执行成功了!

验证其他客户端

在mogeaver里也加上这个参数 allowPublicKeyRetrieval=true
image-jlyz.png
结果: ✅ 也连接成功了!

说明: 但是mogeaver里的useSSL为true,之所以没有报错,是因为mogeaver里还自动加上了enabledTLSProtocols=TLSv1,TLSv1.1,TLSv1.2

连接参数总结

根据测试,自己写的Java代码,连接时必须加上:

  • 方案一: useSSL=false&allowPublicKeyRetrieval=true
  • 方案二: useSSL=true&enabledTLSProtocols=TLSv1,TLSv1.1,TLSv1.2

常见问题及解决

如果是普通的测试人员,测到这里,就会认为连接测试这一项已经测试通过了,但是换几个不同的环境里的GaussDB去测,还可能会出现这样的报错:

问题:Access denied for user

image-itil.png

错误信息: Access denied for user

注意: 如果是用户名密码错误,也会报这个错,所以先要用gsql测试一下用户名密码是否正确,确认用户名密码没有写错后,那么问题就可能发生在密码加密方式上。

原因分析

在官方文档[《配置客户端接入认证》](https://support.huawei.com/carrier/docview?nid=DOC1101458028&path=PBI1-253383977/PBI1-23710112/PBI1-23710137/PBI1-256197501&partNo=k00e)这个章节里写着:

外部客户端使用M-Compatibility兼容协议远程连接M-Compatibility数据库时,只支持 sha256认证方式

于是去检查gs_hba.conf,发现无论是配置成md5还是sha256,Access denied for user这个问题都依然存在。

然后继续翻官方文档,发现在《设置密码安全策略》这个章节里写着:

使用M-Compatibility兼容协议连接数据库时,仅支持sha256加密模式,即 password_encryption_type = 2

也就是说,必须确保数据库用户的密码存储时,必须是仅存储sha256密文,不能支持其他方式。

解决步骤
  1. 修改密码加密参数:
gs_guc reload -I all -N all -c "password_encryption_type=2"
  1. 重新设置用户密码:
ALTER USER mysql_user PASSWORD 'mysql_123';

到此,使用MySQL客户端连接GaussDB就顺利了…吗?


进阶配置:RSA加密支持

搜索官方文档,发现还有这么一个章节:《使用RSA加密登录密码》

RSA加密登录配置要求:

  1. 设置 plat_compat_allow_public_key_retrieval 参数值为 on
  2. 设置 require_ssl 参数值为 off
  3. 设置 hba type 参数值为 hosthostnossl

也就是说,如果 require_sslon,那么本文的配置方式也会连接不上去了。

连接方式总结

综合分散在文档各个地方的信息来看,连接应该是可以用RSA或者不用RSA:

服务端配置客户端配置说明
plat_compat_allow_public_key_retrieval=offuseSSL=true&enabledTLSProtocols=TLSv1,TLSv1.1,TLSv1.2禁用RSA,使用SSL
plat_compat_allow_public_key_retrieval=onuseSSL=false&allowPublicKeyRetrieval=true使用RSA,不使用SSL
plat_compat_allow_public_key_retrieval=onuseSSL=true&enabledTLSProtocols=TLSv1,TLSv1.1,TLSv1.2允许使用RSA,但仍然使用SSL

实测也的确如此。


补充说明

另外,数据库里还有个参数 plat_compat_default_database,可以配置MySQL协议连过来需要连接哪个库。

  • 在没有设置这个参数时: JDBC连接串里的dbname就真的是GaussDB里面的数据库名称
  • 如果设置了这个参数: JDBC连接串里的dbname就是 plat_compat_default_database 指定的库下的schema名称

重要声明

⚠️ 版本说明:本文这里的这些内容,仅为在 506.0 SPC0100 集中式版本上测试的结果,不代表新版本的表现(目前已知有些东西在新版本改了)。


相关文档

  • 《基于MySQL JDBC开发-开发步骤-环境准备》
  • 《基于MySQL JDBC开发-开发步骤-连接数据库-以常规方式连接》
  • 《设置密码安全策略》
  • 《使用RSA加密登录密码》
  • 本文作者: DarkAthena
  • 本文链接: https://www.darkathena.top/archives/Connecting-to-GaussDB-M-Compatibility-Mode-via-MySQL-Client
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处
http://www.dtcms.com/a/347261.html

相关文章:

  • 智慧零售漏扫率↓79%!陌讯多模态融合算法在智能收银与货架管理的实战解析
  • 【Linux】深度学习Linux下的包管理器yum/apt
  • Day22: Python涡轮增压计划:用C扩展榨干最后一丝性能!
  • 微前端架构常见框架
  • 深度学习之PyTorch框架(安装,手写数字识别)
  • pid自适应调节实战设计-基于输出电流的PI参数切换方案
  • deepseek应用技巧-MCP服务操作网页和文档
  • ESP32应用——UDP组播/广播(ESP-IDF框架)
  • AI 辅助编程完全新手指南 - 从零基础到高效协作
  • Java试题-选择题(15)
  • flink常见问题之超出文件描述符限制
  • frp v0.64.0 更新:开源内网穿透工具,最简洁教程
  • 生成一个256 点 Q15 正弦表,deepseek载了
  • TK 直播网络串流 通过VLC本地播放
  • 合合信息acge模型获C-MTEB第一,文本向量化迎来新突破
  • 数据库服务语句应用
  • Vmware虚拟机 处理器配置选项配置介绍
  • 香橙派板子Orange Pi 5 Max开启 WiFi 热点
  • Java 线程相关的三个常见接口、类
  • pytorch与torchvision版本对应情况
  • SHAP分析+KOA-RIME开普勒结合霜冰算法双重优化BP神经网络+9种映射方法+新数据预测!机器学习可解释分析!
  • Excel 条件高亮工具,秒高亮显示符合筛选条件的行数据
  • 数据结构与算法-字符串、数组和广义表(String Array List)
  • pixijs基础学习
  • Huggingface入门实践 图像处理CV与多模态模型调用(二)
  • Android 之wifi连接流程
  • 用 Go + GitHub Models API 打造一个免费的 ChatBot
  • 金山办公的服务端开发工程师-25届春招笔试编程题
  • 密码实现安全基础篇 . KAT(已知答案测试)技术解析与实践
  • 微服务的编程测评系统15-头像上传-OSS