Reference:PL/Java#

PL/Java 是允许使用 Java™ 编程语言定义存储过程、触发器和函数的数据库扩展, OushuDB 的 PL/Java 扩展基于 Greenplum 数据库所用版本和开源的 1.5.0 版本。 本章节对 PL/Java 功能进行说明。

PL/Java 安装#

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

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

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 命名要求, 如果用到了其它依赖项,用户在打包时既可以把所有类打包在一个文件中,形成 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 设置的映射到 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 包可能无法正常使用。