2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0

43.8. PL/Perl 内部机制 #

43.8.1. 配置 #

本节列出了影响 PL/Perl 的配置参数。

plperl.on_init (string) #

指定在 Perl 解释器首次初始化时执行的 Perl 代码,之后它会专门用于 plperlplperlu。执行此代码时 SPI 函数不可用。如果代码因错误而失败,它将中止解释器的初始化并将错误传播给调用查询,导致当前事务或子事务被中止。

Perl 代码限制为单个字符串。较长的代码可以放在模块中,然后由 on_init 字符串加载。示例

plperl.on_init = 'require "plperlinit.pl"'
plperl.on_init = 'use lib "/my/app"; use MyApp::PgInit;'

plperl.on_init 直接或间接加载的任何模块都可供 plperl 使用。这可能会带来安全风险。要查看已加载了哪些模块,您可以使用

DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl;

如果在 shared_preload_libraries 中包含了 plperl 库,则初始化将在 postmaster 中进行,在这种情况下,应额外考虑使 postmaster 不稳定的风险。使用此功能的主要原因是 plperl.on_init 加载的 Perl 模块只需要在 postmaster 启动时加载,并且在各个数据库会话中即可立即使用,无需加载开销。但是,请记住,只有数据库会话使用的第一个 Perl 解释器(即 PL/PerlU,或第一个调用 PL/Perl 函数的 SQL 角色的 PL/Perl)才能避免开销。数据库会话中创建的任何其他 Perl 解释器都必须重新执行 plperl.on_init。此外,在 Windows 上,预加载不会带来任何节省,因为在 postmaster 进程中创建的 Perl 解释器不会传播到子进程。

此参数只能在 postgresql.conf 文件或服务器命令行中设置。

plperl.on_plperl_init (string)
plperl.on_plperlu_init (string) #

这些参数分别指定了在 Perl 解释器专门用于 plperlplperlu 时执行的 Perl 代码。当数据库会话中首次执行 PL/Perl 或 PL/PerlU 函数时,或者当需要创建额外的解释器(因为其他语言被调用或 PL/Perl 函数被新的 SQL 角色调用)时,就会发生这种情况。这发生在 plperl.on_init 完成任何初始化之后。执行此代码时 SPI 函数不可用。在解释器被“锁定”之后,plperl.on_plperl_init 中的 Perl 代码才会被执行,因此它只能执行受信任的操作。

如果代码因错误而失败,它将中止初始化并将错误传播给调用查询,导致当前事务或子事务被中止。Perl 中已执行的任何操作都不会被撤销;但是,该解释器将不再被使用。如果再次使用该语言,将在新的 Perl 解释器中重新尝试初始化。

只有超级用户才能更改这些设置。虽然可以在会话中更改这些设置,但这些更改不会影响已用于执行函数的 Perl 解释器。

plperl.use_strict (boolean) #

当设置为 true 时,后续编译的 PL/Perl 函数将启用 strict pragma。此参数不影响当前会话中已编译的函数。

43.8.2. 限制和缺失的功能 #

PL/Perl 目前缺少以下功能,但欢迎大家贡献。

  • PL/Perl 函数不能直接相互调用。

  • SPI 尚未完全实现。

  • 如果您使用 spi_exec_query 提取非常大的数据集,您应该意识到这些数据都会进入内存。您可以通过使用 spi_query/spi_fetchrow 来避免这种情况,如前所述。

    当一个返回集合的函数通过 return 将大量行集返回给 PostgreSQL 时,会发生类似的问题。您也可以通过使用 return_next 为返回的每一行返回来避免此问题,如前所述。

  • 当会话正常结束,而不是由于致命错误而结束时,将执行已定义的任何 END 块。目前没有执行其他操作。特别是,文件句柄不会自动刷新,对象也不会自动销毁。

提交更正

如果您在文档中发现任何不正确之处、与您对特定功能的实际体验不符或需要进一步澄清的地方,请使用 此表格 报告文档问题。