Estou executando a seguinte UPDATE
instrução MySQL :
mysql> update customer set account_import_id = 1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
Como não estou usando uma transação, por que estaria recebendo esse erro? Eu até tentei reiniciar meu servidor MySQL e não ajudou.
A tabela possui 406.733 linhas.
mysql
sql
timeout
lock-timeout
Jason Swett
fonte
fonte
process
para ficar ociosas. Nesse caso, você pode obter esse erro. Estou certo?connection.commit()
commitINSERT
ouUPDATE
você acabou de passar.Como forçar o desbloqueio de tabelas bloqueadas no MySQL:
Quebrar bloqueios como esse pode fazer com que a atomicidade no banco de dados não seja imposta nas instruções sql que causaram o bloqueio.
Isso é uma tolice, e a solução adequada é corrigir o aplicativo que causou os bloqueios. No entanto, quando os dólares estão em jogo, um chute rápido fará as coisas se moverem novamente.
1) Digite MySQL
2) Vamos ver a lista de tabelas bloqueadas
3) Vamos ver a lista dos processos atuais, um deles está bloqueando sua (s) tabela (s)
4) Mate um desses processos
fonte
Agora, ative a trava novamente. Você tem 100 segundos para emitir um
SHOW ENGINE INNODB STATUS\G
no banco de dados e ver qual outra transação está bloqueando a sua.fonte
lock_wait_timeout
valorVeja se o seu banco de dados está ajustado. Especialmente o isolamento de transações. Não é uma boa ideia aumentar a variável innodb_lock_wait_timeout.
Verifique o nível de isolamento da transação do banco de dados no mysql cli:
Você pode obter melhorias alterando o nível de isolamento, use o oracle como READ COMMITTED e REPEATABLE READ (padrões do InnoDB)
Tente também usar SELECT FOR UPDATE apenas se necessário.
fonte
tx_isolation
variável paratransaction_isolation
.Nenhuma das soluções sugeridas funcionou para mim, mas isso funcionou.
Algo está bloqueando a execução da consulta. Provavelmente outra consulta atualizando, inserindo ou excluindo de uma das tabelas em sua consulta. Você precisa descobrir o que é isso:
Depois de localizar o processo de bloqueio, encontre-o
id
e execute:Execute novamente sua consulta inicial.
fonte
100% com o que o MarkR disse. o autocommit faz de cada instrução uma transação de uma instrução.
SHOW ENGINE INNODB STATUS
deve lhe dar algumas pistas sobre o motivo do impasse. Dê uma boa olhada no seu log de consultas lentas também para ver o que mais está consultando a tabela e tente remover qualquer coisa que esteja executando uma verificação de tabela completa. O bloqueio no nível da linha funciona bem, mas não quando você está tentando bloquear todas as linhas!fonte
Você pode atualizar qualquer outro registro nessa tabela ou essa tabela é muito usada? O que estou pensando é que, enquanto está tentando adquirir um bloqueio, ele precisa atualizar esse registro, o tempo limite definido expirou. Você pode aumentar o tempo que pode ajudar.
fonte
innodb_lock_wait_timeout
emmy.cnf
O número de linhas não é enorme ... Crie um índice em account_import_id, se não for a chave primária.
fonte
Se você acabou de matar uma grande consulta, isso levará tempo
rollback
. Se você emitir outra consulta antes que a consulta finalizada seja revertida, poderá receber um erro de tempo limite de bloqueio. Foi o que aconteceu comigo. A solução foi apenas esperar um pouco.Detalhes:
Eu havia emitido uma consulta DELETE para remover cerca de 900.000 de cerca de 1 milhão de linhas.
Fiz isso por engano (remove apenas 10% das linhas):
DELETE FROM table WHERE MOD(id,10) = 0
Em vez disso (remove 90% das linhas):
DELETE FROM table WHERE MOD(id,10) != 0
Eu queria remover 90% das linhas, não 10%. Então, eu matei o processo na linha de comando do MySQL, sabendo que ele reverteria todas as linhas que havia excluído até agora.
Em seguida, executei o comando correto imediatamente e recebi um
lock timeout exceeded
erro logo depois. Percebi que o bloqueio pode realmente ser orollback
da consulta morta ainda acontecendo no fundo. Então, esperei alguns segundos e refiz a consulta.fonte
Verifique se as tabelas do banco de dados estão usando o mecanismo de armazenamento InnoDB e o nível de isolamento de transação READ-COMMITTED.
Você pode verificá-lo por SELECT @@ GLOBAL.tx_isolation, @@ tx_isolation; no console do mysql.
Se não estiver definido para READ-COMMITTED, você deverá configurá-lo. Antes de configurá-lo, verifique se você possui privilégios SUPER no mysql.
Você pode obter ajuda em http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html .
Ao definir isso, acho que seu problema será resolvido.
Você também pode verificar se não está tentando atualizar isso em dois processos ao mesmo tempo. Os usuários (@tala) encontraram mensagens de erro semelhantes nesse contexto, talvez verifique duas vezes ...
fonte
Eu vim do Google e só queria adicionar a solução que funcionou para mim. Meu problema era que eu estava tentando excluir registros de uma tabela enorme com muito FK em cascata, e obtive o mesmo erro do OP.
Desativei o
autocommit
e, em seguida, funcionou apenas adicionandoCOMMIT
no final da sentença SQL. Tanto quanto eu entendi isso libera o buffer pouco a pouco, em vez de esperar no final do comando.Para manter o exemplo do OP, isso deveria ter funcionado:
mysql> set autocommit=0;
mysql> update customer set account_import_id = 1; commit;
Não se esqueça de reativar
autocommit
novamente se quiser deixar a configuração do MySQL como antes.mysql> set autocommit=1;
fonte
Tarde para a festa (como de costume), no entanto, meu problema foi o fato de eu ter escrito SQL incorreto (sendo iniciante) e vários processos terem bloqueado o (s) registro (s) <- não tenho certeza da verborragia apropriada. Acabei tendo que apenas:
SHOW PROCESSLIST
e depois matar os IDs usandoKILL <id>
fonte
Esse tipo de coisa aconteceu comigo quando eu estava usando a saída de construção da linguagem php; no meio da transação. Então esta transação "trava" e você precisa matar o processo mysql (descrito acima com processlist;)
fonte
Na minha instância, eu estava executando uma consulta anormal para corrigir dados. Se você bloquear as tabelas em sua consulta, não precisará lidar com o tempo limite de bloqueio:
Provavelmente, essa não é uma boa ideia para uso normal.
Para mais informações, consulte: Manual de Referência do MySQL 8.0
fonte
Eu me deparei com isso com duas conexões DBAL do Doctrine, uma delas como não transacional (para logs importantes), e elas devem ser executadas em paralelo, não dependendo uma da outra.
Meus testes de integração foram agrupados em transações para reversão de dados após muito teste.
Minha solução foi desativar a transação de empacotamento nesses testes e redefinir os dados do banco de dados de outra maneira.
fonte
Tive esse mesmo erro, embora eu estivesse atualizando apenas uma tabela com uma entrada, mas depois de reiniciar o mysql, ele foi resolvido.
fonte