KaiwuDB カーネル解析 - SQL クエリのライフサイクル

I. 概要

KaiwuDB カーネル分析シリーズは 2 部に分かれています。この記事はシリーズの第 1 部であり、主にネットワーク プロトコルから SQL  までをカバーします。 executor 、説明 KaiwuDB 実行方法 SQL システムのさまざまなコンポーネントの実行パスを含むクエリ (ネットワーク プロトコル、SQL セッション管理、パーサー、実行計画と最適化、実行プログラム、< /a > エンジン、トランザクション管理など)、その目的は、各コンポーネントの構造とコンポーネント間の関係の高レベルで統一されたビューを提供することです。 KV 

下の図は、 KaiwuDB SQL  クエリ実行の概要です。左側は ゲートウェイ  ノードで、 SQL クライアント  FlowSpec ノード。次に、各コンポーネントがどのように機能するかについて詳しく説明します。 に返します。 network =13>ゲートウェイ を通じてデータを に基づいて物理プラン内のオペレーターを構築して実行し、 FlowSpec  し、クエリされたデータが存在するノードに送信されます。各ノードは、受信した  クエリ、クエリ プラン (論理プランと物理プラン) の生成、および必要な SQL 

二、PostgreSQL ワイヤープロトコル

SQL クエリは、Postgres Wire プロトコルを介して KaiwuDB に送信されます (Postgres プロトコルは、既存のクライアント ドライバーおよびアプリケーションとの互換性のために使用されます)。このコンポーネントは、Postgres ワイヤ プロトコルに関連する機能インターフェイスを実装します。ユーザーが接続すると、最初に認証が行われ、認証に合格すると、SQL ステートメントを継続的に読み取り、実行し、結果を返すループが初期化されます (golang の net.Conn をカプセル化することによって)。

このプロトコルはメッセージ指向です (PostgreSQL メッセージ タイプ、エグゼキュータのセクションを参照): 現在の接続のライフ サイクル中に、SQL ステートメントを含む 1 つ以上のメッセージが読み取られ、実行のために SQL エグゼキュータに渡されます。が実行されて結果が生成され、シリアル化されてクライアントに返されます。

PostgreSQL Wire Protocol Server は、KaiwuDB の起動時に初期化されます。詳細な初期化プロセスを次の図に示します。まず、KaiwuDB の起動コマンドは、server.Start メソッドを通じて startServeSQL を呼び出し、ServConn を初期化します。 ServConn は、SQL クライアントのリクエストを解析し、接続のセキュリティをチェックし、接続パラメータを処理してから、pgServer.ServConn メソッドを呼び出して SQL ステートメントを処理します。

3. SQL 実行プログラム

KaiwuDB は 1 つのポートを使用して、pg/http/grpc の 3 つのプロトコルを同時に処理します。開始フェーズでは、KaiwuDB は pgServer をインスタンス化し、Postgres ワイヤ プロトコルのリクエストを処理します。 pgServer は、KaiwuDB の SQL エグゼキュータをインスタンス化して、ユーザー クエリを処理します。

SQL エグゼキューターはプロデューサー (Producer) として機能し、引き続きユーザー入力を読み取り、パーサーを呼び出して SQL をステートメントに解析し、解析された結果がステートメント バッファー (StmtBuf) に保存されます。同時に、StmtBuf 内の SQL ステートメントを順番に処理するコンシューマーとして go ルーチンが作成されます。

SQLエグゼキュータの具体的な処理の流れを次の図に示します。まず、serverImpl を通じて processCommandsAsync を呼び出して新しい goroutine を作成し、クライアント接続を認証し、Statement バッファー (StmtBuf) (前述のコンシューマー) 内のコマンドを処理します。

戻り値は、ゴルーチンが終了したかどうかを示すために使用されるチャネルです。この期間中に発生したエラーの詳細はすでに SQL クライアントに通知されているため、このチャネルのエラー メッセージは無視されることに注意してください。 processCommandsAsync は認証作業も実行します。認証が失敗すると、このゴルーチンは終了し、cancelConn が呼び出されて接続全体が閉じられます。

