告别碎片化手工操作!看我用 plugin_ctl 将 OpenTenBase 插件管理效率提升 10 倍

大家好,我是 iamkz。

在 OpenTenBase 分布式环境中,插件开发完成以后,还需要经历编译、文件分发、数据库注册、功能验证和回滚等环节。

对于 SQL-only 插件,需要将 .control 和 SQL 安装脚本部署到 OpenTenBase 的 extension 目录。

对于 C 插件,还要使用目标 OpenTenBase 的开发环境完成编译,生成 .so 共享库,再将 .control、SQL 和 .so 分发到相关服务器。

当集群中存在多个 CN、DN 和多台服务器时,手工完成这些操作会遇到很多实际问题:

  • 插件文件应该发送到哪些服务器;
  • .control、SQL 和 .so 应分别进入什么目录;
  • C 插件应该使用哪一个 pg_config 编译;
  • 编译产物是否完整;
  • 远端文件是否与本地文件一致;
  • 数据库注册前是否已经能够发现 extension;
  • 应该在哪个 CN 上执行注册;
  • 注册完成后插件能否在多个 CN 上正常调用;
  • 回滚时应该清理哪些数据库对象。

为了解决这些问题,我开发了 plugin_ctl

项目地址:

https://github.com/iamkuangzhang/opentenbase-plugin_ctl

那么接下来,我将使用一个 C 语言编写的 hello_world 插件,演示 plugin_ctl 如何完成项目创建、集群初始化、状态检查、编译、部署、注册、验证和回滚。


一、plugin_ctl 解决什么问题?

plugin_ctl 是一个面向 OpenTenBase 的插件生命周期管理工具。

在设计过程中,我们学习了 opentenbase_ctlpgxc_ctl 的管理风格,将插件相关操作集中到一个交互式控制台中。

它可以创建 SQL-only 或 C 插件项目,识别 OpenTenBase 集群,检查插件文件,编译 C 共享库,将安装文件分发到 CN、DN 所在服务器,在数据库中注册 extension,并执行功能验证和数据库对象回滚。

对于已经存在的插件源码,也可以将其加入管理,再继续完成检查、编译、部署和注册。

在执行过程中,plugin_ctl 会根据本地文件、远端文件和数据库状态判断插件当前所处的阶段。当编译产物、部署文件或数据库条件不满足时,会阻止后续操作并给出对应提示。


二、测试环境与下载方式

本文使用的 OpenTenBase 测试环境如下:

OpenTenBase 版本:
OpenTenBase_v5.21.8.11

服务器:
192.168.244.130
192.168.244.132

GTM:
192.168.244.130:6666

CN:
192.168.244.130:30004
192.168.244.132:30005

DN:
192.168.244.130:20008
192.168.244.132:20009

OpenTenBase 安装目录为:

/data/opentenbase/install/opentenbase_bin_v2.0

本文使用的 Python 路径为:

/opt/python3.11/bin/python3.11

其他环境需要根据实际安装位置调整相关路径。

下载 plugin_ctl

plugin_ctl 已在 GitHub 开源,本文通过源码方式运行。

先使用 root 用户下载项目:

cd /opt

git clone https://github.com/iamkuangzhang/opentenbase-plugin_ctl.git \
    opentenbase-pluginctl

将项目目录交给 opentenbase 用户:

chown -R opentenbase:opentenbase /opt/opentenbase-pluginctl

创建全局启动命令:

cat >/usr/local/bin/plugin_ctl <<'EOF'
#!/usr/bin/env bash
export PYTHONPATH=/opt/opentenbase-pluginctl/src${PYTHONPATH:+:$PYTHONPATH}
exec /opt/python3.11/bin/python3.11 -m plugin_ctl "$@"
EOF

chmod +x /usr/local/bin/plugin_ctl

切换到 OpenTenBase 运行用户:

su - opentenbase

查看版本:

plugin_ctl --version

当前正式版本输出为:

plugin_ctl 1.0.0


三、使用 init 初始化集群配置

开始管理插件之前,需要先让 plugin_ctl 识别当前 OpenTenBase 集群。

进入 OpenTenBase 工作目录:

cd /data/opentenbase

启动 plugin_ctl 交互式控制台:

plugin_ctl

进入控制台后执行:

pluginctl> init

初始化完成后,会生成:

~/.plugin_ctl/cluster.toml

这份配置记录了后续插件管理需要使用的集群信息,包括:

  • 当前使用的集群管理后端;
  • CN 和 DN 的节点名称;
  • 节点所在服务器;
  • 数据库连接端口;
  • extension 目录;
  • 共享库目录;
  • 数据库连接信息。

