¿Los bloqueos muertos de InnoDB son exclusivos de INSERT / UPDATE / DELETE?

8

Estoy trabajando en el error de MySQL "Se encontró un punto muerto al intentar bloquear; intente reiniciar la transacción" .

Voy a tener que actualizar un programa para permitir puntos muertos. ¿Es posible que esa SELECTdeclaración produzca errores de punto muerto? Sé que es sólo un bloqueo de lectura por lo que múltiples selecciona no será un problema, pero lo que si hay una INSERT, UPDATEo DELETEdeclaración (con subconsultas posible con uniones) y una SELECTdeclaración (es posible con une o subconsultas) ?

¿Es posible que el error se arroje en SELECTlugar de INSERT, UPDATEo DELETE?

La historia está aquí si tienes curiosidad.

Bryan Field
fuente
+1 para esta es una buena pregunta porque saca a la luz una peculiaridad de InnoDB que la mayoría de la gente no conoce junto con SELECTs en las tablas de InnoDB.
RolandoMySQLDBA

Respuestas:

5

La respuesta directa al título de su pregunta es No.

Las consultas SELECT pueden realizar bloqueos en el gen_clust_index , también conocido como el índice agrupado .

Aquí hay tres preguntas de Intercambios de pila de DBA que miré agresivamente con @RedBlueThing , la persona que hizo estas preguntas. @RedBlueThing encontró soluciones para sus preguntas.

Solo para mantener su pregunta en perspectiva, cuando revise estas respuestas (no mire demasiado profundamente, incluso me mareo al mirar mis propias respuestas enrevesadas) debería ser rápidamente evidente que las consultas SELECT pueden bloquear datos.

También tiene casos especiales de SELECT donde puede bloquear filas específicas bajo demanda .

ACTUALIZACIÓN 2011-08-08 16:49 EDT

Hiciste la pregunta de variación: "¿SELECT puede lanzar excepciones de punto muerto de InnoDB? La respuesta a eso puede ser Sí bajo una determinada condición. ¿Cuál es esa condición? Si solo una declaración SQL se revierte como resultado de un error, algunos de los bloqueos establecidos por la declaración pueden conservarse. Esto sucede porque InnoDB almacena bloqueos de fila en un formato tal que no puede saber después qué bloqueo se estableció con qué instrucción .

En base a esa afirmación, las secuencias de eventos para causar esto podrían ser teóricamente las siguientes:

  • Su SQL ACTUALIZA una sola fila pero genera un error
  • La ACTUALIZACIÓN provoca una reversión de la fila
  • La fila tiene una cerradura persistente

Personalmente, esa última declaración me asusta. Hubiera sido bueno para MySQL informar a todos de esta peculiaridad. Sin embargo, esa declaración es de la documentación de MySQL. (Oh sí, Oracle posee InnoDB)

ACTUALIZACIÓN 2015-09-22 18:40 EST

A principios de año, aprendí que Percona tiene un cheque de Nagios genial para encontrar estas molestas cerraduras escondidas detrás de las conexiones para dormir. Todo lo que tiene que hacer ahora es ejecutar el código desde ese enlace:

SELECT COALESCE(MAX(IF(p.command = 'Sleep', p.time, 0)), 0) AS idle_in_trx
FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS AS w
INNER JOIN INFORMATION_SCHEMA.INNODB_TRX        AS b ON  b.trx_id = w.blocking_trx_id
INNER JOIN INFORMATION_SCHEMA.INNODB_TRX        AS r ON  r.trx_id = w.requesting_trx_id
LEFT JOIN  INFORMATION_SCHEMA.PROCESSLIST       AS p ON  p.id     = b.trx_mysql_thread_id;

Esto solo funcionará para MySQL 5.5+. Si tiene MySQL 5.1 o anterior, debe eliminar todas las conexiones inactivas para liberar los bloqueos.

RolandoMySQLDBA
fuente
@Rolando: ¿no es cierto con MVCC de InnoDB que las lecturas nunca se bloquean (excepto cuando se usa, for updatepor supuesto)?
Jack dice que intente topanswers.xyz
@Jack: si lee los enlaces en los primeros 3 puntos, verá que MVCC no está en cuestión. Es un punto muerto profundo en el índice agrupado que ni siquiera MVCC puede mitigar.
RolandoMySQLDBA
@Rolando: he leído los enlaces con un poco más de atención y todavía no puedo ver ninguna indicación de que una normal selectpueda bloquear filas o de alguna manera ser bloqueada por DML en otra transacción. ¿Eso es cierto para Oracle y, por lo que puedo decir, también es cierto para InnoDB? Excepto el caso cuando la selectdeclaración realmente hace DML a través de una función o alguna otra ruta circular, por supuesto.
Jack dice que intente topanswers.xyz
@Jack: si los SELECT pueden bloquear un índice, cuánto más una ACTUALIZACIÓN como se muestra en mis primeros 3 enlaces.
RolandoMySQLDBA