通常,PL/Perl 会被安装为一种名为 plperl 的 “可信”编程语言。在这种设置下,为了保持安全性,某些 Perl 操作会被禁用。一般来说,受限制的是那些与环境交互的操作,包括文件句柄 操作、require 和 use (针对外部模块)。它无法像 C 函数那样访问数据库服务器进程的内部, 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无权限 的数据库用户使用这种语言。
可信 PL/Perl 依赖 Perl 的 Opcode 模块来维持安全性。 Perl 的 文档 指出,该模块对于可信 PL/Perl 这一使用场景并不有效。若你的安全需求 不能接受该警告中的不确定性,请考虑执行 REVOKE USAGE ON LANGUAGE plperl FROM PUBLIC。
下面示例中的函数将无法工作,因为出于安全原因不允许它做文件操作:
CREATE FUNCTION badfunc() RETURNS integer AS $$
my $tmpfile = "/tmp/badfile";
open my $fh, '>', $tmpfile
or elog(ERROR, qq{could not open the file "$tmpfile": $!});
print $fh "Testing writing to a file\n";
close $fh or elog(ERROR, qq{could not close the file "$tmpfile": $!});
return 1;
$$ LANGUAGE plperl;
这个函数的创建会失败,因为验证器会捕捉到它使用了禁用的操作。
有时需要编写不受这些限制的 Perl 函数。例如,可能需要一个能发送邮件的 Perl 函数。为处理这类情况,也可以把 PL/Perl 安装成一种 “不可信”语言(通常称为 PL/PerlU)。 在这种情况下,完整的 Perl 语言都可用。安装该语言时,使用语言名 plperlu 就会选择不可信的 PL/Perl 变体。
PL/PerlU 函数的编写者必须注意,函数不能被 用于任何非预期用途,因为它能够执行以数据库管理员身份登录的用户所能 做的任何事情。请注意,数据库系统只允许数据库超级用户用不可信语言创建 函数。
如果上述函数是由超级用户使用 plperlu 语言创建的, 执行就会成功。
同样地,如果把语言指定为 plperlu 而不是 plperl,用 Perl 编写的匿名代码块也可以使用原本受限的 操作,但调用者必须是超级用户。
虽然 PL/Perl 函数会为每个 SQL 角色在独立的 Perl 解释器中运行,但给定会话中执行的所有 PL/PerlU 函数都运行在同一个 Perl 解释器中 (而且这个解释器并不是任何一个用于 PL/Perl 函数的解释器)。这允许 PL/PerlU 函数自由共享 数据,但 PL/Perl 与 PL/PerlU 函数之间不能进行通信。
Perl 无法在单个进程内支持多个解释器,除非构建时使用了适当的标志, 即 usemultiplicity 或 useithreads 之一。(除非确实需要使用线程,否则更推荐 usemultiplicity。更多细节见 perlembed 手册页。)如果 PL/Perl 使用的是未按这种方式 构建的 Perl 副本,那么每个会话中就只能有一个 Perl 解释器,因此任一 会话只能执行 PL/PerlU 函数,或者执行全部由同一 SQL 角色调用的 PL/Perl 函数。
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。