バージョンごとのドキュメント一覧

15.4. パラレル安全 #

<title>Parallel Safety</title>

The planner classifies operations involved in a query as either <firstterm>parallel safe</firstterm>, <firstterm>parallel restricted</firstterm>, or <firstterm>parallel unsafe</firstterm>. A parallel safe operation is one that does not conflict with the use of parallel query. A parallel restricted operation is one that cannot be performed in a parallel worker, but that can be performed in the leader while parallel query is in use. Therefore, parallel restricted operations can never occur below a <literal>Gather</literal> or <literal>Gather Merge</literal> node, but can occur elsewhere in a plan that contains such a node. A parallel unsafe operation is one that cannot be performed while parallel query is in use, not even in the leader. When a query contains anything that is parallel unsafe, parallel query is completely disabled for that query. プランナは、クエリ中に実行される操作をパラレル安全(parallel safe)パラレル制限(parallel restricted)パラレル非安全(parallel unsafe)に分類します。 パラレル安全操作は、パラレルクエリとコンフリクトしない操作です。 パラレル制限操作は、パラレルクエリを利用中に、パラレルワーカー中では実行できないが、リーダーによって実行できる操作です。 したがって、パラレル制限操作は、GatherあるいはGather Mergeノードより下では決して実行されませんが、Gatherノードを含むプランの別の場所では実行されるかもしれません。 パラレル非安全操作は、パラレルクエリ利用中に、リーダーも含めて実行できない操作です。 クエリがパラレル非安全なものを含む場合は、クエリ中でのパラレルクエリの利用は全くできなくなります。

The following operations are always parallel restricted: 次の操作は常にパラレル制限です。

15.4.1. 関数と集約のためのパラレルラベル付け #

<title>Parallel Labeling for Functions and Aggregates</title>

The planner cannot automatically determine whether a user-defined function or aggregate is parallel safe, parallel restricted, or parallel unsafe, because this would require predicting every operation that the function could possibly perform. In general, this is equivalent to the Halting Problem and therefore impossible. Even for simple functions where it could conceivably be done, we do not try, since this would be expensive and error-prone. Instead, all user-defined functions are assumed to be parallel unsafe unless otherwise marked. When using <xref linkend="sql-createfunction"/> or <xref linkend="sql-alterfunction"/>, markings can be set by specifying <literal>PARALLEL SAFE</literal>, <literal>PARALLEL RESTRICTED</literal>, or <literal>PARALLEL UNSAFE</literal> as appropriate. When using <xref linkend="sql-createaggregate"/>, the <literal>PARALLEL</literal> option can be specified with <literal>SAFE</literal>, <literal>RESTRICTED</literal>, or <literal>UNSAFE</literal> as the corresponding value. プランナは、自動的にはユーザ定義関数や集約がパラレル安全か、パラレル制限か、あるいはパラレル非安全かを決定することはできません。 この関数が潜在的に実行する可能性のあるすべての操作を予測することが、このために要求されるからです。 一般的には、これは停止性問題と同等で、それ故に不可能です。 おそらく終了できると思われる単純な関数においてさえ、私達は試みません。なぜなら、そうした予測は高価でエラーを起こしやすいからです。 その代わりに、そうではないとマークされない限り、すべてのユーザ定義関数は、パラレル非安全と見なされます。 CREATE FUNCTIONあるいはALTER FUNCTIONを使用するときは、 適当なPARALLEL SAFEPARALLEL RESTRICTEDPARALLEL UNSAFEを指定することによってマーキングを行うことができます。 CREATE AGGREGATEを利用するときは、対応する値にしたがって、SAFERESTRICTEDUNSAFEのどれかをPARALLELオプションに指定します。

