AUTO_RANDOM v3.1.0の新機能

ノート:

AUTO_RANDOMは v4.0.3 以降で一般提供されています。

ユーザーシナリオ

TiDB にデータを集中的に書き込み、TiDB に自動インクリメント整数型の主キーを持つテーブルがある場合、ホットスポットの問題が発生する可能性があります。ホットスポットの問題を解決するには、 AUTO_RANDOM属性を使用できます。

詳細については、 高度な同時書き込みのベスト プラクティスを参照してください。

例として、次の作成済みテーブルを取り上げます。

CREATE TABLE t (a bigint PRIMARY KEY AUTO_INCREMENT, b varchar(255))

このtのテーブルで、次のように主キーの値を指定しないINSERTのステートメントを大量に実行します。

INSERT INTO t(b) VALUES ('a'), ('b'), ('c')

上記のステートメントでは、主キー (列a ) の値が指定されていないため、TiDB は連続自動インクリメント行の値を行 ID として使用します。これにより、単一の TiKV ノードで書き込みホットスポットが発生し、パフォーマンスに影響を与える可能性があります。このような書き込みホットスポットを回避するには、テーブルを作成するときに、列aAUTO_INCREMENT属性ではなくAUTO_RANDOM属性を指定できます。次の例を参照してください。

CREATE TABLE t (a bigint PRIMARY KEY AUTO_RANDOM, b varchar(255))

また

CREATE TABLE t (a bigint AUTO_RANDOM, b varchar(255), PRIMARY KEY (a))

次に、 INSERT INTO t(b) VALUES...などのINSERTステートメントを実行します。結果は次のようになります。

  • 暗黙的な値の割り当て: INSERTステートメントで整数の主キー列 (列a ) の値が指定されていないか、値がNULLとして指定されていない場合、TiDB はこの列に値を自動的に割り当てます。これらの値は必ずしも自動インクリメントまたは連続ではありませんが、一意であるため、連続する行 ID によって引き起こされるホットスポットの問題を回避できます。
  • 明示的な値の挿入: INSERTステートメントが整数の主キー列の値を明示的に指定する場合、TiDB はこれらの値を保存します。これはAUTO_INCREMENT属性と同様に機能します。 @@sql_modeシステム変数にNO_AUTO_VALUE_ON_ZEROを設定しない場合、整数の主キー列の値を0として明示的に指定したとしても、TiDB は自動的にこの列に値を割り当てることに注意してください。

ノート:

v4.0.3 以降、値を明示的に挿入する場合は、システム変数@@allow_auto_random_explicit_insertの値を1 (デフォルトでは0 ) に設定します。この明示的な挿入はデフォルトではサポートされておらず、その理由は制限セクションに記載されています。

TiDB は、次の方法で値を自動的に割り当てます。

バイナリ (つまり、シャード ビット) の行値の上位 5 桁 (符号ビットを無視) は、現在のトランザクションの開始時間によって決定されます。残りの桁には、自動インクリメント順で値が割り当てられます。

異なる数のシャード ビットを使用するには、括弧のペアをAUTO_RANDOMに追加し、括弧内に目的のシャード ビット数を指定します。次の例を参照してください。

CREATE TABLE t (a bigint PRIMARY KEY AUTO_RANDOM(3), b varchar(255))

上記のCREATE TABLEのステートメントでは、 3のシャード ビットが指定されています。シャード ビット数の範囲は[1, 16)です。

テーブルを作成したら、 SHOW WARNINGSステートメントを使用して、現在のテーブルでサポートされている暗黙的な割り当ての最大数を確認します。

SHOW WARNINGS
+-------+------+----------------------------------------------------------+ | Level | Code | Message | +-------+------+----------------------------------------------------------+ | Note | 1105 | Available implicit allocation times: 1152921504606846976 | +-------+------+----------------------------------------------------------+

ノート:

v4.0.3 以降、 AUTO_RANDOM列の型はBIGINTのみです。これは、暗黙的な割り当ての最大数を確保するためです。

さらに、 AUTO_RANDOM属性を持つテーブルのシャード ビット数を表示するには、 information_schema.tablesシステム テーブルのTIDB_ROW_ID_SHARDING_INFO列でPK_AUTO_RANDOM_BITS=xモードの値を確認できます。 xはシャード ビットの数です。

AUTO_RANDOM列に割り当てられた値はlast_insert_id()に影響します。 SELECT last_insert_id ()を使用して、TiDB が最後に暗黙的に割り当てた ID を取得できます。例えば:

INSERT INTO t (b) VALUES ("b") SELECT * FROM t; SELECT last_insert_id()

次の結果が表示される場合があります。

+------------+---+ | a | b | +------------+---+ | 1073741825 | b | +------------+---+ +------------------+ | last_insert_id() | +------------------+ | 1073741825 | +------------------+

互換性

TiDB は、バージョン コメント構文の解析をサポートしています。次の例を参照してください。

CREATE TABLE t (a bigint PRIMARY KEY /*T![auto_rand] auto_random */)
CREATE TABLE t (a bigint PRIMARY KEY AUTO_RANDOM)

上記の 2 つのステートメントは同じ意味です。

SHOW CREATE TABLEの結果では、 AUTO_RANDOM属性がコメントアウトされています。このコメントには、属性識別子 ( /*T![auto_rand] auto_random */など) が含まれます。ここで、 auto_randAUTO_RANDOM属性を表します。この識別子に対応する機能を実装する TiDB のバージョンのみが、SQL ステートメントのフラグメントを適切に解析できます。

この属性は、前方互換性、つまりダウングレード互換性をサポートします。この機能を実装していない以前のバージョンの TiDB は、テーブルのAUTO_RANDOM属性 (上記のコメント付き) を無視し、属性を持つテーブルを使用することもできます。

制限

AUTO_RANDOMを使用する場合は、次の制限に注意してください。

  • この属性は、 bigint型の主キー列のみに指定します。そうしないと、エラーが発生します。また、主キーの属性がNONCLUSTEREDの場合、整数の主キーでもAUTO_RANDOMはサポートされません。 CLUSTEREDタイプの主キーの詳細については、 クラスター化インデックスを参照してください。
  • この属性の追加または削除を含め、 ALTER TABLEを使用してAUTO_RANDOM属性を変更することはできません。
  • 最大値が列タイプの最大値に近い場合、 ALTER TABLEを使用してAUTO_INCREMENTからAUTO_RANDOMに変更することはできません。
  • AUTO_RANDOM属性で指定された主キー列の列型は変更できません。
  • 同じ列にAUTO_RANDOMAUTO_INCREMENTを同時に指定することはできません。
  • 同じ列にAUTO_RANDOMDEFAULT (列のデフォルト値) を同時に指定することはできません。
  • 列でAUTO_RANDOMを使用すると、自動生成された値が非常に大きくなる可能性があるため、列属性をAUTO_INCREMENTに戻すのは困難です。
  • データを挿入するときに、 AUTO_RANDOM属性を使用して列の値を明示的に指定することは勧めしません。そうしないと、このテーブルに自動的に割り当てられる数値が事前に使い果たされる可能性があります。