La risposta diretta al titolo della tua domanda è No.
Le query SELECT possono eseguire blocchi su gen_clust_index , noto anche come Clustered Index.
Ecco tre domande sugli scambi di stack DBA che ho esaminato in modo aggressivo con @RedBlueThing , la persona che ha posto queste domande. @RedBlueThing ha trovato soluzioni per le sue domande.
Solo per mantenere la tua domanda in prospettiva, quando guardi queste risposte (non guardare troppo in profondità, anche se ho le vertigini guardando le mie risposte contorte), dovrebbe essere rapidamente evidente che le query SELECT possono bloccare i dati.
Esistono anche casi speciali di SELECT in cui è possibile bloccare specifiche righe su richiesta .
AGGIORNAMENTO 2011-08-08 16:49 EDT
È stata posta la domanda di variazione: "Le eccezioni del deadlock di InnoDB potrebbero essere generate da SELECT" La risposta può essere Sì in determinate condizioni. Qual è quella condizione? Se viene eseguito il rollback di una sola istruzione SQL a seguito di un errore, alcuni dei blocchi impostati dall'istruzione potrebbero essere conservati. Ciò accade perché InnoDB archivia i blocchi di riga in un formato tale da non poter sapere in seguito quale blocco è stato impostato da quale istruzione .
Sulla base di tale affermazione, le sequenze di eventi che causano ciò potrebbero teoricamente essere le seguenti:
- L'aggiornamento SQL di una singola riga ma genera un errore
- UPDATE provoca un rollback di una riga
- La fila ha un blocco persistente
Personalmente, quell'ultima affermazione mi spaventa. Sarebbe stato bello per MySQL informare tutti di questa stranezza. Tuttavia, questa affermazione proviene dalla documentazione di MySQL. (Oh sì, Oracle possiede InnoDB)
AGGIORNAMENTO 2015-09-22 18:40 EST
All'inizio dell'anno, ho appreso che Percona ha un bel controllo di Nagios per trovare queste fastidiose serrature che si nascondono dietro connessioni notturne. Ora non ti resta che eseguire il codice da quel link:
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;
Funzionerà solo con MySQL 5.5+. Se si dispone di MySQL 5.1 o precedenti, è necessario interrompere tutte le connessioni in sospensione per rilasciare i blocchi.