バックエンド処理に挑戦!
エクゼキュータ
システム内部のお話は、最後の工程であるエクゼキュータです。これは作成された実行プランを実行します。ここではsrc/backend/executor/READMEから拾い読みをします。最初の部分から始めましょう。
The executor processes a tree of "plan nodes". The plan tree is essentially a demand-pull pipeline of tuple processing operations. Each node, when called, will produce the next tuple in its output sequence, or NULL if no more tuples are available.
「エクゼキュータは『プランノード』の木を処理します。プラン木は基本的に、タプル処理操作のデマンドプルパイプラインです。呼び出されたとき、それぞれのノードはその出力シーケンスに次のタプルを作成するか、もはやタプルが入手できなくなった場合、NULLを出力します」
ここではそのままカタカナ表記にしましたが、"demand-pull pipeline"は「要求に基づいて引き出される(要求引き出し型)パイプライン(処理のつながり)」という意味です。それぞれのノードは呼び出される度に次の出力行を計算して返します。エクゼキュータは処理を淡々と進め、最後にNULLを出力して一区切りの処理を終了します。
The plan tree delivered by the planner contains a tree of Plan nodes (struct types derived from struct Plan). Each Plan node may have expression trees associated with it, to represent its target list, qualification conditions, etc.
「プランナで与えられたプラン木にはプランノード(構造体プランから渡された構造体型の)木が含まれます。それぞれのプランノードは、ターゲットリストや制約条件などを表す、式木を伴うことがあります」
ターゲットリストとは、テーブル検索で入手したい列のリストのことを指し、これはSELECT命令の後に記述されます。「SELECT col1, col2 FROM table_foo;」のcol1とcol2 です。 "qualification condition(s)"は「制約(諸)条件」です。これらの条件式、制約式を含むため"expression"、「式」という言葉を使います。
During executor startup we build a parallel tree of identical structure containing executor state nodes --- every plan and expression node type has a corresponding executor state node type.
「エクゼキュータの開始時点で、エクゼキュータの状態ノードを含んだまったく同じの構造体の同時実行木を作成します。プランと式のノードの型はそれぞれに相応するエクゼキュータ状態ノード型を所有します」
The executor can also be used to evaluate simple expressions without any Plan tree ("simple" meaning "no aggregates and no sub-selects", though such might be hidden inside function calls).
「エクゼキュータはプラン木が1つもない単純式を評価する場合も使用できます。関数呼び出しの内部に隠されている場合があるとしても、『単純』は『集約や副問い合わせがない』という意味です」
"aggregate function"とは「集約関数」です。
エクゼキュータによるそのほかの管理
エクゼキュータはメモリー管理、ストレージ管理などプランの実行以外にも仕事を受け持ちます。この部分について同じくREADMEに何が書いてあるのか参照してみましょう。原文と訳を見比べてながら読んでみましょう。
A "per query" memory context is created during CreateExecutorState(); all storage allocated during an executor invocation is allocated in that context or a child context.
「『問い合わせごとの』メモリコンテキストはCreateExecutorState()間で作成されます。エクゼキュータ起動時に割り当てられたすべてのストレージは、そのコンテキスト内、もしくは子コンテキストに配分されます」
"allocate"は「配分する」または「割り当てる」という意味です。
This allows easy reclamation of storage during executor shutdown --- rather than messing with retail pfree's and probable storage leaks, we just destroy the memory context.
「このことは、そこにあるpfreeの対象、および起こるかもしれないストレージリークによる混乱に陥るよりも、単にメモリコンテキストを廃棄することで、エクゼキュータが停止中であった場合のストレージ再生を容易にします」
"retail"をどう解釈するか、筆者はおおいに悩みました。そのままでは「小売り」で、スーパの棚に陳列されている商品を想像します。とは言っても、「棚にある売り物」とは訳せませんので、「そこにあるpfreeの対象」としてみました。 "probable"は「あるかもしれない、ないかもしれない」で、ありそうの方に軍配を挙げているファジーな表現です。
In particular, the plan state trees and expression state trees described in the previous section are allocated in the per-query memory context.
「特に、前節で記述したプラン状態木と式状態木は問い合わせ前メモリコンテキストに割り当てられます」
To avoid intra-query memory leaks, most processing while a query runs is done in "per tuple" memory contexts, which are so-called because they are typically reset to empty once per tuple.
「内部問い合わせメモリリークを防ぐため、問い合わせが実行されている間のほとんどの処理は『タプルごとの』メモリコンテキストで行われます。それらは典型的にタプルごとに一度空にリセットされるため、そのように呼ばれます」
Per-tuple contexts are usually associated with ExprContexts, and commonly each PlanState node has its own ExprContext to evaluate its qual and targetlist expressions in.
「タプルごとのコンテキストは通常ExprContextsに伴われ、一般にそれぞれのPlanStateノードは中にある制約条件とターゲットリスト式を評価するため自身のExprContextを所有します」
"qual"は先ほど説明した"qualification"の略です。
いかがでしたでしょうか。今回はバックエンド処理を駆け足で紹介しました。次回の最終回はメインルーティンのCコード、そのほかの話題を取り上げる予定です。