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

INSERT ... SELECT, InnoDB e blocco

È 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".