Mysql
 sql >> Base de données >  >> RDS >> Mysql

INSERT ... SELECT, InnoDB et verrouillage

C'est correct. Les lignes de la table en cours de lecture sont verrouillées avec un verrou partagé (le SELECT est implicitement LOCK IN SHARE MODE ). Il n'y a aucun moyen d'éviter cela. C'est en quelque sorte ce que vous demandez au système :copier toutes les lignes qui correspondent à une condition. La seule façon de s'assurer qu'il s'agit bien de toutes les lignes qui correspondent à la condition et que cette liste ne change pas pendant ou immédiatement après l'exécution de cette instruction, est de verrouiller les lignes.

Pour clarifier pourquoi vous ne pouvez pas INSERT avec group_id = 2 :

Cela a à voir avec votre requête étant spécifiquement WHERE group_id = 3 AND created < '2014-01-04' sur KEY group_id_created (group_id, created) . Afin de rechercher toutes les lignes qui correspondent à group_id = 3 AND created < '2014-01-04' l'index sera parcouru en arrière en commençant par la première ligne qui dépasse cette condition la limite supérieure, qui est (3, '2014-01-14') et continuer jusqu'à trouver une ligne qui ne correspond pas à la condition, qui depuis created n'a pas de limite inférieure sera la première ligne où group_id < 3 qui est bien sûr group_id = 2 .

Cela signifie que la première ligne rencontrée avec group_id = 2 est aussi verrouillé, qui sera la ligne avec le maximum de created évaluer. Il sera alors impossible de INSERT dans "l'écart" entre (2, MAX(created)) et (3, MIN(created)) (pas le bon SQL bien sûr, juste du pseudo-SQL), bien qu'il ne s'agisse pas spécifiquement d'un "gap lock".