TiDB を使用して TiFlash レプリカを読み取る

このドキュメントでは、TiDB を使用して TiFlash レプリカを読み取る方法を紹介します。

TiDB は、TiFlash レプリカを読み取る 3 つの方法を提供します。エンジン構成なしで TiFlash レプリカを追加した場合、CBO (コストベースの最適化) モードがデフォルトで使用されます。

スマートセレクション

TiFlash レプリカを含むテーブルの場合、TiDB オプティマイザは、コストの見積もりに基づいて TiFlash レプリカを使用するかどうかを自動的に決定します。 descまたはexplain analyzeステートメントを使用して、TiFlash レプリカが選択されているかどうかを確認できます。例えば:

desc select count(*) from test.t;
+--------------------------+---------+--------------+---------------+--------------------------------+
| id                       | estRows | task         | access object | operator info                  |
+--------------------------+---------+--------------+---------------+--------------------------------+
| StreamAgg_9              | 1.00    | root         |               | funcs:count(1)->Column#4       |
| └─TableReader_17         | 1.00    | root         |               | data:TableFullScan_16          |
|   └─TableFullScan_16     | 1.00    | cop[tiflash] | table:t       | keep order:false, stats:pseudo |
+--------------------------+---------+--------------+---------------+--------------------------------+
3 rows in set (0.00 sec)
explain analyze select count(*) from test.t;
+--------------------------+---------+---------+--------------+---------------+----------------------------------------------------------------------+--------------------------------+-----------+------+
| id                       | estRows | actRows | task         | access object | execution info                                                       | operator info                  | memory    | disk |
+--------------------------+---------+---------+--------------+---------------+----------------------------------------------------------------------+--------------------------------+-----------+------+
| StreamAgg_9              | 1.00    | 1       | root         |               | time:83.8372ms, loops:2                                              | funcs:count(1)->Column#4       | 372 Bytes | N/A  |
| └─TableReader_17         | 1.00    | 1       | root         |               | time:83.7776ms, loops:2, rpc num: 1, rpc time:83.5701ms, proc keys:0 | data:TableFullScan_16          | 152 Bytes | N/A  |
|   └─TableFullScan_16     | 1.00    | 1       | cop[tiflash] | table:t       | time:43ms, loops:1                                                   | keep order:false, stats:pseudo | N/A       | N/A  |
+--------------------------+---------+---------+--------------+---------------+----------------------------------------------------------------------+--------------------------------+-----------+------+

cop[tiflash]は、タスクが処理のために TiFlash に送信されることを意味します。 TiFlash レプリカを選択していない場合は、 analyze tableステートメントを使用して統計を更新してから、 explain analyzeステートメントを使用して結果を確認できます。

テーブルに TiFlash レプリカが 1 つしかなく、関連するノードがサービスを提供できない場合、CBO モードのクエリは繰り返し再試行されることに注意してください。この状況では、エンジンを指定するか、手動ヒントを使用して TiKV レプリカからデータを読み取る必要があります。

エンジンの分離

エンジンの分離とは、対応する変数を構成することにより、すべてのクエリが指定されたエンジンのレプリカを使用することを指定することです。オプションのエンジンは、「tikv」、「tidb」(一部の TiDB システム テーブルを格納し、ユーザーが積極的に使用できない TiDB の内部メモリ テーブル領域を示します)、および「tiflash」です。

次の 2 つの構成レベルでエンジンを指定できます。

  • TiDB インスタンス レベル、つまり INSTANCE レベル。 TiDB 構成ファイルに次の構成項目を追加します。

    [isolation-read]
    engines = ["tikv", "tidb", "tiflash"]
    

    INSTANCE レベルのデフォルト設定は["tikv", "tidb", "tiflash"]です。

  • セッションレベル。次のステートメントを使用して構成します。

    set @@session.tidb_isolation_read_engines = "engine list separated by commas";
    

    また

    set SESSION tidb_isolation_read_engines = "engine list separated by commas";
    

    SESSION レベルのデフォルト構成は、TiDB INSTANCE レベルの構成を継承しています。

