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.