Estou seguindo esta resposta para adicionar uma NOT NULL
restrição a uma tabela de banco de dados existente com aproximadamente 100 milhões de linhas. No entanto, quando tento executar o processo de back-end, um arquivo ShareLock
.
ALTER TABLE mytable VALIDATE CONSTRAINT myfield_not_null;
Confirmei isso verificando pg_locks
em outra sessão, onde posso ver o seguinte (5447 é o pid do backend tentando VALIDATE CONSTRAINT):
mydb=> select l.pid, l.mode, l.granted, l.waitstart, a.xact_start, a.query_start, a.state from pg_locks l join pg_stat_activity a on l.pid = a.pid;
pid | mode | granted | waitstart | xact_start | query_start | state
-------+--------------------------+---------+-------------------------------+-------------------------------+-------------------------------+--------
5447 | ShareLock | t | | 2023-10-06 14:58:23.133136+00 | 2023-10-06 14:58:23.355743+00 | active
5447 | ShareUpdateExclusiveLock | t | | 2023-10-06 14:58:23.133136+00 | 2023-10-06 14:58:23.355743+00 | active
Os documentos dizem explicitamente:
um comando VALIDATE CONSTRAINT pode ser emitido para verificar se as linhas existentes satisfazem a restrição. A etapa de validação não precisa bloquear atualizações simultâneas, pois sabe que outras transações imporão a restrição às linhas que inserem ou atualizam; apenas as linhas pré-existentes precisam ser verificadas. Portanto, a validação adquire apenas um bloqueio SHARE UPDATE EXCLUSIVE na tabela que está sendo alterada.
O ShareLock está bloqueando algumas consultas que precisam de RowExclusiveLock (atualizar/inserir/excluir).
Como posso validar a restrição sem usar um ShareLock?
A AWS confirmou que este é um problema com sua versão do postgres. Eu acho que eles fizeram algum tipo de patch interno e bagunçaram tudo. O suporte confirmou que este comportamento está presente nas versões 14.7 e 14.8, mas não na 14.6 ou 14.9