Aller au contenu
PostgreSQL managé en production

PostgreSQL managé en production

300 Concevoir ⏱ 1 h 30 cloudscalewaypostgresql

À la fin, vous saurez

  • Distinguer instantané de volume, sauvegarde logique, clone et réplica, et savoir ce que chacun permet de restaurer
  • Régler la politique de sauvegarde automatique et restaurer une base dans une nouvelle instance, en mesurant la durée
  • Choisir entre haute disponibilité et réplica en lecture, et décrire ce qui se passe lors d'une bascule
  • Conduire une montée de version majeure sans perte de données, avec répétition et retour arrière
  • Créer des utilisateurs de moindre privilège pour l'application, la lecture et la migration
  • Diagnostiquer et prévenir le passage en disque plein
  • Mettre en place une sauvegarde logique hors du fournisseur

Prérequis

Testé avec postgresql 17 scaleway-cli 2.62.0 , vérifié le 5 octobre 2026

Pourquoi

La base de Signalements, sig-db, a été créée à la leçon 2 du cours précédent et rattachée au réseau privé à la leçon 6. On avait alors noté que le service managé prenait en charge les sauvegardes, les correctifs et la bascule, et que le reste restait à notre charge. Un an plus tard, la base contient trois ans de signalements de trois métropoles, et elle doit survivre à des événements que l'on n'a encore jamais vécus :

  • un développeur exécute en production une migration destinée à la préproduction, et vide la table des signalements ;
  • le nœud principal tombe en panne un mardi à 10 h ;
  • PostgreSQL 17 arrive en fin de vie, et il faut changer de version majeure ;
  • le disque se remplit pendant la nuit, et la base passe en lecture seule ;
  • Scaleway lui-même est indisponible, ou Lyneko doit changer de fournisseur.

Pour chaque événement, la question n'est pas « le service a-t-il une fonction pour cela ? », mais : quelle donnée puis-je récupérer, de quand, en combien de temps, et l'ai-je déjà fait une fois ? Cette leçon répond produit par produit, à partir de la documentation de Scaleway au 5 octobre 2026 et de celle de PostgreSQL.

Les concepts

Quatre copies qui ne se valent pas

Le vocabulaire de Scaleway mélange des mécanismes très différents. Il faut les distinguer avant de choisir.

MécanismeCe qui est copiéGrain de restaurationOù va la copieUsage
Instantané (snapshot)Le volume bloc entier, à un instantL'instance entière, dans une nouvelle instanceStockage de ScalewayRetour à un état passé, clonage
Sauvegarde logique (backup)Une base logique, exportée (format de PostgreSQL)Une base, dans l'instance d'origine ou une autreStockage de Scaleway, éventuellement dans une autre régionRestauration ciblée, export hors du fournisseur
CloneL'instance entière, avec utilisateurs et droitsUne nouvelle instance, indépendanteUne nouvelle instanceEssai d'une migration, copie pour une analyse
Réplica (haute disponibilité ou réplica en lecture)Chaque transaction, en continuAucun : c'est une copie vivanteUn autre nœudDisponibilité, lectures

La dernière ligne est la plus importante : un réplica n'est pas une sauvegarde. Une suppression accidentelle est répliquée en quelques millisecondes. Seuls les instantanés et les sauvegardes permettent de revenir en arrière.

Ce que font les sauvegardes automatiques

