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

15.4. 并行安全性 #

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

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

以下操作始终并行受限

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

规划器无法自动确定用户定义的函数或聚合是并行安全、并行受限还是并行不安全,因为这需要预测该函数可能执行的所有操作。这与停机问题等效,因此不可能。即使对于理论上可能实现的简单函数,我们也不会尝试,因为这样做代价高且容易出错。相反,除非另有标记,否则所有用户定义函数都被认为是并行不安全的。当使用 CREATE FUNCTIONALTER FUNCTION 时,可以通过指定 PARALLEL SAFEPARALLEL RESTRICTEDPARALLEL UNSAFE(视情况而定)来设置标记。当使用 CREATE AGGREGATE 时,PARALLEL 选项可以指定 SAFERESTRICTEDUNSAFE 作为相应的值。

如果函数和聚合写入数据库、更改事务状态(不通过使用子事务进行错误恢复)、访问序列或对设置进行持久更改,则必须将其标记为 PARALLEL UNSAFE。类似地,如果函数访问临时表、客户端连接状态、游标、已准备好的语句或系统无法跨工作进程同步的其他后端本地状态,则必须将其标记为 PARALLEL RESTRICTED。例如,setseedrandom 出于最后这个原因而受并行限制。

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

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

请注意,查询规划器不会考虑延迟评估查询中涉及的并行受限函数或聚合,以获得更好的计划。例如,如果应用于特定表的 WHERE 子句受并行限制,查询计划程序不会考虑在计划的并行部分扫描该表。在某些情况下,可能(甚至是有效的)将该表的扫描包含在查询的并行部分中,并延迟对 WHERE 子句的评估,以便在 Gather 节点上方发生此评估。但是,计划程序不会执行此操作。