优化器将查询中涉及的所有函数与运算符划分为三大安全等级:并行安全(Parallel Safe)、并行受限(Parallel Restricted)以及并行不安全(Parallel Unsafe)。并行安全的操作完全不与并发机制冲突。并行受限的操作严禁在后台 worker 进程中执行,但允许在主 leader 进程中执行(即可以出现在 Gather 节点上方,但严禁出现在其下方)。并行不安全的操作在整个查询执行期间严禁出现;一旦查询中包含任何并行不安全的元素,该查询的并行能力将被彻底全局禁用。
以下行为属于典型的并行受限操作:
扫描公用表表达式(CTE)。
扫描会话级临时表。
扫描外部表(除非该外部数据包装器明确实现了安全并发接口)。
引用了相关子查询(SubPlan)。
优化器无法仅凭代码本身自动预测任意函数在执行时究竟会触碰哪些底层资源(这在理论上等价于计算机科学中的图灵停机问题)。因此系统采取保守的安全原则:除少数确定安全的内置函数外,所有用户自定义函数在默认情况下均被标记为并行不安全(PARALLEL UNSAFE)。在定义函数(CREATE FUNCTION)或修改函数(ALTER FUNCTION)时,必须由开发者显式声明其安全等级:PARALLEL SAFE、PARALLEL RESTRICTED 或 PARALLEL UNSAFE。
若函数涉及写入数据库、推进或修改事务状态、操作自增序列、或修改全局配置参数,必须严格标记为 PARALLEL UNSAFE。若函数访问了连接级私有状态(如 random() 随机数种子或服务端游标),必须标记为 PARALLEL RESTRICTED。严禁对不安全函数虚假标安全,否则在并发环境下极易导致数据竞争损坏或错误计算结果。