Mostrar transacciones abiertas en MySQL


95

Hice algunas consultas sin un compromiso. Entonces se detuvo la aplicación.

¿Cómo puedo mostrar estas transacciones abiertas y confirmarlas o cancelarlas?


Creo que todas sus transacciones se cancelan al desconectarse, pero no estoy 100% seguro.
Johan

¿Qué tipo de tablas estás usando? ¿MyISAM, InnoDB, etc.?
cdeszaq

@cdeszaq, obviamente no MyISAM no tiene transacciones, además la pregunta realmente no tiene nada que ver con tablas.
Johan

2
@Johan: solo di MyISAM como ejemplo del tipo de tabla. Y es mucho lo hace la materia, porque no todas las tablas que las transacciones de apoyo se comportan de la misma manera con respecto a las transacciones en la pérdida de conexión.
cdeszaq

@cdeszaq, Los documentos de MySQL dicen algo muy diferente.
Johan

Respuestas:


60

¿Cómo puedo mostrar estas transacciones abiertas y confirmarlas o cancelarlas?

No hay una transacción abierta, MySQL revertirá la transacción al desconectarse.
No puede confirmar la transacción (IFAIK).

Muestra hilos usando

SHOW FULL PROCESSLIST  

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

No le ayudará, porque no puede realizar una transacción desde una conexión rota.

¿Qué sucede cuando se rompe una conexión?
De los documentos de MySQL: http://dev.mysql.com/doc/refman/5.0/en/mysql-tips.html

4.5.1.6.3. Deshabilitar la reconexión automática de mysql

Si el cliente mysql pierde su conexión con el servidor mientras envía una declaración, inmediatamente y automáticamente intenta volver a conectarse una vez al servidor y enviar la declaración nuevamente. Sin embargo , incluso si mysql logra reconectarse, su primera conexión ha finalizado y todos los objetos y configuraciones de su sesión anterior se pierden : tablas temporales, el modo de confirmación automática y las variables de sesión y definidas por el usuario. Además, cualquier transacción actual se revierte .

Este comportamiento puede ser peligroso para usted, como en el siguiente ejemplo en el que el servidor se apagó y reinició entre la primera y la segunda declaración sin que usted lo supiera:

Ver también: http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html

Cómo diagnosticar y solucionar este problema
Para comprobar la reconexión automática:

Si ocurre una reconexión automática (por ejemplo, como resultado de llamar a mysql_ping ()), no hay ninguna indicación explícita de ello. Para verificar la reconexión, llame mysql_thread_id()para obtener el identificador de conexión original antes de llamar mysql_ping(), luego mysql_thread_id()vuelva a llamar para ver si el identificador ha cambiado.

Asegúrese de mantener su última consulta (transacción) en el cliente para poder volver a enviarla si es necesario.
Y deshabilite el modo de reconexión automática, ya que es peligroso, implemente su propia reconexión en su lugar, para que sepa cuándo ocurre una caída y puede volver a enviar esa consulta.


Esto no tiene nada que ver con la pregunta. Esto solo afecta al cliente mysql, y el OP está hablando de una aplicación genérica, lo que probablemente significa su aplicación. Además, dado que la aplicación de llamada se detuvo, ¿cómo podría mantener la transacción en la memoria?
cdeszaq

@cdeszaq, tiene todo que ver con la pregunta. Una aplicación generalmente usa mysqld.dllAKA el cliente. Y usted mantiene la declaración SQL que contiene la transacción completa en la memoria, de modo que pueda reproducirla cuando la conexión se interrumpa. O lo mantiene localmente en el disco, de modo que al reiniciarlo pueda volver a enviarlo.
Johan

Solo se muestra el comando de mi lista de procesos en SHOW FULL PROCESSLIST. Así que supongo que simplemente no hay transacciones abiertas. La parte divertida es que los autoincrement_ids parecen haberse perdido.
Alex

@alex, los documentos oficiales afirman que, por lo que es un comportamiento documentado. Vea los enlaces.
Johan

Hermoso, Johan. Respondió la pregunta y mostró algunas consecuencias y las soluciones a esas consecuencias, todo en un par de párrafos.
Gerard ONeill

53

Aunque no habrá ninguna transacción restante en el caso, como dijo @Johan, puede ver la lista de transacciones actual en InnoDB con la consulta a continuación si lo desea.

SELECT * FROM information_schema.innodb_trx\G

Del documento :

La tabla INNODB_TRX contiene información sobre cada transacción (excluidas las transacciones de solo lectura) que se están ejecutando actualmente dentro de InnoDB, incluido si la transacción está esperando un bloqueo, cuándo comenzó la transacción y la declaración SQL que se está ejecutando la transacción, si corresponde.


¿No supone que hay alguna forma de saber si las transacciones en esa tabla pertenecen a su solicitud / sesión específica?
Captain Hypertext

1
Tenga en cuenta que el \Gmodificador al final solo es útil si desea formatear la salida de la consulta dentro de la herramienta CLI de mysql. Si usa una herramienta GUI como Mysql Workbench, no la necesita.
barell

29

Puede usar show innodb status(o show engine innodb statuspara versiones más recientes de mysql) para obtener una lista de todas las acciones actualmente pendientes dentro del motor InnoDB. Enterradas en la pared de salida estarán las transacciones y el ID de proceso interno bajo el que se ejecutan.

No podrá forzar una confirmación o una reversión de esas transacciones, pero PUEDE matar el proceso de MySQL que las ejecuta, lo que esencialmente se reduce a una reversión. Mata la conexión de los procesos y hace que MySQL limpie el desorden que dejó.

Esto es lo que querría buscar:

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

En este caso, solo hay una conexión con el motor InnoDB en este momento (mi inicio de sesión, ejecutando la showconsulta). Si esa línea fuera una conexión real / transacción atascada que quisiera terminar, entonces haría un kill 10594.


Realmente no es necesario eliminar una conexión de forma activa después de un tiempo de espera, la conexión se eliminará de todos modos y la transacción pendiente de una conexión rota no se puede confirmar, por lo que se pueden volver a enviar sin temor a duplicaciones.
Johan

3
Es mejor eliminar las transacciones atascadas sin esperar un tiempo de espera para limpiar; de lo contrario, corre el riesgo de que se produzcan puntos muertos.
Marc B

Ah, sí, +1 por ese comentario. Olvidé esos puntos muertos por un minuto.
Johan

@MarcB, ¿Por qué lo cambiaron a show engine innodb status?
Pacerier

1

Al utilizar esta consulta, puede ver todas las transacciones abiertas.

Listar todo:

SHOW FULL PROCESSLIST  

si desea eliminar una transacción colgada, copie la identificación de la transacción y elimine la transacción usando este comando:

KILL <id>    // e.g KILL 16543
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.