Eu sei que quando um índice está sendo criado simultaneamente, apenas um bloqueio SHARE ShareUpdateExclusiveLock é necessário.
Mas existe um tipo mais rigoroso de bloqueio necessário no início do processo por um pequeno período de tempo? Ou é necessário apenas um bloqueio SHARE ShareUpdateExclusiveLock para toda a operação?
Estou perguntando porque estou querendo saber quais tipos de tempos limite são vantajosos para definir ao criar um índice simultaneamente.
Bem, quando a documentação não é suficiente é possível olhar diretamente no código. Darei links para já lançados
PostgreSQL 13.1
(REL_13_1
tag) para evitar possíveis alterações de número de linha no futuro.Provavelmente não descreverei todo o caminho do código do comando do cliente. Pela gramática, sabemos que precisamos
IndexStmt
do nó de comando - a mesma gramática para o índice de criação simultânea e não concorrente. Tudo o que for útil começará emProcessUtilitySlow
E aqui, no comentário de
case T_IndexStmt
, pode ser encontrada a resposta direta para a pergunta:Em geral, o PostgreSQL não atualizará o bloqueio durante a execução do comando. E levará o bloqueio mais forte que eventualmente será necessário. Pois
CREATE INDEX CONCURRENTLY
éShareUpdateExclusiveLock
. Não é umSHARE
bloqueio como mencionado em questão.Mas vamos continuar lendo:
find_all_inheritors
adquirirá o mesmo lockmode nos herdeiros.transformIndexStmt
podem ser encontrados alguns modos de bloqueio, masNoLock
eAccessShareLock
- eles são mais fracos do queShareUpdateExclusiveLock
DefineIndex
vemos outro lembrete:E decida usar novamente o ShareUpdateExclusiveLock para compilar simultaneamente. Esta parte do código é visivelmente longa (ainda não tão grande quanto, por exemplo, planner), mas legível.
estou faltando alguma coisa? Provavelmente. Então vamos construir o PostgreSQL com
-DLOCK_DEBUG
a opção de depurar o comportamento de bloqueio e ver isso acontecer:trace_locks
registrará muitas coisas, mas estamos interessados em:lock [12664,16387]
aqui significa databaseOID = 12664
,pg_class
OID = 16387
(essas linhas são registradas emLockAcquireExtended
).Então, na verdade, adquirimos apenas
ShareUpdateExclusiveLock
na própria mesa.OID=16393
com vários outros bloqueios é o índice que este comando construiu. Embora níveis de bloqueio pesados sejam mencionados para esse objeto, ele não interferirá em outras consultas.Create index concurrently
O comando foi especialmente projetado para funcionar com segurança durante a execução de consultas normais de aplicativos.