AUTO_RANDOM v3.1.0の新機能

ユーザーシナリオ

AUTO_RANDOMの値はランダムで一意であるため、TiDB が連続した ID を割り当てることによって発生する単一ストレージ ノードでの書き込みホットスポットを回避するために、 AUTO_INCREMENTの代わりにAUTO_RANDOMがよく使用されます。現在のAUTO_INCREMENT列が主キーで、タイプがBIGINTの場合、 ALTER TABLE t MODIFY COLUMN id BIGINT AUTO_RANDOM(5);ステートメントを実行してAUTO_INCREMENTからAUTO_RANDOMに切り替えることができます。

TiDB で同時書き込み負荷の高いワークロードを処理する方法の詳細については、 高度な同時書き込みのベスト プラクティスを参照してください。

基本概念

AUTO_RANDOMは、 BIGINT列に値を自動的に割り当てるために使用される列属性です。自動的に割り当てられる値はランダム一意です。

AUTO_RANDOM列のテーブルを作成するには、次のステートメントを使用できます。 AUTO_RANDOM列は主キーに含める必要があり、主キーにはAUTO_RANDOM列のみを含める必要があります。

CREATE TABLE t (a BIGINT AUTO_RANDOM, b VARCHAR(255), PRIMARY KEY (a)); CREATE TABLE t (a BIGINT PRIMARY KEY AUTO_RANDOM, b VARCHAR(255)); CREATE TABLE t (a BIGINT AUTO_RANDOM(6), b VARCHAR(255), PRIMARY KEY (a)); CREATE TABLE t (a BIGINT AUTO_RANDOM(5, 54), b VARCHAR(255), PRIMARY KEY (a));

実行可能なコメントでキーワードAUTO_RANDOMをラップできます。詳細については、 TiDB 固有のコメント構文を参照してください。

CREATE TABLE t (a bigint /*T![auto_rand] AUTO_RANDOM */, b VARCHAR(255), PRIMARY KEY (a)); CREATE TABLE t (a bigint PRIMARY KEY /*T![auto_rand] AUTO_RANDOM */, b VARCHAR(255)); CREATE TABLE t (a BIGINT /*T![auto_rand] AUTO_RANDOM(6) */, b VARCHAR(255), PRIMARY KEY (a)); CREATE TABLE t (a BIGINT /*T![auto_rand] AUTO_RANDOM(5, 54) */, b VARCHAR(255), PRIMARY KEY (a));

INSERTステートメントを実行すると、次のようになります。

  • AUTO_RANDOM列の値を明示的に指定すると、そのままテーブルに挿入されます。
  • AUTO_RANDOM列の値を明示的に指定しない場合、TiDB はランダムな値を生成し、それをテーブルに挿入します。
tidb> CREATE TABLE t (a BIGINT PRIMARY KEY AUTO_RANDOM, b VARCHAR(255)); Query OK, 0 rows affected, 1 warning (0.01 sec) tidb> INSERT INTO t(a, b) VALUES (1, 'string'); Query OK, 1 row affected (0.00 sec) tidb> SELECT * FROM t; +---+--------+ | a | b | +---+--------+ | 1 | string | +---+--------+ 1 row in set (0.01 sec) tidb> INSERT INTO t(b) VALUES ('string2'); Query OK, 1 row affected (0.00 sec) tidb> INSERT INTO t(b) VALUES ('string3'); Query OK, 1 row affected (0.00 sec) tidb> SELECT * FROM t; +---------------------+---------+ | a | b | +---------------------+---------+ | 1 | string | | 1152921504606846978 | string2 | | 4899916394579099651 | string3 | +---------------------+---------+ 3 rows in set (0.00 sec)

TiDB によって自動的に割り当てられるAUTO_RANDOM(S, R)列の値は、合計 64 ビットです。

  • Sはシャード ビットの数です。値の範囲は1から15です。デフォルト値は5です。
  • Rは自動割り当て範囲の全長です。値の範囲は32から64です。デフォルト値は64です。

AUTO_RANDOM値の構造は次のとおりです。

総ビット数符号ビット予約ビットシャードビット自動インクリメント ビット
64ビット0/1 ビット(64-R) ビットS ビット(R-1-S) ビット
  • 符号ビットの長さは、 UNSIGNED属性の存在によって決まります。 UNSIGNED属性がある場合、長さは0です。それ以外の場合、長さは1です。
  • 予約ビットの長さは64-Rです。予約ビットは常に0です。
  • シャード ビットの内容は、現在のトランザクションの開始時刻のハッシュ値を計算することによって取得されます。別の長さのシャード ビット (10 など) を使用するには、テーブルの作成時にAUTO_RANDOM(10)を指定します。
  • 自動インクリメント ビットの値は、ストレージ エンジンに格納され、順番に割り当てられます。新しい値が割り当てられるたびに、値は 1 ずつインクリメントされます。自動インクリメント ビットは、 AUTO_RANDOMの値がグローバルに一意であることを保証します。自動インクリメント ビットが使い果たされると、値が再度割り当てられるときにエラーFailed to read auto-increment value from storage engineが報告されます。

ノート:

シャード ビットの選択 ( S ):

  • 合計 64 の使用可能なビットがあるため、シャード ビット長は自動インクリメント ビット長に影響します。つまり、シャード ビットの長さが増加すると、自動インクリメント ビットの長さが減少し、逆もまた同様です。したがって、割り当てられた値のランダム性と使用可能なスペースのバランスを取る必要があります。
  • ベスト プラクティスは、シャード ビットをlog(2, x)に設定することです。ここで、 xはストレージ エンジンの現在の数です。たとえば、TiDB クラスターに 16 個の TiKV ノードがある場合、シャード ビットをlog(2, 16) 、つまり4に設定できます。すべてのリージョンが各 TiKV ノードに均等にスケジュールされた後、バルク書き込みの負荷を異なる TiKV ノードに均等に分散して、リソースの使用率を最大化できます。

範囲の選択 ( R ):

  • 通常、アプリケーションの数値型が完全な 64 ビット整数を表すことができない場合は、 Rパラメータを設定する必要があります。
  • たとえば、JSON 番号の範囲は[-2^53+1, 2^53-1]です。 TiDB は、この範囲外の整数をAUTO_RANDOM(5)の列に簡単に割り当てることができ、アプリケーションが列を読み取るときに予期しない動作を引き起こします。この場合、 AUTO_RANDOM(5)AUTO_RANDOM(5, 54)に置き換えることができ、TiDB は列に9007199254740991 (2^53-1) より大きい整数を割り当てません。

AUTO_RANDOM列に暗黙的に割り当てられた値はlast_insert_id()に影響します。 TiDB が最後に暗黙的に割り当てた ID を取得するには、 SELECT last_insert_id ()ステートメントを使用できます。

AUTO_RANDOM列のテーブルのシャード ビット数を表示するには、 SHOW CREATE TABLEステートメントを実行できます。また、 information_schema.tablesシステム テーブルのTIDB_ROW_ID_SHARDING_INFO列でPK_AUTO_RANDOM_BITS=xモードの値を確認できます。 xはシャード ビットの数です。

制限

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

  • 値を明示的に挿入するには、システム変数@@allow_auto_random_explicit_insertの値を1 (デフォルトでは0 ) に設定する必要があります。データを挿入するときに、属性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に戻すのは困難です。