Redrock Postgres 搜索 英文
版本: 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16

15.4. 并行安全性 #

15.4.1. 函数和聚合的并行标记

规划器将查询中涉及的操作分类为并行安全并行受限并行不安全。并行安全操作不会与并行查询的使用产生冲突。并行受限操作无法在并行工作程序中执行,但可以在使用并行查询时在领导者中执行。因此,并行受限操作永远不会出现在GatherGather Merge节点下方,但可能出现在包含此类节点的计划中的其他位置。并行不安全操作无法在使用并行查询时执行,即使在领导者中也不行。当查询包含任何并行不安全的内容时,将为该查询完全禁用并行查询。

以下操作始终是并行受限的

15.4.1. 函数和聚合的并行标记 #

规划器无法自动确定用户定义的函数或聚合是并行安全的、并行受限的还是并行不安全的,因为这需要预测函数可能执行的每个操作。通常,这等同于停机问题,因此是不可能的。即使对于可以想象完成的简单函数,我们也不会尝试,因为这既昂贵又容易出错。相反,除非另有标记,否则所有用户定义的函数都假定为并行不安全。使用 CREATE FUNCTIONALTER FUNCTION 时,可以通过指定 PARALLEL SAFEPARALLEL RESTRICTEDPARALLEL UNSAFE(视情况而定)来设置标记。使用 CREATE AGGREGATE 时,可以将 PARALLEL 选项指定为 SAFERESTRICTEDUNSAFE 作为相应的值。

如果函数和聚合写入数据库、访问序列、更改事务状态(即使是临时状态)(例如,建立 EXCEPTION 块来捕获错误的 PL/pgSQL 函数)或对设置进行持久性更改,则必须将它们标记为 PARALLEL UNSAFE。类似地,如果函数访问临时表、客户端连接状态、游标、已准备好的语句或系统无法跨工作程序同步的其他后端本地状态,则必须将它们标记为 PARALLEL RESTRICTED。例如,setseedrandom 由于最后这个原因而受到并行限制。

一般来说,如果一个函数被标记为在受限或不安全时是安全的,或者如果它被标记为在实际上不安全时是受限的,那么在并行查询中使用它时可能会引发错误或产生错误答案。C 语言函数在被错误标记时理论上可能会表现出完全未定义的行为,因为系统无法保护自己免受任意 C 代码的侵害,但在大多数情况下,结果不会比任何其他函数更糟。如有疑问,最好将函数标记为 UNSAFE

如果在并行工作进程中执行的函数获取了领导者未持有的锁,例如通过查询查询中未引用的表,那么这些锁将在工作进程退出时释放,而不是在事务结束时释放。如果您编写了执行此操作的函数,并且此行为差异对您很重要,请将此类函数标记为 PARALLEL RESTRICTED 以确保它们仅在领导者中执行。

请注意,查询计划程序不会考虑延迟评估查询中涉及的并行受限函数或聚合以获取更好的计划。因此,例如,如果应用于特定表的 WHERE 子句是并行受限的,那么查询计划程序将不会考虑在计划的并行部分中扫描该表。在某些情况下,可以(甚至可能很有效)将该表的扫描包括在查询的并行部分中,并延迟评估 WHERE 子句,以便它在 Gather 节点之上发生。但是,计划程序不会这样做。