Това поведение е документирано (параграф в скоби):
Ако посочите ON DUPLICATE KEY UPDATE и е вмъкнат ред, който би причинил дублирана стойност в УНИКАЛЕН индекс или ПЪРВИЧЕН КЛЮЧ, MySQL извършва АКТУАЛИЗИРАНЕ на стария ред. Например, ако колона a е декларирана като УНИКАЛНА и съдържа стойността 1, следните два израза имат подобен ефект:
INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1; UPDATE table SET c=c+1 WHERE a=1;
(Ефектите не са идентични за таблица на InnoDB, където a е колона с автоматично увеличение. С колона с автоматично увеличение, оператор INSERT увеличава стойността за автоматично увеличение, но UPDATE не.)
Ето едно просто обяснение. MySQL се опитва първо да направи вмъкването. Това е, когато идентификаторът се увеличава автоматично. След като се увеличи, остава. След това дубликатът се открива и се извършва актуализацията. Но стойността се пропуска.
Не трябва да разчитате на auto_increment
без празнини. Ако това е изискване, режийните разходи за актуализации и вмъквания са много по-големи. По същество трябва да поставите заключване на цялата таблица и да преномерирате всичко, което трябва да бъде преномерирано, обикновено с помощта на тригер. По-добро решение е да се изчислят инкрементални стойности на изхода.