Estoy ejecutando la siguiente UPDATE
declaración de 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 me ayudó.
La tabla tiene 406,733 filas.
mysql
sql
timeout
lock-timeout
Jason Swett
fuente
fuente
process
para estar inactivo. Si es así, podría obtener este error. Estoy en lo cierto?connection.commit()
para confirmarINSERT
oUPDATE
acaba de pasar.CÓMO FORZAR EL DESBLOQUEO para tablas bloqueadas en MySQL:
Romper bloqueos como este puede causar que no se aplique la atomicidad en la base de datos en las instrucciones sql que causaron el bloqueo.
Esto es hackeo, y la solución adecuada es arreglar su aplicación que causó los bloqueos. Sin embargo, cuando hay dólares en juego, una patada rápida hará que las cosas vuelvan a moverse.
1) Ingrese MySQL
2) Veamos la lista de tablas bloqueadas
3) Veamos la lista de los procesos actuales, uno de ellos es bloquear sus tablas.
4) Mata uno de estos procesos
fuente
Ahora active el bloqueo nuevamente. Tiene 100 segundos para emitir un
SHOW ENGINE INNODB STATUS\G
a la base de datos y ver qué otra transacción está bloqueando la suya.fuente
lock_wait_timeout
valorEche un vistazo a si su base de datos está ajustada. Especialmente el aislamiento de transacciones. No es buena idea aumentar la variable innodb_lock_wait_timeout.
Verifique el nivel de aislamiento de la transacción de su base de datos en mysql cli:
Puede obtener mejoras cambiando el nivel de aislamiento, use el oráculo como READ COMMITTED en lugar de REPEATABLE READ (valores predeterminados de InnoDB)
También intente usar SELECCIONAR PARA ACTUALIZAR solo si es necesario.
fuente
tx_isolation
variable atransaction_isolation
.Ninguna de las soluciones sugeridas funcionó para mí, pero esto sí.
Algo está bloqueando la ejecución de la consulta. Lo más probable es que otra consulta se actualice, inserte o elimine de una de las tablas de su consulta. Tienes que averiguar qué es eso:
Una vez que localice el proceso de bloqueo, búsquelo
id
y ejecute:Vuelva a ejecutar su consulta inicial.
fuente
100% con lo que dijo MarkR. autocommit hace que cada declaración sea una transacción de una declaración.
SHOW ENGINE INNODB STATUS
debería darle algunas pistas sobre la razón del punto muerto. Eche un buen vistazo a su registro de consulta lento también para ver qué más está consultando la tabla e intente eliminar cualquier cosa que esté haciendo un escaneo de tabla completo. ¡El bloqueo de nivel de fila funciona bien, pero no cuando intentas bloquear todas las filas!fuente
¿Puede actualizar cualquier otro registro dentro de esta tabla, o esta tabla es muy utilizada? Lo que estoy pensando es que, mientras intenta adquirir un bloqueo, necesita actualizar este registro, el tiempo de espera establecido se ha agotado. Es posible que pueda aumentar el tiempo que puede ayudar.
fuente
innodb_lock_wait_timeout
enmy.cnf
El número de filas no es enorme ... Cree un índice en account_import_id si no es la clave principal.
fuente
Si acaba de matar una consulta grande, llevará tiempo hacerlo
rollback
. Si emite otra consulta antes de que la consulta finalizada se revierta, es posible que obtenga un error de tiempo de espera de bloqueo. Eso es lo que me pasó. La solución fue solo esperar un poco.Detalles:
Había emitido una consulta DELETE para eliminar aproximadamente 900,000 de aproximadamente 1 millón de filas.
Ejecuté esto por error (elimina solo el 10% de las filas):
DELETE FROM table WHERE MOD(id,10) = 0
En lugar de esto (elimina el 90% de las filas):
DELETE FROM table WHERE MOD(id,10) != 0
Quería eliminar el 90% de las filas, no el 10%. Así que eliminé el proceso en la línea de comando de MySQL, sabiendo que revertiría todas las filas que había eliminado hasta ahora.
Luego ejecuté el comando correcto inmediatamente y recibí un
lock timeout exceeded
error poco después. Me di cuenta de que el bloqueo en realidad podría ser elrollback
de la consulta eliminada que aún se realiza en segundo plano. Así que esperé unos segundos y volví a ejecutar la consulta.fuente
Asegúrese de que las tablas de la base de datos estén usando el motor de almacenamiento InnoDB y el nivel de aislamiento de transacciones READ-COMMITTED.
Puede verificarlo seleccionando @@ GLOBAL.tx_isolation, @@ tx_isolation; en la consola mysql.
Si no está configurado para READ-COMMITTED, debe configurarlo. Antes de configurarlo, asegúrese de tener privilegios SUPER en mysql.
Puede obtener ayuda de http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html .
Al configurar esto, creo que su problema se resolverá.
Es posible que también desee comprobar que no está intentando actualizar esto en dos procesos a la vez. Los usuarios (@tala) han encontrado mensajes de error similares en este contexto, tal vez verifique que ...
fuente
Vengo de Google y solo quería agregar la solución que funcionó para mí. Mi problema era que estaba tratando de eliminar registros de una tabla enorme que tenía muchos FK en cascada, así que recibí el mismo error que el OP.
Inhabilité el
autocommit
y luego funcionó simplemente agregandoCOMMIT
al final de la oración SQL. Según tengo entendido, esto libera el búfer poco a poco en lugar de esperar al final del comando.Para seguir con el ejemplo del OP, esto debería haber funcionado:
mysql> set autocommit=0;
mysql> update customer set account_import_id = 1; commit;
No olvide
autocommit
volver a activarlo nuevamente si desea salir de la configuración de MySQL como antes.mysql> set autocommit=1;
fuente
Tarde a la fiesta (como siempre), sin embargo, mi problema fue el hecho de que escribí algunos SQL incorrectos (siendo un novato) y varios procesos tenían un bloqueo en los registros <- no estoy seguro de la palabrería adecuada. Terminé teniendo que simplemente:
SHOW PROCESSLIST
y luego matar las ID usandoKILL <id>
fuente
Este tipo de cosas me sucedió cuando estaba usando php language construct exit; en medio de la transacción. Luego, esta transacción se "cuelga" y necesita matar el proceso mysql (descrito anteriormente con la lista de procesos;)
fuente
En mi caso, estaba ejecutando una consulta anormal para corregir datos. Si bloquea las tablas en su consulta, no tendrá que lidiar con el tiempo de espera de bloqueo:
Probablemente esta no sea una buena idea para el uso normal.
Para obtener más información, consulte: Manual de referencia de MySQL 8.0
fuente
Me encontré con esto teniendo 2 conexiones Doctrine DBAL, una de ellas como no transaccional (para registros importantes), están destinadas a ejecutarse en paralelo sin depender una de la otra.
Mis pruebas de integración se incluyeron en transacciones para la reversión de datos después de la misma prueba.
Mi solución fue deshabilitar la transacción de ajuste en esas pruebas y restablecer los datos db de otra manera.
fuente
Tuve el mismo error, aunque solo estaba actualizando una tabla con una entrada, pero después de reiniciar mysql, se resolvió.
fuente