quest'n'click 4.5.0 · r1

Construite pour quest'n'click 4.5.0, révision r1. Si elle est publiée, et laquelle est la courante, est dit par publication.json.

Sauvegarde et restauration

English · Type : procédure · Public : administrateur · Contexte : Reality Bridge · Statut : prête · S'applique depuis : 4.2.5

Le Reality Bridge, profil local (SQLite) · contrat : stable · vérifié par la CI (matrice de support de la 4.4.0, 2026-10-23) : Node 22.13+ avec node:sqlite, sous Ubuntu ; Chromium et WebKit de bout en bout · vérifications automatiques : jobs reality, reality-xcheck ; plan de CI reality ; 2 fichiers de tests · passes humaines : aucune · limites connues : bridge-backup-digest-not-signature, bridge-backup-bounds, bridge-replace-store-two-transactions, bridge-leases-older-bridges

Le Reality Bridge, profil distributed (Postgres) · contrat : expérimental · vérifié par la CI (matrice de support de la 4.4.0, 2026-10-23) : Postgres 16 en CI ; Le profil de qualification : HTTPS, trois instances (ops/qualify/) · vérifications automatiques : jobs bridge-postgres, deployment-smoke ; plan de CI reality ; 1 fichier de tests · passes humaines : bridge-postgres-https pas faite (#77) · limites connues : bridge-backup-digest-not-signature, bridge-backup-bounds, bridge-replace-store-two-transactions, bridge-leases-older-bridges

Comment sauvegarder le stockage d’un Reality Bridge dans un seul fichier, le restaurer tout ou rien, et remettre un Bridge en route après la perte d’une instance ou de sa base. Il s’agit de la sauvegarde du Bridge (npm run bridge -- backup), pas de celle du Studio hébergé (studio-server backup, Sauvegardes sur Clever Cloud).

Ce que vous obtenez

Un fichier de sauvegarde du stockage entier, pris en un seul instantané, avec une empreinte qui détecte un fichier modifié ou tronqué par accident ; et, le jour où il le faut, un stockage restauré depuis ce fichier en une seule transaction, vérifié avant et après sa validation, dans un mode que vous nommez.

Contexte et versions

Prérequis

Où lancer les commandes

Sur une machine qui atteint le stockage, avec le dossier du Bridge : la machine du Bridge, ou une machine avec plus de mémoire (une restauration n’a besoin que d’atteindre le stockage). npm run bridge -- … dans le dépôt du moteur ; npx quest-n-click-bridge … avec le paquet autonome.

Étapes

  1. Sauvegardez le stockage :

    # sur la machine du Bridge, dans le dépôt du moteur
    npm run bridge -- backup --out=bridge-2026-10-23.json
    

    Elle affiche ✔ 1 tenant(s), 1 signal(s), 0 run(s), 0 daily record(s) backed up to …/bridge-2026-10-23.json (schema 4, one snapshot, sha256 1edef3c0f48b…). Le stockage entier est lu dans une seule transaction en lecture seule : tenants, runs, enregistrements du jour et quota des speedruns. Le fichier est en mode 600, écrit dans un fichier temporaire puis renommé. Il contient les empreintes des capacités, jamais une capacité ni une clé.

    Son enveloppe donne le backend, les versions du Bridge et du schéma SQL, ce qu’elle contient (completeness : whole-store pour un stockage SQL, tenants-only pour le journal ou la mémoire), le début et la fin, les comptes par famille, et un SHA-256 de l’ensemble (scope: envelope).

Limite · bridge-backup-digest-not-signature L’empreinte est un contrôle d’intégrité contre un fichier modifié ou tronqué par accident, pas une signature : quiconque peut modifier le fichier peut la recalculer. Gardez les sauvegardes là où vous seul pouvez écrire.

Limite · bridge-backup-bounds Un stockage au-delà de --max-rows (2 000 000) ou un fichier au-delà de --max-bytes (256 Mio) est refusé et aucun fichier n’est écrit. Au-delà de quelques centaines de Mio, utilisez les outils de la base elle-même (pg_dump, les instantanés du fournisseur, une copie du fichier SQLite Bridge arrêté).

  1. Pour restaurer, arrêtez d’abord chaque serve sur ce stockage. Depuis la 4.1.20, le stockage refuse une restauration tant que quelque chose tient un bail vivant, en nommant qui le tient et jusqu’à quand ; une restauration ne tourne jamais à côté d’écrivains vivants.
  1. Restaurez avec --mode=merge : dans un stockage vide, ou avec --force par-dessus les tenants que contient le fichier.

    # sur une machine qui atteint le stockage, dans le dépôt du moteur
    npm run bridge -- restore --from=bridge-2026-10-23.json --mode=merge          # dans un stockage vide, sinon refusé
    npm run bridge -- restore --from=bridge-2026-10-23.json --mode=merge --force  # les tenants du fichier remplacés, les autres gardés
    

    Un conflit (un tenant, un run ou un quota de ses tenants, une clé du jour) la refuse sans --force : ✖ the store already holds tenant(s) default: restore into an empty store, or --force; nothing restored. Avec --force, les familles du fichier remplacent ce avec quoi elles entrent en conflit, et ce dont le fichier ne parle pas reste (un autre tenant, une autre clé du jour). Tout schéma, de 1 à 4.

  1. Ou restaurez avec --mode=replace-store : le stockage devient le fichier.

    # sur une machine qui atteint le stockage, dans le dépôt du moteur
    npm run bridge -- restore --from=bridge-2026-10-23.json --mode=replace-store --yes-replace-store --safety-out=before-restore.json
    

    Toutes les tables sauf celles de contrôle (schema_migrations) sont vidées dans la même transaction, puis le fichier est écrit et relu, rien de plus n’est gardé. Ce mode n’accepte qu’une sauvegarde de schéma 4 d’un stockage SQL entier, au schéma SQL de ce stockage. D’abord, une sauvegarde du stockage remplacé est écrite dans --safety-out, un chemin qui ne doit pas exister (pas de lien non plus), relue et vérifiée ; si cela échoue, rien n’est supprimé. Son chemin est rappelé dans chaque issue.

Limite · bridge-replace-store-two-transactions La sauvegarde de sécurité et le remplacement sont deux transactions : arrêtez tout écrivain entre les deux (le bail de maintenance les refuse à partir de la 4.1.20). Le fichier de sécurité est écrit par un lien physique, qui ne remplace jamais un nom : donnez-lui un chemin sur un système de fichiers qui les accepte (ni FAT ni exFAT).

  1. Vérifiez le stockage, puis relancez le Bridge :

    # dans le dépôt du moteur
    npm run bridge -- doctor
    

Garantie · bridge-restore-names-its-mode · référencée · exécutée sur aff6caab7514 · portée vérifiée par son auteur (IA), pas relue Sans --mode, ou avec --force seul, restore s’arrête avec le code de sortie 2, et l’usage nomme les deux modes.

Garantie · bridge-restore-refused-while-serving · référencée · portée vérifiée par son auteur (IA), pas relue Tant qu’un Bridge sert le stockage, une restauration est refusée et dit que rien n’a été restauré. Une fois le Bridge arrêté, elle restaure.

Résultat attendu, et comment le vérifier

restore se termine avec le code 0 et une ligne : ✔ 1 tenant(s), 0 run(s), 0 daily record(s), 0 quota row(s) restored from <date> (schema 4, merge), checked before and after the commit (avec replace-store, suivie de (the store before: <fichier de sécurité>)). Le fichier a été lu de façon bornée et vérifié en entier avant l’ouverture du stockage (schémas 1 à 4 ; chaque ligne, les doublons, les relations, les comptes et l’empreinte de la charge du schéma 3, l’empreinte de l’enveloppe du schéma 4, les dates, la version et la complétude), écrit dans une transaction, relu et comparé avant la validation, puis audité après. doctor liste ensuite les joueurs et les signaux de chaque tenant, sans trou.

Erreurs fréquentes

Message ou code de sortieCauseCorrection
code 2, say the mode: --mode=merge … --mode=replace-store …; nothing restoredPas de --modeNommer le mode
the store already holds tenant(s) …: restore into an empty store, or --force; nothing restoredUn conflit en mergeUn nouveau stockage, ou --force
replace-store needs a schema 4 backup of a whole SQL store (…)Un fichier plus ancien, ou venu du journal (tenants-only)--mode=merge, ou une nouvelle sauvegarde
the backup comes from a store at schema N, newer than this one (M): upgrade the BridgeLe moteur est plus ancien que la sauvegardeMettre le Bridge à jour
the JSON-lines journal cannot be restored all or nothing: migrate it to SQLite first …Le stockage est le journalmigrate --from=jsonl --to=sqlite, puis restaurer avec --store=sqlite
the backup would be N bytes, more than M (--max-bytes=): no file writtenUn stockage trop gros pour un fichierLes outils de la base elle-même
Un refus qui nomme le détenteur du bail, ; nothing restoredUn Bridge sert encore le stockageL’arrêter
code 3, P0: the restore committed but …Une différence trouvée après la validationArrêter toutes les instances, garder ce stockage pour examen ; un écrivain pendant la restauration peut l’expliquer
code 3, the commit's answer was lost …La connexion est tombée à la validationdoctor, et une sauvegarde, pour voir de quel côté c’est tombé

Fichiers ou données modifiés

Reprise ou retour en arrière

Santé et mesures

Mémoire : dimensionner la machine à la sauvegarde

backup, tenant export et restore tiennent le fichier entier en mémoire, lu et canonique ; une restauration le tient deux fois (le fichier, puis le stockage relu pour comparer).

Mesure · bridge-backup-memory Pic de mémoire (RSS) du Bridge de l’archive, pour environ 72 Mo au repos : une sauvegarde de 64 Mio a pris 0,6 Go à l’export, 1,4 Go à la restauration sur SQLite et 1,3 Go sur Postgres ; 128 Mio, 1,1 à 1,3 Go, 2,7 Go et 2,4 Go ; 256 Mio, 2,1 à 2,2 Go, 3,1 Go et 3,7 Go. À lire comme environ 10 Mo de mémoire par Mio de fichier pour une sauvegarde, 20 Mo pour une restauration : une observation, pas une promesse pour votre machine.

  • date: 2026-10-13
  • version: 4.1.20
  • volume: sauvegardes de 64, 128 et 256 Mio, sur SQLite et sur Postgres
  • conditions: le job backup-memory du candidat (tools/backup-memory.ts), un runner Linux de GitHub, le Bridge de l’archive du candidat ; une mesure par taille et par stockage
  • source: REALITY-OPS.md, "Health, measures, backups"

Dans un conteneur de 512 Mio, une restauration tient jusqu’à environ 20 Mio de sauvegarde. Lancez une plus grosse depuis une machine qui a la mémoire, ou abaissez --max-bytes et --max-rows à ce que la machine tient, pour qu’un fichier trop gros soit refusé avant d’être lu.

Les baux de maintenance (4.1.20)

À partir du schéma 5 (migration 0005), chaque écrivain tient un bail dans le stockage lui-même (ADR 0023) :

Limite · bridge-leases-older-bridges Un Bridge antérieur à la 4.1.20 ne prend pas de bail : arrêtez toute instance plus ancienne avant la première restauration. migrate --schema=N en dessous de 5 supprime la table des baux dès sa première étape : arrêtez tout écrivain pour cela.

Les lignes d’un seul tenant

tenant export --tenant=<id> [--out=<fichier>] écrit les lignes d’un tenant, dans chaque table (sur la sortie standard sans --out) ; tenant delete --tenant=<id> --yes les supprime. Sans --yes, rien n’est supprimé. La sauvegarde est logique, portable et bornée ; pour un gros déploiement, pg_dump ou les instantanés du fournisseur restent la sauvegarde de la base elle-même.

Références


Modifier la source de cette page · Signaler une erreur