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.