La création d'une base active par défaut une sauvegarde automatique, une fois par jour, conservée sept jours (le cours précédent l'a vu dans le champ backup_schedule). La documentation précise ce que le mot recouvre selon le type de volume :

  • avec un volume local (nœuds de première génération), la sauvegarde automatique est une sauvegarde logique ;
  • avec un volume bloc (sbs_5k, sbs_15k, et l'ancien bssd), la sauvegarde automatique est un instantané du volume. Une base sur volume bloc n'a pas d'autre forme de sauvegarde automatique.

Les bases récentes, dont sig-db, sont sur volume bloc : leurs sauvegardes automatiques sont des instantanés, et un instantané se restaure dans une nouvelle instance (scw rdb snapshot restore), pas en place. Les sauvegardes logiques restent possibles à la main sur volume bloc, si le volume ne dépasse pas 585 Go, selon la page How to manage backups.

Trois autres faits documentés, qui comptent le jour où l'on en a besoin :

  • les sauvegardes et instantanés automatiques survivent à la suppression de la base ; ils disparaissent à la fin de leur rétention, ou à la main ;
  • une sauvegarde automatique est créée même si le quota d'instantanés est atteint ;
  • l'API permet de stocker les sauvegardes logiques dans une autre région que la base (backup-same-region=false), ce qui protège d'un sinistre régional.

Pas de restauration à un instant

PostgreSQL sait restaurer une base à n'importe quel instant du passé, à la seconde près, en rejouant ses journaux de transactions (WAL, write-ahead log) archivés depuis une sauvegarde de base : c'est la restauration à un instant (point-in-time recovery, PITR), décrite au chapitre 25 de la documentation de PostgreSQL. Plusieurs fournisseurs l'offrent sur leurs bases managées.

La documentation de Scaleway pour PostgreSQL managé ne décrit pas de restauration à un instant au 5 octobre 2026 : on revient à l'instant d'un instantané ou d'une sauvegarde, pas entre deux. Avec une sauvegarde par jour, une erreur commise à 17 h fait perdre, au pire, presque une journée de signalements. C'est l'objectif de point de reprise (RPO) réel de la configuration par défaut, et il faut le comparer à ce que l'on a promis aux clients. La fréquence se règle à l'heure près (backup-schedule-frequency, en heures) : des instantanés toutes les quatre heures ramènent le RPO à quatre heures, au prix du stockage.

Haute disponibilité et réplicas en lecture

Deux mécanismes de réplication, deux usages :

Haute disponibilitéRéplica en lecture
RéplicationSynchrone : une transaction validée est appliquée sur le nœud de secoursAsynchrone : le réplica peut avoir un retard
AccessibleNon, le nœud de secours ne sert que s'il devient principalOui, en lecture seule, par son propre point d'accès
ZoneLa documentation ne précise pas la zone du nœud de secours ; l'API distingue single_zone et multiple_zoneMême zone ou autre zone (same-zone=false)
BasculeAutomatique, en 30 à 60 secondesManuelle : promotion, irréversible, en une instance autonome
Retour arrièreUne fois activée, on ne revient pas à un nœud seulOn supprime le réplica

La page Understanding the autohealing feature décrit la bascule : si le nœud principal tombe, le nœud de secours prend les écritures en 30 à 60 secondes, la base passe à l'état AUTOHEALING, et si le nœud défaillant n'est pas revenu après 700 secondes, un nouveau nœud de secours est créé. Les connexions en cours sont coupées : l'application doit savoir se reconnecter.

Pour Signalements, la haute disponibilité protège de la panne d'un nœud, ce que les sauvegardes ne font pas (elles demandent une restauration de plusieurs minutes à plusieurs heures) ; un réplica dans une autre zone, promu à la main, protège d'une perte de zone. Les deux se combinent.

Les montées de version majeure

Une version mineure (17.4 vers 17.6) ne change pas le format des données : Scaleway l'applique lors des maintenances, qu'il planifie et que l'on peut avancer. Une version majeure (17 vers 18) change le format interne : il faut transformer les fichiers, avec l'outil pg_upgrade, ou recharger les données.

La procédure de Scaleway est prudente : elle crée une nouvelle instance avec la nouvelle version, sans toucher à l'ancienne, avec deux options :

  • mettre à jour seulement : la nouvelle instance est créée, l'ancienne garde ses points d'accès ; on bascule plus tard ;
  • mettre à jour et basculer le trafic : les points d'accès passent automatiquement de l'ancienne instance à la nouvelle.

La documentation énumère les contraintes : volume bloc obligatoire ; aucune synchronisation entre l'ancienne et la nouvelle instance pendant l'opération, donc arrêt des écritures conseillé ; perte de la haute disponibilité et des réplicas, à réactiver ensuite ; suppression préalable des colonnes de types reg*, que pg_upgrade ne sait pas conserver. Elle recommande une répétition (dry run) sans bascule, pour mesurer la durée.

Utilisateurs et privilèges

PostgreSQL distingue les rôles (utilisateurs) et leurs privilèges sur chaque base et chaque objet. Scaleway expose une couche simplifiée : un utilisateur peut être administrateur de l'instance (créer des bases et des utilisateurs), et reçoit sur chaque base une permission parmi none, readonly, readwrite, all ou custom. La documentation signale le piège classique de PostgreSQL : les permissions s'appliquent aux objets existants au moment où on les règle. Une table créée ensuite n'en hérite pas, sauf à utiliser ALTER DEFAULT PRIVILEGES.

Pour une application, on sépare au minimum trois rôles :

RôleUsageDroits
sig_migrationLes migrations de schéma, lancées par le pipelinePropriétaire des tables
sig_appL'application en fonctionnementLecture et écriture des données, pas de changement de schéma
sig_lectureLes tableaux de bord, les analysesLecture seule, idéalement sur un réplica

L'application de production qui se connecte avec le compte administrateur créé avec la base peut, en cas de faille d'injection SQL, supprimer des tables. Avec sig_app, elle ne peut que lire et écrire des lignes.

En pratique

Les commandes ont été vérifiées avec l'aide de scw 2.62 et le SDK Go ; elles visent sig-db dans le projet de production, région fr-par. Plusieurs créent des instances facturées (restauration, clone, réplica) : supprimez-les après l'exercice.

$ DB=$(scw rdb instance list name=sig-db region=fr-par -o json \
    | jq -r '.[] | select(.name == "sig-db") | .id')
$ scw rdb instance get "$DB" region=fr-par -o json \
    | jq '{engine, node_type, volume, is_ha_cluster, backup_schedule, encryption, read_replicas}'

La seconde commande résume l'état de la base : moteur, type de nœud, volume (type et taille), haute disponibilité, planification des sauvegardes, chiffrement, réplicas. C'est le point de départ de toute décision.

Régler la politique de sauvegarde

Passons à un instantané toutes les six heures, conservé quatorze jours :

$ scw rdb instance update "$DB" backup-schedule-frequency=6 backup-schedule-retention=14 region=fr-par

Avant une opération risquée (migration de schéma, montée de version), on prend en plus un instantané manuel, avec une date d'expiration :

$ scw rdb snapshot create instance-id="$DB" name=avant-migration-0042 \
    expires-at=2026-10-19T00:00:00Z region=fr-par

L'instance doit être à l'état ready. Sur un volume bloc, l'instantané est quasi instantané pour la base ; sa taille facturée dépend des données. La documentation fixe à 7 jours la rétention par défaut d'un instantané manuel, et à 100 le nombre d'instantanés par instance et par projet, selon les quotas.

Restaurer, et chronométrer

Une sauvegarde qui n'a jamais été restaurée n'est qu'un espoir. On restaure l'instantané le plus récent dans une nouvelle instance :

$ SNAP=$(scw rdb snapshot list instance-id="$DB" region=fr-par -o json \
    | jq -r 'sort_by(.created_at) | last | .id')
$ date
$ scw rdb snapshot restore "$SNAP" instance-name=sig-db-restauration node-type=DB-DEV-S \
    region=fr-par --wait
$ date

Les deux date mesurent la durée de restauration : c'est la première composante de l'objectif de temps de reprise (RTO). La seconde est le temps de reconnecter l'application à la nouvelle instance : nouveau point d'accès, réseau privé à rattacher (scw rdb endpoint create, comme à la leçon 6 du cours précédent), DATABASE_URL à changer, ou bascule des points d'accès (voir la montée de version, plus bas).

Vérifiez ensuite que les données sont là, par une requête simple qui compare l'original et la restauration (par exemple SELECT count(*), max(cree_le) FROM signalements;), puis supprimez l'instance de test. Notez la date du test, la durée et le volume : la prochaine fois, vous saurez combien de temps annoncer.

Pour une erreur ciblée (une table vidée), restaurer toute l'instance est disproportionné. On restaure l'instantané dans une instance temporaire, on en extrait la table avec pg_dump --table, et on la réinjecte dans la base de production. Avec une sauvegarde logique (volume local, ou sauvegarde manuelle), on peut aussi restaurer une base sous un autre nom dans la même instance :

$ scw rdb backup restore <id de la sauvegarde> instance-id="$DB" database-name=rdb_restauree region=fr-par

Sans database-name, la restauration se fait par-dessus la base d'origine. C'est rarement ce que l'on veut pendant un incident : on restaure à côté, on compare, puis on décide.

Cloner pour répéter une migration

Avant la migration de schéma 0042, on répète sur un clone :

$ scw rdb instance clone "$DB" name=sig-db-repetition node-type=DB-DEV-S region=fr-par

Le clone contient toutes les bases, les utilisateurs et les droits ; il est indépendant de l'original. Pendant le clonage, la base source reste disponible, en mode backing up, avec quelques actions indisponibles. On y lance la migration, on mesure sa durée et ses verrous, on vérifie l'application, puis on supprime le clone.

Activer la haute disponibilité, et ajouter un réplica dans l'autre zone

$ scw rdb instance upgrade "$DB" enable-ha=true region=fr-par --wait
$ scw rdb read-replica create instance-id="$DB" same-zone=false \
    endpoint-spec.0.private-network.private-network-id="$PN" \
    endpoint-spec.0.private-network.ipam-config={} region=fr-par
  • enable-ha=true passe la base en haute disponibilité : la documentation annonce une indisponibilité de quelques secondes, et rappelle qu'on ne peut plus revenir à un nœud seul. L'API expose aussi high-availability-mode (single_zone ou multiple_zone) ; la documentation de la console n'explique pas la différence au 5 octobre 2026, et l'on vérifiera dans la description de l'instance ce qui a été créé.
  • same-zone=false place le réplica dans une autre zone de la région : c'est la configuration Multi-AZ de la documentation, recommandée pour la reprise d'activité.
  • ipam-config={} demande une adresse privée attribuée automatiquement par IPAM sur le réseau pn-signalements (la syntaxe de l'objet vide est celle de la CLI pour un argument de type objet ; vérifiez-la avec scw rdb read-replica create --help si votre version diffère).

Le réplica a le même type de nœud que la base, et en hérite la configuration. Il sert immédiatement aux lectures : tableaux de bord, exports, le rôle sig_lecture. En cas de perte de la zone de la base, on le promeut dans la console : il devient une instance autonome, préfixée promoted, qui garde son point d'accès privé. La promotion est irréversible, et la documentation demande de vérifier que le retard de réplication est nul avant de l'engager, faute de quoi les dernières transactions sont perdues.

Créer des utilisateurs de moindre privilège

$ scw rdb user create instance-id="$DB" name=sig_migration generate-password=true region=fr-par
$ scw rdb user create instance-id="$DB" name=sig_app generate-password=true region=fr-par
$ scw rdb user create instance-id="$DB" name=sig_lecture generate-password=true region=fr-par
$ scw rdb privilege set instance-id="$DB" database-name=rdb user-name=sig_migration permission=all region=fr-par
$ scw rdb privilege set instance-id="$DB" database-name=rdb user-name=sig_app permission=readwrite region=fr-par
$ scw rdb privilege set instance-id="$DB" database-name=rdb user-name=sig_lecture permission=readonly region=fr-par

Comme à la création de la base, generate-password=true affiche le mot de passe une seule fois : copiez-le dans Secret Manager (leçon 8), pas dans un fichier. Puis, connecté en sig_migration, réglez les privilèges des tables futures, que les permissions ci-dessus ne couvrent pas :

ALTER DEFAULT PRIVILEGES FOR ROLE sig_migration IN SCHEMA public
  GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO sig_app;
ALTER DEFAULT PRIVILEGES FOR ROLE sig_migration IN SCHEMA public
  GRANT USAGE, SELECT ON SEQUENCES TO sig_app;
ALTER DEFAULT PRIVILEGES FOR ROLE sig_migration IN SCHEMA public
  GRANT SELECT ON TABLES TO sig_lecture;

Chaque table créée par une migration (donc par sig_migration) sera désormais lisible et modifiable par sig_app, lisible par sig_lecture. La documentation de Scaleway le dit à sa façon : dès que de nouveaux objets apparaissent, la permission affichée passe à custom.

Régler le moteur et lire les journaux

Les paramètres modifiables dépendent du moteur et de sa version ; la page PostgreSQL version updates de Scaleway liste ceux qu'ajoute chaque version. Deux réglages de journalisation utiles pour une API comme Signalements, modifiables depuis PostgreSQL 16 :

$ scw rdb setting add instance-id="$DB" \
    settings.0.name=log_min_duration_statement settings.0.value=500 \
    settings.1.name=log_lock_waits settings.1.value=on \
    region=fr-par
  • log_min_duration_statement=500 journalise toute requête de plus de 500 ms ; la page Shared responsibility model indique que Scaleway le règle par défaut à 5 000 ms, et qu'il n'est modifiable qu'à partir de PostgreSQL 16 ;
  • log_lock_waits=on journalise les attentes de verrou qui dépassent deadlock_timeout (une seconde par défaut dans PostgreSQL) : la trace des migrations qui bloquent l'application.

La documentation prévient qu'un réglage peut affecter les performances, et que passer à un type de nœud avec moins de mémoire réinitialise les paramètres pour qu'ils tiennent dans les ressources. Les journaux se préparent puis se téléchargent :

$ scw rdb log prepare instance-id="$DB" start-date=2026-10-05T00:00:00Z end-date=2026-10-05T12:00:00Z region=fr-par
$ scw rdb log list instance-id="$DB" region=fr-par
$ scw rdb log list-details instance-id="$DB" region=fr-par

La dernière commande donne la taille des journaux conservés sur l'instance, qui comptent dans l'espace disque, et scw rdb log purge les supprime. La rétention se règle avec logs-policy.max-age-retention et logs-policy.total-disk-retention de scw rdb instance update. Les journaux et métriques sont aussi visibles dans Cockpit (leçon 14).

Prévenir le disque plein

La page Dealing with the disk_full mode décrit le mécanisme : quand l'espace libre passe sous 2 % du volume (ou sous 2 Go, si 2 % dépassent 2 Go), l'instance passe à l'état disk_full et bascule en lecture seule. Signalements continue d'afficher les signalements, mais ne peut plus en enregistrer. Sur volume bloc, on agrandit le volume, sans arrêt :

$ scw rdb instance upgrade "$DB" volume-size=60GB region=fr-par

Un volume ne se réduit jamais. La vraie réponse est une alerte sur l'espace disque, déclenchée bien avant 98 % (leçon 14), et une surveillance des journaux du moteur, qui partagent le volume.

Monter de version majeure

Lorsque Scaleway propose une version plus récente, elle apparaît dans le champ upgradable_version de l'instance :

$ scw rdb instance get "$DB" region=fr-par -o json | jq '.upgradable_version[] | {id, name, version}'

La procédure, répétition comprise :

  1. vérifier l'absence de types reg* dans les colonnes (requête fournie par la documentation de Scaleway) ;
  2. répéter sur la base de production, sans bascule : scw rdb instance upgrade "$DB" major-upgrade-workflow.upgradable-version-id=<id> major-upgrade-workflow.with-endpoints=false region=fr-par. Une nouvelle instance est créée avec la nouvelle version ; on mesure la durée, on teste l'application en pointant sur elle, puis on la supprime ;
  3. le jour J, annoncer une fenêtre, arrêter les écritures (Signalements en mode maintenance, ou groupe réduit à zéro instance), prendre un instantané manuel ;
  4. relancer avec with-endpoints=true : les points d'accès passent à la nouvelle instance ;
  5. vérifier l'application, réactiver la haute disponibilité et recréer le réplica sur la nouvelle instance ;
  6. garder l'ancienne instance quelques jours, pour pouvoir revenir en arrière en rebasculant les points d'accès (procédure Migrating Database Instance endpoints via the CLI), puis la supprimer.

L'arrêt des écritures n'est pas une précaution de style : la documentation précise qu'aucune synchronisation n'a lieu entre l'ancienne et la nouvelle instance. Une écriture faite pendant l'opération reste dans l'ancienne, et disparaît pour l'application après la bascule.

Une sauvegarde logique hors du fournisseur

Toutes les copies vues jusqu'ici vivent chez Scaleway, sur le même compte. Une erreur de facturation, une clé d'administration compromise qui supprime tout, une décision de changer de fournisseur : aucune ne protège de ces cas. La règle 3-2-1 (trois copies, deux supports, une hors site) demande une copie ailleurs. La plus simple et la plus portable est une sauvegarde logique, faite avec les outils de PostgreSQL :

$ pg_dump --format=custom --no-owner --dbname="$DATABASE_URL_LECTURE" \
    --file="signalements-$(date +%F).dump"
$ pg_restore --list "signalements-$(date +%F).dump" | head
  • --format=custom produit un fichier compressé, que pg_restore sait restaurer table par table ;
  • --no-owner évite de figer les noms de rôles, différents chez un autre hébergeur ;
  • la connexion utilise le rôle sig_lecture, sur le réplica de préférence, pour ne pas charger la base principale ;
  • pg_restore --list vérifie que le fichier est lisible et liste son contenu, sans rien restaurer.

Le fichier est ensuite chiffré et envoyé vers un stockage d'un autre fournisseur, ou d'une autre organisation Scaleway avec d'autres identifiants. Le cours Sauvegarde, restauration et PRA construit cette chaîne et la teste. Pour les gros volumes, on lui préfère un outil d'archivage continu des journaux de transactions, qui suppose un accès que la base managée ne donne pas.

Sous le capot

Pourquoi un instantané de volume est cohérent. Un instantané pris pendant que PostgreSQL écrit capture un état « comme après une coupure de courant » : des pages partiellement écrites, des transactions en cours. PostgreSQL sait repartir de cet état, parce qu'il écrit chaque modification dans son journal de transactions avant de modifier les fichiers de données : au redémarrage, il rejoue le journal depuis le dernier point de contrôle. C'est le principe du write-ahead logging (chapitre 30 de la documentation de PostgreSQL). La documentation de Scaleway qualifie ses instantanés de « cohérents » ; la leçon 5 du cours précédent appelait cela une cohérence après plantage.

Synchrone ou asynchrone. En réplication synchrone (haute disponibilité), le principal attend que le secours ait reçu la transaction avant de confirmer la validation au client : aucune transaction confirmée n'est perdue lors d'une bascule, au prix d'un aller-retour réseau de plus à chaque validation. En réplication asynchrone (réplica en lecture), le principal confirme sans attendre : les écritures restent rapides, mais une promotion peut perdre les dernières secondes. C'est l'arbitrage que décrit le chapitre 26 de la documentation de PostgreSQL, et la raison pour laquelle la promotion d'un réplica demande de vérifier le retard.

Pourquoi une montée majeure crée une autre instance. pg_upgrade peut transformer les fichiers en place, mais l'opération est délicate à annuler. Créer une instance neuve (clone puis mise à jour) laisse l'ancienne intacte : le retour arrière est une simple bascule de points d'accès. C'est le schéma bleu-vert appliqué aux bases de données, au prix d'une double facturation pendant la transition et d'une coupure des écritures.

Le chiffrement au repos. Scaleway peut chiffrer le volume d'une base avec LUKS (aes-xts-plain64, clé de 512 bits pour les deux clés du mode XTS), avec une clé gérée par Scaleway. Il s'active à la création ou ensuite par l'API (enable-encryption=true de scw rdb instance upgrade), et ne se désactive plus ; l'activation copie les données dans un nouveau volume, à raison d'environ une heure par 100 Go, avec quelques secondes d'indisponibilité. Il couvre les bases, les journaux et les instantanés, mais pas les sauvegardes logiques au 5 octobre 2026. Il protège des supports perdus ou mal effacés, pas d'un accès légitime au service (cours Cloud souverain, leçon 5).

Pièges courants

Croire que les sept jours de sauvegarde suffisent. Une corruption silencieuse découverte au bout de dix jours n'a plus aucune copie saine. La rétention se choisit en fonction du délai de détection, pas de l'habitude.

Restaurer par-dessus la base d'origine. Une restauration de sauvegarde logique sans database-name écrase la base. Pendant un incident, on restaure à côté.

Une montée de version avec des écritures en cours. Les écritures faites pendant l'opération restent dans l'ancienne instance. Arrêtez-les, ou acceptez de les perdre en connaissance de cause.

Oublier la haute disponibilité après la montée. La nouvelle instance est un nœud seul : réactivez la haute disponibilité et recréez les réplicas.

Le compte administrateur dans l'application. C'est la configuration par défaut quand on suit le premier tutoriel venu. Trois rôles, et des privilèges par défaut sur les objets futurs.

Le disque plein par les journaux. log_min_duration_statement=0 (tout journaliser) sur une base chargée remplit le volume en quelques heures. Réglez la rétention des journaux et l'alerte d'espace disque.

Les instantanés qui coûtent après la suppression. Supprimer une base laisse ses sauvegardes et instantanés automatiques jusqu'à la fin de leur rétention ; ils sont facturés (0,03 € par Go et par mois d'après la page How to manage volumes).

Promouvoir un réplica en retard. Les transactions non encore répliquées sont perdues. Vérifiez le retard, et si le principal est déjà perdu, notez l'heure de la dernière transaction connue.

Sécurité

  • Rôles séparés et privilèges par défaut pour que l'application ne puisse pas modifier le schéma.
  • Point d'accès privé seul (leçon 6 du cours précédent) ; le réplica, lui aussi, sur le réseau privé, et non sur un point d'accès public ouvert par défaut.
  • TLS vérifié : sslmode=verify-full avec le certificat de l'instance (scw rdb instance get-certificate), renouvelé avant expiration (scw rdb instance renew-certificate).
  • Mots de passe dans Secret Manager, jamais dans un fichier versionné ni dans les données utilisateur d'une instance.
  • Chiffrement au repos activé à la création des nouvelles bases, en connaissant son prix : le banc d'essai publié par Scaleway en décembre 2024 mesure une baisse de 15 % sur une charge transactionnelle sur un nœud seul, et jusqu'à 30 à 40 % en haute disponibilité sur de gros volumes. L'activer après coup demande une copie des données.
  • Les sauvegardes sont des données. Elles contiennent tout : leur accès (RelationalDatabasesFullAccess permet de les télécharger) se limite comme celui de la base, et la copie hors fournisseur se chiffre.
  • L'extension pgaudit, documentée par Scaleway, journalise les opérations sur les données sensibles, si un client l'exige.

En production

Écrire les objectifs, puis la configuration. Commencez par le RPO et le RTO promis aux clients, par exemple 4 heures et 2 heures. Ils imposent : des instantanés toutes les 4 heures au plus, une restauration testée qui tient en moins de 2 heures, une haute disponibilité pour que la panne d'un nœud ne consomme pas ce temps. Sans objectifs écrits, chaque choix de cette leçon est arbitraire.

Tester la restauration chaque trimestre, en mesurant la durée, et après chaque changement important (taille, type de volume, version). Le test est la seule preuve.

Répéter chaque migration de schéma sur un clone quand la table touchée est grosse : un ALTER TABLE qui réécrit une table de dix millions de lignes peut bloquer l'application de longues minutes.

Planifier les maintenances. Scaleway prévient des maintenances et permet de les appliquer plus tôt, sauf pour certains correctifs de sécurité appliqués à chaud ; une maintenance non appliquée s'exécute à la date prévue, dans une fenêtre qui peut durer jusqu'à quatre heures, avec une indisponibilité de quelques minutes. Lisez ces courriels, et appliquez la maintenance vous-même à une heure creuse.

Mettre en commun les connexions. Chaque connexion PostgreSQL est un processus côté serveur, et les petits types de nœuds en acceptent peu. Un groupe d'autoscaling qui passe de 2 à 6 instances, chacune avec plusieurs processus gunicorn et son propre pool, peut épuiser max_connections. Un regroupement de connexions (pooler, comme PgBouncer) ou des pools bien dimensionnés côté application évitent ce goulet.

Savoir quand redescendre vers l'IaaS. Pas de restauration à un instant, pas d'accès aux journaux de transactions pour un archivage continu, certaines extensions absentes : si l'un de ces manques est bloquant, il faut une autre offre, ou un PostgreSQL exploité soi-même, avec tout ce que cela coûte (leçon 2 du cours précédent).

Exercices

1. Choisir la copie (niveau 200). Pour chaque incident, dites quel mécanisme permet de récupérer, et quelle donnée est perdue : (a) le nœud principal tombe à 10 h 12 ; (b) à 17 h, une migration a supprimé la colonne lieu à 16 h 50 ; la dernière sauvegarde automatique date de 12 h ; (c) un incendie détruit le centre de données de la zone de la base ; (d) la clé d'API du propriétaire est volée, et l'attaquant supprime la base et ses instantanés.

Solution

(a) La haute disponibilité : bascule en 30 à 60 secondes, aucune transaction validée perdue (réplication synchrone), connexions coupées. Sans haute disponibilité : restauration du dernier instantané dans une nouvelle instance, perte depuis l'instantané. (b) Restauration de l'instantané de 12 h dans une instance à côté, extraction de la colonne (par pg_dump ou par une requête), réinjection : les valeurs de lieu saisies entre 12 h et 16 h 50 sont perdues, faute de restauration à un instant. Avec des instantanés toutes les 4 heures, la perte serait bornée à 4 heures. (c) Le réplica dans une autre zone, promu : perte des dernières secondes non répliquées. Ou une restauration à partir d'une sauvegarde stockée dans une autre région, si elle existe. (d) Seule la copie hors du compte (sauvegarde logique chez un autre fournisseur ou dans une autre organisation) survit. D'où la règle 3-2-1.

2. Calculer le RPO et le coût (niveau 300). La base fait 40 Go. Le client exige un RPO de 4 heures et une rétention de 30 jours. Proposez une politique de sauvegarde, et estimez l'ordre de grandeur du stockage des instantanés en supposant que chaque instantané stocke, après le premier, 2 % de données modifiées.

Solution

Instantanés toutes les 4 heures (backup-schedule-frequency=4), rétention 30 jours (backup-schedule-retention=30) : 6 par jour, 180 au total. Stockage : un premier instantané complet (40 Go), puis 179 × 2 % × 40 Go ≈ 143 Go, soit environ 183 Go, ce qui donne au tarif documenté de 0,03 € par Go et par mois un peu plus de 5 € par mois. Le calcul suppose un stockage incrémental des instantanés, que la documentation ne détaille pas : vérifiez sur la facture après un mois. Complétez avec une sauvegarde logique quotidienne hors du fournisseur, qui ne dépend pas de ce mécanisme.

3. Les privilèges oubliés (niveau 200). Après une migration qui crée la table photos, l'application reçoit permission denied for table photos. Les permissions de sig_app avaient été réglées sur readwrite le mois dernier. Expliquez, corrigez, et évitez que cela se reproduise.

Solution

Les permissions s'appliquent aux objets existants au moment où on les règle : photos n'existait pas, sig_app n'a aucun droit dessus. Correction immédiate : GRANT SELECT, INSERT, UPDATE, DELETE ON photos TO sig_app; (et les séquences associées), exécuté par le propriétaire de la table. Prévention : ALTER DEFAULT PRIVILEGES FOR ROLE sig_migration IN SCHEMA public GRANT ... TO sig_app;, pour que toute table future créée par le rôle de migration soit accessible. Et un test de fumée après chaque migration, qui exerce l'application avec son vrai rôle.

4. Préparer la montée de version (niveau 300). Rédigez le plan de la montée de PostgreSQL 17 vers la version suivante proposée, pour Signalements en production, avec ses étapes, ses vérifications, sa durée estimée, son retour arrière, et ce que vous dites aux métropoles.

Solution

Préparation (J−14) : vérifier les types reg* ; lire les notes de version de PostgreSQL pour les incompatibilités ; répéter avec with-endpoints=false, mesurer la durée (par exemple 25 minutes), tester l'application sur l'instance de répétition, la supprimer. Annonce (J−7) : fenêtre de 60 minutes en heure creuse, écriture impossible pendant la fenêtre. Jour J : Signalements en mode maintenance (lecture seule ou page d'attente), instantané manuel, montée avec with-endpoints=true, vérification (/sante, création d'un signalement de test, comptages comparés), réactivation de la haute disponibilité et du réplica, réouverture. Retour arrière : rebascule des points d'accès vers l'ancienne instance, en sachant que les écritures faites après la bascule seraient perdues ; conserver l'ancienne instance sept jours. Communication : avant, pendant (page de statut), après (confirmation, et ce qui a changé).

Récapitulatif

  • Instantané, sauvegarde logique, clone et réplica sont des mécanismes différents ; seuls les deux premiers permettent de revenir en arrière.
  • Sur volume bloc, la sauvegarde automatique est un instantané, restauré dans une nouvelle instance ; les sauvegardes et instantanés automatiques survivent à la suppression de la base.
  • Pas de restauration à un instant documentée au 5 octobre 2026 : le RPO est l'intervalle entre deux instantanés, réglable à l'heure.
  • Haute disponibilité : réplication synchrone, bascule automatique en 30 à 60 secondes, irréversible. Réplica en lecture : asynchrone, éventuellement dans une autre zone, promotion manuelle et irréversible.
  • Une montée de version majeure crée une nouvelle instance, sans synchronisation : on répète, on arrête les écritures, on bascule les points d'accès, on réactive la haute disponibilité.
  • Trois rôles (migration, application, lecture) et ALTER DEFAULT PRIVILEGES pour les objets futurs.
  • Sous 2 % d'espace libre (ou 2 Go), la base passe en lecture seule : une alerte avant.
  • Une sauvegarde logique hors du fournisseur, et une restauration testée et chronométrée.

Pour aller plus loin

  • Les chapitres 25 (Backup and Restore) et 26 (High Availability, Load Balancing, and Replication) de la documentation de PostgreSQL 17, pour comprendre ce que le service managé fait à votre place.
  • La documentation de Scaleway sur les réplicas, la bascule automatique et la montée de version, à relire avant chaque opération.
  • Le cours Sauvegarde, restauration et PRA, qui construit la copie hors fournisseur et le test régulier.
  • La leçon 8, où vivront les mots de passe des trois rôles, et la leçon 14, pour les alertes sur l'espace disque et le retard de réplication.
Voir ma constellation →

Sources