cluster.toml 不直接保存 pg_config 路径。执行 build 时,plugin_ctl 会根据其中的 extension_dirlib_dir 等目录信息推导当前 OpenTenBase 对应的 pg_config

在本文环境中,plugin_ctl 使用 opentenbase_ctl 作为集群操作后端。

初始化时,plugin_ctl 会先获取集群中的初步节点信息,再连接可用 CN 查询数据库中的 pgxc_node,校验节点名称、角色、IP 和端口。

对应的数据库拓扑可以通过下面的 SQL 查看:

SELECT node_name,
       node_type,
       node_host,
       node_port
FROM pgxc_node
ORDER BY node_name;

本文环境最终识别到:

2 个 CN
2 个 DN

对应端口为:

CN:30004、30005
DN:20008、20009

除了 opentenbase_ctlplugin_ctl 也保留了对 pgxc_ctl 环境的兼容能力。

后续的 C 插件编译、文件分发、远程校验和数据库注册,都会使用 cluster.toml 中的配置。


四、进入控制台并查看 help

执行:

plugin_ctl

进入交互式控制台:

pluginctl>

查看当前支持的命令:

pluginctl> help

帮助信息中会列出插件创建、查看、检查、编译、部署、注册和回滚等命令。

切换中文和英文

plugin_ctl 控制台默认使用英文。

输入CH ,可以切换为中文;

这时候,帮助信息、操作提示、错误信息和确认信息都会显示为中文。

输入EN ,可以切换为英文。

同时支持小写形式(ch,en)

命令名称、插件 ID、节点名称、文件路径以及状态值不会随着语言切换而改变。


五、使用 new 创建插件项目

new 用于创建一个新的插件项目,并自动将该插件加入 plugin_ctl 管理目录。

创建 SQL-only 插件

下面两种写法作用相同,选择其中一种即可:

pluginctl> new hello

或者显式指定 SQL-only 类型:

pluginctl> new -sql hello

不要在同一目录下连续执行这两条命令创建同名插件,否则第二次会因为目录已经存在而失败。

生成的目录结构如下:

hello/
├── README.md
├── manifest.yml
├── hello.control
├── sql/
│   ├── hello--0.1.0.sql
│   ├── verify.sql
│   └── rollback.sql
└── .pluginctlignore

SQL-only 插件不包含 C 源码和 .so 共享库,因此不需要执行编译。

完成 SQL 安装脚本后,可以直接进入检查和部署阶段。

创建 C 插件

执行:

pluginctl> new -c hello_world

生成的目录结构如下:

hello_world/
├── README.md
├── manifest.yml
├── Makefile
├── hello_world.control
├── src/
│   └── hello_world.c
├── sql/
│   ├── hello_world--0.1.0.sql
│   ├── verify.sql
│   └── rollback.sql
└── .pluginctlignore

其中:

  • src/hello_world.c 保存 C 源码;
  • Makefile 使用 PGXS 完成编译;
  • hello_world.control 描述 extension;
  • hello_world--0.1.0.sql 定义数据库函数;
  • verify.sql 用于验证插件;
  • rollback.sql 用于回滚数据库对象;
  • manifest.yml 描述插件类型、文件列表和构建方式。

new 创建完成后,插件会自动进入 plugin_ctl 管理目录,不需要再次执行 add


六、在生成的框架上开发 hello_world

本文使用:

pluginctl> new -c hello_world

创建 C 插件项目框架。

随后在生成的框架中完成 C 函数、安装 SQL、验证脚本和回滚脚本。

完成后的插件提供:

SELECT hello();

预期返回:

hello_world

C 插件源码的具体编写过程不是本文重点,这里不再展开

关于 hello_world 扩展的基本开发过程,可以参考:

腾讯云开发者平台:

https://cloud.tencent.com/developer/article/2691122

CSDN:

https://blog.csdn.net/2501_90201337/article/details/162047784?spm=1001.2014.3001.5501

接下来主要演示 plugin_ctl 如何管理已经完成开发的 C 插件。


七、使用 list 查看插件

执行:

pluginctl> list

可以查看当前由 plugin_ctl 管理的插件。

查看指定插件的详细信息:

pluginctl> list hello_world

由于 hello_world 是通过 new 创建的,因此已经自动加入管理目录。

checkbuilddeployregister 都通过插件 ID 查找项目,所以执行这些操作前,插件必须能够在 list 中找到。

