テーブル作成時に、特定の数値列の値が重複せずに連番として保たれる必要がある場合、それが自動インクリメント列です。列の型を AUTO_INCREMENT と定義することで、MySQLテナント内で自動インクリメント列を作成できます。
自動インクリメント列について
自動インクリメント列のプロパティ
自動インクリメント列には、自動インクリメントの開始値、ステップサイズ、キャッシュサイズという3つの重要なプロパティがあり、以下の3つのテナント変数パラメータで制御されます。
システム変数 |
説明 |
|---|---|
| auto_increment_cache_size | グローバル変数で、自動インクリメントのキャッシュサイズを設定します。値の範囲は [1, 100000000] で、デフォルト値は 1000000 です。
説明OceanBaseデータベースでは、テーブル単位で |
| auto_increment_increment | セッション変数で、自動インクリメントのステップサイズを設定します。値の範囲は [1, 65535] で、デフォルト値は 1 です。 |
| auto_increment_offset | セッション変数で、AUTO_INCREMENT 列の値の開始点を決定します。値の範囲は [1, 65535] で、デフォルト値は 1 です。 |
システム変数の設定方法および説明については、パラメータとシステム変数の概要を参照してください。
自動インクリメント列のジャンプ
MySQLデータベースでは、自動インクリメント列はデータベーステーブルの列属性の一種であり、各行データの一意な識別子として使用される、一意で連番の値を自動的に生成します。OceanBaseデータベースは分散データベースであるため、そのテーブルは通常複数の異なるマシンに分散配置されます。MySQLデータベースとの互換性を可能な限り保ちつつ、分散マルチサイト環境における自動インクリメント列の生成パフォーマンスも保証する必要があります。その結果、自動インクリメント値の生成過程でジャンプが発生する問題が生じます。
OceanBaseデータベースでは、自動インクリメント列はNOORDERモードとORDERモードの2種類のモードをサポートしており、デフォルトはORDERモードです。詳細は以下の通りです。
ORDERモード:集中キャッシュに基づく自動インクリメント列です。このモードに設定すると、自動インクリメント列の値はグローバルに連番で増加します。
NOORDERモード:分散キャッシュに基づく自動インクリメント列です。このモードに設定すると、自動インクリメント列の値がグローバルに一意であることのみが保証されます。
以下では、これら2つのモードについて、それぞれどのようにして自動インクリメント値の生成過程でジャンプが発生するかを説明します。
NOORDERモード
OceanBaseデータベースV4.xバージョンでは、AUTO_INCREMENT_MODE = 'NOORDER' を指定して作成されたテーブル、およびV4.0.0(このバージョンを除く)以下のバージョンで作成されたすべての自動インクリメント列を含むテーブルは、NOORDERモードの自動インクリメントテーブルとなります。
NOORDERモードの自動インクリメント列について、その内部原理は以下の図のとおりです。

