Hoo*_*cat 15 mysql autoincrement
我们有一个 MySQL 表,它有一个自动递增字段设置为 INT (11)。该表几乎存储了在应用程序中运行的作业列表。在应用程序生命周期中的任何给定时刻,该表很可能包含数千个条目或完全为空(即一切都已完成)。
该字段不是其他任何东西的外键。
自动增量似乎随机将自身重置为零,尽管我们实际上从未能够捕获重置。
问题变得很明显,因为我们看到自动增量字段增加到 600,000 条左右的记录,然后一段时间后自动增量字段似乎在低 1000 条记录中运行。
如果表为空,几乎就像自动增量会自行重置一样。
这可能吗?如果可能,我该如何关闭它或更改它的重置方式?
如果不是,有没有人解释它为什么会这样做?
谢谢!
Gre*_*mio 33
自增计数器仅存储在主内存中,而不存储在磁盘上。
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);
Run Code Online (Sandbox Code Playgroud)
这始终将最新的 transactionId 生成为表中的一行,而不会不必要地炸毁表。
希望能帮助其他可能遇到这种情况的人。
编辑(2018-04-18):
正如下面提到的 Finesse ,它的行为似乎已在 MySQL 8.0+ 中进行了修改。
https://dev.mysql.com/worklog/task/?id=6204
该工作日志中的措辞充其量是错误的,但是在那些较新版本中的 InnoDB 现在似乎支持跨重新启动的持久性 autoinc 值。
-格雷米奥