如果 INSERT 失败,MySQL 5.1 和更高版本中的默认 auto_increment 行为将“丢失”自动增量值。也就是说,它每次递增 1,但如果 INSERT 失败,则不会撤消递增。丢失约 750 个值并不常见,但并非不可能(我咨询了一个站点,该站点为每个成功的 INSERT 跳过 1500 个)。
您可以更改innodb_autoinc_lock_mode=0
为使用 MySQL 5.0 行为并避免在某些情况下丢失值。有关详细信息,请参阅http://dev.mysql.com/doc/refman/5.1/en/innodb-auto-increment-handling.html 。
要检查的另一件事是auto_increment_increment
配置变量的值。默认情况下为 1,但您可能已更改此值。同样,将其设置为高于 1 或 2 的值非常罕见,但有可能。
我同意其他评论者的观点,autoinc 列旨在是唯一的,但不一定是连续的。您可能不应该太担心它,除非您将 autoinc 值提升得如此之快以至于您可能会超出 INT 的范围(这发生在我身上)。
您究竟是如何修复它跳过 1500 永远插入的?
INSERT 失败的原因是另一列具有 UNIQUE 约束,并且 INSERT 试图在该列中插入重复值。阅读我链接到的手册页,了解为什么这很重要。
解决方法是在尝试插入之前先执行 SELECT 以检查该值是否存在。这违背了常识,即尝试插入并处理任何重复的键异常。但在这种情况下,INSERT 失败的副作用会导致 auto-inc 值丢失。首先执行 SELECT 消除了几乎所有此类异常。
但是,即使您先选择,您也必须处理可能的异常。你仍然有竞争条件。
你是对的!innodb_autoinc_lock_mode=0 就像一个魅力。
就您而言,我想知道为什么这么多插入失败。我怀疑像许多 SQL 开发人员一样,您在 AJAX 处理程序中执行 INSERT 后并没有检查成功状态,因此您永远不知道其中有这么多失败了。
他们可能仍然失败,你只是没有丢失自动 inc id 作为副作用。您应该真正诊断为什么会发生如此多的失败。您可能会生成不完整的数据,或者运行比必要更多的事务。