PostgreSQL 并行安全性

2021-08-27 16:27 更新
15.4.1. 為函數(shù)和聚集加并行標簽

規(guī)劃器把查詢中涉及的操作分類成并行安全并行受限或者并行不安全。并行安全的操作不會與并行查詢的使用產(chǎn)生沖突。并行受限的操作不能在并行工作者中執(zhí)行,但是能夠在并行查詢的領導者中執(zhí)行。因此,并行受限的操作不能出現(xiàn)在Gather或者Gather Merge節(jié)點之下,但是能夠出現(xiàn)在包含這類節(jié)點的計劃的其他位置。并行不安全的操作不能在并行查詢中執(zhí)行,甚至不能在領導者中執(zhí)行。當一個查詢包含任何并行不安全操作時,并行查詢對這個查詢是完全被禁用的。

下面的操作總是并行受限的。

  • 公共表表達式(CTE)的掃描。

  • 臨時表的掃描。

  • 外部表的掃描,除非外部數(shù)據(jù)包裝器有一個IsForeignScanParallelSafe API。

  • InitPlan所掛接到的計劃節(jié)點。

  • 引用一個相關的SubPlan的計劃節(jié)點。

15.4.1. 為函數(shù)和聚集加并行標簽

規(guī)劃器無法自動判定一個用戶定義的函數(shù)或者聚集是并行安全、并行受限還是并行不安全,因為這需要預測函數(shù)可能執(zhí)行的每一個操作。一般而言,這就相當于一個停機問題,因此是不可能的。甚至對于可以做到判定的簡單函數(shù)我們也不會嘗試,因為那會非常昂貴而且容易出錯。相反,除非是被標記出來,所有用戶定義的函數(shù)都被認為是并行不安全的。在使用CREATE FUNCTION或者 ALTER FUNCTION 時,可以通過指定PARALLEL SAFE、PARALLEL RESTRICTED或者PARALLEL UNSAFE來設置標記 。在使用CREATE AGGREGATE時, PARALLEL選項可以被指定為SAFE、RESTRICTED或者 UNSAFE

如果函數(shù)和聚集會寫數(shù)據(jù)庫、訪問序列、改變事務狀態(tài)(即便是臨時改變,例如建立一個EXCEPTION塊來捕捉錯誤的 PL/pgsql)或者對設置做持久化的更改,它們一定要被標記為PARALLEL UNSAFE。類似地,如果函數(shù)會訪問臨時表、客戶端連接狀態(tài)、游標、預備語句或者系統(tǒng)無法在工作者之間同步的后端本地狀態(tài),它們必須被標記為PARALLEL RESTRICTED。例如, setseedrandom由于后一種原因而是并行受限的。

一般而言,如果一個函數(shù)是受限或者不安全的卻被標記為安全,或者它實際是不安全的卻被標記為受限,把它用在并行查詢中時可能會拋出錯誤或者產(chǎn)生錯誤的回答。如果 C 語言函數(shù)被錯誤標記,理論上它會展現(xiàn)出完全不明確的行為,因為系統(tǒng)中無法保護自身不受任意 C 代碼的影響。但是,在最有可能的情況下,結果不會比其他任何函數(shù)更糟糕。如果有疑慮,最好還是標記函數(shù)為UNSAFE。

如果在并行工作者中執(zhí)行的函數(shù)要求領導者沒有持有的鎖,例如讀該查詢中沒有引用的表,那么工作者退出時會釋放那些鎖(而不是在事務結束時釋放)。如果你寫了一個這樣做的函數(shù)并且這種不同的行為對你很重要,把這類函數(shù)標記為PARALLEL RESTRICTED以確保它們只在領導者中執(zhí)行。

注意查詢規(guī)劃器不會為了獲取一個更好的計劃而考慮延遲計算并行受限的函數(shù)或者聚集。所以,如果一個被應用到特定表的WHERE子句是并行受限的,查詢規(guī)劃器就不會考慮對處于計劃并行部分的表執(zhí)行一次掃描。在一些情況中,可以(甚至效率更高)把對表的掃描包括在查詢的并行部分并且延遲對WHERE子句的計算,這樣它會出現(xiàn)在Gather節(jié)點之上。不過,規(guī)劃器不會這樣做。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號