Como posso mostrar bloqueios mysql?

45

Existe alguma maneira de mostrar todos os bloqueios que estão ativos em um banco de dados mysql?

Rory
fonte
1
Você pode consultar as tabelas INNODB_LOCK_WAITS e INNODB_LOCKS.

Respostas:

40

Veja o link de Marko para tabelas do InnoDB e as advertências.

Para o MyISAM, não existe uma solução fácil "esta é a consulta incorreta". Você deve sempre começar com uma lista de processos. Mas lembre-se de incluir a palavra-chave completa para que as consultas impressas não sejam truncadas:

SHOW FULL PROCESSLIST;

Isso mostrará uma lista de todos os processos atuais, sua consulta e estado SQL. Agora, normalmente, se uma única consulta está causando o bloqueio de muitas outras, deve ser fácil identificá-la. As consultas afetadas terão um status de Lockede a consulta incorreta ficará oculta por si só, possivelmente aguardando algo intenso, como uma tabela temporária.

Se não for óbvio, você terá que usar seus poderes de dedução do SQL para determinar qual parte do SQL ofensivo pode ser a causa de seus problemas.

Dan Carley
fonte
21

Se você usa o InnoDB e precisa verificar as consultas em execução, recomendo

show engine innodb status;

como mencionado no link de Marko. Isso fornecerá a consulta de bloqueio, quantas linhas / tabelas estão bloqueadas por ela etc. Procure em TRANSACTIONS.

O problema com o uso SHOW PROCESSLISTé que você não verá os bloqueios, a menos que outras consultas estejam na fila.

Polymorphix
fonte
20

Tente SHOW OPEN TABLES:

show open tables where In_Use > 0 ;
M Sleman
fonte
Eu acho que essa é a melhor maneira de identificar bloqueios em uso imediatamente, especialmente se você tiver vários bancos de dados e centenas de conexões.
nelaaro
7

Usando este comando

SHOW PROCESSLIST

mostrará todo o processo em execução no momento, incluindo o processo que adquiriu bloqueio nas tabelas.

Arie K
fonte
7

Nenhuma das respostas pode mostrar todos os bloqueios mantidos no momento.

Faça isso, por exemplo, no mysql em um terminal.

start transaction;
update someTable set name="foobar" where ID=1234;
-- but no rollback or commit - just let it sit there

Claramente, a transação acima mantém um bloqueio, porque a transação ainda está ativa. Mas nenhuma consulta está acontecendo no momento e ninguém está esperando por um bloqueio em qualquer lugar (pelo menos).

INFORMATION_SCHEMA.INNODB_LOCKSestá vazio, o que faz sentido, dada a documentação , porque há apenas uma transação e atualmente ninguém espera por bloqueios. Também INNODB_LOCKSestá obsoleto.

SHOW ENGINE INNODB STATUSé inútil: someTablenão é mencionado

SHOW FULL PROCESSLIST está vazio, porque o culpado não está realmente executando uma consulta no momento.

Você pode usar INFORMATION_SCHEMA.INNODB_TRX, performance_schema.events_statements_historye performance_schema.threadspara extrair as consultas que quaisquer transações ativas ter executado no passado, conforme descrito na minha outra resposta , mas eu não encontrei nenhuma maneira de ver que someTableestá bloqueado no cenário acima.

As sugestões das outras respostas até agora não ajudarão pelo menos.

Isenção de responsabilidade: não tenho o innotop instalado e não me incomodei. Talvez isso possa funcionar.

Peter V. Mørch
fonte
6

AFAIK ainda não existe uma maneira nativa no MYSQL, mas eu uso o innotop . É gratuito e tem muitas outras funcionalidades também.

Consulte também este link para obter mais informações sobre o uso da ferramenta innotop.

Marko Carter
fonte
4

Referência retirada deste post.

Você pode usar o script abaixo:

SELECT 
    pl.id
    ,pl.user
    ,pl.state
    ,it.trx_id 
    ,it.trx_mysql_thread_id 
    ,it.trx_query AS query
    ,it.trx_id AS blocking_trx_id
    ,it.trx_mysql_thread_id AS blocking_thread
    ,it.trx_query AS blocking_query
FROM information_schema.processlist AS pl 
INNER JOIN information_schema.innodb_trx AS it
    ON pl.id = it.trx_mysql_thread_id
INNER JOIN information_schema.innodb_lock_waits AS ilw
    ON it.trx_id = ilw.requesting_trx_id 
        AND it.trx_id = ilw.blocking_trx_id
Anvesh
fonte