文章目录
昆仑数据库的计算节点基于 PostgreSQL 研发,因而直接可以支持PostgreSQL 的连接协议,所以使用 JDBC、ODBC 等通用的数据库连接协议以及使用各类编程语言的 PostgreSQL 专有的连接库的软件都可以连接到昆仑数据库集群并且正常工作。
为了让原本使用 MySQL 的应用程序可以不需要修改也不需要重新编译就能连接并且正常使用昆仑数据库,我们开发了昆仑数据库的 MySQL 连接协议,本文对此协议实现做一个简介。
总的来说,对于 KunlunBase 来说,连接协议就是客户端与 KunlunBase 服务器通信的管道,MySQL 和 PostgreSQL 协议就是两种形状不同的管道,而其中传输的 SQL 语句和查询结果则本质上是相同的。
也就是说 KunlunBase 支持的任何 SQL 语法和功能都可以在 MySQL 和PostgreSQL 这两种连接协议中的任何一种连接中传输到服务器集群中正常执行并收到其结果。
例如可以在 MySQL 连接中发送 PostgreSQL 私有语法 SQL 或者标准 SQL 语句,包括 prepared statement 语法、存储过程语法、DDL语法等,并且得到遵循MySQL协议的结果,从而可以使用 MySQL 客户端库完成结果读取;也可以 在PostgreSQL 连接中发送 KunlunBase 支持的任何 MySQL 私有语法(例如prepared statement、DML等)的 SQL语句或者标准 SQL 语句,并且得到遵循 PostgreSQL 的结果,从而可以使用 PostgreSQL 客户端库完成结果读取。
昆仑数据库MySQL协议支持的功能
昆仑数据库MySQL协议支持所有常用功能,包括文本和二进制协议,连接验证(只支持mysql_native_password),数据压缩,prepared statement,字符集,错误处理,SSL连接等。
一个Kunlun-server(计算节点)同时监听2个TCP端口 — PostgreSQL协议的端口(默认5432)和MySQL协议的端口(默认5306),都可以通过配置文件自定义配置。
MySQL 和 PostgreSQL 客户端使用统一的用户名和密码连接 Kunlun-server,不论使用哪一种连接协议,Kunlun-server收到TCP连接请求后,会启动本端口的服务端协议(即 PostgreSQL 或者 MySQL)处理模块,完成连接验证,建立起有效的数据库连接。
后续在这两类连接中用户可以发送的 SQL 语句完全相同,与协议无关。
用户可以在任何一类连接中发送标准 SQL 语句,或者 PostgreSQL 或者MySQL 私有语法的 SQL 语句给昆仑数据库并且获得结果。
账号和访问控制
用户通过 Kunlun-server 的 PostgreSQL 或者 MySQL 连接发送 create user 语句建立用户账户,这里的 create user 语法(以及任何其他 DDL 语法)必须是 PostgreSQL 的语法。
DBA 通过在 pg_hba.conf 配置文件中建立访问控制规则,来可选地定义某些用户账号必须来自特定的IP或者域名,或者某个账户只能访问某些 database等访问控制规则。
关于在pg_hba.conf配置访问控制规则,详见PostgreSQL的文档。
错误处理
昆仑数据库 MySQ L协议会自动把 PostgreSQL 的错误号被映射到对应的MySQL 错误号;MySQL 协议运行期间返回的错误则使用与 MySQL 的server 端协议实现完全相同的错误号。
因此应用程序原本处理 MySQL 错误的代码逻辑不需要任何修改就可以按照预期工作。
JDBC 等数据库客户端 API 库基于异常类树进行错误处理,每一个异常类型绑定若干个 MySQL 错误号,因此只要应用程序代码实现了异常捕捉,也可以正确地捕获昆仑数据库的MySQL连接返回的错误异常。
错误描述文本使用 PostgreSQL 的错误字符串,而不是 MySQL 错误号对应的文本。
这通常不会成为问题,因为根据 MySQL 的文档,虽然错误号码在所有MySQL版本中不变,但是错误描述并不承诺不变,所以应用程序本来也不应该基于错误字符串的内容匹配来实现其功能逻辑。
另外,KunlunBase 支持 MySQL 的SHOW WARNINGS和SHOW ERRORS语句,并且其用法和效果与 MySQL 的相同语句完全相同。
字符集
MySQL客户端可以按照其标准方式指定字符集,这个字符集如果昆仑数据库不支持则连接失败报错。
PostgreSQL默认支持丰富的字符集,它与MySQL支持的字符集大部分是重合的,所有常见字符集两者都支持,包括所有中文、日韩字符集以及主要欧洲(西中东欧)各语言字符集。
MySQL客户端发送到昆仑数据库的任何字符串,都会先转换为当前数据库的字符集再使用;返回给MySQL客户端的任何字符串都会先从