È corretto. Le righe della tabella da cui si sta leggendo sono bloccate con un blocco condiviso (il SELECT
è implicitamente LOCK IN SHARE MODE
). Non c'è un modo per evitarlo. È una specie di quello che stai chiedendo al sistema:copia tutte le righe che soddisfano una condizione. L'unico modo per assicurarsi che tutte le righe soddisfino la condizione e che l'elenco non cambi durante o immediatamente dopo l'esecuzione di tale istruzione, è bloccare le righe.
Come chiarimento sul motivo per cui non riesci a INSERT
con group_id = 2
:
Questo ha a che fare con la tua query specificatamente WHERE group_id = 3 AND created < '2014-01-04'
su KEY group_id_created (group_id, created)
. Per cercare tutte le righe che corrispondono a group_id = 3 AND created < '2014-01-04'
l'indice verrà attraversato all'indietro a partire dalla prima riga che supera tale condizione il limite superiore, che è (3, '2014-01-14')
e continuando fino a trovare una riga che non corrisponde alla condizione, che da quando created
non ha limite inferiore sarà la prima riga in cui group_id < 3
che ovviamente è group_id = 2
.
Ciò significa che la prima riga incontrata con group_id = 2
è anche bloccato, che sarà la riga con il massimo created
valore. Ciò renderà impossibile INSERT
nello "spazio" tra (2, MAX(created))
e (3, MIN(created))
(non corretto SQL ovviamente, solo pseudo-SQL), anche se questo non è specificamente un "blocco gap".