Aparece el mensaje "Se excedió el tiempo de espera de bloqueo; intente reiniciar la transacción" aunque no estoy usando una transacción
Estoy ejecutando la siguiente UPDATE
declaración MySQL:
mysql> update customer set account_import_id = 1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
No estoy usando una transacción, entonces ¿por qué recibiría este error? Incluso intenté reiniciar mi servidor MySQL y no ayudó.
La tabla tiene 406.733 filas.
CÓMO FORZAR EL DESBLOQUEO de tablas bloqueadas en MySQL:
Romper bloqueos como este puede causar que la atomicidad en la base de datos no se aplique a las declaraciones SQL que causaron el bloqueo.
Esto es un truco y la solución adecuada es reparar la aplicación que causó los bloqueos. Sin embargo, cuando hay dólares en juego, un rápido impulso hará que las cosas vuelvan a moverse.
1) Ingrese MySQL
mysql -u your_user -p
2) Veamos la lista de tablas bloqueadas.
mysql> show open tables where in_use>0;
3) Veamos la lista de los procesos actuales, uno de ellos está bloqueando su(s) tabla(s)
mysql> show processlist;
4) Mata uno de estos procesos.
mysql> kill <put_process_id_here>;
Estás utilizando una transacción; La confirmación automática no deshabilita las transacciones, simplemente las confirma automáticamente al final de la declaración.
Lo que podría estar sucediendo es que algún otro subproceso mantiene un bloqueo de registro en algún registro (¡estás actualizando todos los registros de la tabla!) durante demasiado tiempo y se está agotando el tiempo de espera de tu subproceso. O tal vez ejecutar múltiples (2+) consultas de ACTUALIZACIÓN en la misma fila durante una sola transacción.
Puedes ver más detalles del evento emitiendo un
SHOW ENGINE INNODB STATUS
después del evento (en el editor SQL). Lo ideal es hacer esto en una máquina de prueba silenciosa.
mysql> set innodb_lock_wait_timeout=100;
Query OK, 0 rows affected (0.02 sec)
mysql> show variables like 'innodb_lock_wait_timeout';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| innodb_lock_wait_timeout | 100 |
+--------------------------+-------+
Ahora active el bloqueo nuevamente. Tiene 100 segundos para enviar un SHOW ENGINE INNODB STATUS\G
a la base de datos y ver qué otra transacción está bloqueando la suya.
Eche un vistazo para ver si su base de datos está ajustada, especialmente el aislamiento de transacciones. No es una buena idea aumentar la innodb_lock_wait_timeout
variable.
Verifique el nivel de aislamiento de transacciones de su base de datos en MySQL:
mysql> SELECT @@GLOBAL.transaction_isolation, @@transaction_isolation, @@session.transaction_isolation;
+--------------------------------+-------------------------+---------------------------------+
| @@GLOBAL.transaction_isolation | @@transaction_isolation | @@session.transaction_isolation |
+--------------------------------+-------------------------+---------------------------------+
| REPEATABLE-READ | REPEATABLE-READ | REPEATABLE-READ |
+--------------------------------+-------------------------+---------------------------------+
1 row in set (0.00 sec)
Podrías obtener mejoras cambiando el nivel de aislamiento. Utilice el tipo Oracle READ COMMITTED
en lugar de REPEATABLE READ
. REPEATABLE READ
es el valor predeterminado de InnoDB.
mysql> SET transaction_isolation = 'READ-COMMITTED';
Query OK, 0 rows affected (0.00 sec)
mysql> SET GLOBAL transaction_isolation = 'READ-COMMITTED';
Query OK, 0 rows affected (0.00 sec)
Además, intenta utilizarlo SELECT FOR UPDATE
sólo si es necesario.