自动增量计数器仅存储在主存储器中,而不存储在磁盘上。
http://dev.mysql.com/doc/refman/4.1/en/innodb-auto-increment-handling.html
因此,当服务(或服务器)重新启动时,将发生以下情况:
服务器启动后,对于第一次插入到表t中,InnoDB执行以下语句的等效项:SELECT MAX(ai_col)FROM t FOR UPDATE;
InnoDB将语句检索的值加1,然后将其分配给列和表的自动递增计数器。如果表为空,则InnoDB使用值1。
因此,以通俗的英语来说,在MySQL服务启动之后,它不知道表的自动增量值应该是多少。因此,当您第一次插入一行时,它会找到使用自动增量的字段的最大值,在该值上加1,然后使用结果值。如果没有行,它将从1开始。
这对我们来说是个问题,因为我们正在使用表和mysql的自动增量功能在多线程环境中整齐地管理ID,在该环境中,用户被重定向到第三方付款站点。因此,我们必须确保第三方获取并发送回给我们的ID是唯一的,并且将保持这种方式(当然,用户重定向后,用户有可能取消交易)。
因此,我们要创建一行,获取生成的自动增量值,删除该行以保持表整洁,然后将该值转发到支付站点。为了解决InnoDB处理AI值的方式问题,我们最终做了以下工作:
$query = "INSERT INTO transactions_counter () VALUES ();";
mysql_query($query);
$transactionId = mysql_insert_id();
$previousId = $transactionId - 1;
$query = "DELETE FROM transactions_counter WHERE transactionId='$previousId';";
mysql_query($query);
这始终将最新生成的transactionId保留为表中的一行,而不会不必要地破坏该表。
希望对其他可能遇到此问题的人有所帮助。
编辑(2018-04-18):
正如下面的Finesse所述,它的行为似乎已在MySQL 8.0+中进行了修改。
https://dev.mysql.com/worklog/task/?id=6204
该工作日志中的措词充其量是错误的,但是,在那些较新版本中的InnoDB现在似乎在重新启动后支持持久的autoinc值。
-格雷米奥