Pelo que entendi, o fato de nossa consulta estar aguardando um bloqueio significa que sempre o aguardou e nunca mudou nada.
Certo - se você perceber que pg_stat_activity.waiting é "verdadeiro" para uma ALTER TABLE, isso quase certamente significa que está aguardando pacientemente o bloqueio ACCESS EXCLUSIVE em sua tabela de destino e seu trabalho real (reescrevendo a tabela, se necessário, alterando catálogos , reconstruir índices etc.) ainda não foi iniciado.
É seguro cancelar completamente nossa consulta ALTER TABLE? Ou é possível que a consulta já tenha modificado algo e cancelá-lo deixaria nosso banco de dados em um estado intermediário de algum tipo?
O cancelamento de consultas (ou, equivalentemente, a reversão de uma transação) no PostgreSQL não apresenta nenhum risco de corrupção de banco de dados que você possa ter assustado em alguns outros bancos de dados (por exemplo, o aviso aterrorizante na parte inferior desta página). É por isso que os não superusuários são, nas versões recentes, livres para usar pg_cancel_backend()
e pg_terminate_backend()
eliminar suas próprias consultas em execução em outros back-ends - eles podem ser usados com segurança, sem se preocupar com a corrupção do banco de dados. Afinal, o PostgreSQL precisa estar preparado para lidar com qualquer processo que seja eliminado, por exemplo, o SIGKILL do assassino OOM, o desligamento do servidor, etc. É para isso que serve o log do WAL .
Você também deve ter visto que no PostgreSQL, é possível executar a maioria dos comandos DDL aninhados em uma transação (multi-instrução), por exemplo
BEGIN;
ALTER TABLE foo ...;
ALTER TABLE bar ...;
-- more stuff
COMMIT; -- or ROLLBACK; if you've changed your mind
(Impressionante para garantir que as migrações de esquema sejam realizadas juntas ou totalmente.) Você disse:
Nós fez não envolva o ALTER TABLE
em uma transação.
Isso é bom para um único comando - dos documentos ,
O PostgreSQL realmente trata cada instrução SQL como sendo executada dentro de uma transação. Se você não emitir um comando BEGIN, cada instrução individual terá um BEGIN implícito e (se bem-sucedido) COMMIT envolvido nele. Às vezes, um grupo de instruções cercado por BEGIN e COMMIT é chamado de bloco de transação.
Portanto, cancelar isso ALTER TABLE
, através de pg_cancel_backend()
um Ctrl-C ou emitido a partir do prompt psql de controle, terá um efeito semelhante como se você tivesse feito
BEGIN;
ALTER TABLE ... ;
ROLLBACK;
(embora você esperasse ver, cancelar esse caro ALTER TABLE
pode salvar o banco de dados de muitas operações desnecessárias, se você quiser ROLLBACK
.