Mysql: Cómo Diagnosticar Bloqueos en Innodb

Mysql: Cómo Diagnosticar Bloqueos en Innodb

MySQL es una base de datos muy popular, y contrario a las creencias que se generaron cuando estaba en sus versiones iniciales, es muy potente y prueba de ellos es su adopción por parte de varios nombre pesados de la Web, como Faceboo, Twitter y Lindkedin solo por nombrar algunas, aquí puedes consultar un listado más amplio.

InnoDB es el motor por defecto para MySQL desde su versión 4 y trae consigo grandes ventajas en consistencia y fiabilidad, por ejemplo, soporta transacciones atómicas, es decir, un grupo de consultas se debe ejecutar por completo o no ejecutarse, el ejemplo típico de esto es sistema bancario dónde para pasar dinero entre cuentas hay que restarlo de una cuenta y sumarlo en otra, hacer solo una de las dos operaciones es inaceptable. Estas ventajas vienen con algunos cuidados que debemos tener.

La atomicidad se logra mediante las sentencias BEGIN, COMMIT, ROLLBACK, que son iniciar transacción, guardar los cambios y descartar los cambios.

En Java un bloque típico para una transacción atómica se vería así:

  1. try {
  2.     begin
  3.     .
  4.     .
  5.     commit
  6. } catch {
  7.     rollback
  8. }

En una oportunidad accidentalmente olvidamos colocar el rollback dentro del catch, un error simple pero de consecuencias desastrosas, que hacía que la transacción nunca terminara y los registros involucrados quedaran bloqueados, y esto generaba un timeout para cualquier otra operación que quisiera trabajar con estos registros y molestias para nuestros los usuarios.

En un sistema tan extenso la tarea encontrar la tablas comprometidas y el código defectuoso hubiera tomado días enteros, pero por fortuna hay una herramienta que nos facilita este trabajo, es la instrucción SHOW INNODB STATUS o SHOW ENGINE INNODB STATUS, según la versión de MySQL.

En el campo STATUS nos entrega un texto bastante extenso que tiene varias secciones, la que nos interesa en esta oportunidad es TRANSACTIONS, ahí podemos ver las transacciones actuales y podremos encontrar si alguna está bloqueada, por cuanto tiempo ha estado así y qué consulta se está tratando de ejecutar.

Por ejemplo, vamos a generar un bloqueo adrede para ver cómo se registra. En una transacción vamos a ejecutar:

  1. BEGIN;
  2. UPDATE una_tabla SET un_atributo = un_valor;

Y en otra transacción vamos a ejecutar:

  1. UPDATE una_tabla SET un_atributo = otro_valor;

Al estar la primera transacción sin terminar la segunda se quedará en espera, generando un bloqueo, la sección TRANSACTIONS dirá algo cómo:

---TRANSACTION BA2732, ACTIVE 29 sec starting index read

mysql tables in use 1, locked 1

  1. ---TRANSACTION BA2732, ACTIVE 29 sec starting index read
  2. mysql tables in use 1, locked 1
  3. LOCK WAIT 2 lock struct(s), heap size 376, 1 row lock(s)
  4. MySQL thread id 58, OS thread handle 0x2f8, query id 1052 localhost 127.0.0.1 root Updating
  5. UPDATE una_tabla SET un_atributo = otro_valor;
  6. ------- TRX HAS BEEN WAITING 29 SEC FOR THIS LOCK TO BE GRANTED:

Todo esto nos ayudará a diagnosticar el sistema y encontrar el problema con mayor rapidez. No hay que olvidar que para obtener todo el potencial de INNODB debemos cuidarnos de terminar correctamente todas las transacciones que iniciemos para así evitar dolores de cabeza.

Gracias por tu atención, no olvides compartirlo si te fue útil o conoces a alguien a quien pueda servirle. Comenta tus experiencias con el uso de MySQL e INNODB.

Deja un Comentario

CAPTCHA code
X