次に、serverImpl は for ループを初期化し、接続が閉じられるかエラーが発生するまで SQL クライアントから入力を受け取ります。ここの for ループはプロデューサーとして機能し、最初に SQL クライアントの権限を確認し、それを渡した後、クライアントから送信されたメッセージの種類に応じてさまざまなメソッドを呼び出します。

メッセージ タイプの定義については、>>https://www.postgresql.org/docs/9.4/protocol を参照してください。 -メッセージ- フォーマット.html

次の章では、SQL Executor が SQL を処理するプロセスを説明するために、handleSimpleQuery メソッドを例として取り上げます。

1. SQLの受信と解析

handleSimpleQuery の目的は、単純な SQL を処理することです。まず、PostgreSQL ワイヤー プロトコルのキャッシュから文字列を読み取ります。読み取りが成功すると、文字列が KaiwuDB の SQL パーサーに送信されます。

KaiwuDB のパーサーはもともと PostgresSQL からコピーされたもので、より多くの SQL 構文をサポートするように徐々に拡張されました。 SQL パーサーの出力は、SQL ステートメントごとに 1 つずつ、AST (抽象構文ツリー) の配列です。 AST のノードは、pkg/sql/sem/tree で定義されたtree.Statement 構造で構成されます。

Go
type Statement interface {
  fmt.Stringer
  NodeFormatter
  StatementType() StatementType
  // StatementTag is a short string identifying the type of statement
  // (usually a single verb). This is different than the Stringer output,
  // which is the actual statement (including args).
  // TODO(dt): Currently tags are always pg-compatible in the future it
  // might make sense to pass a tag format specifier.
  StatementTag() string
}

KaiwuDB は、tree.Statement のサブクラスの使用を実装して、SQL ステートメントの各節を抽象化します。たとえば、tree.SelectClause 構造は、SELECT の From 句と Where 句を含む SQL の SELECT 句を抽象化します。同時に、AST ツリーの多くの部分には、l_extendedprice * (1 - l_discount) などの算術式を表すために使用される 1 つ以上のtree.Expr 構造体が含まれます。

Go
type SelectClause struct {
  Distinct    bool
  DistinctOn  DistinctOn
  Exprs       SelectExprs
  From        From
  Where       *Where
  GroupBy     GroupBy
  Having      *Where
  Window      Window
  TableSelect bool
}

type BinaryExpr struct {
  Operator    BinaryOperator
  Left, Right Expr

  typeAnnotation
  fn *BinOp
}

SQL 解析が成功すると、SQL は Statement バッファに追加され、実行プログラムによる処理を待ちます。

KaiwuDB の AST の構造を示すために、TPCH の Q7 を例に挙げてみましょう。

TPCH の Q7 は、特定の期間 (1995 年 1 月 1 日から 1996 年 12 月 31 日まで) 内に特定の 2 か国 (ここではフランスとドイツ) 間で輸送された商品の合計額をクエリするために使用されます。

SQL
SELECT
    supp_nation,
    cust_nation,
    l_year, sum(volume) AS revenue
FROM (
    SELECT
        n1.n_name AS supp_nation,
        n2.n_name AS cust_nation,
        extract(year FROM l_shipdate) AS l_year,
        l_extendedprice * (1 - l_discount) AS volume
    FROM
        supplier,
        lineitem,
        orders,
        customer,
        nation n1,
        nation n2
    WHERE
        s_suppkey = l_suppkey
        AND o_orderkey = l_orderkey
        AND c_custkey = o_custkey
        AND s_nationkey = n1.n_nationkey
        AND c_nationkey = n2.n_nationkey
        AND (
            (n1.n_name = 'FRANCE' AND n2.n_name = 'GERMANY')
            or (n1.n_name = 'GERMANY' AND n2.n_name = 'FRANCE')
        )
        AND l_shipdate BETWEEN DATE '1995-01-01' AND DATE '1996-12-31'
    ) AS shipping
GROUP BY
    supp_nation,
    cust_nation,
    l_year
