Visualizza le transazioni aperte in MySQL


96

Ho fatto alcune domande senza impegno. Quindi l'applicazione è stata interrotta.

Come posso visualizzare queste transazioni aperte e impegnarle o annullarle?


Penso che tutte le tue transazioni vengano annullate alla disconnessione, ma non sono sicuro al 100%.
Johan,

Che tipo di tabelle stai usando? MyISAM, InnoDB, ecc.?
cdeszaq

@cdeszaq, ovviamente non MyISAM non ha transazioni, inoltre la domanda non ha davvero nulla a che fare con le tabelle.
Johan,

2
@ Johan - Ho fornito MyISAM solo come esempio del tipo di tabella. Ed è molto fa importa, perché non tutte le tabelle che le operazioni di supporto si comportano allo stesso modo per quanto riguarda le transazioni in perdita di connessione.
cdeszaq

@cdeszaq, I documenti di MySQL affermano qualcosa di molto diverso.
Johan

Risposte:


61

Come posso visualizzare queste transazioni aperte e impegnarle o annullarle?

Non ci sono transazioni aperte, MySQL eseguirà il rollback della transazione alla disconnessione.
Non è possibile eseguire il commit della transazione (IFAIK).

Visualizzi i thread usando

SHOW FULL PROCESSLIST  

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

Non ti aiuterà, perché non puoi eseguire il commit di una transazione da una connessione interrotta.

Cosa succede quando una connessione si interrompe
Dai documenti MySQL: http://dev.mysql.com/doc/refman/5.0/en/mysql-tips.html

4.5.1.6.3. Disabilitazione della riconnessione automatica di mysql

Se il client mysql perde la connessione al server durante l'invio di un'istruzione, tenta immediatamente e automaticamente di riconnettersi una volta al server e inviare nuovamente l'istruzione. Tuttavia , anche se mysql riesce a riconnettersi, la prima connessione è terminata e tutti gli oggetti e le impostazioni della sessione precedente vengono persi : tabelle temporanee, modalità autocommit e variabili di sessione e definite dall'utente. Inoltre, qualsiasi transazione corrente viene ripristinata .

Questo comportamento potrebbe essere pericoloso per te, come nell'esempio seguente in cui il server è stato spento e riavviato tra la prima e la seconda istruzione senza che tu lo sapessi:

Vedi anche: http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html

Come diagnosticare e risolvere questo problema
Per verificare la riconnessione automatica:

Se si verifica una riconnessione automatica (ad esempio, come risultato della chiamata a mysql_ping ()), non vi è alcuna indicazione esplicita. Per verificare la riconnessione, chiama mysql_thread_id()per ottenere l'identificatore di connessione originale prima di chiamare mysql_ping(), quindi chiama di mysql_thread_id()nuovo per vedere se l'identificatore è cambiato.

Assicurati di mantenere la tua ultima query (transazione) nel client in modo da poterla inviare nuovamente se necessario.
E disabilita la modalità di riconnessione automatica, poiché è pericolosa, implementa invece la tua riconnessione, in modo da sapere quando si verifica un calo e puoi inviare nuovamente la query.


Questo non ha nulla a che fare con la domanda. Ciò influisce solo sul client mysql e l'OP sta parlando di un'applicazione generica, il che probabilmente significa la sua applicazione. Inoltre, poiché l'applicazione chiamante si è arrestata, come potrebbe mantenere la transazione in memoria?
cdeszaq

@cdeszaq, ha tutto a che fare con la domanda. Un'applicazione in genere utilizza mysqld.dllAKA il client e si mantiene l' istruzione SQL che contiene l'intera transazione in memoria, in modo da poterla riprodurre quando la connessione si interrompe. Oppure lo tieni localmente su disco, in modo che al riavvio lo possa inviare nuovamente.
Johan,

C'è solo il comando dell'elenco dei processi visualizzato in SHOW FULL PROCESSLIST. Quindi immagino che non ci siano transazioni aperte. La parte divertente è che gli autoincrement_ids sembrano essere persi.
Alex

@alex i documenti ufficiali lo affermano, quindi questo è un comportamento documentato. Vedi i link.
Johan,

Bello, Johan. Ha risposto alla domanda e ha mostrato alcune conseguenze e le soluzioni a tali conseguenze, il tutto in un paio di paragrafi.
Gerard ONeill

53

Sebbene non ci saranno transazioni rimanenti nel caso, come ha detto @Johan, puoi vedere l'elenco delle transazioni correnti in InnoDB con la query qui sotto, se lo desideri.

SELECT * FROM information_schema.innodb_trx\G

Dal documento :

La tabella INNODB_TRX contiene informazioni su ogni transazione (escluse le transazioni di sola lettura) attualmente in esecuzione all'interno di InnoDB, incluso se la transazione è in attesa di un blocco, quando la transazione è iniziata e l'istruzione SQL che la transazione sta eseguendo, se presente.


Non supponi che ci sia un modo per sapere se le transazioni in quella tabella appartengono alla tua specifica richiesta / sessione?
Captain Hypertext

1
notare che \G modificatore alla fine è utile solo se si desidera formattare l'output della query all'interno dello strumento CLI mysql. Se usi uno strumento GUI come Mysql Workbench, non ne hai bisogno.
barell

29

Puoi usare show innodb status(o show engine innodb statusper le versioni più recenti di mysql) per ottenere un elenco di tutte le azioni attualmente in sospeso all'interno del motore InnoDB. Sepolte nel muro dell'output ci saranno le transazioni e l'ID di processo interno con cui vengono eseguite.

Non sarai in grado di forzare un commit o un rollback di quelle transazioni, ma PUOI terminare il processo MySQL che le esegue, il che essenzialmente si riduce a un rollback. Uccide la connessione dei processi e fa sì che MySQL ripulisca il casino che gli resta.

Ecco cosa vorresti cercare:

------------
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

In questo caso, al momento c'è solo una connessione al motore InnoDB (il mio accesso, eseguendo il show query). Se quella linea fosse una connessione effettiva / una transazione bloccata che vorresti terminare, dovresti eseguire un file kill 10594.


Non è davvero necessario terminare attivamente una connessione dopo un timeout, la connessione verrà comunque terminata e la transazione in sospeso da una connessione interrotta non può essere confermata in modo che possa essere nuovamente inviata senza timore di duplicazioni.
Johan,

3
Meglio uccidere le transazioni bloccate senza attendere un timeout per ripulire, altrimenti rischi di deadlock.
Marc B

Ah sì, +1 per quel commento. Mi sono dimenticato di quelle situazioni di stallo per un minuto.
Johan,

@ MarcB, perché l'hanno cambiato in show engine innodb status?
Pacerier

1

Usando questa query puoi vedere tutte le transazioni aperte.

Elenca tutto:

SHOW FULL PROCESSLIST  

se vuoi terminare una transazione bloccata, copia l'ID della transazione e uccidi la transazione usando questo comando:

KILL <id>    // e.g KILL 16543
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.