当前仓库属于暂停状态,部分功能使用受限,详情请查阅 仓库状态说明
439 Star 1.5K Fork 1.8K

GVPopenGauss/openGauss-server
暂停

opengauss-serveer多数据库网络协议扩展支持

已完成
特性
创建于  
2022-09-02 11:02

Is this a BUG REPORT or FEATURE REQUEST?:

  • feature

1.特性概述

同MySQL相比,opengauss拥有更加优秀的性能及扩展性,但国内数据库市场早期以Oracle、MySQL为主,经过多年高速增长,已经形成了庞大的用户基数;通过在opengauss server 层实现多网络协议的扩展框架后,可以让opengauss原生兼容其它数据库社区的生态,对于MySQL用户来说,可以在不改变操作习惯的前提下,平滑过渡到opengauss生态体系,它既可以是一个性能加强版本的MySQL,也是一个完整的opengauss。

2.目标

通过在opengauss内核层抽象一层网络协议交互接口,让opengauss具备以插件的方式动态支持多数据库网络协议的能力。

3.特性需求列表

需求编号 需求名称 特性描述 备注
1 协议扩展接口抽象 在opengauss内核提供协议扩展接口 SQL引擎 SIG组评审
2 opengauss协议层包装 基于协议扩展接口轻量包装既有opengauss协议相关逻辑 SQL引擎 SIG组评审
3 MySQL协议插件实现 插件化方式提供MySQL协议扩展接口实现 Plugin SIG组评审

4.总体方案

方案整体架构图,以opengauss兼容MySQL网络协议为例:

当首次创建/使用B兼容类型的数据库后,默认的MySQL 3306监听端口将会被自动拉起,MySQL的网络协议实现也会被绑定到3306 端口所对应的fd中;当用户通过MySQL driver 连接opengauss的3306端口时,opengauss的网络协议处理层,选择监听端口fd所对应的ProtocolExtensionConfig实现来响应这次网络请求。

5.设计思路

通过在port上绑定ProtocolExtensionConfig接口,来区分不通数据库网络协议在opengauss的处理流程;ProtocolExtensionConfig接口的默认实现方式为opengauss的网络协议,当首次创建/使用B兼容类型数据库时,MySQL相关的端口和ProtocolExtensionConfig实现将自动进行创建和绑定,这样用户可以通过MySQL的客户端直连opengauss的MySQL监听端口,可以原生兼容MySQL Client/Server间的网络交互协议。

6. 详细实现(从用户入口的模块级别或进程级别消息序列图)

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 中。

7.opengauss-server源码修改概述

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(-)

8.opengauss适配网络协议接口方式

对于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);
}

评论 (7)

zhaojun 创建了特性 3年前

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 .

zhaojun 修改了描述 3年前
zhaojun 修改了标题 3年前

/sig sqlengine

opengauss-bot 添加了
 
sig/sqlengine
标签
3年前

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.

zhaojun 方案设计设置为2022-08-30 3年前
zhaojun 设计方案评审设置为2022-08-30 3年前
zhaojun 方案设计2022-08-30 修改为2022-06-30 3年前

/assign zhaojun

This issue can not be assigned to zhaojun. Please try to assign to the repository collaborators.

zhaojun 置顶等级设置为 3年前
zhaojun 优先级设置为严重 3年前
zhaojun 置顶等级 修改为不置顶 3年前
zhaojun 置顶等级设置为 3年前
zhaojun 优先级严重 修改为不指定 3年前
zhaojun 任务状态方案设计 修改为测试方案评审 3年前
zhaojun 代码检视设置为2022-09-21 3年前
zhaojun 代码编写与自测设置为2022-09-02 3年前
zhaojun 测试方案评审设置为2022-08-30 3年前
zhaojun 关联分支设置为master 3年前
zhaojun 置顶等级 修改为不置顶 3年前

奇怪了,我部署成功,在服务器上也可以使用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
熊小军 任务状态测试方案评审 修改为已完成 1年前

登录 后才可以发表评论

状态
负责人
项目
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
预计工期 (小时)
开始日期   -   截止日期
-
置顶选项
优先级
组织
未设置
确定
里程碑
分支
方案设计
设计方案评审
测试方案评审
代码编写与自测
代码检视
需求验收
参与者(3)
5622128 opengauss bot 1581905080 zhaojun-kelayzhao 10315954 mu yi fan 1684395195
C++
1
https://gitee.com/opengauss/openGauss-server.git
git@gitee.com:opengauss/openGauss-server.git
opengauss
openGauss-server
openGauss-server

搜索帮助