キャッシュされたテーブル

v6.0.0 では、TiDB は頻繁にアクセスされるがめったに更新されない小さなホットスポット テーブルのキャッシュ テーブル機能を導入します。この機能を使用すると、テーブル全体のデータが TiDBサーバーのメモリにロードされ、TiDB は TiKV にアクセスせずにテーブル データをメモリから直接取得するため、読み取りパフォーマンスが向上します。

このドキュメントでは、キャッシュ テーブルの使用シナリオ、例、および他の TiDB 機能との互換性制限について説明します。

使用シナリオ

キャッシュ テーブル機能は、次の特性を持つテーブルに適しています。

  • テーブルのデータ量が少ない。
  • テーブルが読み取り専用であるか、ほとんど更新されていません。
  • テーブルは頻繁にアクセスされ、より優れた読み取りパフォーマンスが期待されます。

テーブルのデータ量は少ないがデータへのアクセス頻度が高い場合、TiKV ではデータがリージョンに集中し、ホットスポットリージョンとなり、パフォーマンスに影響を与えます。したがって、キャッシュされたテーブルの一般的な使用シナリオは次のとおりです。

  • アプリケーションが構成情報を読み取るConfiguration / コンフィグレーションテーブル。
  • 金融部門の為替レートの表。これらのテーブルは 1 日に 1 回だけ更新されますが、リアルタイムではありません。
  • ほとんど更新されない銀行支店またはネットワーク情報テーブル。

構成テーブルを例に取ります。アプリケーションが再起動すると、構成情報がすべての接続に読み込まれるため、読み取りのレイテンシーが長くなります。この場合、キャッシュされたテーブル機能を使用してこの問題を解決できます。

このセクションでは、キャッシュされたテーブルの使用法について例を挙げて説明します。

通常のテーブルをキャッシュ テーブルに設定する

テーブルusersがあるとします。

CREATE TABLE users ( id BIGINT, name VARCHAR(100), PRIMARY KEY(id) );

このテーブルをキャッシュ テーブルに設定するには、次のALTER TABLEステートメントを使用します。

ALTER TABLE users CACHE;
Query OK, 0 rows affected (0.01 sec)

キャッシュされたテーブルを確認する

キャッシュされたテーブルを確認するには、 SHOW CREATE TABLEステートメントを使用します。テーブルがキャッシュされている場合、返される結果にはCACHED ON属性が含まれます。

SHOW CREATE TABLE users;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | users | CREATE TABLE `users` ( `id` bigint(20) NOT NULL, `name` varchar(100) DEFAULT NULL, PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /* CACHED ON */ | +-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)

キャッシュされたテーブルからデータを読み取った後、TiDB はデータをメモリにロードします。 traceステートメントを使用して、データがメモリにロードされているかどうかを確認できます。キャッシュがロードされていない場合、返される結果にはregionRequest.SendReqCtx属性が含まれます。これは、TiDB が TiKV からデータを読み取ることを示します。

TRACE SELECT * FROM users;
+------------------------------------------------+-----------------+------------+ | operation | startTS | duration | +------------------------------------------------+-----------------+------------+ | trace | 17:47:39.969980 | 827.73µs | | ├─session.ExecuteStmt | 17:47:39.969986 | 413.31µs | | │ ├─executor.Compile | 17:47:39.969993 | 198.29µs | | │ └─session.runStmt | 17:47:39.970221 | 157.252µs | | │ └─TableReaderExecutor.Open | 17:47:39.970294 | 47.068µs | | │ └─distsql.Select | 17:47:39.970312 | 24.729µs | | │ └─regionRequest.SendReqCtx | 17:47:39.970454 | 189.601µs | | ├─*executor.UnionScanExec.Next | 17:47:39.970407 | 353.073µs | | │ ├─*executor.TableReaderExecutor.Next | 17:47:39.970411 | 301.106µs | | │ └─*executor.TableReaderExecutor.Next | 17:47:39.970746 | 6.57µs | | └─*executor.UnionScanExec.Next | 17:47:39.970772 | 17.589µs | | └─*executor.TableReaderExecutor.Next | 17:47:39.970776 | 6.59µs | +------------------------------------------------+-----------------+------------+ 12 rows in set (0.01 sec)

traceを再度実行した後、返された結果にはregionRequest.SendReqCtx属性が含まれなくなりました。これは、TiDB が TiKV からデータを読み取らず、代わりにメモリからデータを読み取ることを示します。

+----------------------------------------+-----------------+------------+ | operation | startTS | duration | +----------------------------------------+-----------------+------------+ | trace | 17:47:40.533888 | 453.547µs | | ├─session.ExecuteStmt | 17:47:40.533894 | 402.341µs | | │ ├─executor.Compile | 17:47:40.533903 | 205.54µs | | │ └─session.runStmt | 17:47:40.534141 | 132.084µs | | │ └─TableReaderExecutor.Open | 17:47:40.534202 | 14.749µs | | ├─*executor.UnionScanExec.Next | 17:47:40.534306 | 3.21µs | | └─*executor.UnionScanExec.Next | 17:47:40.534316 | 1.219µs | +----------------------------------------+-----------------+------------+ 7 rows in set (0.00 sec)

