Eu adicionei restrições NOT NULL a algumas colunas como esta, esperando que o comando fosse muito rápido por causa do NOT VALID
. No entanto, demorou cerca de 60 a 100 segundos e pareceu travar a mesa o tempo todo (com base em outras coisas que falharam durante esse tempo). Isso está em uma tabela com cerca de 8.600.000 linhas. Por quê isso aconteceu? Teria sido melhor fazer 4 comandos em vez de 1?
Postgres 12
ALTER TABLE my_table
ADD CONSTRAINT my_table_column1_not_null CHECK (column1 IS NOT NULL) NOT VALID,
ADD CONSTRAINT my_table_column2_not_null CHECK (column2 IS NOT NULL) NOT VALID,
ADD CONSTRAINT my_table_column3_not_null CHECK (column3 IS NOT NULL) NOT VALID,
ADD CONSTRAINT my_table_column4_not_null CHECK (column4 IS NOT NULL) NOT VALID;
A ALTER TABLE precisa de um bloqueio "exclusivo de acesso" na tabela. Embora ele mantenha esse bloqueio apenas por microssegundos depois de obtê-lo, ele ainda pode bloquear indefinidamente enquanto espera para adquiri-lo se qualquer outra sessão já estiver mantendo algum bloqueio na tabela. E uma vez que ele bloqueie, outras sessões, mesmo aquelas que desejam um bloqueio mais fraco, bloquearão por trás dele. (O PostgreSQL não permite salto de fila, então um bloqueio forte que está esperando para ser concedido bloqueará bloqueios fracos recebidos, mesmo que esses bloqueios recebidos sejam compatíveis com o bloqueio já mantido.)
Se você deseja que ALTER TABLE seja bem-sucedido ou falhe quase instantaneamente, defina lock_timeout para um valor baixo. Tentar executá-los como declarações separadas tornaria a situação pior, não melhor.