对于已有的插件源码目录,可以通过下面的命令加入管理:

pluginctl> add ./hello_world

八、第一次 check:确认当前状态

执行:

pluginctl> check hello_world

此时 C 源码、Makefile、control 文件和 SQL 脚本已经存在,但还没有生成:

hello_world.so

因此插件状态为:

BUILD_REQUIRED

该状态表示 C 插件已经具备源码和构建配置,下一步需要先完成编译。

如果源码、Makefile、manifest 或其他关键文件存在错误,才会进入相应的异常状态。


九、使用 build 编译 C 插件

执行:

pluginctl> build hello_world

build 会读取 manifest.yml,并完成以下操作:

  • 判断插件类型;
  • 检查 C 源码;
  • 检查 Makefile;
  • 定位 pg_config
  • 检查 PGXS;
  • 执行清理和编译;
  • 检查 .so 是否生成。

本文环境使用的 pg_config 为:

/data/opentenbase/install/opentenbase_bin_v2.0/bin/pg_config

对应版本为:

PostgreSQL 11.0 @ OpenTenBase_v5.21.8.11

实际编译过程相当于:

make clean

make \
  PG_CONFIG=/data/opentenbase/install/opentenbase_bin_v2.0/bin/pg_config

编译成功后,插件目录中会生成:

hello_world.so

build 只负责生成编译产物,不会执行:

make install

插件文件的安装和多机分发继续由 deploy 统一完成。

编译结束后再次执行:

pluginctl> check hello_world

此时状态应变为:

READY


十、使用 deploy 分发插件文件

执行:

pluginctl> deploy hello_world

正式复制前,plugin_ctl 会展示部署计划。

C 插件需要部署三类文件:

hello_world.control
→ extension 目录

hello_world--0.1.0.sql
→ extension 目录

hello_world.so
→ library 目录

.control 和安装 SQL 会进入 OpenTenBase 的 extension 目录。

.so 会进入 pg_config --pkglibdir 对应的共享库目录。

目标服务器根据 CN 和 DN 的部署位置确定。

本文环境包含 2 个 CN、2 个 DN,分别位于两台服务器上。

确认部署计划后,控制台会询问是否继续:

Continue? [y/N]: y

随后,plugin_ctl 会完成文件分发,并检查:

  • 远端文件是否存在;
  • SHA-256 是否与本地一致;
  • 所有目标是否同步成功。

部署完成后,立即执行:

pluginctl> check hello_world

文件分发和校验全部通过时,状态变为:

DEPLOYED

同时,数据库应当能够在 pg_available_extensions 中看到 hello_world


十一、使用 register 注册插件并完成功能验证

执行:

pluginctl> register hello_world

注册前,plugin_ctl 会检查:

  • primary CN 是否可以连接;
  • pg_available_extensions 中是否存在该扩展;
  • pg_extension 中是否已经注册。

确认注册计划后,控制台会询问是否继续:

Continue? [y/N]: y

检查通过后,在 primary CN 执行:

CREATE EXTENSION IF NOT EXISTS hello_world;

注册完成后,plugin_ctl 会检查多个 CN 中 pg_extension 记录的版本是否一致。

随后执行:

pluginctl> check hello_world

状态应变为:

REGISTERED

register 负责完成 extension 注册,不会自动运行插件的 verify.sql。功能验证需要继续执行:

pluginctl> verify hello_world

验证成功时会返回:

OK

还可以分别连接两个 CN,执行:

SELECT hello();

预期返回:

 hello
-------------
 hello_world

真实测试中,该函数在两个 CN 上均能正常调用。


十二、使用 rollback 回滚数据库对象

需要回滚时执行:

pluginctl> rollback hello_world

控制台会先展示回滚计划,并询问是否继续:

Continue? [y/N]: y

确认后,plugin_ctl 会读取 manifest 中配置的回滚脚本,并删除数据库中的 extension 和相关对象。

可以使用下面的 SQL 检查:

SELECT count(*)
FROM pg_extension
WHERE extname = 'hello_world';

回滚后结果应为:

0

rollback 不会删除已经分发到服务器上的:

hello_world.control
hello_world--0.1.0.sql
hello_world.so

数据库对象和物理文件分别处理,可以避免自动删除仍可能被其他数据库使用的共享文件。


十三、使用 remove 取消管理

数据库对象回滚完成后,可以执行:

pluginctl> remove hello_world

remove 会将插件从 plugin_ctl 管理目录中移除。

它不会再次执行数据库回滚,也不会删除远端 .control、SQL 和 .so 文件。

