跳转至

修订记录

版本 日期 变更内容 变更原因
1.0 2024-12-23 创建
1.1 2025-03-04 下载开发套件 开发套件已发布

本篇文档介绍如何使用OceanBase的开发套件开发插件。

快速开始

下面以全文检索分词插件为例介绍如何开发OceanBase插件。

安装开发基础环境

yum install -y cmake make glibc-devel glibc-headers gcc gcc-c++

下载oceanbase plugin开发套件

yum install -y yum-utils
yum-config-manager --add-repo https://mirrors.aliyun.com/oceanbase/OceanBase.repo
yum install -y oceanbase-plugin-dev-kit

复制examples/ftparser到自己的开发目录

这里假设你的开发目录是 /your/work/path,你可以修改为自己的目录。

# 复制分词插件的样例代码,如果开发其它插件,需要复制其它插件的样例代码
cp -rf /usr/local/share/examples/ObPlugin/ftparser /your/work/path/ftparser

修改CMakeLists.txt

当前的工程目录下包含了CMakeLists.txt和一个CPP文件,你可以先修改 CMakeLists.txt,符合自己的需求。

CMakeLists.txt 文件中使用 "TODO" 指明了需要修改的内容,包括:

  • PLUGIN_NAME 当前插件的名字,也是项目和链接库的名称,你应该修改成自己需要的名称;
  • SOURCES 实现文件,可以是C代码文件或C++代码文件,这里是一个列表,可以写多个。当你增加了新的实现文件时,应该修改这里的代码。注意不要把头文件放到这里。

实现功能

接下来可以按照特定的接口来实现你的插件,每个插件都有自己特定的接口,需要按照约定来实现。各个插件接口的定义可以在 oceanbase-plugin-dev-kit 开发包中的头文件中找到,也可以参考文档

需要特别注意的是,一个链接库可以实现一到多个插件,在实现文件中定义,示例:

OBP_DECLARE_PLUGIN(example_ftparser)
{
  OBP_AUTHOR_OCEANBASE,       // 作者
  OBP_MAKE_VERSION(0, 1, 0),  // 当前插件库的版本
  OBP_LICENSE_MULAN_PSL_V2,   // 该插件的license
  plugin_init, // init        // 插件的初始化函数,在plugin_init中注册各个插件功能
  nullptr, // deinit          // 插件的析构函数
} OBP_DECLARE_PLUGIN_END;

编译插件

cd /your/work/path/ftparser
mkdir -p build
cd build
cmake ..
make

如果不出现问题,你可以在build下找到一个动态链接库,假设名字叫 libexample_ftparser.so,稍后可以把这个链接库安装到OceanBase集群中。

安装测试

请参考使用手册

说明

自行编写CMake/Makefile文件

开发编译插件时,仅依赖了OceanBase插件开发库中的头文件,CMake的依赖是可选项,如果需要,你可以编写自己的Makefile文件或直接用编译器编译插件库。

oceanbase-plugin-devel 提供哪些内容

默认情况下,开发包会安装在 /usr/ 目录下,在这里可以看到

.
├── include
│   └── oceanbase
│       └── ob_plugin_xxx.h                 # 头文件
├── lib64
│   └── cmake
│       └── ObPlugin                        # CMake辅助文件
│           ├── ObPluginConfig.cmake
│           ├── ObPluginLib.cmake
│           ├── ob_plugin_libmain.c
│           └── ObPluginTargets.cmake
└── share
    └── examples
        └── ObPlugin                       # 样例代码
            └── ftparser
                ├── CMakeLists.txt
                └── space_ftparser.cpp

可执行的链接库

默认情况下,编译出来的动态链接库是可执行的,会输出编译信息、插件信息等,比如:

OceanBase Plugin Library: example_ftparser
COMPILED BY: GCC 9.4.0
COMPILED ON: Linux 3.10.0-327.ali2019.alios7.x86_64 #1 SMP Sun Jan 19 18:21:42 CST 2020 x86_64

AUTHOR: OceanBase Corporation
LIBRARY VERSION: 1.0.0
PLUGIN API VERSION: 0.1.0
LICENSE: Mulan PSL v2
REVISION: 15ee043a402fa07390a4d0d62a26b638ec4eb7ed
BUILD_BRANCH: task/2024112500105253120
BUILD_TIME: Dec 17 2024 15:37:33