UnionScan演算子はキャッシュされたテーブルの読み取りに使用されるため、キャッシュされたテーブルの実行計画でexplainまでのUnionScanを確認できることに注意してください。

+-------------------------+---------+-----------+---------------+--------------------------------+ | id | estRows | task | access object | operator info | +-------------------------+---------+-----------+---------------+--------------------------------+ | UnionScan_5 | 1.00 | root | | | | └─TableReader_7 | 1.00 | root | | data:TableFullScan_6 | | └─TableFullScan_6 | 1.00 | cop[tikv] | table:users | keep order:false, stats:pseudo | +-------------------------+---------+-----------+---------------+--------------------------------+ 3 rows in set (0.00 sec)

キャッシュされたテーブルにデータを書き込む

キャッシュ テーブルはデータ書き込みをサポートします。たとえば、レコードをusersテーブルに挿入できます。

INSERT INTO users(id, name) VALUES(1001, 'Davis');
Query OK, 1 row affected (0.00 sec)
SELECT * FROM users;
+------+-------+ | id | name | +------+-------+ | 1001 | Davis | +------+-------+ 1 row in set (0.00 sec)

ノート:

キャッシュされたテーブルにデータを挿入すると、第 2 レベルの書き込みレイテンシーが発生する場合があります。レイテンシーは、グローバル環境変数tidb_table_cache_leaseによって制御されます。アプリケーションに基づいてレイテンシーが許容できるかどうかを確認することで、キャッシュ テーブル機能を使用するかどうかを決定できます。たとえば、読み取り専用のシナリオでは、 tidb_table_cache_leaseの値を増やすことができます。

set @@global.tidb_table_cache_lease = 10;

キャッシュ テーブル機能は、キャッシュごとにリースを設定する必要がある複雑なメカニズムで実装されているため、キャッシュ テーブルの書き込みレイテンシーは高くなります。複数の TiDB インスタンスがある場合、1 つのインスタンスは、他のインスタンスがデータをキャッシュしているかどうかを認識しません。インスタンスがテーブル データを直接変更すると、他のインスタンスは古いキャッシュ データを読み取ります。正確性を確保するために、キャッシュ テーブルの実装では、リース メカニズムを使用して、リースが期限切れになる前にデータが変更されないようにします。そのため、書き込みレイテンシーが高くなります。

キャッシュされたテーブルを通常のテーブルに戻す

ノート:

キャッシュされたテーブルで DDL ステートメントを実行すると失敗します。キャッシュされたテーブルで DDL ステートメントを実行する前に、まずキャッシュ属性を削除し、キャッシュされたテーブルを通常のテーブルに戻す必要があります。

TRUNCATE TABLE users;
ERROR 8242 (HY000): 'Truncate Table' is unsupported on cache tables.
mysql> ALTER TABLE users ADD INDEX k_id(id);
ERROR 8242 (HY000): 'Alter Table' is unsupported on cache tables.

キャッシュされたテーブルを通常のテーブルに戻すには、 ALTER TABLE t NOCACHEを使用します。

ALTER TABLE users NOCACHE
Query OK, 0 rows affected (0.00 sec)

キャッシュされたテーブルのサイズ制限

TiDB はテーブル全体のデータをメモリにロードし、キャッシュされたデータは変更後に無効になり、再ロードする必要があるため、キャッシュされたテーブルは小さなテーブルのシナリオにのみ適しています。

現在、キャッシュされたテーブルのサイズ制限は、TiDB で 64 MB です。テーブルデータが 64MB を超える場合、 ALTER TABLE t CACHEの実行は失敗します。

他の TiDB 機能との互換性の制限

キャッシュされたテーブルは、次の機能をサポートしていません:

  • 分割されたテーブルでALTER TABLE t ADD PARTITION操作を実行することはサポートされていません。
  • 一時テーブルに対するALTER TABLE t CACHE操作の実行はサポートされていません。
  • ビューでALTER TABLE t CACHE操作を実行することはサポートされていません。
  • ステイル読み取りはサポートされていません。
  • キャッシュされたテーブルに対する直接の DDL 操作はサポートされていません。 DDL 操作を実行する前に、まずALTER TABLE t NOCACHEを使用して、キャッシュされたテーブルを通常のテーブルに戻す必要があります。

次のシナリオでは、キャッシュされたテーブルを使用できません

  • 履歴データを読み取るようにシステム変数tidb_snapshotを設定します。
  • 変更中、キャッシュされたデータは、データがリロードされるまで無効になります。

TiDB 移行ツールとの互換性

キャッシュされたテーブルは、MySQL 構文に対する TiDB 拡張です。 ALTER TABLE ... CACHEステートメントを認識できるのは TiDB だけです。 TiDB 移行ツールは、Backup & Restore (BR)、TiCDC、およびDumplingを含む、キャッシュされたテーブルをサポートしていません。これらのツールは、キャッシュされたテーブルを通常のテーブルとして扱います。

つまり、キャッシュされたテーブルをバックアップして復元すると、通常のテーブルになります。ダウンストリーム クラスターが別の TiDB クラスターであり、キャッシュ テーブル機能を引き続き使用したい場合は、ダウンストリーム テーブルでALTER TABLE ... CACHEを実行することにより、ダウンストリーム クラスターでキャッシュ テーブルを手動で有効にすることができます。

こちらもご覧ください