Como faço para corrigir este problema MySQL / InnoDB Deadlocking em um ambiente não-bloqueio?

StackOverflow https://stackoverflow.com/questions/870097

  •  22-08-2019
  •  | 
  •  

Pergunta

Estamos usando o MySQL com armazenamento InnoDB Engine. Temos um ambiente "evented" que envia várias solicitações simultâneas em uma mesa. Basicamente, funciona assim: Nós temos uma função find_or_insert que faz isso: - encontrar() -> sobre o resultado, se vazia -> Inserir -> on achado resultado ()

Estamos usando um driver non-blocking MySQL, então, basicamente, quando começamos este pequeno algoritmo mais de uma vez, ao mesmo tempo, ele executa todos os achados antes de inserir o primeiro resultado ... etc.

Infelizmente, temos esses erros: "Impasse encontrado ao tentar obter bloqueio, tente reiniciar a transação"

Qualquer pessoa pode ajudar com isso?

[EDIT]: Além disso, eu realmente não entendo por que o MySQL necessidade de bloquear a tabela apenas para inserir um novo elemento aqui. Inicialmente I embora o auto-incremento foi o culpado aqui, então eu o retirei ... bu eu ainda obter o erro. Existe uma maneira de impedir que o MySQL para bloquear a tabela em inserções?

Foi útil?

Solução

Tente o mysql referência manual para diagnosticar e resolução. Parece que você está fazendo um cache. A razão provável pode ser que um monte de clientes simultaneamente bateu na mesa tentando criar a 'primeira versão' (isto é, acertar o 'se inserir vazio'). Talvez você poderia adicionar um atraso pseudo-aleatório ou coordenar os criadores para que você não obter lotes de concorrentes criam chamadas para o db?

EDIT: Você já viu desta página ? Parece que você precisa definir uma configuração my.cnf para desativar bloqueios per-mesa com innodb. O que principalmente estava sugerindo, porém, era que o teste pode não ser representável, uma vez que podem conter uma escritores percentuais muito mais altos do que em uma situação realista. Se você começar a 100 threads com uma tabela vazia todos iriam instantaneamente bloquear, criar (mesmo para o mesmo valor, talvez). Isto é muito pior do que em uma situação média onde você tem uma melhor distribuição das chaves, menos acidentes e uma percentagem muito maior de leituras. Se este é o comportamento esperado (ou seja, você teria este comportamento ao vivo), gostaria de sugerir a adição de uma estratégia de recuo na criação de declarações.

Outras dicas

Você precisa desses pedidos de acontecer uma de cada vez, então talvez parar de usar esse driver non-blocking. Ou implementar seu próprio mecanismo de bloqueio. Aguarde um ao fim antes de passar para a próxima.

Você não reembolsaram disse que este não é razoável, ou que por alguma necessidade razão estas coisas se mover ao longo tão rapidamente.

Eu estou mudando a minha resposta para refletir que a questão seja revista. Agora parece que este é apenas um problema com as inserções concorrentes, não uma dependência no comportamento achado.

É meu entendimento que o InnoDB faz bloqueio de linha em inserções e você não pode desligar isso. No entanto, você [editar] não são capazes de usar INSERT DELAYED. Acabei de ler este não está disponível no InnoDB.

http://dev.mysql.com/doc /refman/5.0/en/insert-delayed.html

Talvez uma explícitas LOCK TABLES em torno de todas suas escritas coletivamente irá substituir o comportamento de bloqueio padrão. Se não houver outras operações sobre a mesa durante o intervalo quando ocorrem os eventos de gravação, este trabalho poder.

http://dev.mysql.com/doc /refman/5.0/en/lock-tables.html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top