Exibir transações abertas no MySQL

95

Fiz algumas consultas sem commit. Em seguida, o aplicativo foi interrompido.

Como posso exibir essas transações abertas e confirmá-las ou cancelá-las?

Alex
fonte
Acho que todas as suas transações são canceladas ao desconectar, mas não tenho 100% de certeza.
Johan
Que tipo de mesa você está usando? MyISAM, InnoDB, etc?
cdeszaq
@cdeszaq, obviamente não é MyISAM ele não tem transações, além da questão realmente não ter nada a ver com tabelas.
Johan,
2
@Johan - Eu dei MyISAM apenas como um exemplo do tipo de tabela. E é muito faz matéria, porque nem todas as tabelas de que as operações de apoio se comportam da mesma forma com relação às transacções da perda de conexão.
cdeszaq
@cdeszaq, A documentação do MySQL afirma algo muito diferente.
Johan

Respostas:

60

Como posso exibir essas transações abertas e confirmá-las ou cancelá-las?

Não há transação aberta, o MySQL irá reverter a transação ao desconectar.
Você não pode confirmar a transação (IFAIK).

Você exibe tópicos usando

SHOW FULL PROCESSLIST  

Veja: http://dev.mysql.com/doc/refman/5.1/en/thread-information.html

Não vai ajudá-lo, porque você não pode confirmar uma transação de uma conexão interrompida.

O que acontece quando uma conexão é interrompida
Dos documentos do MySQL: http://dev.mysql.com/doc/refman/5.0/en/mysql-tips.html

4.5.1.6.3. Desativando a reconexão automática do mysql

Se o cliente mysql perder sua conexão com o servidor enquanto envia uma instrução, ele tenta se reconectar imediatamente e automaticamente uma vez ao servidor e enviar a instrução novamente. No entanto , mesmo se o mysql tiver sucesso na reconexão, sua primeira conexão terminou e todos os seus objetos de sessão anteriores e configurações foram perdidos : tabelas temporárias, o modo autocommit e variáveis ​​definidas pelo usuário e de sessão. Além disso, qualquer transação atual é revertida .

Esse comportamento pode ser perigoso para você, como no exemplo a seguir, em que o servidor foi desligado e reiniciado entre a primeira e a segunda instruções sem você saber:

Veja também: http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html

Como diagnosticar e corrigir isso
Para verificar a reconexão automática:

Se uma reconexão automática ocorrer (por exemplo, como resultado da chamada de mysql_ping ()), não há indicação explícita disso. Para verificar a reconexão, chame mysql_thread_id()para obter o identificador de conexão original antes de chamar e mysql_ping(), em seguida, chame mysql_thread_id()novamente para ver se o identificador foi alterado.

Certifique-se de manter sua última consulta (transação) no cliente para que possa reenviá-la se necessário.
E desabilite o modo de reconexão automática, porque isso é perigoso, implemente sua própria reconexão, para saber quando ocorrer uma queda e reenviar essa consulta.

João
fonte
Isso não tem nada a ver com a questão. Isso afeta apenas o cliente mysql, e o OP está falando sobre um aplicativo genérico, o que provavelmente significa seu aplicativo. Além disso, como o aplicativo de chamada parou, como ele seria capaz de manter a transação na memória?
cdeszaq
@cdeszaq, tem tudo a ver com a questão. Um aplicativo normalmente usa o clientemysqld.dll AKA e você mantém a instrução SQL que contém a transação completa na memória, para que possa reproduzi-la quando a conexão cair. Ou você o mantém localmente no disco, para que, ao reiniciar, possa reenviá-lo.
Johan
Há apenas meu comando de lista de processos exibido em SHOW FULL PROCESSLIST. Acho que simplesmente não há transações abertas. A parte engraçada é que os autoincrement_ids parecem perdidos.
Alex
@alex os documentos oficiais afirmam isso, então esse é um comportamento documentado. Veja os links.
Johan
Linda, Johan. Respondeu a pergunta e mostrou algumas consequências e as soluções para essas consequências, tudo dentro de alguns parágrafos.
Gerard ONeill
53

Embora não haja nenhuma transação restante no caso, como @Johan disse, você pode ver a lista de transações atuais no InnoDB com a consulta abaixo, se desejar.

SELECT * FROM information_schema.innodb_trx\G

Do documento :

A tabela INNODB_TRX contém informações sobre cada transação (excluindo transações somente leitura) atualmente em execução dentro do InnoDB, incluindo se a transação está esperando por um bloqueio, quando a transação começou, e a instrução SQL que a transação está executando, se houver.

Sanghyun Lee
fonte
Não suponha que haja alguma maneira de saber se as transações nessa tabela pertencem à sua solicitação / sessão específica?
Capitão Hypertext
1
Observe que o \Gmodificador no final só é útil se você deseja formatar a saída da consulta na ferramenta CLI mysql. Se você usa uma ferramenta GUI como o Mysql Workbench, você não precisa dela.
barell
29

Você pode usar show innodb status(ou show engine innodb statuspara versões mais recentes do mysql) para obter uma lista de todas as ações atualmente pendentes dentro do mecanismo InnoDB. Enterradas na parede de saída estarão as transações e sob qual ID de processo interno elas estão rodando.

Você não será capaz de forçar um commit ou rollback dessas transações, mas você PODE matar o processo MySQL que as executa, o que essencialmente se reduz a um rollback. Ele interrompe a conexão dos processos e faz com que o MySQL limpe a bagunça que resta.

Aqui está o que você deseja procurar:

------------
TRANSACTIONS
------------
Trx id counter 0 140151
Purge done for trx's n:o < 0 134992 undo n:o < 0 0
History list length 10
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0 0, not started, process no 17004, OS thread id 140621902116624
MySQL thread id 10594, query id 10269885 localhost marc
show innodb status

Nesse caso, há apenas uma conexão com o mecanismo InnoDB agora (meu login, executando a showconsulta). Se essa linha fosse uma conexão real / transação travada que você deseja encerrar, faça a kill 10594.

Marc B
fonte
Não há realmente necessidade de encerrar ativamente uma conexão após um tempo limite; a conexão será encerrada de qualquer maneira e a transação pendente de uma conexão interrompida não pode ser confirmada, para que possa ser reenviada sem medo de duplicações.
Johan
3
É melhor eliminar as transações travadas sem esperar um tempo limite para limpar - caso contrário, você corre o risco de bloqueios.
Marc B
Ah sim, +1 para esse comentário. Esqueci esses impasses por um minuto.
Johan
@MarcB, Por que eles mudaram para show engine innodb status?
Pacerier,
1

Usando esta consulta, você pode ver todas as transações abertas.

Listar tudo:

SHOW FULL PROCESSLIST  

se você deseja encerrar uma transação travada, copiar o id da transação e encerrar a transação usando este comando:

KILL <id>    // e.g KILL 16543
M. Hamza Rajput
fonte