From de6e68085df4ddbd5a8a781f5c69d031ebcea3b0 Mon Sep 17 00:00:00 2001 From: Ran Date: Wed, 10 Jun 2020 21:29:13 +0800 Subject: [PATCH 1/5] add a doc for auto-increment attribute --- auto-increment.md | 209 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 auto-increment.md diff --git a/auto-increment.md b/auto-increment.md new file mode 100644 index 0000000000000..603e75873ad90 --- /dev/null +++ b/auto-increment.md @@ -0,0 +1,209 @@ +--- +title: AUTO_INCREMENT +summary: Learn the `AUTO_INCREMENT` column attribute of TiDB. +category: reference +--- + +# AUTO_INCREMENT + +This document introduces the `AUTO_INCREMENT` column attribute in terms of its concept, working principles, auto-increment feature and restrictions. + +## Concept + +`AUTO_INCREMENT` is a column attribute that is used to automatically fill in default column values. When the `INSERT` statement does not specify the value of the `AUTO_INCREMENT` column, the system automatically assign a value to this column. The value is unique as well as incremental and continuous in **special cases**. + +You can use it as follows: + +{{< copyable "sql" >}} + +```sql +create table t(id int primary key AUTO_INCREMENT, c int); +``` + +{{< copyable "sql" >}} + +```sql +insert into t(c) values (1); +insert into t(c) values (2); +insert into t(c) values (3), (4), (5); +``` + +```sql +mysql> select * from t; ++----+---+ +| id | c | ++----+---+ +| 1 | 1 | +| 2 | 2 | +| 3 | 3 | +| 4 | 4 | +| 5 | 5 | ++----+---+ +5 rows in set (0.01 sec) +``` + +In addition, `AUTO_INCREMENT` also supports the `INSERT` statements that explicitly specify column values. In such case, TiDB stores the explicitly specified values: + +{{< copyable "sql" >}} + +```sql +insert into t(id, c) values (6, 6); +``` + +```sql +mysql> select * from t; ++----+---+ +| id | c | ++----+---+ +| 1 | 1 | +| 2 | 2 | +| 3 | 3 | +| 4 | 4 | +| 5 | 5 | +| 6 | 6 | ++----+---+ +6 rows in set (0.01 sec) +``` + +The usage above is the same as that of `AUTO_INCREMENT` in MySQL. However, in terms of the specific value that is assigned implicitly, TiDB differs from MySQL significantly. + +## Working principles + +TiDB implements the `AUTO_INCREMENT` implicit assignment in the following way: + +For each auto-increment column, a globally visible key-value pair is used to record the maximum ID that has been assigned. In a distributed environment, communication between nodes has a certain amount of overhead. Therefore, to avoid the issue of write amplification, each TiDB node applies for a section of ID as a cache when ID is assigned, and then obtains the next section after the first section is used. TiDB nodes do not have to apply to the storage node for ID at each assigning. For example: + +```sql +create table t(id int unique key AUTO_INCREMENT, c int); +``` + +Assume that there are two TiDB instances, `A` and `B`, in the cluster. If you execute an `INSERT` statement for `t` to `A` and `B` respectively: + +```sql +insert into t (c) values (1) +``` + +Instance `A` might cache the auto-increment ID of `[1,30000]`, and instance `B` might cache the auto-increment ID of `[30001,60000]`. In the future `INSERT` statements, these cached ID of each instance will be assigned to the `AUTO_INCREMENT` column as the default value. + +## Features + +### Uniqueness + +> **Warning:** +> +> When the cluster has multiple TiDB instances, if the table schema contains the auto-increment ID, it is recommended not to use explicit insert and implicit insert together (i.e. using the default value of the auto-increment column and the custom value). Otherwise, it might break the uniqueness of implicitly assigned values. + +In the example above, take the following steps: + +1. The client inserts a statement `insert into t values (2, 1)` to instance `B`, which sets `id` to `2`. The statement is successfully executed. + +2. The client sends a statement `insert into t (c) (1)` to instance `A`. This statement does not specify the value of `id`, so the ID is assigned by `A`. At present, because `A` caches the ID of `[1, 30000]`, it might assign `2` as the value of the auto-increment ID, and increases the local counter by `1`. At this time, the data whose ID is `2` already exists in the database, so the `Duplicated Error` error is returned. + +### Increment + +TiDB guarantee that implicitly assigned value of the `AUTO_INCREMENT` column are incremental only in the cluster with a single TiDB instance. That is, for the same auto-increment column, the value assigned earlier is smaller than the value assigned later. However, in a cluster with multiple instances, TiDB cannot guarantee that the auto-increment column is incremental. + +In the example above, if you first execute an `INSERT` statement in instance `B`, and then execute an `INSERT` statement to instance `A`. According to the nature of the cached incremental ID, the auto-increment column might assign `30002` and `2` respectively. The assigned values are not incremental in the time order. + +### Continuity + +In a cluster with multiple TiDB instances, the `AUTO_INCREMENT` assigned values are **only** continuous in the batch insert statement. + +Take the following table as an example: + +```sql +create table t (a int primary key AUTO_INCREMENT) +``` + +Execute the following statement on the table: + +```sql +insert into t values (), (), (), () +``` + +Even if other TiDB instances are performing concurrent write operations, or if the current instance does not have enough cached IDs left, the assigned values are still continuous. + +### Relationship with `_tidb_rowid` + +If no primary key of integer type exists, TiDB uses `_tidb_rowid` to identify rows. `_tidb_rowid` uses the same allocator with the auto-increment column (if any). In such case, the cache size might be shared between `_tidb_rowid` and the auto-increment column. Therefore, the following situation might occur: + +```sql +mysql> create table t(id int unique key AUTO_INCREMENT); +Query OK, 0 rows affected (0.05 sec) + +mysql> insert into t values (),(),(); +Query OK, 3 rows affected (0.00 sec) +Records: 3 Duplicates: 0 Warnings: 0 + +mysql> select _tidb_rowid, id from t; ++-------------+------+ +| _tidb_rowid | id | ++-------------+------+ +| 4 | 1 | +| 5 | 2 | +| 6 | 3 | ++-------------+------+ +3 rows in set (0.01 sec) +``` + +### Case size control + +In earlier versions of TiDB, the cache size of the auto-increment ID was transparent to users. Starting from v3.0.14, v3.1.2, and v4.0.rc-2, TiDB has introduced the `AUTO_ID_CACHE` table option to allow users to set the cache size allocated to the auto-increment ID. + +```sql +mysql> create table t(a int auto_increment key) AUTO_ID_CACHE 100; +Query OK, 0 rows affected (0.02 sec) + +mysql> insert into t values(); +Query OK, 1 row affected (0.00 sec) +Records: 1 Duplicates: 0 Warnings: 0 + +mysql> select * from t; ++---+ +| a | ++---+ +| 1 | ++---+ +1 row in set (0.01 sec) +``` + +At this time, if you invalidate the auto-increment cache of this column and redo the implicit assignment, the results are as follows: + +```sql +mysql> delete from t; +Query OK, 1 row affected (0.01 sec) + +mysql> rename table t to t1; +Query OK, 0 rows affected (0.01 sec) + +mysql> insert into t1 values() +Query OK, 1 row affected (0.00 sec) + +mysql> select * from t; ++-----+ +| a | ++-----+ +| 101 | ++-----+ +1 row in set (0.00 sec) +``` + +The re-assigned value is `101`, which means the size of cache allocated to the auto-increment ID is `100`. + +In addition, when the length of consecutive IDs in a batch insert statement exceeds the length of `AUTO_ID_CACHE`, TiDB increases the cache size accordingly to ensure that the statement can be inserted normally. + +### Auto-increment step and offset setting + +Starting from v3.0.9 and v4.0.0-rc.1, similar to the behavior of MySQL, the value implicitly assigned by auto-increment columns is controlled by the `@@auto_increment_increment` and `@@auto_increment_offset` session variables. + +The value implicitly assigned by auto-increment columns (ID) satisfy the equation: `(ID - auto_increment_offset) % auto_increment_increment == 0`. + +## Restrictions + +Currently, `AUTO_INCREMENT` has the following restrictions when used in TiDB: + +- It must be defined on the column of the primary key or unique index. +- It must be defined on the column of `INTEGER`, `FLOAT`, or `DOUBLE` type. +- It cannot specify the same column as the `DEFAULT` value of the column. +- `ALTER TABLE` cannot be used to add the `AUTO_INCREMENT` attribute. +- `ALTER TABLE` can be used to remove the `AUTO_INCREMENT` attribute. However, starting from v2.1.18 and v3.0.4, TiDB uses the session variable `@@tidb_allow_remove_auto_inc` to control whether `ALTER TABLE MODIFY` or `ALTER TABLE CHANGE` can be used to remove the `AUTO_INCREMENT` attribute of a column. By default, `ALTER TABLE MODIFY` or `ALTER TABLE CHANGE`cannot remove the `AUTO_INCREMENT` attribute. From d55bdeebffc948cbbdbf09201d72a146915e81f5 Mon Sep 17 00:00:00 2001 From: Ran Date: Thu, 11 Jun 2020 14:34:59 +0800 Subject: [PATCH 2/5] update wording --- auto-increment.md | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/auto-increment.md b/auto-increment.md index 603e75873ad90..ca8a0a7f47975 100644 --- a/auto-increment.md +++ b/auto-increment.md @@ -6,13 +6,13 @@ category: reference # AUTO_INCREMENT -This document introduces the `AUTO_INCREMENT` column attribute in terms of its concept, working principles, auto-increment feature and restrictions. +This document introduces the `AUTO_INCREMENT` column attribute in terms of its concept, working principles, auto-increment related features, and restrictions. ## Concept -`AUTO_INCREMENT` is a column attribute that is used to automatically fill in default column values. When the `INSERT` statement does not specify the value of the `AUTO_INCREMENT` column, the system automatically assign a value to this column. The value is unique as well as incremental and continuous in **special cases**. +`AUTO_INCREMENT` is a column attribute that is used to automatically fill in default column values. When the `INSERT` statement does not specify the value of the `AUTO_INCREMENT` column, the system automatically assign a value to this column. The value is unique, as well as incremental and continuous in **special cases**. -You can use it as follows: +You can use it as in the following example: {{< copyable "sql" >}} @@ -42,7 +42,7 @@ mysql> select * from t; 5 rows in set (0.01 sec) ``` -In addition, `AUTO_INCREMENT` also supports the `INSERT` statements that explicitly specify column values. In such case, TiDB stores the explicitly specified values: +In addition, `AUTO_INCREMENT` also supports the `INSERT` statements that explicitly specify column values. In such cases, TiDB stores the explicitly specified values: {{< copyable "sql" >}} @@ -65,19 +65,19 @@ mysql> select * from t; 6 rows in set (0.01 sec) ``` -The usage above is the same as that of `AUTO_INCREMENT` in MySQL. However, in terms of the specific value that is assigned implicitly, TiDB differs from MySQL significantly. +The usage above is the same as that of `AUTO_INCREMENT` in MySQL. However, in terms of the specific value that is implicitly assigned, TiDB differs from MySQL significantly. ## Working principles TiDB implements the `AUTO_INCREMENT` implicit assignment in the following way: -For each auto-increment column, a globally visible key-value pair is used to record the maximum ID that has been assigned. In a distributed environment, communication between nodes has a certain amount of overhead. Therefore, to avoid the issue of write amplification, each TiDB node applies for a section of ID as a cache when ID is assigned, and then obtains the next section after the first section is used. TiDB nodes do not have to apply to the storage node for ID at each assigning. For example: +For each auto-increment column, a globally visible key-value pair is used to record the maximum ID that has been assigned. In a distributed environment, communication between nodes has some overhead. Therefore, to avoid the issue of write amplification, each TiDB node applies for a batch of consecutive IDs as cache when assigning IDs, and then applies for the next batch of IDs after the first batched is assigned. TiDB nodes do not have to apply to the storage node for IDs at each assigning. For example: ```sql create table t(id int unique key AUTO_INCREMENT, c int); ``` -Assume that there are two TiDB instances, `A` and `B`, in the cluster. If you execute an `INSERT` statement for `t` to `A` and `B` respectively: +Assume two TiDB instances, `A` and `B`, in the cluster. If you execute an `INSERT` statement for the `t` table on `A` and `B` respectively: ```sql insert into t (c) values (1) @@ -85,15 +85,15 @@ insert into t (c) values (1) Instance `A` might cache the auto-increment ID of `[1,30000]`, and instance `B` might cache the auto-increment ID of `[30001,60000]`. In the future `INSERT` statements, these cached ID of each instance will be assigned to the `AUTO_INCREMENT` column as the default value. -## Features +## Basic Features ### Uniqueness > **Warning:** > -> When the cluster has multiple TiDB instances, if the table schema contains the auto-increment ID, it is recommended not to use explicit insert and implicit insert together (i.e. using the default value of the auto-increment column and the custom value). Otherwise, it might break the uniqueness of implicitly assigned values. +> When the cluster has multiple TiDB instances, if the table schema contains the auto-increment ID, it is recommended not to use explicit insert and implicit assignment at the same time (i.e. using the default value of the auto-increment column and the custom value). Otherwise, it might break the uniqueness of implicitly assigned values. -In the example above, take the following steps: +In the example above, perform the following operations in order: 1. The client inserts a statement `insert into t values (2, 1)` to instance `B`, which sets `id` to `2`. The statement is successfully executed. @@ -101,9 +101,9 @@ In the example above, take the following steps: ### Increment -TiDB guarantee that implicitly assigned value of the `AUTO_INCREMENT` column are incremental only in the cluster with a single TiDB instance. That is, for the same auto-increment column, the value assigned earlier is smaller than the value assigned later. However, in a cluster with multiple instances, TiDB cannot guarantee that the auto-increment column is incremental. +TiDB guarantees that implicitly assigned value of the `AUTO_INCREMENT` column are incremental only in the cluster with a single TiDB instance. That is, for the same auto-increment column, the value assigned earlier is smaller than the value assigned later. However, in a cluster with multiple instances, TiDB cannot guarantee that the auto-increment column is incremental. -In the example above, if you first execute an `INSERT` statement in instance `B`, and then execute an `INSERT` statement to instance `A`. According to the nature of the cached incremental ID, the auto-increment column might assign `30002` and `2` respectively. The assigned values are not incremental in the time order. +In the example above, if you first execute an `INSERT` statement in instance `B`, and then execute an `INSERT` statement in instance `A`. Because of the principle of caching auto-increment ID, the auto-increment column might implicitly assign `30002` and `2` respectively. The assigned values are not incremental in the time order. ### Continuity @@ -125,7 +125,7 @@ Even if other TiDB instances are performing concurrent write operations, or if t ### Relationship with `_tidb_rowid` -If no primary key of integer type exists, TiDB uses `_tidb_rowid` to identify rows. `_tidb_rowid` uses the same allocator with the auto-increment column (if any). In such case, the cache size might be shared between `_tidb_rowid` and the auto-increment column. Therefore, the following situation might occur: +If no primary key of integer type exists, TiDB uses `_tidb_rowid` to identify rows. `_tidb_rowid` uses the same allocator with the auto-increment column (if any). In such cases, the cache size might be shared between `_tidb_rowid` and the auto-increment column. Therefore, you might encounter the following situation: ```sql mysql> create table t(id int unique key AUTO_INCREMENT); @@ -146,7 +146,7 @@ mysql> select _tidb_rowid, id from t; 3 rows in set (0.01 sec) ``` -### Case size control +### Cache size control In earlier versions of TiDB, the cache size of the auto-increment ID was transparent to users. Starting from v3.0.14, v3.1.2, and v4.0.rc-2, TiDB has introduced the `AUTO_ID_CACHE` table option to allow users to set the cache size allocated to the auto-increment ID. @@ -167,7 +167,7 @@ mysql> select * from t; 1 row in set (0.01 sec) ``` -At this time, if you invalidate the auto-increment cache of this column and redo the implicit assignment, the results are as follows: +At this time, if you invalidate the auto-increment cache of this column and redo the implicit assignment, the result is as follows: ```sql mysql> delete from t; @@ -190,13 +190,15 @@ mysql> select * from t; The re-assigned value is `101`, which means the size of cache allocated to the auto-increment ID is `100`. -In addition, when the length of consecutive IDs in a batch insert statement exceeds the length of `AUTO_ID_CACHE`, TiDB increases the cache size accordingly to ensure that the statement can be inserted normally. +In addition, when the length of consecutive IDs in a batch insert statement exceeds the length of `AUTO_ID_CACHE`, TiDB increases the cache size accordingly to ensure that the statement can be inserted properly. -### Auto-increment step and offset setting +### Auto-increment step and offset Starting from v3.0.9 and v4.0.0-rc.1, similar to the behavior of MySQL, the value implicitly assigned by auto-increment columns is controlled by the `@@auto_increment_increment` and `@@auto_increment_offset` session variables. -The value implicitly assigned by auto-increment columns (ID) satisfy the equation: `(ID - auto_increment_offset) % auto_increment_increment == 0`. +The value (ID) implicitly assigned by auto-increment columns satisfies the following equation: + +`(ID - auto_increment_offset) % auto_increment_increment == 0` ## Restrictions @@ -204,6 +206,6 @@ Currently, `AUTO_INCREMENT` has the following restrictions when used in TiDB: - It must be defined on the column of the primary key or unique index. - It must be defined on the column of `INTEGER`, `FLOAT`, or `DOUBLE` type. -- It cannot specify the same column as the `DEFAULT` value of the column. +- It cannot be specified on the same column as the `DEFAULT` column. - `ALTER TABLE` cannot be used to add the `AUTO_INCREMENT` attribute. - `ALTER TABLE` can be used to remove the `AUTO_INCREMENT` attribute. However, starting from v2.1.18 and v3.0.4, TiDB uses the session variable `@@tidb_allow_remove_auto_inc` to control whether `ALTER TABLE MODIFY` or `ALTER TABLE CHANGE` can be used to remove the `AUTO_INCREMENT` attribute of a column. By default, `ALTER TABLE MODIFY` or `ALTER TABLE CHANGE`cannot remove the `AUTO_INCREMENT` attribute. From f854bb78f2bdda67fcb3f7167df6ec66ea0a59e7 Mon Sep 17 00:00:00 2001 From: Ran Date: Thu, 11 Jun 2020 14:40:54 +0800 Subject: [PATCH 3/5] Update TOC.md --- TOC.md | 1 + 1 file changed, 1 insertion(+) diff --git a/TOC.md b/TOC.md index e386ef62acb81..8f57b43e3cb5b 100644 --- a/TOC.md +++ b/TOC.md @@ -188,6 +188,7 @@ + SQL + SQL Language Structure and Syntax + Attributes + + [AUTO_INCREMENT](/auto-increment.md) + [AUTO_RANDOM](/auto-random.md) + [Literal Values](/literal-values.md) + [Schema Object Names](/schema-object-names.md) From 722788f1098692f482a365be3e488c46ac8fb28a Mon Sep 17 00:00:00 2001 From: Ran Date: Fri, 12 Jun 2020 10:41:35 +0800 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: tangenta --- auto-increment.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/auto-increment.md b/auto-increment.md index ca8a0a7f47975..2d1a051a41682 100644 --- a/auto-increment.md +++ b/auto-increment.md @@ -167,7 +167,7 @@ mysql> select * from t; 1 row in set (0.01 sec) ``` -At this time, if you invalidate the auto-increment cache of this column and redo the implicit assignment, the result is as follows: +At this time, if you invalidate the auto-increment cache of this column and redo the implicit insertion, the result is as follows: ```sql mysql> delete from t; @@ -188,7 +188,7 @@ mysql> select * from t; 1 row in set (0.00 sec) ``` -The re-assigned value is `101`, which means the size of cache allocated to the auto-increment ID is `100`. +The re-assigned value is `101`. This shows that the size of cache allocated to the auto-increment ID is `100`. In addition, when the length of consecutive IDs in a batch insert statement exceeds the length of `AUTO_ID_CACHE`, TiDB increases the cache size accordingly to ensure that the statement can be inserted properly. From 57caa8375b9e753315bea18de1f47deb6bc46c64 Mon Sep 17 00:00:00 2001 From: Ran Date: Mon, 15 Jun 2020 10:35:27 +0800 Subject: [PATCH 5/5] Apply suggestions from code review Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- auto-increment.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/auto-increment.md b/auto-increment.md index 2d1a051a41682..8d1a66d8528e5 100644 --- a/auto-increment.md +++ b/auto-increment.md @@ -6,11 +6,11 @@ category: reference # AUTO_INCREMENT -This document introduces the `AUTO_INCREMENT` column attribute in terms of its concept, working principles, auto-increment related features, and restrictions. +This document introduces the `AUTO_INCREMENT` column attribute, including its concept, implementation principles, auto-increment related features, and restrictions. ## Concept -`AUTO_INCREMENT` is a column attribute that is used to automatically fill in default column values. When the `INSERT` statement does not specify the value of the `AUTO_INCREMENT` column, the system automatically assign a value to this column. The value is unique, as well as incremental and continuous in **special cases**. +`AUTO_INCREMENT` is a column attribute that is used to automatically fill in default column values. When the `INSERT` statement does not specify values for the `AUTO_INCREMENT` column, the system automatically assigns values to this column. Each value is unique, as well as incremental and continuous in **special cases**. You can use it as in the following example: @@ -67,23 +67,23 @@ mysql> select * from t; The usage above is the same as that of `AUTO_INCREMENT` in MySQL. However, in terms of the specific value that is implicitly assigned, TiDB differs from MySQL significantly. -## Working principles +## Implementation principles TiDB implements the `AUTO_INCREMENT` implicit assignment in the following way: -For each auto-increment column, a globally visible key-value pair is used to record the maximum ID that has been assigned. In a distributed environment, communication between nodes has some overhead. Therefore, to avoid the issue of write amplification, each TiDB node applies for a batch of consecutive IDs as cache when assigning IDs, and then applies for the next batch of IDs after the first batched is assigned. TiDB nodes do not have to apply to the storage node for IDs at each assigning. For example: +For each auto-increment column, a globally visible key-value pair is used to record the maximum ID that has been assigned. In a distributed environment, communication between nodes has some overhead. Therefore, to avoid the issue of write amplification, each TiDB node applies for a batch of consecutive IDs as caches when assigning IDs, and then applies for the next batch of IDs after the first batch is assigned. Therefore, TiDB nodes do not apply to the storage node for IDs when assigning IDs each time. For example: ```sql create table t(id int unique key AUTO_INCREMENT, c int); ``` -Assume two TiDB instances, `A` and `B`, in the cluster. If you execute an `INSERT` statement for the `t` table on `A` and `B` respectively: +Assume two TiDB instances, `A` and `B`, in the cluster. If you execute an `INSERT` statement on the `t` table on `A` and `B` respectively: ```sql insert into t (c) values (1) ``` -Instance `A` might cache the auto-increment ID of `[1,30000]`, and instance `B` might cache the auto-increment ID of `[30001,60000]`. In the future `INSERT` statements, these cached ID of each instance will be assigned to the `AUTO_INCREMENT` column as the default value. +Instance `A` might cache the auto-increment IDs of `[1,30000]`, and instance `B` might cache the auto-increment IDs of `[30001,60000]`. In `INSERT` statements to be executed, these cached IDs of each instance will be assigned to the `AUTO_INCREMENT` column as the default values. ## Basic Features @@ -91,19 +91,19 @@ Instance `A` might cache the auto-increment ID of `[1,30000]`, and instance `B` > **Warning:** > -> When the cluster has multiple TiDB instances, if the table schema contains the auto-increment ID, it is recommended not to use explicit insert and implicit assignment at the same time (i.e. using the default value of the auto-increment column and the custom value). Otherwise, it might break the uniqueness of implicitly assigned values. +> When the cluster has multiple TiDB instances, if the table schema contains the auto-increment IDs, it is recommended not to use explicit insert and implicit assignment at the same time, which means using the default values of the auto-increment column and the custom values. Otherwise, it might break the uniqueness of implicitly assigned values. In the example above, perform the following operations in order: 1. The client inserts a statement `insert into t values (2, 1)` to instance `B`, which sets `id` to `2`. The statement is successfully executed. -2. The client sends a statement `insert into t (c) (1)` to instance `A`. This statement does not specify the value of `id`, so the ID is assigned by `A`. At present, because `A` caches the ID of `[1, 30000]`, it might assign `2` as the value of the auto-increment ID, and increases the local counter by `1`. At this time, the data whose ID is `2` already exists in the database, so the `Duplicated Error` error is returned. +2. The client sends a statement `insert into t (c) (1)` to instance `A`. This statement does not specify the value of `id`, so the ID is assigned by `A`. At present, because `A` caches the IDs of `[1, 30000]`, it might assign `2` as the value of the auto-increment ID, and increases the local counter by `1`. At this time, the data whose ID is `2` already exists in the database, so the `Duplicated Error` error is returned. ### Increment -TiDB guarantees that implicitly assigned value of the `AUTO_INCREMENT` column are incremental only in the cluster with a single TiDB instance. That is, for the same auto-increment column, the value assigned earlier is smaller than the value assigned later. However, in a cluster with multiple instances, TiDB cannot guarantee that the auto-increment column is incremental. +TiDB guarantees that implicitly assigned values of the `AUTO_INCREMENT` column are incremental only in the cluster with a single TiDB instance. That is, for the same auto-increment column, the value assigned earlier is smaller than the value assigned later. However, in a cluster with multiple instances, TiDB cannot guarantee that the auto-increment column is incremental. -In the example above, if you first execute an `INSERT` statement in instance `B`, and then execute an `INSERT` statement in instance `A`. Because of the principle of caching auto-increment ID, the auto-increment column might implicitly assign `30002` and `2` respectively. The assigned values are not incremental in the time order. +In the example above, if you first execute an `INSERT` statement on instance `B`, and then execute an `INSERT` statement on instance `A`. Because of the behavior of caching auto-increment ID, the auto-increment column might be implicitly assigned `30002` and `2` respectively. The assigned values are not incremental in the time order. ### Continuity @@ -123,9 +123,9 @@ insert into t values (), (), (), () Even if other TiDB instances are performing concurrent write operations, or if the current instance does not have enough cached IDs left, the assigned values are still continuous. -### Relationship with `_tidb_rowid` +### Relation with `_tidb_rowid` -If no primary key of integer type exists, TiDB uses `_tidb_rowid` to identify rows. `_tidb_rowid` uses the same allocator with the auto-increment column (if any). In such cases, the cache size might be shared between `_tidb_rowid` and the auto-increment column. Therefore, you might encounter the following situation: +If the primary key of integer type does not exist, TiDB uses `_tidb_rowid` to identify rows. `_tidb_rowid` and the auto-increment column (if any) share an allocator. In such cases, the cache size might be consumed by both `_tidb_rowid` and the auto-increment column. Therefore, you might encounter the following situation: ```sql mysql> create table t(id int unique key AUTO_INCREMENT); @@ -148,7 +148,7 @@ mysql> select _tidb_rowid, id from t; ### Cache size control -In earlier versions of TiDB, the cache size of the auto-increment ID was transparent to users. Starting from v3.0.14, v3.1.2, and v4.0.rc-2, TiDB has introduced the `AUTO_ID_CACHE` table option to allow users to set the cache size allocated to the auto-increment ID. +In earlier versions of TiDB, the cache size of the auto-increment ID was transparent to users. Starting from v3.0.14, v3.1.2, and v4.0.rc-2, TiDB has introduced the `AUTO_ID_CACHE` table option to allow users to set the cache size for allocating the auto-increment ID. ```sql mysql> create table t(a int auto_increment key) AUTO_ID_CACHE 100; @@ -188,15 +188,15 @@ mysql> select * from t; 1 row in set (0.00 sec) ``` -The re-assigned value is `101`. This shows that the size of cache allocated to the auto-increment ID is `100`. +The re-assigned value is `101`. This shows that the size of cache for allocating the auto-increment ID is `100`. -In addition, when the length of consecutive IDs in a batch insert statement exceeds the length of `AUTO_ID_CACHE`, TiDB increases the cache size accordingly to ensure that the statement can be inserted properly. +In addition, when the length of consecutive IDs in a batch `insert` statement exceeds the length of `AUTO_ID_CACHE`, TiDB increases the cache size accordingly to ensure that the statement can be inserted properly. -### Auto-increment step and offset +### Auto-increment step size and offset -Starting from v3.0.9 and v4.0.0-rc.1, similar to the behavior of MySQL, the value implicitly assigned by auto-increment columns is controlled by the `@@auto_increment_increment` and `@@auto_increment_offset` session variables. +Starting from v3.0.9 and v4.0.0-rc.1, similar to the behavior of MySQL, the value implicitly assigned to the auto-increment column is controlled by the `@@auto_increment_increment` and `@@auto_increment_offset` session variables. -The value (ID) implicitly assigned by auto-increment columns satisfies the following equation: +The value (ID) implicitly assigned to auto-increment columns satisfies the following equation: `(ID - auto_increment_offset) % auto_increment_increment == 0` @@ -206,6 +206,6 @@ Currently, `AUTO_INCREMENT` has the following restrictions when used in TiDB: - It must be defined on the column of the primary key or unique index. - It must be defined on the column of `INTEGER`, `FLOAT`, or `DOUBLE` type. -- It cannot be specified on the same column as the `DEFAULT` column. +- It cannot be specified on the same column with the `DEFAULT` column value. - `ALTER TABLE` cannot be used to add the `AUTO_INCREMENT` attribute. -- `ALTER TABLE` can be used to remove the `AUTO_INCREMENT` attribute. However, starting from v2.1.18 and v3.0.4, TiDB uses the session variable `@@tidb_allow_remove_auto_inc` to control whether `ALTER TABLE MODIFY` or `ALTER TABLE CHANGE` can be used to remove the `AUTO_INCREMENT` attribute of a column. By default, `ALTER TABLE MODIFY` or `ALTER TABLE CHANGE`cannot remove the `AUTO_INCREMENT` attribute. +- `ALTER TABLE` can be used to remove the `AUTO_INCREMENT` attribute. However, starting from v2.1.18 and v3.0.4, TiDB uses the session variable `@@tidb_allow_remove_auto_inc` to control whether `ALTER TABLE MODIFY` or `ALTER TABLE CHANGE` can be used to remove the `AUTO_INCREMENT` attribute of a column. By default, you cannot use `ALTER TABLE MODIFY` or `ALTER TABLE CHANGE` to remove the `AUTO_INCREMENT` attribute.