I deadlock di InnoDB sono esclusivi di INSERT / UPDATE / DELETE?


8

Sto lavorando intorno all'errore MySQL "Trovato deadlock durante il tentativo di ottenere il blocco; provare a riavviare la transazione" .

Dovrò aggiornare un programma per consentire deadlock. È possibile che tale SELECTistruzione produca errori di deadlock? So che è solo un blocco di lettura in modo più seleziona non sarà un problema, ma se c'è una INSERT, UPDATEo di DELETEdichiarazione (con subqueries possibile con unisce) e una SELECTdichiarazione (possibile con raccordi, né sottoquery) ?

È possibile che l'errore venga generato al SELECTposto del INSERT, UPDATEo DELETE.

La storia è qui se sei curioso.


+1 per questo è una buona domanda perché mette in luce una stranezza di InnoDB di cui la maggior parte delle persone non è a conoscenza insieme a SELECT contro le tabelle di InnoDB.
RolandoMySQLDBA

Risposte:


5

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.


@Rolando - non è vero con l'MVCC di InnoDB che non legge mai il blocco (tranne quando si usa for updateovviamente)?
Jack dice di provare topanswers.xyz il

@Jack - Se leggi i link nei primi 3 punti elenco, vedrai che MVCC non è in discussione. È un deadlock profondo nell'indice cluster che nemmeno MVCC può mitigare.
RolandoMySQLDBA

@Rolando - Ho letto i collegamenti un po 'più attentamente e ancora non vedo alcuna indicazione che un normale selectpuò bloccare le righe o in qualche modo essere bloccato dal DML in un'altra transazione. Questo è certamente vero per Oracle e per quanto posso dire è vero anche per InnoDB? Tranne il caso in cui l' selectistruzione esegue effettivamente il DML tramite una funzione o un altro percorso circolare ovviamente.
Jack dice di provare topanswers.xyz il

@Jack - Se SELECTs riesce a bloccare un indice, quanto più un AGGIORNAMENTO, come mostrato dai miei primi 3 collegamenti.
RolandoMySQLDBA,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.