Nous avons lancé une ALTER TABLE
requête il y a quelques heures et nous avons récemment réalisé (via pg_stat_activity
) qu'elle attendait un verrou. Nous avons découvert l'autre requête qui contient un verrou sur la table que nous voulons modifier et ne pas le laisser partir.
Notre requête est une requête "simple" (modification d'un type de données de colonne), mais elle s'exécute sur une table massive.
Plutôt que de tuer le processus qui maintient la serrure, nous avons décidé que nous préférions tuer le ALTER TABLE
.
Nous n'avons pas encapsulé le ALTER TABLE
dans une transaction.
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é.
Est-ce vrai? Est-il sûr pour nous d'annuler purement et simplement notre ALTER TABLE
requête? 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?
PS: Le plan est de l'annuler en utilisant SELECT pg_cancel_backend(pid);
. Si c'est une mauvaise idée, faites-le moi savoir.
la source
Réponses:
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é.
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()
etpg_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
(génial pour vous assurer que les migrations de schéma se déroulent toutes ensemble ou pas du tout.) Vous avez dit, cependant:
C'est bien pour une seule commande - à partir des documents ,
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(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 deROLLBACK
toute façon.)la source
Pour développer la réponse correcte et excellente de Josh:
Oui.
Ce serait sûr même s'il était en train de réécrire la table .
Si vous le vouliez, vous pouvez simplement arrêter l'ensemble du serveur PostgreSQL, ou en fait la machine sur laquelle il fonctionne, le redémarrer, et tout irait bien. DDL dans PostgreSQL est transactionnel et sûr.
Les opérations DDL sont enregistrées via WAL et il est garanti qu'elles peuvent être annulées ou terminées lors de la récupération après un crash ou un abandon.
la source