Mysql
 sql >> Database >  >> RDS >> Mysql

MySQL/InnoDB e query di lunga durata

In primo luogo, penso che sarebbe utile come sfondo per leggere su controllo della concorrenza multi-versione (MVCC) come sfondo per questa risposta.

InnoDB implementa MVCC, il che significa che può utilizzare letture non bloccanti per SELECT regolari . Ciò non richiede la creazione di uno "snapshot" e infatti InnoDB non ha alcun concetto reale di snapshot come oggetto. Invece, ogni record nel database tiene traccia del proprio numero di versione e mantiene un "puntatore di rollio" a un record di "registro annullamenti" (che può o non può ancora esistere) che modifica la riga alla sua versione precedente. Se è necessaria una versione precedente di un record, viene letta la versione corrente, vengono seguiti i puntatori di rollio e applicati i record di annullamento fino a quando non viene prodotta una versione sufficientemente vecchia del record.

Normalmente il sistema ripulisce costantemente quei registri di annullamento e riutilizza lo spazio che consumano.

In qualsiasi momento qualsiasi transazione di lunga durata (nota, non necessariamente una singola query) è presente, i registri di annullamento devono essere conservati (non eliminati) per ricreare sufficientemente vecchie versioni sufficientemente vecchie di tutti i record per soddisfare quella transazione. In un sistema molto impegnato, i registri di annullamento possono accumularsi molto rapidamente per consumare gigabyte di spazio. Inoltre, se singoli record specifici vengono modificati molto frequentemente, il ripristino di tale record a una versione sufficientemente vecchia per soddisfare la query potrebbe richiedere moltissime applicazioni di registro di annullamento (migliaia).

Questo è ciò che rende le "interrogazioni di lunga durata" costose e disapprovate. Aumenteranno il consumo di spazio su disco per mantenere i registri di annullamento nella tablespace di sistema e funzioneranno male a causa dell'applicazione del record di registro di annullamento per ripristinare le versioni di riga al momento della lettura.

Alcuni database implementano una quantità massima di spazio di registro di annullamento che può essere consumata e, una volta raggiunto tale limite, iniziano a eliminare i record di registro di annullamento meno recenti e a invalidare le transazioni in esecuzione. Questo genera un messaggio di errore "istantanea troppo vecchia" per l'utente. InnoDB non ha tale limite e consente l'accumulo indefinitamente.