Afficher les transactions ouvertes dans MySQL

96

J'ai fait quelques requêtes sans commit. Ensuite, l'application a été arrêtée.

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

Alex
la source
Je pense que toutes vos transactions sont annulées lors de la déconnexion, mais pas sûr à 100%.
Johan le
Quel type de tables utilisez-vous? MyISAM, InnoDB, etc.?
cdeszaq le
@cdeszaq, évidemment pas MyISAM il n'a pas de transactions, d'ailleurs la question n'a vraiment rien à voir avec les tables.
Johan le
2
@Johan - Je n'ai donné MyISAM qu'à titre d'exemple du type de table. Et très bien fait affaire, car toutes les tables qui supportent les transactions se comportent de la même façon en ce qui concerne les transactions sur la perte de connexion.
cdeszaq le
@cdeszaq, la documentation MySQL indique quelque chose de très différent.
Johan le

Réponses:

61

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 interrompue?
Depuis la documentation 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 lors de l'envoi d'une instruction, il essaie immédiatement et automatiquement de se reconnecter une fois au serveur et de renvoyer l'instruction. Cependant , même si mysql réussit à se reconnecter, votre première connexion est terminée et tous vos objets et paramètres de session précédents sont perdus : les tables temporaires, le mode autocommit et les variables définies par l'utilisateur et de session. En outre, 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 les première et deuxième instructions sans que vous le sachiez:

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

Comment diagnostiquer et résoudre ce problème
Pour vérifier la reconnexion automatique:

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

Assurez-vous de 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 cela est dangereux, implémentez votre propre reconnexion à la place, afin que vous sachiez quand une suppression se produit et que vous puissiez resoumettre cette requête.

Johan
la source
Cela n'a rien à voir avec la question. Cela n'affecte que le client mysql et l'OP parle d'une application générique, ce qui signifie probablement son application. De plus, depuis que l'application appelante s'est arrêtée, comment pourrait-elle conserver la transaction en mémoire?
cdeszaq le
@cdeszaq, cela a tout à voir avec la question. Une application utilise généralement mysqld.dllAKA le client et vous conservez l' instruction SQL qui contient la transaction complète en mémoire, afin de pouvoir la lire lorsque la connexion est interrompue. Ou vous le gardez localement sur le disque, de sorte qu'au redémarrage, vous puissiez le soumettre à nouveau.
Johan le
Il n'y a que ma commande de liste de processus affichée dans la LISTE DE PROCESSUS PLEINE AFFICHER. Donc, je suppose qu'il n'y a tout simplement aucune transaction ouverte. Le plus drôle, c'est que les autoincrement_ids semblent être perdus.
Alex le
@alex la documentation officielle indique cela, donc c'est un comportement documenté. Voir les liens.
Johan le
Magnifique, Johan. A répondu à la question et montré quelques conséquences et les solutions à ces conséquences, le tout en quelques paragraphes.
Gerard ONeill
53

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

SELECT * FROM information_schema.innodb_trx\G

À partir du 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 attend un verrou, quand la transaction a démarré et l'instruction SQL que la transaction est en cours d'exécution, le cas échéant.

Sanghyun Lee
la source
Ne supposez pas qu'il existe un moyen de savoir si les transactions de cette table appartiennent à votre demande / session spécifique?
Captain Hypertext le
1
Veuillez noter que le \Gmodificateur à la fin n'est utile que si vous souhaitez formater la sortie de la requête dans l'outil CLI mysql. Si vous utilisez un outil graphique comme Mysql Workbench, vous n'en avez pas besoin.
barell le
29

Vous pouvez utiliser show innodb status(ou show engine innodb statuspour les versions plus récentes de mysql) pour obtenir une liste de toutes les actions actuellement en attente dans le moteur InnoDB. Les transactions et l'ID de processus interne sous lequel elles s'exécutent seront enfouies dans le mur de la sortie.

Vous ne pourrez pas forcer une validation ou une annulation de ces transactions, mais vous POUVEZ tuer le processus MySQL qui les exécute, ce qui se résume essentiellement à une annulation. Il tue la connexion des processus et oblige MySQL à nettoyer le désordre à sa gauche.

Voici ce que vous voudriez 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 le moment (mon login, l'exécution de la showrequête). Si cette ligne était une connexion réelle / une transaction bloquée que vous souhaitiez mettre fin, vous feriez alors un kill 10594.

Marc B
la source
Il n'est vraiment pas nécessaire de désactiver activement une connexion après un délai d'expiration, la connexion sera supprimée de toute façon et la transaction en attente à partir d'une connexion interrompue ne peut pas être validée afin de pouvoir être resoumise sans crainte de duplications.
Johan le
3
Mieux vaut tuer les transactions bloquées sans attendre un délai d'attente pour le nettoyage - sinon, vous risquez des blocages.
Marc B du
Ah oui, +1 pour ce commentaire. J'ai oublié ces impasses pendant une minute.
Johan le
@MarcB, pourquoi l'ont-ils changé en show engine innodb status?
Pacerier
1

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

Tout lister:

SHOW FULL PROCESSLIST  

si vous souhaitez supprimer un identifiant de transaction de copie de transaction de blocage et supprimer une transaction à l'aide de cette commande:

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