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列のテーブルを作成するには、次のステートメントを使用できます。3 列は主キーに含まれている必要があり、 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)) /*T! PRE_SPLIT_REGIONS=2 */ ;
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> SHOW CREATE TABLE t;
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t | CREATE TABLE `t` (
`a` bigint(20) NOT NULL /*T![auto_rand] AUTO_RANDOM(5) */,
`b` varchar(255) DEFAULT NULL,
PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T! PRE_SPLIT_REGIONS=2 */ |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
tidb> SHOW TABLE t REGIONS;
+-----------+-----------------------------+-----------------------------+-----------+-----------------+---------------------+------------+---------------+------------+----------------------+------------------+------------------------+------------------+
| REGION_ID | START_KEY | END_KEY | LEADER_ID | LEADER_STORE_ID | PEERS | SCATTERING | WRITTEN_BYTES | READ_BYTES | APPROXIMATE_SIZE(MB) | APPROXIMATE_KEYS | SCHEDULING_CONSTRAINTS | SCHEDULING_STATE |
+-----------+-----------------------------+-----------------------------+-----------+-----------------+---------------------+------------+---------------+------------+----------------------+------------------+------------------------+------------------+
| 62798 | t_158_ | t_158_r_2305843009213693952 | 62810 | 28 | 62811, 62812, 62810 | 0 | 151 | 0 | 1 | 0 | | |
| 62802 | t_158_r_2305843009213693952 | t_158_r_4611686018427387904 | 62803 | 1 | 62803, 62804, 62805 | 0 | 39 | 0 | 1 | 0 | | |
| 62806 | t_158_r_4611686018427387904 | t_158_r_6917529027641081856 | 62813 | 4 | 62813, 62814, 62815 | 0 | 160 | 0 | 1 | 0 | | |
| 9289 | t_158_r_6917529027641081856 | 78000000 | 48268 | 1 | 48268, 58951, 62791 | 0 | 10628 | 43639 | 2 | 7999 | | |
+-----------+-----------------------------+-----------------------------+-----------+-----------------+---------------------+------------+---------------+------------+----------------------+------------------+------------------------+------------------+
4 rows in set (0.00 sec)
TiDB によって自動的に割り当てられるAUTO_RANDOM(S, R)列の値の合計は 64 ビットです。
Sはシャードビットの数です。値の範囲は1から15です。デフォルト値は5です。Rは自動割り当て範囲の合計長です。値の範囲は32から64です。デフォルト値は64です。
符号付きビットを持つAUTO_RANDOM値の構造は次のとおりです。
| 符号付きビット | 予約ビット | 破片の断片 | 自動増分ビット |
|---|---|---|---|
| 1ビット | 64-Rビット | Sビット | R-1-Sビット |
符号付きビットのないAUTO_RANDOM値の構造は次のとおりです。
| 予約ビット | 破片の断片 | 自動増分ビット |
|---|---|---|
64-Rビット | Sビット | R-Sビット |
- 値に符号付きビットがあるかどうかは、対応する列に
UNSIGNED属性があるかどうかによって決まります。 - 符号ビットの長さは、
UNSIGNED属性の存在によって決まります。UNSIGNED属性がある場合、長さは0です。それ以外の場合、長さは1です。 - 予約ビットの長さは
64-Rです。予約ビットは常に0です。 - シャード ビットの内容は、現在のトランザクションの開始時刻のハッシュ値を計算することによって取得されます。異なる長さのシャード ビット (10 など) を使用するには、テーブルの作成時に
AUTO_RANDOM(10)指定します。 - 自動増分ビットの値はstorageエンジンに格納され、順番に割り当てられます。新しい値が割り当てられるたびに、値は 1 ずつ増加します。自動増分ビットにより、
AUTO_RANDOMの値がグローバルに一意であることが保証されます。自動増分ビットが使い果たされると、値が再度割り当てられるときにエラーFailed to read auto-increment value from storage engineが報告されます。 - 値の範囲: 最終的に生成される値の最大ビット数 = シャード ビット + 自動増分ビット。符号付き列の範囲は
[-(2^(R-1))+1, (2^(R-1))-1]で、符号なし列の範囲は[0, (2^R)-1]です。 AUTO_RANDOMPRE_SPLIT_REGIONSと一緒に使用できます。テーブルが正常に作成されると、PRE_SPLIT_REGIONSテーブル内のデータを2^(PRE_SPLIT_REGIONS)で指定された数のリージョンに事前に分割します。
注記:
シャードビットの選択(
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)に置き換え、符号なし列の場合はAUTO_RANDOM(5)をAUTO_RANDOM(5, 53)に置き換えて、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モードの値を確認することもできます。11 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)
IDの暗黙的な割り当てルール
TiDB は、 AUTO_INCREMENT列と同様にAUTO_RANDOM列に値を暗黙的に割り当てます。これらは、セッション レベルのシステム変数auto_increment_incrementおよびauto_increment_offsetによっても制御されます。暗黙的に割り当てられた値の自動増分ビット (ID) は、式(ID - auto_increment_offset) % auto_increment_increment == 0に従います。
制限
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に戻すことは困難です。