Bug #92662 autoinc counter does not respect auto_increment_offset in some cases
Submitted: 3 Oct 2018 21:45 Modified: 4 Oct 2018 12:45
Reporter: Trey Raymond Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: DDL Severity:S3 (Non-critical)
Version:5.7.21,5.7.23, 5.6.41, 8.0.12 OS:Any
Assigned to: CPU Architecture:Any
Tags: auto_increment

[3 Oct 2018 21:45] Trey Raymond
Description:
In some cases, a table's AUTO_INCREMENT counter value will be set to [previous value + 1] when auto_increment_increment is set to larger than one.

See test case below, which has comments for each case, first test shows that inserting a value explicitly sets it incorrectly, second test shows that resetting it to auto detected value (alter table auto_increment=1) also fails, third test shows that it updates correctly when letting the sequence generate the value on a new insert (the main expected operation).

This is lower severity because actual inserts do check and pick the next valid value to write if the one in the sequence counter is wrong, as shown by the write between cases 2 and 3, but anything reading table metadata will get this odd impossible value for its auto increment counter.

How to repeat:
mysql> select @@global.auto_increment_offset,@@global.auto_increment_increment;
+--------------------------------+-----------------------------------+
| @@global.auto_increment_offset | @@global.auto_increment_increment |
+--------------------------------+-----------------------------------+
|                              3 |                                10 |
+--------------------------------+-----------------------------------+
1 row in set (0.00 sec)

mysql> create table test (id int unsigned not null auto_increment primary key);
Query OK, 0 rows affected (0.01 sec)

mysql> insert into test set id=10000+@@global.auto_increment_offset;
Query OK, 1 row affected (0.00 sec)

mysql> select * from test;
+-------+
| id    |
+-------+
| 10003 |
+-------+
1 row in set (0.00 sec)

mysql> show create table test\G
*************************** 1. row ***************************
       Table: test
Create Table: CREATE TABLE `test` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10004 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql> /* that should say AUTO_INCREMENT=10013 */
mysql>
mysql>
mysql> update test set id=5000+@@global.auto_increment_offset;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> alter table test auto_increment=1;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> select * from test;
+------+
| id   |
+------+
| 5003 |
+------+
1 row in set (0.00 sec)

mysql> show create table test\G
*************************** 1. row ***************************
       Table: test
Create Table: CREATE TABLE `test` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5004 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql> /* that should say AUTO_INCREMENT=10013 */
mysql>
mysql>
mysql> insert into test set id=null;
Query OK, 1 row affected (0.00 sec)

mysql> select * from test;
+------+
| id   |
+------+
| 5003 |
| 5013 |
+------+
2 rows in set (0.00 sec)

mysql> /* the insert does get the correct value vs using the table's counter, which is good */
mysql>
mysql>

mysql> show create table test\G
*************************** 1. row ***************************
       Table: test
Create Table: CREATE TABLE `test` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5023 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql> /* that time it is correct */
mysql>
mysql>

Suggested fix:
for anything that updates the counter, ensure it sets a possible value, by including increment/offset the way normal inserts do.
[4 Oct 2018 12:45] MySQL Verification Team
Hello Trey Raymond,

Thank you for the report and test case.

regards,
Umesh