上記の図からわかるように、NOORDERモードの自動インクリメント列のデータ構造は、以下の2つの部分に分かれています:
内部テーブル:現在使用中の自動インクリメント値のポイントを永続化する役割を担います。
キャッシュ:内部構造に記録された一連の自動インクリメント値の区間であり、内部テーブルから取得します。
NOORDERモードの自動インクリメント列では、各OBServerノードが独立しており、各ノードは内部テーブルから自動インクリメント区間を取得してマシンキャッシュに記録することで、自動インクリメント値の生成を高速化できます。以下では、いくつかの典型的なシナリオを例に、NOORDERモードで自動インクリメント値にジャンプが発生する原因を説明します。
シナリオ1:複数のマシンとパーティションで自動インクリメント値を生成する場合
auto_increment_cache_size の値が100だと仮定します。パーティションテーブルが配置されているOBServerノードOBServer1、OBServer2、OBServer3が、それぞれ以下の順序で insert into values (null) リクエストを受信した場合、内部での処理ロジックは次のとおりです:
OBServer1は自身のキャッシュがないことを検出すると、内部テーブルから自動インクリメント区間[1,100]を取得し、自動インクリメント値1を生成します。
OBServer2は自身のキャッシュがないことを検出すると、内部テーブルから自動インクリメント区間[101,200]を取得し、自動インクリメント値101を生成します。
OBServer3は自身のキャッシュがないことを検出すると、内部テーブルから自動インクリメント区間[201,300]を取得し、自動インクリメント値201を生成します。
OBServer1はキャッシュ[2,100]を使用して自動インクリメント値2を生成します。
OBServer2はキャッシュ[102,200]を使用して自動インクリメント値102を生成します。
……
このように、テーブルへのデータ挿入順序は 1、101、201、2、102、... となり、自動インクリメント値が常にジャンプしていることがわかります。
シナリオ2:INSERT ステートメントで指定された最大値を挿入する場合
MySQLデータベースでは、自動インクリメントテーブルに明示的に指定値を挿入すると、その後生成される自動インクリメント値は、その値以上になりません。
OceanBaseデータベースの分散シナリオでは、指定値を挿入する際にその値が自動インクリメントテーブル内の他の値よりも大きい(つまり最大値である)場合、OBServerノード自身が現在最大値が挿入されたことを認識するだけでなく、他のOBServerノードや内部テーブルにも同期する必要があります。この同期処理は非常に時間がかかります。毎回最大値を指定するたびに同期操作を実行することを避けるため、システムは最大値を挿入する際に現在のキャッシュを破棄します。これにより、現在の値から次のキャッシュ値までの範囲で同期を行う必要がなくなります。
例えば、パーティションテーブルが配置されているOBServer1、OBServer2、OBServer3が、それぞれ以下の順序で明示的に指定された増分シーケンス(1, 2, 3, ...)のリクエストを受信した場合、そしてこれらのマシンにキャッシュが保存されていると仮定した場合:
OBServer1は値1を受信し、キャッシュ[1,100]を破棄して、内部テーブルから新しいキャッシュ区間[301,400]を取得し、101を同期値として内部テーブルおよび他のOBServerノードに同期します。
OBServer2は値2を受信し、現在のキャッシュ区間[101,200]の値よりも小さいことを確認して、操作を行いません。
OBServer3は値3を受信し、現在のキャッシュ区間[201,300]の値よりも小さいことを確認して、操作を行いません。
OBServer1は値4を受信し、現在のキャッシュ区間[301,400]の値よりも小さいことを確認して、操作を行いません。 ...
このように、一部の値を挿入した後、自動インクリメント列を使用してシーケンスを生成し続けると、自動インクリメント値にジャンプが発生します。例えば、OBServer1の最初の区間[1,100]は使用されず、直接301にジャンプします。
マルチマシン環境だけでなく、シングルマシン環境でも、指定された最大値を挿入すると、自動インクリメント値にジャンプが発生する問題が発生します。例:
自動インクリメント列を含むテーブル
t1を作成します。obclient> CREATE TABLE t1 (c1 int not null auto_increment) AUTO_INCREMENT_MODE='NOORDER';同時に、
auto_increment_cache_sizeの値は100に設定します。このテーブルに複数回データを挿入します。
obclient> INSERT INTO t1 VALUES(null);obclient> INSERT INTO t1 VALUES(3);obclient> INSERT INTO t1 VALUES(null);挿入が成功した後、テーブル内のデータを確認します。
obclient> SELECT * FROM t1;クエリ結果は次のとおりです:
+-----+ | c1 | +-----+ | 1 | | 3 | | 101 | +-----+クエリ結果によると、自動インクリメント列は3から101にジャンプしています。
シナリオ3:マシンの再起動またはダウン
自動インクリメント列のキャッシュはメモリ構造であり、OBServerノードのマシンが再起動またはダウンした場合、そのマシンで未使用のキャッシュ区間は内部テーブルに書き戻されません。これにより、未使用の区間は今後使用されなくなります。例えば、OBServer1上の初期の自動インクリメント列のキャッシュ区間が[1,100]で、自動インクリメント値1と2が生成されていると仮定します。この時、OBServer1がダウンした場合、再起動後、そのマシン上のキャッシュ区間は新しい区間[101,200]に変わり、次の自動インクリメント値は101となります。最終的な自動インクリメント値の順序は 1、2、101、... となり、ジャンプが発生します。
ORDERモード
NOORDERモードで述べたような、複数マシン・複数パーティションにおける自動インクリメント値の生成や**INSERTステートメントによる指定された最大値の挿入**といった一般的なユースケースで発生する自動インクリメント値のジャンプを回避するため、OceanBaseデータベースはV4.xバージョンからORDERモードの自動インクリメント列を新たに追加しました。このモードはテーブル作成後のデフォルトモードであり、MySQLデータベースとの互換性をより高めることができます。
ORDERモードの自動インクリメント列の内部原理は以下の図のとおりです。

