115 votes

Afficher les transactions ouvertes dans MySQL

J'ai fait quelques requêtes sans validation. Puis l'application a été arrêtée.

Comment puis-je afficher ces transactions ouvertes et les valider ou les annuler ?

0 votes

Je pense que toutes vos transactions sont annulées lors de la déconnexion, mais je ne suis pas sûr à 100%.

0 votes

Quel type de tables utilisez-vous ? MyISAM, InnoDB, etc ?

0 votes

@cdeszaq, évidemment pas MyISAM il n'a pas de transactions, d'ailleurs la question n'a vraiment rien à voir avec les tables.

87voto

Johan Points 34755

Comment puis-je afficher ces transactions ouvertes et les valider ou les annuler ?

Il n'y a pas de transaction ouverte, MySQL annulera la transaction lors de la déconnexion.
Vous ne pouvez pas valider la transaction (IFAIK).

Vous affichez les fils en utilisant

SHOW FULL PROCESSLIST  

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

Cela ne vous aidera pas, car vous ne pouvez pas valider une transaction à partir d'une connexion interrompue.

Que se passe-t-il lorsqu'une connexion est rompue ?
Dans la documentation de MySQL : http://dev.mysql.com/doc/refman/5.0/en/mysql-tips.html

4.5.1.6.3. Désactiver la reconnexion automatique à mysql

Si le client mysql perd sa connexion au serveur pendant l'envoi d'une déclaration, il essaie immédiatement et automatiquement de se reconnecter une fois au serveur et d'envoyer à nouveau la déclaration. Cependant Même si mysql réussit à se reconnecter, votre première connexion est terminée et tous les objets et paramètres de la session précédente sont perdus. sont perdus : les tables temporaires, le mode autocommit, les variables définies par l'utilisateur et les variables de session. Également, toute transaction en cours est annulée .

Ce comportement peut être dangereux pour vous, comme dans l'exemple suivant où le serveur a été arrêté et redémarré entre la première et la deuxième déclaration sans que vous le sachiez :

Voir aussi : http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html

Comment diagnostiquer et réparer ce problème
Pour vérifier l'auto-reconnexion :

Si une reconnexion automatique se produit (par exemple, à la suite de l'appel de mysql_ping()), il n'y a pas d'indication explicite à ce sujet. Pour vérifier la reconnexion, appelez mysql_thread_id() pour obtenir l'identifiant de connexion original avant d'appeler mysql_ping() puis appeler mysql_thread_id() pour voir si l'identifiant a changé.

Veillez à conserver votre dernière requête (transaction) dans le client afin de pouvoir la soumettre à nouveau si nécessaire.
Et désactivez le mode de reconnexion automatique, car il est dangereux. Mettez en place votre propre reconnexion à la place, afin de savoir quand un abandon se produit et vous pouvez soumettre à nouveau cette requête.

0 votes

Cela n'a rien à voir avec la question. Cela n'a d'impact que sur le client mysql, et le PO parle d'une application générique, ce qui signifie probablement que son application. De plus, l'application appelante s'étant arrêtée, comment pourrait-elle conserver la transaction en mémoire ?

0 votes

@cdeszaq, cela a tout à voir avec la question. Une application utilise généralement mysqld.dll AKA le client Et vous gardez le Déclaration SQL qui contient l'intégralité de la transaction en mémoire, de sorte que vous pouvez la réécouter lorsque la connexion est interrompue. Ou vous la conservez localement sur le disque, de sorte qu'au redémarrage, vous pouvez la soumettre à nouveau.

0 votes

Seule ma commande de liste de processus est affichée dans la commande SHOW FULL PROCESSLIST. Je suppose donc qu'il n'y a pas de transactions ouvertes. Le plus drôle, c'est que les autoincrement_ids semblent avoir été perdus.

78voto

Sangdol Points 3374

Bien qu'il n'y ait pas de transaction restante dans ce cas, comme @Johan l'a dit, vous pouvez voir la liste des transactions actuelles dans InnoDB avec la requête ci-dessous si vous le souhaitez.

SELECT * FROM information_schema.innodb_trx\G

Desde le document :

La table INNODB_TRX contient des informations sur chaque transaction (à l'exception des transactions en lecture seule) en cours d'exécution dans InnoDB, y compris si la transaction est en attente d'un verrou, quand la transaction a commencé et l'instruction SQL que la transaction exécute, le cas échéant.

0 votes

Je ne pense pas qu'il y ait un moyen de savoir si les transactions de cette table appartiennent à votre demande/session spécifique ?

4 votes

Veuillez noter \G à la fin n'est utile que si vous voulez formater la sortie de la requête dans l'outil mysql CLI. Si vous utilisez un outil GUI comme Mysql Workbench, vous n'en avez pas besoin.

40voto

Marc B Points 195501

Vous pouvez utiliser show innodb status (ou show engine innodb status pour les versions plus récentes de mysql) pour obtenir une liste de toutes les actions en cours dans le moteur InnoDB. Les transactions et l'identifiant du processus interne sous lequel elles sont exécutées sont cachés dans le mur des résultats.

Vous ne pourrez pas forcer un commit ou un rollback de ces transactions, mais vous pouvez tuer le processus MySQL qui les exécute, ce qui revient essentiellement à un rollback. Cela tue la connexion du processus et permet à MySQL de nettoyer le désordre qu'il a laissé.

Voici ce que vous devez rechercher :

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

Dans ce cas, il n'y a qu'une seule connexion au moteur InnoDB pour l'instant (mon login, qui exécute la commande show query). Si cette ligne était une connexion réelle/une transaction bloquée à laquelle vous voudriez mettre fin, vous feriez alors un kill 10594 .

0 votes

Il n'y a pas vraiment besoin de tuer activement une connexion après un délai d'attente, la connexion sera tuée de toute façon et les transactions en attente d'une connexion interrompue ne peuvent pas être commitées, elles peuvent donc être resoumises sans crainte de duplications.

3 votes

Il est préférable de tuer les transactions bloquées sans attendre un délai d'attente pour les nettoyer - sinon, vous risquez des blocages.

0 votes

Ah oui, +1 pour ce commentaire. J'avais oublié ces blocages pendant une minute.

3voto

Hamza Points 125

En utilisant cette requête, vous pouvez voir toutes les transactions ouvertes.

Lister tout :

SHOW FULL PROCESSLIST  

si vous voulez tuer une transaction suspendue, copiez l'identifiant de la transaction et tuez la transaction en utilisant cette commande :

KILL <id>    // e.g KILL 16543

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X