008. アーキテクチャのSQL実行処理

読み取り実行

  • メタデータの読み込み
    ここに画像の説明を挿入
    executor は常に information_schema からテーブルのメタデータ情報 (テーブルメタ) を取得しますが、情報スキーマがキャッシュされているため、メタデータ情報をメモリから読み出すことができます。

  • DistSQL
    ここに画像の説明を挿入
    DistSQL: 複数テーブル(t1 t2)関連クエリなどのクエリ文に加え、単一テーブルクエリ(select * from t1 where xx)(select * from t2 where xx)に変換して処理します。単純な SQL は「Send it to TiKV」です。これは、TikV と複雑な SQL を切り離すことに相当します。

  • UnifyRead Pool
    TiKV は、これらの SQL ステートメントを受信すると、まずスナップショット オブジェクト (特定の時点のコンテンツ) を構築します。
    これらの単純な SQL ステートメントはすべて UnifyRead Pool スレッド プールに入ります。(これらのSQLを優先的に実行します)

  • Rocksdb KV はデータを読み取り
    、次に Rocksdb KV データを階層的に読み取ります。
    注: この領域は別の tikv 上にある可能性があるため、並行してクエリを実行できます。これが DistSQL と呼ばれる理由です。TiKV には
    ここに画像の説明を挿入
    演算子をプッシュダウンする機能があり、一部の操作を TiKV にプッシュダウンします。これは実行で確認できます。それを cop task と呼ぶ予定です。
    もちろん、複数のテーブルに関連付けられたデータ要約操作などの一部の操作は、依然として TiDB サーバー上の実行計画のルート タスクとして見ることができます。

書き込み実行

ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入
まず、読み取り操作がまだあり、処理されたデータを memBuffer (順序付けされた KV レコード) に読み込んで
操作データを見つけて送信を開始した後、2 フェーズの送信に入ります。
簡単に理解すると、
第 1 段階: トランザクション (データの変更 + ロック)
第 2 段階: コミット (ロックの解放の記録の追加 + コミット)

DDLの実行

ここに画像の説明を挿入

  • TiDB サーバーによって発行された ddl ステートメントは、所有者が誰であっても、TiDB サーバーによって実行される必要はありません。
  • インデックスを追加するステートメントはインデックス追加キューに配置されます。

ここに画像の説明を挿入
オンライン DDL は、DML をブロックせずに実行できます。
一度に 1 つの TiDB ワーカー (所有者) のみが実行できます。
スキーマ ロード: 最新のオブジェクトのロードを担当します。

ここに画像の説明を挿入
この所有者は TiDB サーバーでポーリングされます

SQL操作

SQLの解析とコンパイル

ここに画像の説明を挿入
SQL の解析とコンパイル、AST 構文ツリーの
最適化には、論理最適化 (サブテーブル クエリを結合クエリに変換するなど) と物理最適化 (行数に基づいてインデックスを使用するかどうかを判断するなど) が含まれており、最適な最適化を見つけます。実行計画を生成するオペレーター。

SQL層アーキテクチャ

  • TiDB の SQL 層、つまり TiDB サーバーは、SQL を Key-Value 操作に変換し、共有分散 Key-Value ストレージ層 TiKV に転送し、TiKV から返された結果を組み立てて、最終的にクエリ結果をクライアントに返す役割を担います。 。
  • この層のノードはすべてステートレスであり、ノード自体はデータを保存せず、ノードは完全にピアツーピアです。

SQL操作

最も簡単な解決策は、前のセクションで説明したテーブル データと Key-Value の間のマッピング関係を通じて SQL クエリを KV クエリにマッピングし、KV インターフェイスを通じて対応するデータを取得し、最後にさまざまな計算を実行することです。

たとえばselect count(*) from user where name = "TiDB"、このような SQL ステートメントはテーブル内のすべてのデータを読み取り、名前フィールドが TiDB かどうかを確認し、そうであればこの行を返す必要があります。

具体的なプロセスは次のとおりです。

  • キー範囲の構築: テーブル内のすべての RowID は [0, MaxInt64) の範囲内にあり、行データのキー エンコード規則に従って 0 と MaxInt64 を使用して、左で閉じた [StartKey, EndKey) を構築できます。間隔を開くと、権利。
  • スキャン キー範囲: 上記で構築されたキー範囲に従って、TiKV 内のデータを読み取ります。
  • データのフィルタリング: 読み取られたデータの各行について、式名 = "TiDB" を計算し、それが true の場合はこの行を上方に返し、それ以外の場合はこのデータ行を破棄します。
  • Count( ) の計算: 要件を満たす各行について、 Count( ) の結果まで累積します。

プロセス全体の概略図は次のとおりです。

ここに画像の説明を挿入
このソリューションは直感的で実現可能ですが、分散データベースのシナリオには明らかな問題がいくつかあります。

  • データをスキャンするときは、KV 操作を通じて TiKV から各行を読み取る必要があり、少なくとも 1 つの RPC オーバーヘッドが必要です。スキャンするデータが多い場合、オーバーヘッドは非常に大きくなります。
  • すべての行がフィルタ条件名 = "TiDB" を満たすわけではないため、条件を満たさない場合は読み込む必要はありません。このクエリは、対象となる行の数を返すためにのみ必要であり、それらの行の値を返す必要はありません。

分散SQL操作

上記の問題を解決するには、多数の RPC 呼び出しを回避するために、コンピューティングをできるだけストレージ ノードに近づける必要があります。まず、SQL の述語条件名 = "TiDB" を計算のためにストレージ ノードにプッシュダウンして、無意味なネットワーク送信を避けるために有効な行のみを返す必要があるようにする必要があります。その後、集計関数 Count( ) を事前集計のためにストレージ ノードにプッシュダウンすることもできます。各ノードは Count( ) の結果を返すだけでよく、SQL レイヤーは Count(*) を返します。結果は蓄積され、合計した。

以下は、レイヤーごとに返されるデータの概略図です。

ここに画像の説明を挿入

SQL層アーキテクチャ

上記の例を通じて、SQL ステートメントの処理の基本を理解していただければ幸いです。実際、TiDB の SQL レイヤーは、多くのモジュールとレイヤーで構成され、より複雑です。次の図は、重要なモジュールとその呼び出し関係を示しています: ユーザーの SQL リクエストは直接またはロード バランサー経由で TiDB サーバーに送信され、TiDB サーバーは MySQL を解析し
ここに画像の説明を挿入
ますプロトコル パケット、リクエスト コンテンツの取得、SQL の構文分析と意味分析の実行、クエリ プランの策定と最適化、クエリ プランの実行、データの取得と処理。すべてのデータは TiKV クラスターに保存されるため、このプロセス中に TiDB サーバーは TiKV と対話してデータを取得する必要があります。最後に、TiDB サーバーはクエリ結果をユーザーに返す必要があります。

おすすめ

転載: blog.csdn.net/wangzhicheng987/article/details/131031744