web-dev-qa-db-fra.com

L'ajout d'une colonne nulle à une table postgres provoque-t-il un verrouillage?

Je pense avoir lu quelque part que l'exécution d'un ALTER TABLE foo ADD COLUMN baz text sur une base de données postgres ne provoquera pas de verrouillage en lecture ou en écriture. La définition d'une valeur par défaut provoque le verrouillage, mais autoriser une valeur par défaut nulle empêche un verrouillage.

Je ne trouve cependant pas cela dans la documentation. Quelqu'un peut-il indiquer un endroit qui dit, définitivement, si cela est vrai ou non?

28
jpadvo

Les différents types de verrous et quand ils sont utilisés sont mentionnés dans la doc dans Table-level Locks . Par exemple, Postgres 11 ALTER TABLE peut acquérir un SHARE UPDATE EXCLUSIVE, SHARE ROW EXCLUSIVE, ou ACCESS EXCLUSIVE fermer à clé.

Postgres 9.1 à 9.3 prétendait prendre en charge deux des trois précédents, mais en fait forcé Access Exclusive pour toutes les variantes de cette commande . Cette limitation était levée dans Postgres 9.4 mais ADD COLUMN reste à ACCESS EXCLUSIVE par conception.

Il est facile de vérifier le code source car il existe une fonction dédiée à l'établissement du niveau de verrouillage requis pour cette commande dans divers cas: AlterTableGetLockLevel in src/backend/commands/tablecmds.c.


Concernant combien de temps le verrou est maintenu , une fois acquis:

  • Lorsque la valeur par défaut de la colonne est NULL, l'ajout de la colonne doit être très rapide car elle n'a pas besoin d'une réécriture de table: c'est seulement une mise à jour dans le catalogue.
  • Lorsque la colonne a une valeur par défaut non NULL, cela dépend de la version de PostgreSQL: avec la version 11 ou plus récente, il n'y a pas de réécriture immédiate de toutes les lignes, donc cela devrait être aussi rapide que le cas NULL. Mais avec la version 10 ou antérieure, la table est entièrement réécrite, donc elle peut être assez chère selon la taille de la table.
23
Daniel Vérité

L'ajout d'une nouvelle colonne nulle verrouillera la table pendant très très peu de temps car il n'est pas nécessaire de réécrire toutes les données sur le disque. Pour ajouter une colonne avec la valeur par défaut, PostgreSQL doit créer de nouvelles versions de toutes les lignes et les stocker sur le disque. Et pendant ce temps, le calendrier sera verrouillé.

Ainsi, lorsque vous devez ajouter une colonne avec une valeur par défaut à une grande table, il est recommandé d'ajouter d'abord une valeur nulle, puis de mettre à jour toutes les lignes par petites portions. De cette façon, vous éviterez une charge élevée sur le disque et permettrez à autovacuum de faire son travail afin de ne pas finir par doubler la taille de la table.

23
alexius

http://www.postgresql.org/docs/current/static/sql-altertable.html#AEN5729

"L'ajout d'une colonne avec une valeur par défaut non nulle ou la modification du type d'une colonne existante nécessitera la réécriture de la table entière et des index."

La documentation ne spécifie donc que lorsque la table n'est pas réécrite. Il y aura toujours un verrou, mais il sera très court au cas où la table ne serait pas réécrite.

12
Leo