在编译动态链接库时,使用链接选项给链接库指定入口函数("-e,_ob_plugin_lib_main"),在代码中指定ELF interpret(可能是 /lib64/ld-linux-x86-64.so.2),这样编译的动态链接库就可以执行了。入口函数_ob_plugin_lib_mainoceanbase-plugin-devel开发包的 ob_plugin_libmain.c文件中提供。

如果动态库在一个平台上编译在另一个平台上运行,但是遇到"Bad interpreter" 或 "No such file or directory",可能是运行时平台的ELF Interpreter与编译环境上的不同,可以直接使用运行平台上的ELF Interpreter运行动态链接库:

/path/to/interpreter ./your/library
# 比如
/lib64/ld-linux-x86-64.so.2 ./libexample_ftparser.so

跨平台兼容

动态链接库通常不具备良好的跨平台兼容性,比如在高版本的操作系统上编译,在低版本的系统上运行,最常见的是libc版本不兼容。因此建议在不同的系统上,都进行一次编译。

C++ 异常

不要抛出C++异常,OceanBase不会捕获插件库抛出的异常。

内存分配

OceanBase 是一个多租户系统,内存资源是受租户配置限制的,因此我们在分配内存时,是比常规的应用程序更大可能遇到内存不足分配失败的情况,所以建议分配内存后检测结果,并合理的处理错误,比如返回 OBP_ALLOCATE_MEMORY_FAILED。

可以使用系统内存分配器,比如 malloc/free,或者C++的new/delete,在new分配内存时建议使用new(std::nothrow)。也可以使用开发库提供的 obp_malloc/obp_free或 obp_allocate/obp_deallocate函数。不管使用哪种,最终分配的内存都会被统计到对应的运行时租户。

FAQ

如何在插件中打印日志

可以参考插件开发库 oceanbase-plugin-devel 中的头文件 ob_plugin_log.h,使用 OBP_LOG_TRACEOBP_LOG_INFOOBP_LOG_WARN打印日志,打印风格与 printf类似。

如何链接新的链接库

在 CMakeLists.txt 中,可以使用下面的命令增加新的链接库:

TARGET_LINK_LIBRARIES (${PLUGIN_NAME} PRIVATE library1 library2)

注意,新的链接库需要使用静态链接库。如果依赖动态链接库,那么在安装插件时,也需要把依赖的动态链接库安装到observer机器的系统目录。

其它的依赖项,比如链接时链接库查找目录、头文件目录、编译选项等,也可以使用 TARGET_XXX(${PLUGIN_NAME} PRIVATE option1 option2)添加。

如何不安装开发库oceanbase-plugin-dev-kit到系统目录

使用下面的命令可以将RPM包安装到当前目录的 ./usr/ 下,也就是 $PWD/usr/

# pkgname 是 oceanbase-plugin-devel 的RPM包文件名
rpm2cpio `pkgname` | cpio -ivd

也可以使用下面的命令安装到指定目录(需要sudo权限):

# pkgname 是 oceanbase-plugin-dev-kit 的RPM包文件名
# /your/install/path 是你想要安装的目录
rpm -ivh `pkgname` --prefix `/your/install/path`

如果安装的最终路径不是系统目录,也就是不在CMake的查找列表中(参考CMake文档),在编译执行cmake命令时需要手动指定,比如:

mkdir build
cd build
# 使用 -DCMAKE_PREFIX_PATH 参数指定安装目录
cmake -DCMAKE_PREFIX_PATH=`/oceanbase-plugin-dev-kit/install/prefix` ..
make

可以不使用开发包oceanbase-plugin-dev-kit开发插件吗

如果要基于比较新的插件接口开发,而OceanBase还没有发包,或者没有对应某个操作系统的包,也可以基于OceanBase源码开发,步骤如下:

# 下载源码
git clone https://github.com/oceanbase/oceanbase-plugin-dev-kit
# 初始化
cd oceanbase-plugin-dev-kit
# 执行安装命令,使用 --prefix 参数指定安装的目录,这里使用 build_debug/usr/local
mkdir build && cd build
cmake -DOCEANBASE_GIT_TAG=master ..
cmake --install . --prefix ./usr/local

# 编译自己的开发库
cd `/your/plugin/dev/path`
mkdir build
cd build
# 使用 -DCMAKE_PREFIX_PATH 参数指定 OceanBase插件开发库安装目录
cmake -DCMAKE_PREFIX_PATH=`/your/oceanbase-plugin-dev-kit/build/usr/local` ..
make

注意,基于源码开发要找稳定版本的接口或联系OceanBase开发人员。