ORDER BY
    supp_nation,
    cust_nation,
    l_year;

以下の図は、KaiwuDB の TPCH Q7 の AST を示しています (表示の便宜上簡略化されています)。各ノードの白い部分は null 値 (nil) を表し、現在のノードに構造が含まれていないことを示します。紫の部分は構造が展開できること、つまり次の子ノードを指していることを示します。緑の部分はリーフノード。

Q7 は SELECT ステートメントであるため、そのルート ノードは、tree.Statement のサブクラスであるtree.Select です。 Q7 の各ステートメントは、特定のノードに抽象化されます。たとえば、ORDER BY は、tree.OrderBy として表され、WHERE 句は、tree.Where として表されます。

2. SQL文の実行

前述したように、SQL Executor のコンシューマゴルーチンは、Statement バッファから SQL の AST を継続的に読み出して実行します。この機能は、sqlServer.ServeConn を通じて connExecutor の execCmd を呼び出すことで実装されます。主な処理は次の図に示されています。

execCmd  メソッドは、 stmtBuf  の内容を継続的に読み取り、実行します。各 SQL  クライアント接続が初期化されると、 KaiwuDB  は有限状態を初期化します。 SQL  を実行するために使用されるマシン (FSM)。 >  は次のように述べています:

  • stateNoTxn –  は、 BEGIN  ステートメントまたは暗黙的なトランザクションを処理するために使用されます (新しいトランザクションを開きます)それは問題です)

  • stateOpen – 用来执行普通的 SQL 语句

  • stateAborted – 用来处理 ROLLBACK 语句

  • stateCommitWait –  は COMMIT  ステートメントを処理するために使用されます。

  • stateInternalError –  は、 eventNonRetriableErr、stateInternalError  などのさまざまなエラーを処理するために使用されます。< /span>

stmtBuf  SQL  命令がステート マシンに追加された後、命令は次に従って個別に処理されます。そのタイプに。通常の SQL  は ExecStmt  タイプとして定義され、  メソッドが実行されます。 execStmt  の connExecutor 

execStmt  メソッドは、まず現在のステート マシンのステータスを確認します。ステータス マシンが BEGIN  ステートメントを作成すると、 connExecutor  の execStmtInNoTxnState  メソッドが実行されます。新しいトランザクション。通常の SQL  の場合、 connExecutor  実行します。 execStmtInOpenState 

下の図は、新しいものを作成する execStmtInNoTxnState  プロセスを示しています。現在のステートメントが BEGIN の場合、新しいことが開始されます。 If tree.CommitTransaction、 tree.ReleaseSavepoint< a i =9>、tree.RollbackTransaction、 tree.SetTransaction  または  に変換し、暗黙的なトランザクションを作成します。 stateOpen  ステートメント)、ステート マシンの状態を SQL その他の状況 (つまり、通常の  いずれかがエラーを報告します。tree.Savepoint 

トランザクションが正常に作成され、ステート マシンの状態が stateOpen  に変換された後、 SQL  は実行フェーズに入ります。これについては後続の記事で詳しく紹介します。

SenseTime 創設者、Tang Xiaoou 氏が 55 歳で死去 2023 年、PHP は停滞 Wi-Fi 7 が完全に利用可能になる2024 年初頭にデビュー、Wi-Fi 6 の 5 倍高速 Hongmeng システムが独立しつつあり、多くの大学が「Hongmeng クラス」を設立 Zhihui Jun の新興企業が借り換え、金額は 6 億元を超え、事前評価額は 35 億元 Quark Browser PC 版が内部テストを開始 AI コード アシスタントは人気があり、プログラミング言語のランキングはすべてです できることは何もありません Mate 60 Pro の 5G モデムと無線周波数技術ははるかに先を行っています MariaDB が SkySQL を分割し、確立されました独立した企業として<​​/span> Xiaomi、Yu Chengdong 氏の Huawei からの「キールピボット」盗作声明に対応
{{名前}}
{{名前}}

Supongo que te gusta

Origin my.oschina.net/u/5148943/blog/10140674
Recomendado
Clasificación