NOORDERモードと比較して、ORDERモードの自動インクリメント列では、すべてのOBServerノードの中から現在のクラスタのLeaderを自動インクリメント列サービスのLeaderとして選出します。他のFollowerとなるOBServerノードは、RPCリクエストを送信することで、LeaderとなっているOBServerノードから自動インクリメント値を取得する必要があります。一方、LeaderとなっているOBServerノードは、内部テーブルから自動インクリメント区間を取得して、自動インクリメントキャッシュとして使用します。
例えば、同じく複数マシン・複数パーティションのシナリオにおいて、自動インクリメント列のauto_increment_cache_sizeを100と仮定します。パーティションテーブルが配置されているOBServerノードOBServer1、OBServer2、OBServer3がそれぞれ以下の順序でinsert into values (null)リクエストを受信した場合、内部での処理ロジックは以下のとおりです:
OBServer1は自身がLeaderではないことを検出し、OBServer2にRPCリクエストを送信します。OBServer2は内部テーブルから自動インクリメント区間[1,100]を取得し、OBServer1に自動インクリメント値1を返します。
OBServer2は自身がLeaderであり、キャッシュ区間[2,100]が存在することを確認し、直接自動インクリメント値2を生成します。
OBServer3は自身がLeaderではないことを検出し、OBServer2にRPCリクエストを送信します。OBServer2はキャッシュ区間[3,100]が存在することを確認し、OBServer3に自動インクリメント値3を返します。
……
これにより、ORDERモードでは、すべてのOBServerノードがLeaderから自動インクリメント値を取得するため、ほとんどの場合、単一マシンシナリオと同様に、システムは常に連続した自動インクリメント値のシーケンスを生成できます。しかし、並行性が高い複数マシンシナリオでは、ORDERモードのパフォーマンスはNOORDERモードよりも劣ります。
ORDERモードの自動インクリメント列では、複数マシン・複数パーティションにおける自動インクリメント値の生成や**INSERTステートメントによる指定された最大値の挿入**といったシナリオでの自動インクリメント値のジャンプ問題は解決されています。しかし、LeaderとなっているOBServerノードのマシンが再起動またはダウンした場合、またはリーダー切り替えが発生した場合、依然として自動インクリメント値のジャンプが発生する可能性があります。
シナリオ1:マシンの再起動またはダウン
ORDERモードでは、LeaderとなっているOBServerノードにメモリ上のキャッシュ区間が保存されます。LeaderとなっているOBServerノードのマシンが再起動またはダウンした場合、その区間内で未使用の自動インクリメント値は引き続き使用されず、新しいキャッシュ区間が使用されるため、自動インクリメント値にジャンプが発生します。
注意
このシナリオでは、自動インクリメント値のジャンプ問題は、LeaderとなっているOBServerノードのみが再起動またはダウンした場合に発生します。他のFollowerとなるOBServerノードはキャッシュを保存しないため、たとえダウンしても自動インクリメント値の連続性に影響はありません。
シナリオ2:リーダー切り替え
OBServer2上の初期の自動インクリメント列のキャッシュ区間が[1,100]であり、自動インクリメント値1と2が生成されていると仮定します。クラスタ内でリーダー切り替えが発生した場合、通常の処理ロジックに従って:
リーダーがOBServer1に切り替わり、OBServer1は内部テーブルから新しい自動インクリメント区間[101,200]を取得し、自動インクリメント値101と102の生成を続けます。
OBServer2のマシンが正常に再起動した後、再度OBServer2にリーダーが切り替わり、前回のキャッシュ区間[3,100]を使用して、自動インクリメント値3と4を生成します。
これにより、101から3にかけて自動インクリメント値が増加しない問題が発生しました。
上記のような往復リーダー切り替えによる自動インクリメント値の増加停止問題を回避するため、OceanBaseデータベースはリーダー切り替え時に、元のLeaderであったOBServerノード上のキャッシュ区間をクリアします。これにより、自動インクリメント値にジャンプが発生します。
自動インクリメント列の作成
テーブル作成時に自動インクリメント列を指定した場合、INSERT ステートメントでレコードを挿入する際にその列の値を指定する必要はありません。OceanBaseデータベースが自動的に値を設定します。
INSERT 時に自動インクリメント列の値を指定し、かつ SQL_MODE の値が NO_AUTO_VALUE_ON_ZERO に設定されていない場合、指定した値が 0 または現在の最大値より大きいとき、OceanBaseデータベースは自動インクリメント列の次の値で列を補完します。指定した値が現在の最大値より小さい場合、自動インクリメント列の次の値の計算には影響しません。
説明
SQL_MODE が NO_AUTO_VALUE_ON_ZERO に設定されている場合、列に INSERT する値が 0 のときに AUTO_INCREMENT を生成しないことを意味します。
t1テーブルを作成し、列制約を指定する
obclient> CREATE TABLE t1(id bigint not null auto_increment primary key, name varchar(50), gmt_create timestamp not null default current_timestamp);
Query OK, 0 rows affected
obclient> INSERT INTO t1(name) VALUES('A'),('B'),('C');
Query OK, 3 rows affected
obclient> SELECT * FROM t1;
+----+------+---------------------+
| id | name | gmt_create |
+----+------+---------------------+
| 1 | A | 2020-04-03 17:09:55 |
| 2 | B | 2020-04-03 17:09:55 |
| 3 | C | 2020-04-03 17:09:55 |
+----+------+---------------------+
3 rows in set
例では:
id列のデータ型をbigintと指定します。空値禁止 (
NOT NULL):制約された列の値がNULLであることを許可しません。auto_increment:自動インクリメント列を設定します。現在、整数型のデータ列(BOOL/BOOLEAN型を除く)のみを自動インクリメント列に設定できます。primary key:id列を主キー列に設定します。name varchar(50):name列に挿入できるデータ型は文字型(varchar)です。50は最大文字長を表します。id列を自動インクリメント列に設定しているため、INSERTステートメントでレコードを挿入する際には、自動インクリメント列の値を指定する必要はありません。OceanBaseデータベースがこの列に値を自動的に入力します。
t1テーブルに1件のデータを挿入し、自動インクリメント列の値を0に指定する
obclient> INSERT INTO t1(id, name) VALUES(0, 'D');
Query OK, 1 row affected
obclient> SELECT * FROM t1;
+----+------+---------------------+
| id | name | gmt_create |
+----+------+---------------------+
| 1 | A | 2021-12-17 14:21:53 |
| 2 | B | 2021-12-17 14:21:53 |
| 3 | C | 2021-12-17 14:21:53 |
| 4 | D | 2021-12-17 14:22:36 |
+----+------+---------------------+
例からわかるように、INSERT 時に自動インクリメント列の値を指定し、その値が 0 の場合、OceanBaseデータベースは自動インクリメント列の次の値で列の値を補完します。
t1テーブルに1件のデータを挿入し、自動インクリメント列の値を-1に指定する
obclient> INSERT INTO t1(id, name) VALUES(-1,'E');
Query OK, 1 row affected
obclient> SELECT * FROM t1;
+----+------+---------------------+
| id | name | gmt_create |
+----+------+---------------------+
| -1 | E | 2021-12-17 15:25:04 |
| 1 | A | 2021-12-17 14:21:53 |
| 2 | B | 2021-12-17 14:21:53 |
| 3 | C | 2021-12-17 14:21:53 |
| 4 | D | 2021-12-17 14:22:36 |
+----+------+---------------------+
5 rows in set
例の結果から、-1 は現在の自動インクリメント列の最大値より小さいため、自動インクリメント列の次の値の計算には影響しません。
t1テーブルに1件のデータを挿入し、自動インクリメント列の値を10に指定する
obclient> INSERT INTO t1(id, name) VALUES(10,'F');
Query OK, 1 row affected
obclient> SELECT * FROM t1;
+----+------+---------------------+
| id | name | gmt_create |
+----+------+---------------------+
| -1 | E | 2021-12-17 15:25:04 |
| 1 | A | 2021-12-17 14:21:53 |
| 2 | B | 2021-12-17 14:21:53 |
| 3 | C | 2021-12-17 14:21:53 |
| 4 | D | 2021-12-17 14:22:36 |
| 10 | F | 2021-12-17 15:33:28 |
+----+------+---------------------+
6 rows in set
数値10は現在の自動インクリメント列(id列)の最大値(4)より大きいため、テーブルt1にname列がGでid列の値を指定しない状態で再度1件のデータを挿入すると、OceanBaseデータベースは自動的に自動インクリメント列の値10の次の値を使用してid列の値を設定します。
クエリ結果は以下のとおりです:
obclient> INSERT INTO t1(name) VALUES('G');
Query OK, 1 row affected
obclient> SELECT * FROM t1;
+---------+------+---------------------+
| id | name | gmt_create |
+---------+------+---------------------+
| -1 | E | 2020-04-03 17:10:24 |
| 1 | A | 2020-04-03 17:09:55 |
| 2 | B | 2020-04-03 17:09:55 |
| 3 | C | 2020-04-03 17:09:55 |
| 4 | D | 2020-04-03 17:10:19 |
| 10 | F | 2020-04-03 17:10:29 |
| 11 | G | 2020-04-03 17:10:34 |
+---------+------+---------------------+
7 rows in set
通常列を自動インクリメント列に変更する
OceanBaseデータベースでは、テーブル作成後に、そのテーブル内の通常列を自動インクリメント列に変更できます。
構文は以下のとおりです:
obclient> ALTER TABLE table_name MODIFY column_name data_type AUTO_INCREMENT;
構文の使用方法:
table_name:変更対象のテーブル名。column_name:自動インクリメント列に変更する列名。data_type:変更対象の列のデータ型。説明
自動インクリメント列に変更する際には、同時にその列のデータ型も変更できますが、変更後のデータ型が自動インクリメントを許可するデータ型である必要があります。
データ型の詳細については、データ型の概要を参照してください。
例:
テーブル
tbl1を作成します。obclient> CREATE TABLE tbl1(id bigint(10));テーブル
tbl1の列を自動インクリメント列に変更します。obclient> ALTER TABLE tbl1 MODIFY id bigint(10) AUTO_INCREMENT;
自動インクリメント列のモードの設定と変更
テーブル作成時にテーブルレベルパラメータ AUTO_INCREMENT_MODE を使用して自動インクリメント列のモードを指定することができます。また、テーブル作成後にその中の自動インクリメント列のモードを変更することも可能です。さらに、テナントレベル構成パラメータ default_auto_increment_mode を使用して、テナント内のテーブルの自動インクリメント列のデフォルトモードを指定することもできます。
説明
テーブル作成時に自動インクリメントモードが指定されていない場合、テーブル作成後、システムは構成パラメータの自動インクリメントモードに従って指定します。この構成パラメータのデフォルトは ORDER です。
例:
テーブル作成時に自動インクリメントモードを指定する。
obclient> CREATE TABLE tbl2(id bigint(10) AUTO_INCREMENT PRIMARY KEY, name varchar(50)) AUTO_INCREMENT_MODE='NOORDER'; Query OK, 0 rows affected obclient> SHOW CREATE TABLE tbl2\G *************************** 1. row *************************** Table: tbl2 Create Table: CREATE TABLE `tbl2` ( `id` bigint(10) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) AUTO_INCREMENT = 1 AUTO_INCREMENT_MODE = 'NOORDER' DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 1 row in setテーブル作成後に、その中の自動インクリメント列のモードを変更する。
obclient> CREATE TABLE tbl2(id bigint(10) AUTO_INCREMENT PRIMARY KEY, name varchar(50)); Query OK, 0 rows affected obclient> SHOW CREATE TABLE tbl2\G *************************** 1. row *************************** Table: tbl2 Create Table: CREATE TABLE `tbl2` ( `id` bigint(10) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) AUTO_INCREMENT = 1 AUTO_INCREMENT_MODE = 'ORDER' DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 1 row in set obclient> ALTER TABLE tbl2 auto_increment_mode = 'NOORDER'; Query OK, 0 rows affected obclient> SHOW CREATE TABLE tbl2\G *************************** 1. row *************************** Table: tbl2 Create Table: CREATE TABLE `tbl2` ( `id` bigint(10) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) AUTO_INCREMENT = 1 AUTO_INCREMENT_MODE = 'NOORDER' DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 1 row in set構成パラメータを使用して、テナント内のテーブルの自動インクリメント列のデフォルトモードを指定する。
obclient> ALTER SYSTEM SET default_auto_increment_mode = 'ORDER'; Query OK, 0 rows affected obclient> CREATE TABLE tbl3(id bigint(10) AUTO_INCREMENT PRIMARY KEY, name varchar(50)); Query OK, 0 rows affected obclient> SHOW CREATE TABLE tbl3\G *************************** 1. row *************************** Table: tbl3 Create Table: CREATE TABLE `tbl3` ( `id` bigint(10) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) AUTO_INCREMENT = 1 AUTO_INCREMENT_MODE = 'ORDER' DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 1 row in set
自動インクリメントフィールドの値の変更
以下のSQLステートメントを使用して、テーブル内の自動インクリメント列の次の値を設定できます。値を増やすことも減らすこともできます。
ALTER TABLE table_name AUTO_INCREMENT [=] int_value;
ここで、table_name はテーブル名、int_value はテーブル内の自動インクリメント列の次の値です。
注意
テーブルの自動インクリメントフィールドの値を減らす場合、以下の点に注意してください:
テーブルに既存データが存在し、かつ自動インクリメント列の最大値が新しく指定された AUTO_INCREMENT 値以上である場合、新しい AUTO_INCREMENT 値は、テーブル内の自動インクリメント列の現在の最大値の次の値に自動的に調整されます。例えば、自動インクリメント列の現在の最大値が5、現在の AUTO_INCREMENT の値が8で、AUTO_INCREMENT を0から6の間の任意の値に設定した場合、ステートメントの実行後、実際の AUTO_INCREMENT 値は6に調整されます。
例
以下のSQLステートメントは、テーブルの自動インクリメント列の次の値を調整する方法を示しています。
自動インクリメント列の次の値を増やす。
テストテーブル
tbl1を作成します。obclient [test]> CREATE TABLE tbl1(id INT AUTO_INCREMENT, name VARCHAR(50));テーブル
tbl1の現在の自動インクリメントフィールドの値を確認します。obclient [test]> SHOW CREATE TABLE tbl1\G実行結果は次のとおりです:
*************************** 1. row *************************** Table: tbl1 Create Table: CREATE TABLE `tbl1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL ) AUTO_INCREMENT = 1 AUTO_INCREMENT_MODE = 'ORDER' DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 3 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 1 row in setテーブル
tbl1に5件のデータを挿入します。obclient [test]> INSERT INTO tbl1(name) VALUES('A1'),('A2'),('A3'),('A4'),('A5');実行結果は次のとおりです:
Query OK, 5 rows affected Records: 5 Duplicates: 0 Warnings: 0再度、テーブル
tbl1の現在の自動インクリメントフィールドの値を確認します。obclient [test]> SHOW CREATE TABLE tbl1\G実行結果は次のとおりです:
*************************** 1. row *************************** Table: tbl1 Create Table: CREATE TABLE `tbl1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL ) AUTO_INCREMENT = 6 AUTO_INCREMENT_MODE = 'ORDER' DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 3 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 1 row in setテーブル
tbl1の現在の自動インクリメント列の次の値を10に変更します。obclient [test]> ALTER TABLE tbl1 AUTO_INCREMENT = 10;再度、テーブル
tbl1の現在の自動インクリメントフィールドの値を確認します。obclient [test]> SHOW CREATE TABLE tbl1\G実行結果は次のとおりです:
*************************** 1. row *************************** Table: tbl1 Create Table: CREATE TABLE `tbl1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL ) AUTO_INCREMENT = 10 AUTO_INCREMENT_MODE = 'ORDER' DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 3 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 1 row in set
自動インクリメント列の次の値を減らす。
テーブル
tbl1の現在の自動インクリメント列の次の値を8に変更します。obclient [test]> ALTER TABLE tbl1 AUTO_INCREMENT = 8;テーブル
tbl1の現在の自動インクリメントフィールドの値を確認します。obclient [test]> SHOW CREATE TABLE tbl1\G実行結果は次のとおりです:
*************************** 1. row *************************** Table: tbl1 Create Table: CREATE TABLE `tbl1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL ) AUTO_INCREMENT = 8 AUTO_INCREMENT_MODE = 'ORDER' DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 3 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 1 row in setテーブル
tbl1の自動インクリメント列から4以下の値を削除します。obclient [test]> DELETE FROM tbl1 WHERE id <= 4;実行結果は次のとおりです:
Query OK, 4 rows affectedテーブル
tbl1のデータをクエリします。obclient [test]> SELECT * FROM tbl1;実行結果は次のとおりです:
+------+------+ | id | name | +------+------+ | 5 | A5 | +------+------+ 1 row in set以下のSQLステートメントを実行し、テーブル
tbl1の現在の自動インクリメント列の次の値を3に変更します。obclient [test]> ALTER TABLE tbl1 AUTO_INCREMENT = 3;実行結果は次のとおりです:
Query OK, 0 rows affected再度、テーブル
tbl1の現在の自動インクリメントフィールドの値を確認します。obclient [test]> SHOW CREATE TABLE tbl1\G実行結果は次のとおりです:
*************************** 1. row *************************** Table: tbl1 Create Table: CREATE TABLE `tbl1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL ) AUTO_INCREMENT = 6 AUTO_INCREMENT_MODE = 'ORDER' DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 3 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 1 row in set説明
クエリ結果から、
AUTO_INCREMENTの値が6であることがわかります。これは、テーブルの自動インクリメント列に既にデータが含まれており、現在の自動インクリメント列の最大値(5)が設定しようとしたより小さい値(3)を超えていたためです。そのため、自動インクリメント値を減らすコマンドの実行時にエラーは発生しませんでしたが、実際のAUTO_INCREMENT値は既存の最大自動インクリメント値の次の数、すなわち6に自動的に調整されました。