Por que o incremento automático salta mais do que o número de linhas inseridas?

11

Estou muito perturbado com esse comportamento estranho que estou vendo no auto_incrementvalor registrado no bidID de uma tabela de lances após executar a inserção em massa usando um procedimento armazenado:

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;

Por exemplo, se o auto_incrementvalor do bidID for 101 no início e eu inserir 100 linhas, o valor final será 213 em vez de 201. No entanto, os bidIDs dessas linhas inseridas serão executados sequencialmente até o máximo de 201.

Tendo verificado o seguinte,

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

Eu não tenho idéia do por que isso está acontecendo. O que poderia estar causando o salto no auto incrementvalor?

Pergunta Overflow
fonte
Tabelas MyISAM ou InnoDB?
Cristian Porta
@CristianPorta, é o InnoDB.
Pergunta Overflow
Você pode compartilhar sua show variables like '%innodb_autoinc_lock_mode%';saída?
Cristian Porta
Tem certeza de que não há outra conexão / atividade relacionada à tabela (inserção de linhas)?
ypercubeᵀᴹ
1
@QuestionOverflow um bom ponto de partida: dev.mysql.com/doc/refman/5.5/en/…
Cristian Porta

Respostas:

10

Isso não é incomum e existem algumas causas. Às vezes, é devido às otimizações feitas pelo executor de consultas para reduzir problemas de contenção com o recurso de contador, melhorando a eficiência quando há atualizações simultâneas na tabela afetada. Às vezes, isso ocorre devido a transações que foram explicitamente revertidas (ou implicitamente revertidas devido a um erro).

As únicas garantias de uma auto_incrementcoluna (ou IDENTITYno MSSQL, e os outros nomes que o conceito segue) é que cada valor será único e nunca menor que o anterior: para que você possa confiar nos valores para fazer pedidos, mas não pode confiar eles para não ter lacunas.

Se você precisar que os valores da coluna não tenham lacunas, será necessário gerenciar os valores você mesmo, em outra camada da lógica de negócios ou no DB por meio de um gatilho (tenha cuidado com possíveis problemas de desempenho com gatilhos), é claro se você faz o seu próprio processo, terá que lidar com todos os problemas de simultaneidade / reversão / limpeza após exclusão / outros que os mecanismos de banco de dados resolverem, permitindo lacunas).

David Spillett
fonte
Você pode fornecer algumas referências onde esse comportamento está sendo discutido?
Pergunta Overflow
1
Existem algumas referências ao assunto aqui, no SO e em geral. Pesquise "lacunas de IDENTIDADE", "lacunas de incremento automático" e assim por diante, e você deve encontrar muita discussão. Você pode adicionar o nome do DBMS para tornar a pesquisa mais específica, embora esse seja um conceito geral, para que não faça nenhuma diferença real, a menos que você esteja procurando informações detalhadas sobre como ela funciona em detalhes.
precisa
4
Veja os detalhes do MySQL: AUTO_INCREMENT Handling in InnoDB , onde ele menciona: " Lacunas nos valores de incremento automático para" inserções em massa " ... Nos modos de bloqueio 1 ou 2, podem ocorrer lacunas entre instruções sucessivas, porque para inserções em massa o número exato dos valores de incremento automático exigidos por cada instrução pode não ser conhecido e a superestimação é possível ".
ypercubeᵀᴹ
@ypercube, obrigado, isso é muito útil para você.
Pergunta Overflow
Consulte também bugs.mysql.com/bug.php?id=34696 .
trss