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.
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.
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.
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.
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
Respostas:
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:
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
Locked
e 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.
fonte
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.fonte
Tente
SHOW OPEN TABLES
:fonte
Usando este comando
mostrará todo o processo em execução no momento, incluindo o processo que adquiriu bloqueio nas tabelas.
fonte
Nenhuma das respostas pode mostrar todos os bloqueios mantidos no momento.
Faça isso, por exemplo, no mysql em um terminal.
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_LOCKS
está vazio, o que faz sentido, dada a documentação , porque há apenas uma transação e atualmente ninguém espera por bloqueios. TambémINNODB_LOCKS
está obsoleto.SHOW ENGINE INNODB STATUS
é inútil:someTable
não é mencionadoSHOW 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_history
eperformance_schema.threads
para 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 quesomeTable
está 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.
fonte
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.
fonte
Referência retirada deste post.
Você pode usar o script abaixo:
fonte