Dlaczego automatyczny przyrost zwiększa się o więcej niż liczba wstawionych wierszy?

11

Jestem bardzo zaniepokojony tym dziwnym zachowaniem, które widzę w auto_incrementwartości zapisanej w bidID tabeli ofert po wykonaniu masowego wstawiania przy użyciu procedury składowanej:

INSERT INTO Bids (itemID, buyerID, bidPrice)
 SELECT itemID, rand_id(sellerID, user_last_id), FLOOR((1 + RAND())*askPrice)
 FROM Items
 WHERE closing BETWEEN NOW() AND NOW() + INTERVAL 1 WEEK ORDER BY RAND() LIMIT total_rows;

Na przykład, jeśli auto_incrementwartość bidID wynosi 101 na początku, a wstawiłem 100 wierszy, wartość końcowa staje się 213 zamiast 201. Jednak bidID tych wstawionych wierszy działa sekwencyjnie do maksymalnie 201.

Po sprawdzeniu,

SHOW VARIABLES LIKE 'auto_inc%';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 1     |
| auto_increment_offset    | 1     |
+--------------------------+-------+

Nie mam pojęcia, dlaczego tak się dzieje. Co może powodować skok auto incrementwartości?

Przepełnienie pytania
źródło
Stoły MyISAM czy InnoDB?
Cristian Porta
@CristianPorta, to InnoDB.
Pytanie Przepełnienie
Czy możesz podzielić się swoją show variables like '%innodb_autoinc_lock_mode%';produkcją?
Cristian Porta
Czy na pewno nie ma innego połączenia / działania związanego z tabelą (wstawianie wierszy)?
ypercubeᵀᴹ
1
@QuestionOverflow dobrym punktem wyjścia: dev.mysql.com/doc/refman/5.5/en/…
Cristian Porta

Odpowiedzi:

10

Nie jest to niczym niezwykłym i istnieje kilka przyczyn. Czasami jest to spowodowane optymalizacjami wykonywanymi przez moduł uruchamiający kwerendy, aby zmniejszyć problemy rywalizacji z zasobem licznika, poprawiając wydajność, gdy istnieją równoległe aktualizacje tabeli, której dotyczy problem. Czasami jest to spowodowane transakcjami, które zostały jawnie wycofane (lub domyślnie wycofane z powodu napotkania błędu).

Jedynymi gwarancjami z auto_incrementkolumny (lub IDENTITYw MSSQL i innych nazwach, pod którymi kryje się ta koncepcja) jest to, że każda wartość będzie unikalna i nigdy mniejsza niż poprzednia: możesz więc polegać na wartościach przy zamawianiu, ale nie możesz polegać na aby nie mieć luk.

Jeśli potrzebujesz, aby wartości w kolumnie nie miały żadnych luk, będziesz musiał samodzielnie zarządzać wartościami, albo w innej warstwie logiki biznesowej, albo w DB za pomocą wyzwalacza (uważaj jednak na potencjalne problemy z wydajnością z wyzwalaczami), oczywiście jeśli robisz własne, będziesz musiał zmagać się ze wszystkimi problemami współbieżności / przywracania / czyszczenia po usunięciu / innymi problemami, na które działają silniki DB, dopuszczając luki).

David Spillett
źródło
Czy możesz podać odniesienia, w których omawiane jest to zachowanie?
Pytanie Przepełnienie
1
Jest tu sporo odniesień do tej kwestii, na SO i ogólnie. Wyszukaj „luki w tożsamości”, „luki w auto_increment” i tak dalej, i powinieneś znaleźć wiele dyskusji. Możesz dodać swoją nazwę DBMS, aby uszczegółowić wyszukiwanie, chociaż jest to dość ogólna koncepcja, więc może nie mieć żadnej realnej różnicy, chyba że spojrzysz pod maską na to, jak to działa szczegółowo.
David Spillett
4
Zobacz szczegóły dotyczące MySQL: AUTO_INCREMENT Obsługa w InnoDB , gdzie wspomina: Luki w wartościach automatycznego przyrostu dla„
ypercubeᵀᴹ
@ypercube, dzięki, to jest najbardziej pomocne z twojej strony.
Pytanie Przepełnienie,
Zobacz także bugs.mysql.com/bug.php?id=34696 .
trss