openGauss MySQL兼容性函数开发流程和要点
发表于 2023/12/07
0
开发流程
(1)在openGauss社区Plugin仓进行兼容性相关开发(https://gitee.com/opengauss/Plugin)。
(2)通过 fastcheck 自测以及 CI 门禁。
(3)提供 checkin 测试报告和开发文档并通过 SIG 组评审。
开发要点
1.开放接口函数 DLL_PUBLIC PG_FUNCTION_INFO_V1_PUBLIC 统一管理
为了避免插件与内核同名函数所产生的符号冲突,我们在 makefile 中使用-fvisibility=hidden 参数,使得插件函数不会注册进符号表进而避免,但是这样内核就无法调用其中的函数,因此对于需要开放给内核调用的接口函数,我们需要添加一个 DLL_PUBLIC 关键字将其注册进符号表,还需用 PG_FUNCTION_INFO_V1_PUBLIC 添加函数,来避免 API 版本报错。
因此后续考虑使用一个头文件统一管理需要开放的接口函数。
如果写在 builtin 中的函数或者有同名重载函数需要开放或者供内部引用,extern 后面不能加“C”。


如第四节的time函数需要在实现函数功能之前需要添加如下代码:
PG_FUNCTION_INFO_V1_PUBLIC(time_mysql);
extern "C" DLL_PUBLIC Datum time_mysql(PG_FUNCTION_ARGS);
2. Makefile 需要添加相对应.o
对于新增的 cpp 文件,需要在其对应模块的 makefile 和主目录下的 makefile 中分别添加其.o 文件来生成 so,使得其中函数能在插件中调用。

3. 新增代码添加 DOLPHIN 宏
对于内核已有的文件进行的改动,需要添加相应的 DOLPHIN 宏
添加: #ifdef DOLPHIN 新增内容 #endif
修改: #ifdef DOLPHIN 修改内容 #else 原内容 #endif
删除: #ifndef DOLPHIN 删除内容 #endif
4. fastcheck 自测方法
将测试用的.sql 文件放入 sql 文件夹 预期结果放入 expected 文件夹。注意使用 LF 行尾序列避免格式问题

通过make check p=xxx命令就能进行自测,如提示变量值不对需要手动修改pg_regress.cpp中相应值。


memcheck并不是一个新的check,只是编译openGauss时,编译一个memcheck版的,然后通过跑fastcheck来发现代码中的内存问题。 编译方式和编译普通的openGauss基本一致,只是在configure时,添加一个--enable-memory-check参数,编译出来的就是memcheck版本的openGauss。
./configure --gcc-version=7.3.0 CC=g++ CFLAGS='-O0' --prefix=$GAUSSHOME --3rd=$BINARYLIBS --enable-debug --enable-cassert --enable-thread-safety --with-readline --without-zlib --enable-memory-check
Install check需要自己设置asan option
export HOME=~ ulimit -v unlimited
export
ASAN_OPTIONS=detect_leaks=1:halt_on_error=0:alloc_dealloc_mismatch=0:log_path=$HOME/memchk/memcheck
设置完环境变量后,正常跑 fastcheck 即可,跑完后,会在 $HOME/memchk/memcheck路径下生成文件名为runlog.xxx的memcheck报告。根据 memcheck报告分析是否有内存问题。如何分析memcheck报告可自行网上搜索memcheck 报告分析、asan 报告分析等关键字。
5. 升级
5.0.0版本之后,需要考虑插件的升级,新增的创建函数、类型等SQL语句均需写到升级脚本中。如dolphin插件版本为1.1,则需要写到升级脚本contrib/dolphin/upgrade_script/dolphin--1.0--1.1.sql中,与升级相对应的还有回滚,回滚需要还原到升级前的插件状态,回滚语句写到contrib/dolphin/rollback_script/dolphin--1.1--1.0.sql中。
例如1.0版本中有函数bool_text,入参为true时返回1,为false时返回0,假设在1.1版本中,我们将其修改为true时返回0,false时返回1,则dolphin--1.0--1.1.sql应如下先删除后以新的定义创建。
drop function if exists pg_catalog.bool_text(a bool) cascade;
CREATE OR REPLACE FUNCTION pg_catalog.bool_text(a bool)
returns text
as
$$
begin
IF a is null then
return null;
else
if a = true then
return '0';
else
return '1';
end if;
end if;
end;
$$
language plpgsql;
回滚脚本dolphin--1.1--1.0.sql应创建回原先1.0版本的函数。
drop function if exists pg_catalog.bool_text(a bool) cascade;
CREATE OR REPLACE FUNCTION pg_catalog.bool_text(a bool)
returns text
as
$$
begin
IF a is null then
return null;
else
if a = true then
return '1';
else
return '0';
end if;
end if;
end;
$$
language plpgsql;
如果是新增的对象,则在升级脚本中直接创建,回滚脚本中将其删除即可。