db : amorce la zone or, hypertable « mesure » et compression au-delà de 7 jours #106
Labels
No labels
Compat/Breaking
EC01
EC02
EC03
EC04
EC05
EC06
Kind/BDD
Kind/Back
Kind/Bug
Kind/CICD
Kind/Cloud
Kind/Contenu
Kind/Data
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Front
Kind/IA
Kind/Infra
Kind/Monitoring
Kind/Security
Kind/Testing
Portée/Post-jury
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
ops/alerte
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
g2/enervision!106
Loading…
Reference in a new issue
No description provided.
Delete branch "olivier/29-hypertables-compression"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Amorce la zone or pour débloquer le ticket #29.
Le problème. #29 demande de convertir les tables de mesures en hypertables et d'y poser une compression. Il n'y avait rien à convertir :
enervision_prodetenervision_preprodcomptaient zéro table danspublic, seuls les catalogues internes de TimescaleDB étaient présents. C'est le constat que fait aussi #105.Ce que fait cette migration. Le strict nécessaire pour que #29 ait un objet, pas plus :
site, le référentiel des sept sites, peuplé depuisdocs/GLOSSAIRE.md;mesure, convertie en hypertable de fragments d'un jour ;Les cinq autres tables de la zone or (
prevision,alerte,qualite_jour,recommandation,acces_site) restent au #105.Le modèle est celui du dossier d'architecture collectif, et non la forme esquissée dans
docs/POSTGRESQL.md. Celle-ci est écartée pour trois raisons, consignées dans le document corrigé : sa clécapteur_idn'est pas celle des zones bronze et argent (donc pas d'auditabilité sans table de correspondance) ; sa colonne de valeur unique ne peut pas porter la brute à côté de la retenue, ce que l'ADR 0006 exige ; et sondata_qualitypar défaut à'ok'n'appartient à aucune des deux énumérations de qualité retenues.Relevé après application sur le serveur
enervision_prodenervision_preprodsitemesureLa production reste vide volontairement : la conversion d'une table remplie est longue, elle passe donc avant le chargement de la collecte (#33). Le jeu de test vit en préproduction seule.
Latence, agrégat horaire sur 24 h et les 7 sites, 20 exécutions : médiane 3,67 ms, p95 4,09 ms, max 10,31 ms — cible 400 ms. Une fenêtre de 24 h prise dans les fragments comprimés reste à 4,9 ms. Le plan montre
ChunkAppendne touchant que 2 fragments sur 36.Un écart d'installation corrigé au passage.
pg_default_aclétait vide surenervision_preprodalors queenervision_prodportait biengrafana=rsurpublic: les mêmes tables auraient été lisibles par Grafana en production et muettes en préproduction. La clause manquante a été posée sur le serveur, et legrant selectest explicite dans la migration pour ne plus dépendre d'elle.La migration se rejoue sans effet de bord — vérifié en transaction annulée sur préproduction, hypertable déjà comprimée : uniquement des
NOTICE.Le lot complet de la zone or est ouvert en #110 (ticket #105). Il ne défait rien ici : la
0007reste la première pose, et le lot passe au-dessus en0008à0015. Les deux demandes fusionnent dans n'importe quel ordre — les fichiers0008et0010créent la forme complète sur une base neuve et complètent une table déjà posée.Trois choses relevées depuis, dont deux qui touchent cette demande.
1. Sur les deux bases,
siteetmesureappartiennent àpostgres— et sur la production, le schémaopsetops.schema_migrationsaussi. La0007y a été appliquée en superutilisateur. Legrant select on site, mesure to grafanaexplicite sauve la lecture pour ces deux tables, et c'était bien vu ; mais deux effets restent :alter tablede mon lot échouent sur un refus de droits tant que la propriété n'est pas reprise ;ALTER DEFAULT PRIVILEGES FOR ROLE enervision_prodne couvre que les objets créés par ce rôle : la prochaine table posée enpostgressansgrantexplicite serait muette pour Grafana, sans message.La reprise (
alter ... owner to) est dansdb/migrations/README.mdde #110, et le test d'intégration vérifie désormais le propriétaire.Sur l'argument du
grantexplicite : il tient, mais son motif — « la clause existe surenervision_prodmais pas surenervision_preprod» — est plus faible qu'il n'y paraît.grafanan'a pasCONNECTsurenervision_preprod(10-roles-bases-droits.shne l'accorde que sur la production) : il ne lira jamais la préproduction, l'asymétrie est donc sans conséquence. Ça ne rend pas legrantnuisible, seulement facultatif.2. La méthode d'imputation.
check (methode_imputation in ('interpolated', 'forward_fill', 'none'))avecnonepar défaut fait porter ànonedeux sens distincts — « valeur mesurée » et « trou assumé ». Le §9 dedocs/data/etl-pipeline.mdet l'ADR 0006 nommentmeasuredle régime de la valeur présente et valide. Les confondre interdit de compter les valeurs réellement mesurées, ce que la répartition par méthode dequalite_jourdemande. La0010de #110 élargit donc la contrainte à quatre valeurs et remet le défaut àmeasured. Dis-moi si tu vois une raison de garder trois régimes, je la retirerai.3. Pour information : les six migrations d'authentification n'ont jamais été jouées sur
enervision_prod—opsn'y contient queschema_migrations. Elles passeront avec #110, dont la0015référenceops.users.Rien à changer ici de mon point de vue. Je relis la #110 avec toi si tu veux, et l'inverse.
Relu et vérifié sur le serveur, tout ce qui est annoncé est exact : 7 sites des deux côtés, 0 mesure en production, 352 807 en préproduction, 36 fragments dont 28 comprimés, politique à 7 jours,
grafanalitsiteetmesuredans les deux bases.J'ai poussé deux vérifications de plus. La chaîne complète 0001 à 0007 rejouée dans l'ordre sur une base neuve passe sans une erreur, extension comprise. Et 0007 rejoué sur une base où il est déjà appliqué est idempotent, cinq avis, aucune erreur.
Le choix de garder la production vide et de convertir avant le chargement est le bon, et le motif est écrit. Les trois raisons d'écarter l'ancienne forme sont justes, celle sur la clé commune du bronze à l'or particulièrement. La section du manuel sur la décompression avant reprise servira plus tôt que prévu, voir ma relecture de la #110.
Une remarque en commentaire de ligne, non bloquante.
Hors périmètre, pour information :
ops.schema_migrationsdansenervision_prodne contient que 0007. Les migrations 0001 à 0006 n'y sont jamais passées etops.usersn'existe pas en production. La chaîne se rattrapera au premier démarrage de l'API contre la production, mais ce chemin n'a encore jamais été parcouru.À fusionner avant la #110, qui la complète.
@ -0,0 +57,4 @@('SITE005', 'Hôpital Toulouse Purpan', 'hospital', 600),('SITE006', 'Bureau Bordeaux Centre', 'office', 180),('SITE007', 'Usine Nantes Rezé', 'factory', 950)on conflict (site_id) do nothing;Le commentaire au-dessus dit qu'une capacité corrigée à la main sur le serveur ne doit pas être écrasée par un rejeu. Je le prendrais dans l'autre sens : le
GLOSSAIREse déclare source unique de ces valeurs, donc c'est la correction manuelle qui devrait céder, pas le dépôt.Avec
do nothing, une capacité corrigée ici n'atteindra jamais une base déjà peuplée, et rien ne le signalera. Undo update set libelle = excluded.libelle, type = excluded.type, capacite_kw = excluded.capacite_kwgarde les deux alignés et reste rejouable.Pas bloquant pour cette fusion.