最終的なエンジン構成はセッション レベルの構成です。つまり、セッション レベルの構成がインスタンス レベルの構成をオーバーライドします。たとえば、INSTANCE レベルで「tikv」を構成し、SESSION レベルで「tiflash」を構成した場合、TiFlash レプリカが読み取られます。最終的なエンジン構成が「tikv」および「tiflash」である場合、TiKV および TiFlash レプリカの両方が読み取られ、オプティマイザーは実行するより適切なエンジンを自動的に選択します。

ノート:

TiDB ダッシュボードおよびその他のコンポーネントは、TiDB メモリ テーブル領域に格納されているシステム テーブルを読み取る必要があるため、インスタンス レベルのエンジン構成に常に「tidb」エンジンを追加することをお勧めします。

次のステートメントを使用してエンジンを指定できます。

set @@session.tidb_isolation_read_engines = "engine list separated by commas";

また

set SESSION tidb_isolation_read_engines = "engine list separated by commas";

照会されたテーブルに指定されたエンジンのレプリカがない場合 (たとえば、エンジンが「tiflash」として構成されているが、テーブルに TiFlash レプリカがない場合)、クエリはエラーを返します。

手動ヒント

手動ヒントは、TiDB が特定のテーブルに対して指定されたレプリカを使用するように強制することができます。手動ヒントの使用例を次に示します。

select /*+ read_from_storage(tiflash[table_name]) */ ... from table_name;

クエリ ステートメントでテーブルにエイリアスを設定する場合、ヒントを有効にするには、ヒントを含むステートメントでエイリアスを使用する必要があります。例えば:

select /*+ read_from_storage(tiflash[alias_a,alias_b]) */ ... from table_name_1 as alias_a, table_name_2 as alias_b where alias_a.column_1 = alias_b.column_2;

上記のステートメントで、 tiflash[]はオプティマイザーに TiFlash レプリカを読み取るように促します。 tikv[]を使用して、オプティマイザーに必要に応じて TiKV レプリカを読み取るように指示することもできます。ヒント構文の詳細については、 READ_FROM_STORAGEを参照してください。

ヒントで指定されたテーブルに指定されたエンジンのレプリカがない場合、ヒントは無視され、警告が報告されます。また、ヒントはエンジン分離前提でのみ有効です。ヒントで指定されたエンジンがエンジン分離リストにない場合、ヒントも無視され、警告が報告されます。

ノート:

5.7.7 以前のバージョンの MySQL クライアントは、デフォルトでオプティマイザ ヒントをクリアします。これらの初期バージョンでヒント構文を使用するには、クライアントを--commentsオプション (例: mysql -h 127.0.0.1 -P 4000 -uroot --comments ) で起動します。

スマートセレクション、エンジンアイソレーション、マニュアルヒントの関係

上記の 3 つの TiFlash レプリカの読み取り方法では、エンジンの分離により、エンジンの使用可能なレプリカの全体的な範囲が指定されます。この範囲内では、手動ヒントにより、よりきめ細かいステートメント レベルおよびテーブル レベルのエンジン選択が提供されます。最後に、CBO が決定を下し、指定されたエンジン リスト内のコスト見積もりに基づいてエンジンのレプリカを選択します。

ノート:

v4.0.3 より前では、読み取り専用ではない SQL ステートメント (たとえば、 INSERT INTO ... SELECTSELECT ... FOR UPDATEUPDATE ...DELETE ... ) での TiFlash レプリカからの読み取りの動作は定義されていません。 v4.0.3 以降のバージョンでは、データの正確性を保証するために、TiDB は非読み取り専用 SQL ステートメントの TiFlash レプリカを内部的に無視します。つまり、 スマートセレクションの場合、TiDB は非 TiFlash レプリカを自動的に選択します。 TiFlash レプリカのみを指定するエンジン分離の場合、TiDB はエラーを報告します。 手動ヒントの場合、TiDB はヒントを無視します。

エコシステム
TiDB
TiKV
TiSpark
Chaos Mesh
© 2022 PingCAP. All Rights Reserved.