Functions and aggregates must be marked <literal>PARALLEL UNSAFE</literal> if they write to the database, change the transaction state (other than by using a subtransaction for error recovery), access sequences, or make persistent changes to settings. Similarly, functions must be marked <literal>PARALLEL RESTRICTED</literal> if they access temporary tables, client connection state, cursors, prepared statements, or miscellaneous backend-local state that the system cannot synchronize across workers. For example, <literal>setseed</literal> and <literal>random</literal> are parallel restricted for this last reason. 関数あるいは集約は、データベースに書き込むか、(エラー回復のためにサブトランザクションを使う場合以外で)トランザクションの状態を変更するか、シーケンスにアクセスするか、あるいは、恒久的な設定変更を行う場合、PARALLEL UNSAFEとマークされなければなりません。 同様に関数は、一時テーブル、クライアントの接続状態、カーソル、準備された文、システムがワーカーの間で同期できないその他のバックエンドローカルな状態にアクセスする場合、PARALLEL RESTRICTEDとマークされなければなりません。 たとえば、setseedrandomは、最後の理由により、パラレル制限です。

In general, if a function is labeled as being safe when it is restricted or unsafe, or if it is labeled as being restricted when it is in fact unsafe, it may throw errors or produce wrong answers when used in a parallel query. C-language functions could in theory exhibit totally undefined behavior if mislabeled, since there is no way for the system to protect itself against arbitrary C code, but in most likely cases the result will be no worse than for any other function. If in doubt, it is probably best to label functions as <literal>UNSAFE</literal>. 一般的に制限あるいは非安全な関数が安全とラベル付されたり、実際には非安全なのに制限付きとラベル付されると、パラレルクエリの中で使用される際に、エラーを生じたり、間違った結果を生成するかもしれません。 誤ったラベル付をされると、C言語関数は理論的にはまったく未定義の振る舞いを示すことがあります。 システムは任意のCコードから身を守るすべがないからです。 しかしもっとも起こりえる可能性としては、他の関数のよりも悪いということはなさそうです。 もし自信がないなら、たぶんその関数をUNSAFEとラベル付するのが最善でしょう。

If a function executed within a parallel worker acquires locks that are not held by the leader, for example by querying a table not referenced in the query, those locks will be released at worker exit, not end of transaction. If you write a function that does this, and this behavior difference is important to you, mark such functions as <literal>PARALLEL RESTRICTED</literal> to ensure that they execute only in the leader. パラレルワーカーの中で実行される関数がリーダーが獲得していないロックを獲得する場合、たとえばクエリ中で参照されていないテーブルに対して問い合わせを実行する場合などは、これらのロックはトランザクションが終了した時点ではなく、ワーカーが終了する際に解放されます。 もしあなたがこれを行う関数を作成し、こうした振る舞いの違いがあなたにとって重要ならば、関数がリーダーの中だけで実行されることを保証するために、関数をPARALLEL RESTRICTEDとマーク付けしてください。

Note that the query planner does not consider deferring the evaluation of parallel-restricted functions or aggregates involved in the query in order to obtain a superior plan. So, for example, if a <literal>WHERE</literal> clause applied to a particular table is parallel restricted, the query planner will not consider performing a scan of that table in the parallel portion of a plan. In some cases, it would be possible (and perhaps even efficient) to include the scan of that table in the parallel portion of the query and defer the evaluation of the <literal>WHERE</literal> clause so that it happens above the <literal>Gather</literal> node. However, the planner does not do this. より良いプランを得るために、プランナがクエリの中で実行されるパラレル制限な関数や集約の評価の遅延を考慮することはないことに注意してください。 したがって、たとえばあるテーブルに適用されるWHERE句がパラレル制限であるときに、クエリプランナはプランの並列実行部分中のテーブルに対してスキャンを実行をすることを考慮しません。 ある場合においては、クエリ中のパラレル部分におけるテーブルのスキャンを含むようにして、WHERE句の評価を遅らせ、Gatherノード上で実行されるようにすることも可能でしょう(そしてその方が効率が良いことさえあります)。 しかし、プランナはそうしたことは行いません。