Reference:PL/Java#

PL/Java 是基于 Java™ 语言的数据库扩展,支持在 OushuDB 中创建存储过程、触发器和函数。本文档基于 OushuDB 的 PL/Java 实现(整合 Greenplum 与开源 PL/Java 1.5.0 版本),提供完整的安装、使用和注意事项说明。

安装 PL/Java#

PL/Java 提供了单独的rpm安装包,在所有数据库节点上使用 yum install 安装:

oushudb ssh -f ~/oushuhosts -e "yum install -y oushu-plava"

请确保 ~/oushuhosts 文件存在,内容为所有节点主机名或 IP,每行一个。

PL/Java 使用#

创建 Extension(扩展)#

PL/Java 扩展只能被 CREATE EXTENSION 命令创建和初始化 。初始化过程需要建立元数据表及其索引, 因为 Magma 存储对索引的支持相对完善,建议在执行该命令时,将默认表空间设置为 Magma 存储上的表空间,通常推荐使用 magma_catalog。此时创建 Extension 的语句如下:

SET default_tablespace TO magma_catalog;
CREATE EXTENSION pljava;

部署 JAR 包#

用户自行编写的 Java 函数需要打包为 JAR 包,命名应符合 JDK 命名要求,如果存在其它依赖项,用户可以选择将所有类打包到一个 JAR 文件中(即 Fat JAR),也可以将依赖的 JAR 包与用户自有的 JAR 包分别部署。

强烈建议用户把JAR 包统一部署在默认路径 $GPHOME/share/postgresql/pljava/ 目录中,便于集中管理。如有需要,用户可以在该目录下创建子目录进行分类管理。尽管不建议这么做,但在有特殊需求时,用户仍然可以选择把 JAR 包部署在任意目录下,只需要确认数据库拥有对应目录的读取权限。所有 JAR 包应在所有节点的相同目录下进行复制和部署,并授予数据库读取权限。

在使用对应的用户自定义函数或触发器等时,用户需要设置 GUC 参数 pljava_classpath,其值包含所需 JAR 包或其所在的目录的路径,多个路径之间用英文分号分隔。详细说明可参考Greenplum 的 PL/Java 语言扩展文档

使用 Extension#

PL/Java 提供了 javajavau 两种存储过程语言,可以在创建用户自定义函数时使用,更多详细用法可参考Greenplum 的 PL/Java 语言扩展文档开源 PL/Java 主页

以 PL/Java 内置的一个示例函数为例,类 org.postgresql.pljava.example.Parameters 的静态函数 getTimestamp 输入参数为空,返回值为 java.sql.Timestamp 类型,将其定义为数据库中输入参数为空,返回值为 timestamp 类型的用户自定义函数 java_getTimestamp

用 SQL 声明用户自定义函数:

CREATE FUNCTION java_getTimestamp()
RETURNS timestamp
AS 'org.postgresql.pljava.example.Parameters.getTimestamp'
LANGUAGE java;

设置 pljava_classpath 包含对应 JAR 包路径,示例 JAR 包被部署在默认目录中,可使用相对路径( JAR 包名称中的版本号 1.5.0.1 请以实际为准):

SET pljava_classpath TO 'pljava-examples-1.5.0.1.jar';

调用用户自定义函数,该函数的作用是返回当前系统时间的时间戳:

SELECT java_getTimestamp();

不再需要该函数时可使用 SQL 删除:

DROP FUNCTION java_getTimestamp;

删除Extension#

删除 PL/Java EXTENSION 的方法如下所示:

DROP EXTENSION pljava [CASCADE];

注意事项#

如果 EXTENSION 被其他对象依赖(如已创建的用户自定义函数),需要加入 CASCADE (级联)关键字,删除所有依赖对象。

使用限制#

OushuDB 的 PL/Java 扩展相比于 Greenplum 的 PL/Java 语言扩展有一些额外的使用限制,已知问题包括:

  • 当 Java 函数包含多线程代码时,PL/Java 仅保证主线程(入口线程)能够正常使用所有功能,新创建的线程无法使用 PL/Java 提供的与 PostgreSQL SPI 函数映射的 JDBC 驱动程序。

  • PL/Java 定义的 javajavau 两种语言在功能上已无实质性区别,用户无法通过 javau 实现对 Java 代码执行危险操作(如读写文件、修改 JVM 系统设置甚至关闭 JVM 等)的限制;

  • 在大多数场景下,pljava_vmoptions 参数不会生效。用户初次使用时通常会收到提示信息:INFO:  Java virtual machine is already running. PL/Java will reuse it and "pljava_vmoptions" takes no effects.。如需修改 JVM 启动参数,应调整外表参数 oushu_external_jni_vmoptions 并重启数据库。

  • OushuDB 使用的 Java 运行时版本为 17,用户在编译和打包 JAR 包时需要注意编译目标版本,如 javac 命令的 --target 参数,低于 Java 1.8 的 JAR 包可能无法正常使用。