AUTO_RANDOM v3.1.0 の新機能
ユーザーシナリオ
AUTO_RANDOMの値はランダムで一意であるため、TiDB が連続する ID を割り当てることによって生じる単一storageノード内の書き込みホットスポットを避けるために、 AUTO_INCREMENTの代わりにAUTO_RANDOMがよく使用されます。現在のAUTO_INCREMENT列が主キーで、型がBIGINT場合、 ALTER TABLE t MODIFY COLUMN id BIGINT AUTO_RANDOM(5);ステートメントを実行してAUTO_INCREMENTからAUTO_RANDOMに切り替えることができます。
TiDB で同時書き込み負荷の高いワークロードを処理する方法の詳細については、 高度な同時書き込みのベスト プラクティスを参照してください。
テーブルの作成ステートメントのAUTO_RANDOM_BASEパラメータは、増分部分の初期値auto_randomを設定するために使用されます。このオプションは、内部インターフェイスの一部として考えることができます。このパラメータは無視して構いません。
基本概念
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));
CREATE TABLE t (a BIGINT AUTO_RANDOM(5, 54), b VARCHAR(255), PRIMARY KEY (a, b));
キーワード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)を指定します。 - 自動インクリメント ビットの値はstorageエンジンに保存され、順次割り当てられます。新しい値が割り当てられるたびに、値は 1 ずつ増分されます。自動インクリメント ビットにより、
AUTO_RANDOMの値がグローバルに一意であることが保証されます。自動インクリメント ビットが使い果たされると、値が再度割り当てられるときにエラーFailed to read auto-increment value from storage engineが報告されます。
ノート:
シャード ビットの選択 (
S):
- 利用可能なビットは合計 64 あるため、シャードのビット長は自動インクリメントのビット長に影響します。つまり、シャード ビットの長さが増加すると、自動インクリメント ビットの長さは減少し、その逆も同様です。したがって、割り当てられた値のランダム性と利用可能なスペースのバランスを取る必要があります。
- ベスト プラクティスは、シャード ビットを
log(2, x)に設定することです。ここで、xは現在のstorageエンジンの数です。たとえば、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ステートメントを実行します。 PK_AUTO_RANDOM_BITS=xモードの値は、 information_schema.tablesシステム テーブルのTIDB_ROW_ID_SHARDING_INFO列でも確認できます。 xはシャード ビットの数です。
AUTO_RANDOM列のテーブルを作成した後、 SHOW WARNINGSを使用して最大暗黙的割り当て時間を表示できます。
CREATE TABLE t (a BIGINT AUTO_RANDOM, b VARCHAR(255), PRIMARY KEY (a));
SHOW WARNINGS;
出力は次のとおりです。
+-------+------+---------------------------------------------------------+
| Level | Code | Message |
+-------+------+---------------------------------------------------------+
| Note | 1105 | Available implicit allocation times: 288230376151711743 |
+-------+------+---------------------------------------------------------+
1 row in set (0.00 sec)
制限
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_RANDOMとAUTO_INCREMENT同時に指定することはできません。 - 同じ列に
AUTO_RANDOMとDEFAULT(列のデフォルト値) を同時に指定することはできません。 - 列で
AUTO_RANDOMが使用されている場合、自動生成された値が非常に大きくなる可能性があるため、列属性をAUTO_INCREMENTに戻すのは困難です。