Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

INSERT ... SELECT, InnoDB e bloqueio


Está correto. As linhas na tabela que estão sendo lidas são bloqueadas com um bloqueio compartilhado (o SELECT é implicitamente LOCK IN SHARE MODE ). Não há como evitar isso. É mais ou menos o que você está pedindo ao sistema:copie todas as linhas que correspondem a uma condição. A única maneira de garantir que todas as linhas correspondam à condição e que essa lista não seja alterada durante ou imediatamente após a execução dessa instrução é bloquear as linhas.

Como um esclarecimento sobre por que você não consegue INSERT com group_id = 2 :

Isso tem a ver com sua consulta sendo especificamente WHERE group_id = 3 AND created < '2014-01-04' em KEY group_id_created (group_id, created) . Para pesquisar todas as linhas que correspondem a group_id = 3 AND created < '2014-01-04' o índice será percorrido para trás começando com a primeira linha que excede essa condição do limite superior, que é (3, '2014-01-14') e continuando até encontrar uma linha que não corresponda à condição, que desde created não tem limite inferior será a primeira linha onde group_id < 3 que, claro, é group_id = 2 .

Isso significa que a primeira linha encontrada com group_id = 2 é também bloqueado, que será a linha com o máximo de created valor. Isso tornará impossível INSERT no "intervalo" entre (2, MAX(created)) e (3, MIN(created)) (não é SQL adequado, é claro, apenas pseudo-SQL), embora isso não seja um "bloqueio de lacuna" especificamente.