重复使用丢失的AUTO INCREMENT值

时间:2013-05-23 08:09:35

标签: mysql innodb

我尝试了解innodb关于重复使用AUTO_INCREMENT值序列中可能出现的间隙的确切行为。问题是,在我看来,我在文档中发现了两个相互矛盾的描述。

  1. http://dev.mysql.com/doc/refman/5.6/en/innodb-auto-increment-configurable.html
  2.   

    在所有锁定模式(0,1和2)中,如果生成了一个事务   自动递增值回滚,这些自动递增值为   “丢失”。为自动增量列生成一个值后   无论是否“INSERT-like”语句都无法回滚   已完成,以及是否已滚动包含的事务   背部。这些丢失的值不会被重复使用。

    2。 http://dev.mysql.com/doc/refman/5.6/en/innodb-restrictions.html

      

    当您重新启动MySQL服务器时,InnoDB可能会重用旧的值   是为AUTO_INCREMENT列生成但从未存储(即,   在已滚动的旧事务期间生成的值   回)。

    那些失去的价值观会被重复使用吗?如果它们在重新启动MYSQL服务器之后确实会被重用,那么考虑到InnoDB通过执行语句的等效来确定新的AUTO_INCREMENT值,怎么可能呢?

      

    SELECT MAX(ai_col)FROM t FOR UPDATE

2 个答案:

答案 0 :(得分:1)

第一种情况是正常行为和你期望的。

第二种情况是一个奇怪的案例。

假设我们为写入分配1024,但写入或事务未完成,因为MySQL已停止或崩溃。在某些情况下,会记录使用1024,因此接下来将分配1025。但是,有一个小窗口,其中未在表中记录1024的分配以进行启动。这解释了案例2.

此外,InnoDB实际上并没有为新的分配做一个真正的MAX(但是MyISAM)。它是等价的。它确实在启动时做到了

另见

更新

问题中的第一个链接(http://dev.mysql.com/doc/refman/5.6/en/innodb-auto-increment-traditional.html)解释了该行为。如果链接失效,请在下面选择引号:

  

如果为InnoDB表指定AUTO_INCREMENT列,则InnoDB数据字典中的表句柄包含一个称为自动增量计数器的特殊计数器,用于为列分配新值。此计数器仅存储在主存储器中,而不存储在磁盘上

因此,这是一个运行时的事情,数字与实际表分开增加。这解释了差距:新值的分配与编写它不同。

  

InnoDB使用以下算法初始化包含名为ai_col的AUTO_INCREMENT列的表t的自动递增计数器:在服务器启动后,对于第一次插入表t,InnoDB执行此语句的等效项: / p>

因此,由于服务器重启而成功分配但写入失败将被丢弃。

答案 1 :(得分:0)

我相信这意味着

  

如果生成自动增量值的事务回滚,   除非服务器重新启动,否则这些自动增量值将“丢失”   在需要生成任何进一步的自动增量值之前

我找不到确认此行为的权威参考,但以下测试似乎同意:

bash > mysql test

mysql > CREATE TABLE ai (id INT AUTO_INCREMENT PRIMARY KEY);
mysql > BEGIN;
mysql > INSERT INTO ai VALUES (NULL);
mysql > ROLLBACK;
mysql > BEGIN;
mysql > INSERT INTO ai VALUES (NULL);
mysql > COMMIT;
mysql > SELECT * FROM ai;
+----+
| id |
+----+
|  2 |
+----+
mysql > BEGIN;
mysql > INSERT INTO ai VALUES (NULL);
mysql > ROLLBACK;
mysql > -- expecting auto-increment value "3" to be "consumed"
mysql > quit;

bash > service mysql restart
bash > mysql test

mysql > BEGIN;
mysql > INSERT INTO ai VALUES (NULL);
mysql > COMMIT;
mysql > SELECT * FROM ai;
+----+
| id |
+----+
|  2 |
|  3 |
+----+