Is this a BUG REPORT or FEATURE REQUEST?:
- feature
同MySQL相比,opengauss拥有更加优秀的性能及扩展性,但国内数据库市场早期以Oracle、MySQL为主,经过多年高速增长,已经形成了庞大的用户基数;通过在opengauss server 层实现多网络协议的扩展框架后,可以让opengauss原生兼容其它数据库社区的生态,对于MySQL用户来说,可以在不改变操作习惯的前提下,平滑过渡到opengauss生态体系,它既可以是一个性能加强版本的MySQL,也是一个完整的opengauss。
通过在opengauss内核层抽象一层网络协议交互接口,让opengauss具备以插件的方式动态支持多数据库网络协议的能力。
需求编号 | 需求名称 | 特性描述 | 备注 |
---|---|---|---|
1 | 协议扩展接口抽象 | 在opengauss内核提供协议扩展接口 | SQL引擎 SIG组评审 |
2 | opengauss协议层包装 | 基于协议扩展接口轻量包装既有opengauss协议相关逻辑 | SQL引擎 SIG组评审 |
3 | MySQL协议插件实现 | 插件化方式提供MySQL协议扩展接口实现 | Plugin SIG组评审 |
方案整体架构图,以opengauss兼容MySQL网络协议为例:
当首次创建/使用B兼容类型的数据库后,默认的MySQL 3306监听端口将会被自动拉起,MySQL的网络协议实现也会被绑定到3306 端口所对应的fd中;当用户通过MySQL driver 连接opengauss的3306端口时,opengauss的网络协议处理层,选择监听端口fd所对应的ProtocolExtensionConfig实现来响应这次网络请求。
通过在port上绑定ProtocolExtensionConfig接口,来区分不通数据库网络协议在opengauss的处理流程;ProtocolExtensionConfig接口的默认实现方式为opengauss的网络协议,当首次创建/使用B兼容类型数据库时,MySQL相关的端口和ProtocolExtensionConfig实现将自动进行创建和绑定,这样用户可以通过MySQL的客户端直连opengauss的MySQL监听端口,可以原生兼容MySQL Client/Server间的网络交互协议。
ProtocolExtensionConfig定义了网络协议交互的action,包含如下方法:
typedef struct ProtocolExtensionConfig {
bool server_handshake_first;
int (*fn_accept)(pgsocket server_fd, struct Port *port);
void (*fn_close)(pgsocket server_fd);
void (*fn_init)(void);
int (*fn_start)(struct Port *port);
void (*fn_authenticate)(struct Port *port);
void (*fn_send_message)(ErrorData *edata);
void (*fn_send_cancel_key)(int32 pid, int32 key);
void (*fn_comm_reset)(void);
void (*fn_send_ready_for_query)(CommandDest dest);
int (*fn_read_command)(StringInfo inBuf);
void (*fn_end_command)(const char *tag, CommandDest dest);
DestReceiver* (*fn_printtup_create_DR)(CommandDest dest);
void (*fn_set_DR_params)(DestReceiver* self, List* target_list);
int (*fn_process_command)(StringInfo inBuf);
void (*fn_report_param_status)(const char *name, char *val);
} ProtocolExtensionConfig;
其中,默认的opengauss网络协议的实现方式为:
ProtocolExtensionConfig default_protocol_config = {
false,
StreamConnection,
StreamClose,
pq_init,
StartupPacketInitialize,
ClientAuthentication,
send_message_to_frontend,
libpq_send_cancel_key,
pq_comm_reset,
ReadyForQuery,
SocketBackend,
EndCommand,
printtup_create_DR,
NULL,
NULL,
libpq_report_param_status
};
对于内核代码而言,需要把函数的直接调用包装为port->protocol_config->fn_xxxx方式进行调用(例如:StartupPacketInitialize 修改为 port->protocol_config->fn_start);在完全兼容既有内核的功能点的同时,增加了扩展其它网络协议的可能性。内核代码的修改点主要集中在 postmaster.cpp, postgres.cpp, postinit.cpp 中。
src/common/backend/libpq/pqcomm.cpp | 25 ++++++++-----
=> 创建监听端口时,绑定网络协议扩展配置
src/common/backend/utils/error/elog.cpp | 9 +++--
=> 适配send_message_to_frontend
src/common/backend/utils/init/postinit.cpp | 11 +++---
=> 适配ClientAuthentication
src/common/backend/utils/misc/guc.cpp | 15 +++-----
=> 适配 report_param_status
src/gausskernel/process/postmaster/postmaster.cpp | 227 +++++++++++++-----
=> 增加全局的协议扩展配置,定义opengauss默认网络协议实现,支持动态刷新监听的fd
src/gausskernel/process/tcop/dest.cpp | 2 +-
=> 适配 printtup_create_DR
src/gausskernel/process/tcop/postgres.cpp | 71 +++++++++++++++++++++--------------
=> 适配EndCommand,read_command,send_cancel_key, comm_reset, send_ready_for_query, process_command
src/gausskernel/process/threadpool/knl_thread.cpp | 1 -
=>移动ListenContext相关变量至g_instance中
src/gausskernel/process/threadpool/threadpool_listener.cpp | 6 ++++-
=> epoll中增加写事件,兼容由server端发起握手的数据库网络协议
src/gausskernel/process/threadpool/threadpool_worker.cpp | 14 +++----
=> 适配send_ready_for_query, send_cancel_key
src/gausskernel/runtime/executor/spi.cpp | 9 ++++-
=> spi中兼容dolphin事务处理, 增加printtup需要的stmt参数透传
src/include/access/printtup.h | 1 +
=> DR_printtup增加target_list, 用于通过spi输出数据报文header到客户端
src/include/knl/knl_instance.h | 12 ++++++
=> 增加knl_g_listen_context结构体,用于运行时动态修改监听端口信息
src/include/knl/knl_thread.h | 7 +++---
=> 移动listen_context相关的属性至knl_instance.h
src/include/libpq/libpq-be.h | 28 ++++++++++++++
=> 定义ProtocolExtensionConfig接口,Port结构体中增加protocol_config属性
src/include/libpq/libpq.h | 6 ++-
=> StreamServerPort中增加ProtocolExtensionConfig*参数
src/include/catalog/pg_authid.h | 6 +++++-
=> authid系统表中增加rolepasswordext,用于保存dolphin格式的密码
17 files changed, 291 insertions(+), 160 deletions(-)
对于opengauss内核代码,需要把 default_protocol_config 涉及的函数进行简单的适配,适配方法如下:
StreamConnection:
protocol->fn_accept(serverFd, port) != STATUS_OK
StreamClose:
protocol->fn_close(port->sock);
pq_init:
if (port->protocol_config && port->protocol_config->fn_init) {
port->protocol_config->fn_init();
} else {
pq_init();
}
StartupPacketInitialize:
int status = port->protocol_config->fn_start(port);
ClientAuthentication:
port->protocol_config->fn_authenticate(port);
**send_message_to_frontend: **
void send_message_to_frontend_ext(ErrorData* edata) {
if (u_sess->proc_cxt.MyProcPort) {
u_sess->proc_cxt.MyProcPort->protocol_config->fn_send_message(edata);
}
}
libpq_send_cancel_key:
Port* MyProcPort = u_sess->proc_cxt.MyProcPort;
if (MyProcPort && MyProcPort->protocol_config->fn_send_cancel_key) {
MyProcPort->protocol_config->fn_send_cancel_key((int32)t_thrd.proc_cxt.MyPMChildSlot,
(int32)t_thrd.proc_cxt.MyCancelKey);
}
extern void libpq_send_cancel_key(int32 pid, int32 key);
void libpq_send_cancel_key(int32 pid, int32 key)
{
StringInfoData buf;
pq_beginmessage(&buf, 'K');
pq_sendint32(&buf, pid);
pq_sendint32(&buf, key);
pq_endmessage(&buf);
}
pq_comm_reset:
Port* MyProcPort = u_sess->proc_cxt.MyProcPort;
if (MyProcPort && MyProcPort->protocol_config->fn_comm_reset) {
MyProcPort->protocol_config->fn_comm_reset();
}
ReadyForQuery:
session->proc_cxt.MyProcPort->protocol_config->fn_send_ready_for_query((CommandDest)t_thrd.postgres_cxt.whereToSendOutput);
SocketBackend
result = u_sess->proc_cxt.MyProcPort->protocol_config->fn_read_command(inBuf);
EndCommand
void EndCommandExt(const char *completionTag, CommandDest dest) {
Port* MyProcPort = u_sess->proc_cxt.MyProcPort;
if (MyProcPort) {
MyProcPort->protocol_config->fn_end_command(completionTag, dest);
}
}
printtup_create_DR
u_sess->proc_cxt.MyProcPort->protocol_config->fn_printtup_create_DR(dest);
libpq_report_param_status
/*
* ReportGUCOption: if appropriate, transmit option value to frontend
*/
static void ReportGUCOption(struct config_generic* record)
{
if (u_sess->utils_cxt.reporting_enabled && (record->flags & GUC_REPORT)) {
Port* MyProcPort = u_sess->proc_cxt.MyProcPort;
if (MyProcPort && MyProcPort->protocol_config->fn_report_param_status) {
char* val = _ShowOption(record, false);
(MyProcPort->protocol_config->fn_report_param_status)(record->name, val);
pfree(val);
}
}
}
void libpq_report_param_status(const char *name, char *val)
{
StringInfoData msgbuf;
pq_beginmessage(&msgbuf, 'S');
pq_sendstring(&msgbuf, name);
pq_sendstring(&msgbuf, val);
pq_endmessage(&msgbuf);
}
Hey @kelayzhao, Welcome to openGauss Community.
All of the projects in openGauss Community are maintained by @opengauss-bot.
That means the developers can comment below every pull request or issue to trigger Bot Commands.
Please follow instructions at Here to find the details.
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
Hi @kelayzhao, please use the command /sig xxx to add a SIG label to this issue.
For example: /sig sqlengine or /sig storageengine or /sig om or /sig ai and so on.
You can find more SIG labels from Here.
If you have no idea about that, please contact with @xiangxinyong , @zhang_xubo .
/sig sqlengine
Hi @kelayzhao,
if you want to get quick review about your issue, please contact the owner in first: @yanghaos ,
and then any of the maintainers: @zankyfun4 , @chenhao7253886
and then any of the committers: @ziki77 , @yanghaos , @llzx373 , @lee1002 , @scarbor_fair , @hemny , @totaj , @zzy0310 , @April01xxx , @haoqingyun , @dengxuyue , @gentle_hu
if you have any question, please contact the SIG: SQLEngine.
/assign zhaojun
This issue can not be assigned to zhaojun. Please try to assign to the repository collaborators.
奇怪了,我部署成功,在服务器上也可以使用mysql的语法,但是本地用navicat连服务器的数据库,却连不上,在服务器上安装了mysql的客户端,依然连不上
这是我的部署文档:
新建一个/opt/onekey-build-og.sh文件,存入以下内容
#!/bin/bash
# 环境 centos 7.9 4C 8G (配置越高编译越快,4G内存编译不了,磁盘大概需要14GB)
# 安装一些依赖 (libaio-devel如果不卸载重装,可能会找不到io_context_t)
yum remove libaio-devel libaio -y
yum install -y git gmp gmp-devel mpfr mpfr-devel libmpc libmpc-devel libaio libaio-devel flex bison ncurese-devel glibc-devel patch rehat-lsb-core readline-devel perl gcc gcc-c++
# 新建一个用户
useradd omm500
# 创建目录
mkdir /opt/omm500
chown omm500 /opt/omm500 -R
# 切换用户执行编译及安装
chown omm500 install.sh
chmod 777 install.sh
su - omm500 -c "cd /opt && bash install.sh"
新建一个/opt/install.sh文件,存入以下内容
#!/bin/bash
# 创建数据目录
cd /opt/omm500
mkdir data
# 下载编译好的三方库并解压(这里下载的是Centos7.6_x86_64的版本,在7.6和7.9都能用)
wget https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.0.0/binarylibs/openGauss-third_party_binarylibs_Centos7.6_x86_64.tar.gz
tar -xvf openGauss-third_party_binarylibs_Centos7.6_x86_64.tar.gz
# 克隆数据库源码仓
git clone https://gitee.com/opengauss/openGauss-server -b 5.0.0
# 配置环境变量(这里最核心的一点就是把gcc的默认路径改了,操作系统默认的版本太低)
echo "export CODE_BASE=/opt/omm500/openGauss-server # Path of the openGauss-server file " >> ~/.bash_profile
echo "export BINARYLIBS=/opt/omm500/openGauss-third_party_binarylibs_Centos7.6_x86_64 # Path of the binarylibs file " >> ~/.bash_profile
echo "export GAUSSHOME=\$CODE_BASE/dest/ " >> ~/.bash_profile
echo "export GCC_PATH=\$BINARYLIBS/buildtools/gcc7.3/ " >> ~/.bash_profile
echo "export CC=\$GCC_PATH/gcc/bin/gcc " >> ~/.bash_profile
echo "export CXX=\$GCC_PATH/gcc/bin/g++ " >> ~/.bash_profile
echo "export LD_LIBRARY_PATH=\$GAUSSHOME/lib:\$GCC_PATH/gcc/lib64:\$GCC_PATH/isl/lib:\$GCC_PATH/mpc/lib/:\$GCC_PATH/mpfr/lib/:\$GCC_PATH/gmp/lib/:\$LD_LIBRARY_PATH " >> ~/.bash_profile
echo "export PATH=\$GAUSSHOME/bin:\$GCC_PATH/gcc/bin:\$PATH " >> ~/.bash_profile
echo "export PGDATA=/opt/omm500/data" >> ~/.bash_profile
echo "export PGPORT=5432" >> ~/.bash_profile
echo "export PGDATABASE=postgres" >> ~/.bash_profile
# 加载环境变量
source ~/.bash_profile
# 进入源码目录
cd $CODE_BASE
# 编译server (这里就是openGauss提供的一键式编译脚本)
sh build.sh -m release -3rd $BINARYLIBS
# 文件夹改名 (原文档说会生成dest目录,但实际上是生成到了mppdb_temp_install,所以改个名)
mv mppdb_temp_install dest
# 克隆插件仓,并复制到server源码目录内(必须单独编译,因为如果先放到server源码内,server都会编译不成功)
git clone https://gitee.com/opengauss/Plugin -b 5.0.0
cp Plugin/contrib/* $CODE_BASE/contrib/ -r
# 编译dolphin插件
cd contrib/dolphin
make install
# 复制插件到编译好的server目录
cp *.so $GAUSSHOME/lib/postgresql/
cp *.control $GAUSSHOME/share/postgresql/extension/
cp *.sql $GAUSSHOME/share/postgresql/extension/
# 初始化数据库
gs_initdb --nodename=primary --pwpasswd=Sinvie@123
# 配置一些数据库参数
echo "port=$PGPORT" >> $PGDATA/postgresql.conf
echo "listen_addresses = '0.0.0.0'" >> $PGDATA/postgresql.conf
echo "password_encryption_type = 0" >> $PGDATA/postgresql.conf
echo "log_directory = 'pg_log'" >> $PGDATA/postgresql.conf
echo "remote_read_mode=non_authentication" >> $PGDATA/postgresql.conf
echo "host all all 0.0.0.0/0 md5" >> $PGDATA/pg_hba.conf
# 启动数据库
gs_ctl start
# 连接数据库并创建一个B库
gsql -c "create database sioc_3_3 dbcompatibility='B'";
# 开启一些mysql特性
gsql -c "alter database sioc_3_3 set enable_set_variable_b_format = on;";
gsql -c "alter database sioc_3_3 set dolphin.lower_case_table_names = 0;";
gsql -c "alter database sioc_3_3 set dolphin.B_COMPATIBILITY_MODE = on;";
gsql -c "alter database sioc_3_3 set dolphin.sql_mode = '';";
gsql -c "alter system set enable_dolphin_proto= on;";
# gsql -c "alter system set default_database_name=sioc_3_3;";
gsql -c "alter system set dolphin_server_port=3307;";
gs_ctl restart
对onekey-build-og.sh 授权可执行
chmod 777 onekey-build-og.sh
然后执行这个sh文件(4C 8G 100M宽带 大约30分钟)
./onekey-build-og.sh
su - omm500
gsql -r -d sioc_3_3 -h 127.0.0.1 -U omm500 -W Sinvie@123
表名大小写敏感及反引号
create table Test_123 (`a` int, `B` int ,"Ab" int);
\d+ "Test_123"
select * from Test_123;--不会报错
select * from test_123;--会报错
mysql客户端连接
如果机器上没有安装mysql客户端,则先安装一下
yum -y install http://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm
yum search mysql
yum install -y mysql-community-client.x86_64
创建一个新的数据库用户
su - omm500
gsql -c "create user emt password 'Sinvie@123';"
su - omm500
gs_ctl stop
exit
userdel omm500
rm -rf /opt/omm500
rm -rf /home/omm500
登录 后才可以发表评论