因此推荐先执行:

rollback hello_world

再执行:

remove hello_world

如需删除服务器上的物理文件,应先确认没有其他数据库或插件版本继续使用,再单独进行清理。

可以重新管理该插件:

pluginctl> add ./hello_world

十四、使用 plugin_ctl 时需要注意什么?

1. init 会根据现有集群管理工具识别环境

plugin_ctl 不会替代 opentenbase_ctlpgxc_ctl

执行 init 时,它会根据当前环境选择可用的集群管理后端,获取 CN、DN、服务器和安装目录等信息,再结合数据库中的 pgxc_node 校验集群拓扑,最终生成 cluster.toml

当前环境使用 opentenbase_ctl 时,plugin_ctl 会优先通过它识别集群;存量环境仍使用 pgxc_ctl 时,也可以通过对应的兼容方式完成初始化。

2. init 应在正式管理插件前执行

首次使用时,应先在控制台执行:

pluginctl> init

该命令会生成 ~/.plugin_ctl/cluster.toml。后续的编译、部署和注册都会使用其中的节点、目录和数据库连接信息。

3. build 只针对已经管理的插件

执行 build 前,插件必须能够通过下面的命令找到:

pluginctl> list

通过 new 创建的插件会自动加入管理。已有源码项目需要先执行:

pluginctl> add ./hello_world

4. SQL-only 插件不需要 build

SQL-only 插件不包含 C 源码和 .so,文件完整后可以直接检查和部署。

只有 C 插件需要执行:

pluginctl> build hello_world

5. C 插件应使用目标 OpenTenBase 的 pg_config

C 插件编译时,应使用当前 OpenTenBase 安装目录中的 pg_config,例如:

/data/opentenbase/install/opentenbase_bin_v2.0/bin/pg_config

使用其他 PostgreSQL 版本的 pg_config,可能造成头文件、PGXS 或库目录不一致。

6. build 不会执行 make install

build 只生成 .so 编译产物,不会将文件直接安装到数据库目录。

插件文件的安装和多机分发统一由 deploy 完成。

7. rollback 不会删除物理文件

rollback 只清理数据库中的 extension 和相关对象。

已经部署到服务器上的 .control、SQL 和 .so 文件仍然保留。

8. remove 不等于卸载 extension

remove 只取消 plugin_ctl 对插件的管理,不会执行数据库回滚。

推荐顺序是:

pluginctl> rollback hello_world
pluginctl> remove hello_world

9. 可以使用上下方向键浏览历史命令

交互式控制台支持使用上下方向键查看以前输入过的命令。

历史记录保存在:

~/.plugin_ctl/history

退出并重新进入控制台后,历史命令仍然保留。

10. 中英文切换只在当前会话生效

输入:

CH

切换中文,输入:

EN

切回英文。

重新进入控制台后,默认仍然使用英文。命令名称、插件 ID、文件路径和状态值不会被翻译。


总结

plugin_ctl 是一个面向 OpenTenBase 分布式环境的插件生命周期管理工具。

它将插件项目创建、集群识别、状态检查、C 代码编译、文件分发、数据库注册、功能验证和对象回滚集中到同一个交互式控制台中,为 SQL-only 插件和 C 插件提供统一的管理入口。

在没有 plugin_ctl 时,C 插件的处理过程通常需要手工查找 pg_config、执行 PGXS 编译、确认 .so 产物、复制 extension 文件和共享库,再连接数据库执行 CREATE EXTENSION。在多机集群中,还需要逐台确认 CN、DN 所在服务器的文件是否完整。

plugin_ctl 将这些分散操作组织成一条可以检查状态、预览计划、执行操作和验证结果的流程。

对于 SQL-only 插件,可以在完成项目文件后直接检查、部署和注册;对于 C 插件,则可以通过 build 使用目标 OpenTenBase 的开发环境生成共享库,再继续完成多机部署和数据库注册。

这套方式减少了手工复制和重复操作,也让每个阶段的状态更加清晰。当源码尚未编译、远端文件缺失或者数据库注册条件不满足时,plugin_ctl 会在进入下一步之前给出提示,避免问题继续扩散到整个集群。

通过本文的 hello_world 示例,plugin_ctl 1.0.0 已经在真实双机 OpenTenBase 集群中完成了 C 插件创建、PGXS 编译、文件分发、extension 注册、双 CN 调用和数据库对象回滚。

从源码到数据库可用,OpenTenBase 插件所需要经历的关键步骤,现在可以通过一套统一、可检查、可验证的流程完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值