Closed alhyss closed 1 month ago
En attendant un correctif, ci-après deux méthodes pour éviter que l'erreur n'apparaisse. Elles compliquent un peu le processus de sauvegarde/restauration mais sont fiables et ne sont pas susceptibles de produire des effets de bord.
Méthode n°1, avec une restauration par étape :
z_asgard_admin.asgard_sortie_gestion_schema
. Par exemple, pour le schéma z_plume
de l'extension PlumePg :
SELECT z_asgard_admin.asgard_sortie_gestion_schema('z_plume') ;
NB : Plusieurs procédés sont possibles pour séparer la restauration de la structure et des données selon le format de sauvegarde. Pour le format plain
, il est nécessaire d'utiliser les paramètres -s
/ --schema-only
et -a
/ --data-only
de pg_dump
pour obtenir deux scripts de restauration distincts à exécuter ensuite avec psql
: la sauvegarde est faite en deux fois, d'abord avec pg_dump -s
pour la structure puis pg_dump -a
pour les données. Pour les autres formats, il possible d'utiliser la même méthode ou de ne créer qu'une seule archive au moment de la sauvegarde et d'utiliser ensuite les paramètres -s
/ --schema-only
et -a
/ --data-only
de pg_restore
pour ne restaurer à chaque étape que la partie de l'archive qui doit l'être.
Méthode n°2, en intervenant avant la sauvegarde :
z_asgard_admin.asgard_sortie_gestion_schema
. Par exemple, pour le schéma z_plume
de l'extension PlumePg :
SELECT z_asgard_admin.asgard_sortie_gestion_schema('z_plume') ;
z_asgard_admin.asgard_sortie_gestion_schema
- les schémas créés par des extensions qui n'avaient pas lieu d'être référencés.La méthode n°1 est conseillée dans le cas général, car elle ne nécessite pas de reprise manuelle.
Pour connaître les schémas créés par des extensions sur une base :
SELECT
pg_namespace.nspname AS nom_schema,
pg_extension.extname AS nom_extension
FROM pg_depend
INNER JOIN pg_extension ON pg_extension.oid = pg_depend.refobjid
INNER JOIN pg_namespace ON pg_namespace.oid = pg_depend.objid
WHERE pg_depend.deptype = 'e'
AND pg_depend.classid = 'pg_namespace'::regclass
AND pg_depend.refclassid = 'pg_extension'::regclass
AND NOT pg_namespace.nspname IN ('z_asgard', 'z_asgard_admin') ;
Les schémas d'Asgard sont exclus de la commande ci-avant, car leur référencement éventuel ne pose pas de problème. Le script de l'extension assure qu'ils soient créés avant le déclencheur asgard_on_create_schema
.
Plutôt que de déréférencer un par un les schémas concernés, il est possible d'inclure la fonction de référencement dans la requête précédente :
SELECT
pg_namespace.nspname AS nom_schema,
pg_extension.extname AS nom_extension,
z_asgard_admin.asgard_sortie_gestion_schema(pg_namespace.nspname) AS dereferencement
FROM pg_depend
INNER JOIN pg_extension ON pg_extension.oid = pg_depend.refobjid
INNER JOIN pg_namespace ON pg_namespace.oid = pg_depend.objid
WHERE pg_depend.deptype = 'e'
AND pg_depend.classid = 'pg_namespace'::regclass
AND pg_depend.refclassid = 'pg_extension'::regclass
AND NOT pg_namespace.nspname IN ('z_asgard', 'z_asgard_admin') ;
La fonction indique __ DEREFERENCEMENT REUSSI.
dès lors qu'il n'y a pas eu d'erreur et même si le schéma n'était pas référencé. Dans ce cas elle n'a juste aucun effet.
Avertissements temporairement ajoutés dans la documentation - à retirer lorsque la version corrective aura été publiée :
J'en ai profité pour ajouter une remarque (pérenne) sur le fait qu'il est fortement déconseillé de désactiver les déclencheurs pendant la restauration.
Problème résolu par la version 1.4.1. La fonction z_asgard_admin.asgard_on_modify_gestion_schema_before
appelée par le déclencheur asgard_on_modify_gestion_schema_before
procède désormais à un dé-référencement préalable en cas de tentative d'insertion dans la table de gestion d'un schéma actif déjà référencé.
Le déréférencement n'affectant pas les droits, cette manipulation est peu susceptible d'avoir des effets de bord gênants. Elle pourra échouer dans certains cas - notamment pour les schémas de la nomenclature nationale dont le dé-référencement n'est pas autorisé - mais devrait au moins permettre de gérer le cas des schémas créés par des extensions.
Résumé : La restauration d'une base sur laquelle Asgard est active est très susceptible d'échouer lorsqu'une autre extension active sur la base crée un ou plusieurs schémas qui sont référencés dans la table de gestion d'Asgard.
Cette anomalie, détaillée ci-dessous a été détectée lors de la restauration d'une base PostgreSQL 10 avec l'extension PlumePg sur PostgreSQL 16, néanmoins elle ne semble pas propre à une version spécifique de PostgreSQL et paraît pouvoir concerner d'autres extensions dès lors qu'elles créent des schémas.
La table
z_asgard_admin.gestion_schema
est marquée comme table de configuration de l'extension, ce qui fait que ses enregistrements sont inclus dans les fichiers de sauvegarde et restaurés avec le reste des données de la base. Ceci permet de préserver des informations qu'il n'est pas possible de déduire de l'état de la base. Notamment quels schémas sont ou non référencés par Asgard, leurs rôles lecteurs et éditeurs s'ils en ont, leur arborescence de classement.Cette commande de restauration des données est susceptible d'échouer si les enregistrements qu'elle insère dans
z_asgard_admin.gestion_schema
ne respectent pas les contraintes définies sur la table. Notamment, elle échoue si l'un des enregistrements correspond à un schéma qui apparaitrait déjà dans la table. L'erreur - non respect de l'unicité du champ clé primairenom_schema
- est capturée en amont par le déclencheurasgard_on_modify_gestion_schema_before
, qui renvoie un message de la forme suivante :Le déclencheur sur évènements
asgard_on_create_schema
est activé par les commandesCREATE SCHEMA
et référence automatiquement les nouveaux schémas créés dans la table de gestion. Ceci n'engendre pas de conflit avec les commandesCREATE SCHEMA
exécutées au cours du processus de restauration, car celui-ci restaure les schémas avant de restaurer les extensions. Autrement dit, le déclencheurasgard_on_create_schema
n'intervient pas lors de la restauration des schémas, car, tant que la commandeCREATE EXTENSION asgard
n'a pas été lancée, il n'existe pas encore. Ainsi, les seuls enregistrements ajoutés à la table de gestion relativement à ces schémas le sont lors de la restauration des données des tables de configuration, et - hormis pour les OID qui, comme il se doit, seront automatiquement actualisés - les informations restaurées correspondent exactement à celles qui se trouvaient dans la table lors de la sauvegarde.Dans le cas général, il n'y a donc pas d'erreur.
Mais les schémas créés par les extensions faussent la donne, car une extension quelconque est très susceptible d'être restaurée après Asgard, et non avant comme les schémas autonomes. Le risque est d'autant plus grand que le nom "Asgard" commence par la lettre "A" et a toutes les chances d'être l'une des premières extensions restaurées.
Au moment où le processus de restauration arrive à la commande
CREATE EXTENSION
, il exécute les commandes qui se trouvent dans le script de l'extension, incluant les éventuelles commandesCREATE SCHEMA
. Si Asgard a alors déjà été restaurée, le déclencheurasgard_on_create_schema
est actif et va référencer les schémas dans la table de gestion à mesure de leur création. Si ces mêmes schémas se trouvaient être déjà référencés dans la table de gestion sur la base sauvegardée, alors la commande de restauration des données de la table de configuration inclut des lignes pour ces schémas et va par conséquent échouer, car les enregistrements qu'elle tente de restaurer seront considérés comme des doublons des enregistrements qui viennent d'être insérés par le déclencheur.Cet échec est lourd de conséquences, car il se traduit par un déréférencement de fait de tous les autres schémas, qui ne sont dès lors plus pris en compte par les mécanismes d'Asgard (mise en cohérence des propriétaires, etc.). Il reste possible de les re-référencer a posteriori avec les fonctions
z_asgard_admin.asgard_initialisation_gestion_schema
ouz_asgard.asgard_initialise_schema
, mais au prix de la perte de toutes les informations qui n'apparaissaient que dans la table de gestion : éditeur, lecteur, valeurs des champsniv1
,niv1_abr
, etc.Une anomalie annexe est que la restauration de la base va de fait silencieusement référencer dans la table de gestion d'Asgard tous les schémas créés par les extensions qui sont restaurées après Asgard, même si ces schémas n'étaient initialement pas référencés, et ce potentiellement pour d'excellentes raisons.