Pour autant que je sache, le fait que notre requête attend un verrou signifie qu'elle a toujours attendu un verrou et qu'elle n'a rien changé.
Droite - si vous voyez que pg_stat_activity.waiting est "vrai" pour une ALTER TABLE, cela signifie presque certainement qu'il attend patiemment le verrou ACCESS EXCLUSIVE sur sa table cible et son vrai travail (réécriture de la table si nécessaire, changement de catalogues , reconstruction d'index, etc.) n'a pas encore commencé.
Est-il sûr pour nous d'annuler purement et simplement notre requête ALTER TABLE? Ou est-il possible que la requête ait déjà modifié quelque chose et que son annulation laisserait notre base de données dans un état intermédiaire?
L'annulation de requêtes (ou, de manière équivalente, l'annulation d'une transaction) dans PostgreSQL ne présente aucun risque de corruption de base de données qui pourrait vous avoir effrayé dans certaines autres bases de données (par exemple l' avertissement terrifiant au bas de cette page). C'est pourquoi les non-superutilisateurs sont, dans les versions récentes, libres d'utiliser pg_cancel_backend()
et pg_terminate_backend()
de tuer leurs propres requêtes exécutées dans d'autres backends - ils sont sûrs à utiliser sans s'inquiéter de la corruption de la base de données. Après tout, PostgreSQL doit être prêt à faire face à tout processus interrompu, par exemple SIGKILL du tueur OOM, arrêt du serveur, etc. C'est à cela que sert le journal WAL .
Vous avez peut-être également vu que dans PostgreSQL, il est possible d'exécuter la plupart des commandes DDL imbriquées dans une transaction (multi-instructions), par exemple
BEGIN;
ALTER TABLE foo ...;
ALTER TABLE bar ...;
-- more stuff
COMMIT; -- or ROLLBACK; if you've changed your mind
(génial pour vous assurer que les migrations de schéma se déroulent toutes ensemble ou pas du tout.) Vous avez dit, cependant:
Nous n'avons pas encapsulé le ALTER TABLE
dans une transaction.
C'est bien pour une seule commande - à partir des documents ,
PostgreSQL traite en fait chaque instruction SQL comme étant exécutée dans une transaction. Si vous n'émettez pas de commande BEGIN, chaque instruction individuelle est entourée d'un BEGIN implicite et (en cas de succès). Un groupe d'instructions entouré de BEGIN et COMMIT est parfois appelé un bloc de transaction.
Ainsi, l'annulation de cela ALTER TABLE
, soit par le biais d' pg_cancel_backend()
un Ctrl-C émis à partir de l'invite de contrôle de psql, aura un effet similaire à celui que vous aviez fait
BEGIN;
ALTER TABLE ... ;
ROLLBACK;
(même si, comme vous l'espérez, vous avez pu le voir, l'annulation de ce prix ALTER TABLE
peut sauver la base de données de beaucoup de meulage inutile si vous y allez de ROLLBACK
toute façon.)