Mirajv1.0
FR

19. Sauvegarde et restauration : BACKUP, miraj-backup, miraj-dump

MIRAJ propose deux façons de sauvegarder une base, complémentaires :

Sauvegarde physique à chaudSauvegarde logique en SQL
OutilBACKUP DATABASE / RESTORE DATABASE, miraj-backupmiraj-dump
ContenuCopie des fichiers de la base (tables, BLOB, journal)Script SQL qui recrée la base
VitesseTrès rapide : copie de fichiersPlus lente : chaque ligne est relue puis réinsérée
ServeurReste en service ; les écritures ne sont suspendues que quelques millisecondesReste en service ; lecture dans une transaction
RestaurationMême version de MIRAJ (ou plus récente)Toute version, toute machine ; script modifiable
ComptesNon (le coffre des comptes est lié à la machine)Oui, avec --users

Règle pratique : sauvegardez chaque jour avec BACKUP DATABASE (rapide, restauration immédiate) et gardez de temps en temps un export miraj-dump --users (portable, lisible, indépendant de la version).

Sous Windows, le gestionnaire Miraj Server Manager planifie sans script une sauvegarde complète de toutes les bases vers un dossier choisi, en gardant les N plus récentes (voir 22.10).

19.1 Sauvegarde physique à chaud#

Dossier de données chiffré (éditions Entreprise et Cluster) : la copie d'une base chiffrée reste chiffrée et emporte le trousseau, protégé par la phrase secrète ; sa restauration demande la même clé maîtresse. Voir le chapitre 25, §25.6.

19.1.1 Activer : --backup-dir#

Les deux instructions sont refusées (erreur 1290) tant que le serveur n'a pas de dossier de sauvegardes :

miraj-server --root D:\miraj\data --backup-dir E:\sauvegardes --log

ou dans miraj_config.xml :

<backup_dir>E:\sauvegardes</backup_dir>

Le dossier est créé s'il n'existe pas. Il ne doit ni contenir ni se trouver dans le dossier de données, celui des clés du coffre, celui de la clé privée TLS, celui du journal des requêtes lentes (fixé au démarrage par un chemin absolu) ni dans le dossier --secure-file-priv (dans un sens comme dans l'autre), et ne doit pas contenir le fichier de configuration ; sinon le serveur refuse de démarrer en nommant les deux dossiers. Un compte ayant le privilège FILE ne peut ainsi ni lire les sauvegardes par LOAD_FILE, ni y déposer une sauvegarde forgée par SELECT … INTO DUMPFILE. Toutes les sauvegardes et restaurations SQL s'y font : un chemin relatif s'y rapporte, un chemin absolu doit s'y trouver, .. est refusé. Placez-le de préférence sur un autre disque que les données.

19.1.2 BACKUP DATABASE#

BACKUP DATABASE nom TO 'dossier'
BACKUP DATABASE nom1, nom2 TO 'dossier'
BACKUP ALL DATABASES TO 'dossier'
  • Le dossier de destination est créé ; s'il existe, il doit être vide.
  • Avec plusieurs bases (liste ou ALL DATABASES), chaque base a son sous-dossier dossier\nom. ALL DATABASES exclut la base système.
  • Le résultat compte une ligne par base : Database, Directory, Files, Bytes, End_lsn (position du journal atteinte par la copie).
  • Droit requis : BACKUP_ADMIN.
BACKUP DATABASE gestion TO 'gestion-2026-09-24';
+----------+-----------------------------------+-------+---------+---------+
| Database | Directory                         | Files | Bytes   | End_lsn |
+----------+-----------------------------------+-------+---------+---------+
| gestion  | E:\sauvegardes\gestion-2026-09-24 |     5 | 1069338 |     208 |
+----------+-----------------------------------+-------+---------+---------+
BACKUP DATABASE gestion, essai TO 'multi';
+----------+------------------------------+-------+---------+---------+
| Database | Directory                    | Files | Bytes   | End_lsn |
+----------+------------------------------+-------+---------+---------+
| gestion  | E:\sauvegardes\multi\gestion |     5 | 1069338 |     208 |
| essai    | E:\sauvegardes\multi\essai   |     2 |  609250 |  608945 |
+----------+------------------------------+-------+---------+---------+

Refus : dossier de destination non vide, erreur 9018 (Backup directory '…' is not empty) ; chemin hors de --backup-dir (par exemple '../x'), erreur 1290 (The server is running with the --backup-dir option so it cannot execute this statement).

Ce qui se passe pendant la copie. La sauvegarde attend la fin des écritures de fichier en cours, puis tient brièvement toutes les tables de la base en lecture. Pendant ce court instant, de l'ordre de quelques millisecondes, les écritures attendent et les lectures continuent. La sauvegarde pose alors un second lien vers chaque fichier dans un dossier de travail et relève la position du journal. Tout est ensuite rendu. La copie proprement dite se fait sans rien bloquer, pendant que les clients continuent d'écrire.

Le résultat est une coupure nette : toutes les transactions validées avant la phase figée sont dans la sauvegarde, aucune de celles validées après. Une transaction n'y est jamais à moitié. Avec plusieurs bases, chacune est coupée à son propre instant : la sauvegarde de plusieurs bases n'est pas un instantané commun.

Cas particuliers :

  • Une transaction ouverte par la session qui lance BACKUP est validée d'abord, comme avant un DDL.
  • BACKUP est refusé sous LOCK TABLES de la session et dans une routine (1314). Une table tenue par le LOCK TABLES ... WRITE d'une autre session fait échouer la sauvegarde (table occupée).
  • En politique save_policy = manual (aucun journal), les tables sont d'abord écrites sur le disque, toute autre instruction étant suspendue le temps de cette écriture. Une transaction ouverte sur une table empêche alors la sauvegarde.
  • Un dossier de destination incomplet (serveur arrêté pendant la copie) n'a pas de manifest.json : il n'est pas restaurable et peut être supprimé. Le dossier de travail éventuel (<root>\.backup-…) est supprimé au redémarrage suivant.

19.1.3 Contenu d'une sauvegarde#

gestion-2026-09-24\
  manifest.json      description de la sauvegarde, écrite en dernier
  clients.mrj        une table par fichier .mrj
  clients.bmrj       BLOB longs de la table
  journaux.dmrj      table disque (ENGINE = Aria, MyISAM ou DISK), à la place d'un .mrj
  journaux.dbmrj     BLOB longs d'une table disque
  routines.mrp       procédures et fonctions
  views.mrv          vues
  sequences.mrq      séquences (définition et état)
  triggers.mrt       déclencheurs
  events.mre         événements
  journal.mrl        journal : transactions à rejouer sur les tables à la restauration

manifest.json indique :

  • le format (2), la base d'origine, la date et la version du moteur ;
  • les positions du journal ;
  • pour chaque fichier, sa taille, sa somme de contrôle CRC32 (usure du support) et son empreinte SHA-256 (altération volontaire) ;
  • sa signature (signature) : HMAC-SHA256 du manifeste, calculé avec une clé dérivée de la clé du coffre des comptes du serveur, et l'identifiant public de cette clé. La clé du coffre ne quitte jamais son dossier. Une sauvegarde faite sans coffre des comptes ouvert (moteur embarqué sans comptes, miraj-backup hors ligne sans accès aux clés) n'est pas signée.

Toutes les tables de la base sont copiées de la même façon, en mémoire comme sur disque : une table disque se sauvegarde, se restaure et se vérifie (miraj-backup verify) comme les autres, et la table compagnon de l'historique d'une table à versionnement système (chapitre 12) en fait partie. Seuls le journal d'origine, l'état de réplication du nœud et les fichiers temporaires ne sont pas recopiés ; le journal de la copie est reconstruit.

La sauvegarde n'est pas compressée : compressez le dossier avec l'outil de votre choix si nécessaire.

19.1.4 RESTORE DATABASE#

RESTORE DATABASE nom FROM 'dossier' [REPLACE]
  1. Le nom nom doit être libre (erreur 1007 sinon, sauf REPLACE). Le manifeste est ensuite lu et sa signature contrôlée (voir ci-dessous). Chaque fichier est recopié dans un dossier de travail de la racine, et sa taille, sa somme de contrôle et son empreinte SHA-256 sont vérifiées au passage. Une sauvegarde altérée est refusée sans rien toucher.
  2. Les définisseurs des routines, déclencheurs, événements et vues sont contrôlés (voir ci-dessous).
  3. La base est ensuite installée sous le nom nom, puis chargée. Le journal de la copie est rejoué, comme à un redémarrage.

Signature.

SauvegardeRestauration
Signée par la clé de ce serveur, signature valideAcceptée
Signée par la clé de ce serveur, signature invalide (manifeste ou fichier modifié, sommes recalculées comprises)Refusée (erreur 9029)
Non signée (faite sans coffre, ou format 1 antérieur à la signature)Acceptée, avertissement 9030 « sauvegarde non signée » : seules les sommes de contrôle sont vérifiées
Signée par une autre clé (autre serveur, comptes recréés par --reset-accounts) ou serveur sans coffreAcceptée, avertissement 9031 : signature non vérifiée

Une sauvegarde non signée ou signée ailleurs ne prouve pas son origine : ne restaurez que des sauvegardes dont vous connaissez la provenance, et gardez --backup-dir hors de portée des comptes FILE (voir 19.1.1).

Définisseurs. Les routines, déclencheurs, événements et vues s'exécutent avec les droits de leur définisseur (DEFINER). Comme CREATE DEFINER=…, garder un définisseur autre que soi demande SUPER ou SET_USER_ID :

  • avec l'un de ces droits (par exemple root), les définisseurs de la sauvegarde sont gardés ;
  • sans eux, chaque objet dont le définisseur est un autre compte est réattribué au compte qui restaure (texte CREATE DEFINER=… d'une routine compris), avec un avertissement 9032 par objet (« PROCEDURE p : définisseur root@localhost remplacé par ops@% »). Les objets du compte qui restaure sont inchangés.

Un compte BACKUP_ADMIN et CREATE ne peut donc pas, par une sauvegarde, installer un déclencheur ou une routine qui s'exécuterait avec les droits de root.

Le nom peut différer de celui de la base sauvegardée : c'est ainsi qu'on restaure à côté de la base en service pour comparer ou récupérer des lignes. Un avertissement (SHOW WARNINGS) le rappelle. Les références qualifiées par l'ancien nom dans les vues, les routines ou les clés étrangères vers une autre base gardent l'ancien nom.

  • Nom déjà pris : erreur 1007, sauf avec REPLACE, qui supprime d'abord la base existante, comme DROP DATABASE. Des lignes tenues par une transaction ouverte empêchent le remplacement.
  • Nom invalide ou base système : erreur 1102.
  • Droits requis : BACKUP_ADMIN et CREATE, plus DROP avec REPLACE.
  • Cluster : refusé sur un nœud secondaire et dans un cluster à plusieurs nœuds. Une base restaurée n'est pas transmise aux secondaires : restaurez sur un nœud seul.
  • Arrêt pendant la restauration : au redémarrage, la base est soit absente, soit entière, jamais à moitié installée. Le dossier de travail (<root>\.restore-…) est supprimé.
RESTORE DATABASE gestion_hier FROM 'gestion-2026-09-24';
SHOW WARNINGS;
SELECT id, nom FROM gestion_hier.clients WHERE id = 42;
+--------------+-----------------------------------+-------+---------+---------+
| Database     | Directory                         | Files | Bytes   | End_lsn |
+--------------+-----------------------------------+-------+---------+---------+
| gestion_hier | E:\sauvegardes\gestion-2026-09-24 |     5 | 1069338 |     208 |
+--------------+-----------------------------------+-------+---------+---------+
+---------+------+-------------------------------------------------------------------------------------------------------------------------------------------+
| Level   | Code | Message                                                                                                                                   |
+---------+------+-------------------------------------------------------------------------------------------------------------------------------------------+
| Warning | 1105 | base gestion restaurée sous le nom gestion_hier : les références qualifiées par l'ancien nom (vues, routines, clés étrangères) le gardent |
+---------+------+-------------------------------------------------------------------------------------------------------------------------------------------+
+----+--------+
| id | nom    |
+----+--------+
| 42 | Durand |
+----+--------+

Relancée, la même restauration rend ERREUR 1007 (HY000) : Can't create database 'gestion_hier'; database exists.

19.1.5 Sauvegarde incrémentielle continue (archivage du journal)#

Éditions Entreprise et Cluster. En édition Express, les réglages et la clause WITH ARCHIVE sont refusés (erreur 9001).

Une sauvegarde complète fige la base à un instant ; ce qui est écrit ensuite n'est protégé qu'à la sauvegarde suivante. L'archivage continu du journal comble cet intervalle : le serveur recopie dans un dossier d'archive, au fil de l'eau (en moins d'une seconde), chaque modification validée. Une restauration part alors d'une sauvegarde complète et rejoue l'archive, jusqu'à la dernière modification archivée ou jusqu'à un instant choisi (point-in-time recovery).

Activer.

VariableRôle
journal_archiveON : archivage actif (défaut OFF)
journal_archive_dirdossier de l'archive, absolu ; ni dans le dossier de données, ni dans secure_file_priv (il peut se trouver dans backup_dir)
journal_archive_max_lagretard maximal de l'archive sur le journal, en octets (défaut 1 Gio, au moins 1 Mio)

Les trois variables se règlent dans miraj_config.xml (valeurs de départ) ou à chaud par SET GLOBAL, avec SUPER, SYSTEM_VARIABLES_ADMIN ou BACKUP_ADMIN. SET GLOBAL n'est pas persisté : Miraj Server Manager écrit les deux (voir 22.10.3).

SET GLOBAL journal_archive_dir = 'D:\\Archive MIRAJ';
SET GLOBAL journal_archive = ON;
SHOW STATUS LIKE 'Miraj_journal_archive%';

Refus : journal_archive = ON sans dossier (1290), en politique de sauvegarde manuelle ou sur un nœud en lecture seule ; dossier relatif ou mal placé (1231) ; dossier retiré pendant l'archivage (1231).

Contenu du dossier d'archive. Un sous-dossier par base :

<journal_archive_dir>\gestion\
    archive.json                       lignée courante et ses coupures
    archive-<lignée>.json              lignées précédentes
    <lignée>-<LSN>.mra                 segments (16 Mo ou 5 minutes au plus chacun)
    base-AAAAMMJJ-hhmmss\              sauvegardes complètes prises par le serveur lui-même

Chaque segment porte les enregistrements du journal, précédés des octets des BLOB longs qu'ils citent, et des repères horaires. Une fin de segment tronquée par un arrêt brutal est retirée au redémarrage, et l'archivage reprend où il s'était arrêté.

Lignées. Une lignée est une suite ininterrompue de modifications d'une base. Une nouvelle lignée commence, avec une nouvelle sauvegarde complète prise aussitôt par le serveur dans base-…, quand la continuité ne peut plus être garantie :

  • archivage activé, ou réactivé après une pause ;
  • base créée, supprimée ou restaurée ;
  • enregistrements retirés du journal avant d'être archivés ;
  • retard au-delà de journal_archive_max_lag, par exemple si le disque de l'archive est plein ou débranché. Le serveur signale l'incident dans son journal et cesse de retenir le journal, pour ne pas remplir le disque des données.

Un arrêt propre du serveur ne rompt pas la lignée. Après un arrêt brutal, elle reprend si le journal contient encore ce qui n'avait pas été archivé ; sinon, une nouvelle lignée commence.

Coupures (DDL). Un DDL ne se rejoue pas : CREATE/ALTER/DROP TABLE, RENAME, les index, les routines, les déclencheurs, les événements, les vues, OPTIMIZE et REPAIR. Chacun est noté comme une coupure au point du journal où il s'exécute. Une restauration depuis une sauvegarde antérieure s'arrête avant la première coupure qui la suit, avec un avertissement. Environ trente secondes après un DDL (le temps qu'une série de DDL s'achève), le serveur prend une nouvelle base dans base-…, à partir de laquelle la restauration va au-delà.

Sauvegardes prolongeables. Une sauvegarde complète faite pendant l'archivage (BACKUP, planifiée ou non, ou base prise par le serveur) porte dans son manifeste la lignée et le numéro de la prochaine coupure ("archive", signés avec le reste). Une sauvegarde faite sans archivage ne se prolonge pas.

Restaurer.

RESTORE DATABASE nom FROM 'dossier'
    WITH ARCHIVE ['dossier d'archive']
    [UNTIL TIME 'AAAA-MM-JJ hh:mm:ss' | UNTIL LSN n]
    [REPLACE]
  • WITH ARCHIVE : sans dossier, celui du serveur (journal_archive_dir). Un dossier donné doit se trouver sous backup_dir ou sous journal_archive_dir.
  • FROM accepte aussi une base prise par le serveur, sous journal_archive_dir.
  • UNTIL TIME : état de la base à cette heure locale du serveur, à la seconde près. Ce sont les modifications que l'archive avait reçues à cet instant.
  • UNTIL LSN : état à cette position du journal. Une position au-delà de l'archive est refusée.
  • Sans borne : jusqu'à la dernière modification archivée, ou jusqu'à la première coupure.

Le résultat donne la position atteinte (End_lsn). Un avertissement rappelle la plage rejouée et, le cas échéant, le DDL qui l'a arrêtée.

-- État d'hier 15 h 30, à côté de la base en service
RESTORE DATABASE gestion_1530 FROM 'miraj-2026-09-29_020000\gestion'
    WITH ARCHIVE UNTIL TIME '2026-09-29 15:30:00';

Purge. L'archive grossit tant que rien ne la purge. Miraj Server Manager la purge après chaque sauvegarde planifiée : il garde ce qui prolonge les sauvegardes conservées. Hors du gestionnaire, supprimez les segments d'une lignée dont le LSN de départ du segment suivant est inférieur au End_lsn de la plus ancienne sauvegarde gardée. miraj-backup list --from <dossier d'archive de la base> montre les lignées et leurs périodes.

Limites.

  • La restauration se fait base par base ; il n'y a pas d'instant commun à plusieurs bases.
  • En cluster, l'archivage se règle sur le primaire seulement (refusé sur un nœud en lecture seule).
  • Un dossier de données remplacé serveur arrêté (restauration hors ligne par miraj-backup --root) doit être suivi d'une désactivation puis d'une réactivation de l'archivage.

19.2 L'outil miraj-backup#

miraj-backup pilote les mêmes opérations depuis la ligne de commande, par exemple dans une tâche planifiée.

miraj-backup backup  --db <base>[,<base>…] | --all  --to <dossier>  [connexion | --root <dossier de données>]
miraj-backup restore --from <dossier> --db <nom> [--replace]      [connexion | --root <dossier de données>]
                     [--with-archive | --archive <dossier>] [--until "AAAA-MM-JJ hh:mm:ss" | --until-lsn <n>]
miraj-backup verify  --from <dossier> [--deep]
miraj-backup list    --from <dossier>
ModeQuandDossier --to / --from
Réseau (par défaut)Serveur démarré : l'outil envoie BACKUP / RESTORE au serveurCelui du serveur, relatif à son --backup-dir
Hors ligne (--root)Serveur arrêté : l'outil ouvre le dossier de données lui-mêmeLocal, hors du dossier de données

Connexion :

OptionDéfaut
--host127.0.0.1
--port7007
--userroot
--passwordDemandé au clavier, sans écho (aussi --ask-password) ; sans l'option, la variable MIRAJ_PASSWORD si elle existe, sinon aucun
--password=<mot de passe>Déconseillé : visible dans la liste des processus (avertissement)
--ssl, --ssl-ca <fichier.pem>, --ssl-insecure, --no-sslTLS proposé par défaut (voir ci-dessous)
--protocol auto|miraj|postgresqlauto : langage de l'instance reconnu à la connexion ; BACKUP / RESTORE écrits dans ce langage (voir 30.12)

Mot de passe. Un mot de passe écrit sur la ligne de commande (--password=secret, ou --password secret comme dans les versions précédentes) est visible des autres utilisateurs de la machine dans la liste des processus ; l'outil affiche un avertissement. En usage interactif, donner --password seul : il est demandé au clavier sans être affiché. Dans une tâche planifiée, définir MIRAJ_PASSWORD dans l'environnement de la tâche (ou dans un fichier lisible du seul compte de service, droits 0600 sous Linux, chargé avant l'appel). Un mot de passe qui commence par un tiret s'écrit --password=-motdepasse.

Chiffrement TLS. Les lignes lues ou écrites, et avec miraj-dump --users les vérificateurs des comptes, passent par cette connexion :

OptionEffet
(aucune)TLS proposé : chiffré si le serveur annonce TLS (--tls-cert, chapitre 16), en clair sinon. Le certificat n'est pas vérifié : protège d'une écoute passive, pas d'un intermédiaire actif.
--sslTLS exigé ; le certificat doit être signé par une autorité publique reconnue ou par celle de --ssl-ca, et valable pour le nom ou l'adresse de --host.
--ssl-ca <fichier.pem>Autorité (fichier PEM) qui a signé le certificat du serveur ; pour un certificat autosigné, le certificat lui-même. Implique --ssl.
--ssl-insecureTLS exigé, certificat accepté sans vérification, avec un avertissement.
--no-sslConnexion en clair.

Hors de la machine du serveur, utiliser --ssl-ca : sans vérification du certificat, un intermédiaire peut se faire passer pour le serveur, relayer la connexion et lire les données.

Hors ligne : --root <dossier de données> et, si la clé du coffre n'est pas à son emplacement par défaut, --key-dir. Si un serveur tient le dossier, l'outil le signale et conseille le mode réseau.

verify et list lisent un dossier de sauvegarde local, sans serveur :

  • verify contrôle la présence, la taille, la somme de contrôle et l'empreinte SHA-256 de chaque fichier, ainsi que le journal ; la signature, qui demande la clé du coffre du serveur, n'est vérifiée qu'à la restauration ;
  • verify --deep relit en plus chaque table ;
  • list affiche le manifeste, signature comprise.

Hors ligne, une sauvegarde est signée si l'outil a accès à la clé du coffre du dossier de données (même compte Windows que le serveur, --key-dir) ; une restauration hors ligne signale une sauvegarde non signée ou signée par une autre clé. Elle garde les définisseurs (l'outil agit en administrateur du dossier).

Code de sortie : 0 si tout a réussi, 1 sinon.

Exemple de tâche planifiée quotidienne (mot de passe dans la variable MIRAJ_PASSWORD de la tâche, pas sur la ligne de commande) :

miraj-backup backup --all --to quotidien-%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%

19.3 L'outil miraj-dump : sauvegarde en SQL#

miraj-dump [export] --db <base>[,<base>…] | --all  [-r <fichier.sql>] [options] [connexion | --root <dossier>]
miraj-dump restore <fichier.sql> [-d <base>] [--force] [connexion | --root <dossier>]

La connexion se règle avec les mêmes options que miraj-backup (section 19.2) : --host, --port, --user, --password (saisie masquée), MIRAJ_PASSWORD, TLS proposé par défaut (--ssl, --ssl-ca, --ssl-insecure, --no-ssl) et --protocol auto|miraj|postgresql.

Langage du script : celui de l'instance lue (reconnu à la connexion, ou d'après son sql_mode hors ligne). Sur une instance en langage PostgreSQL, le script est écrit en langage PostgreSQL et se recharge aussi avec psql -f ; les routines et déclencheurs y sont écrits en PL/pgSQL (traduits au mieux s'ils ont été écrits en langage MIRAJ, sinon cités en commentaire, comme les événements), et les comptes (--users) perdent leur vérificateur SCRAM-SHA-256 jusqu'à la redéfinition de leur mot de passe : voir 30.12. restore découpe le script dans le langage de l'instance cible. Pour un export --users d'un serveur distant, exigez TLS avec --ssl-ca : les vérificateurs des comptes circulent sur cette connexion.

19.3.1 Export#

Le script est écrit sur la sortie standard, ou dans le fichier -r. Le fichier est d'abord écrit sous un nom temporaire, puis renommé à la fin : un export interrompu ne laisse pas de script tronqué.

OptionEffet
--db a,b / --allBases exportées (--all : toutes sauf les bases système). Aussi --databases et --all-databases.
--tables t1,t2Seulement ces tables d'une seule base, sans vues ni routines.
--no-dataSchéma seul.
--no-create-infoLignes seules, sans CREATE.
--no-routines, --no-triggers, --no-eventsSans procédures et fonctions (et sans endpoints de l'API REST, qui les accompagnent), sans déclencheurs, sans événements. Par défaut, ils sont exportés.
--single-transactionLecture dans une seule transaction (comportement par défaut, accepté pour la compatibilité des scripts existants).
--usersAjoute les comptes (sauf root) avec leur mot de passe, sous forme de vérificateur et jamais en clair, leur verrou et leurs droits.
--lock-tablesLOCK TABLES ... READ par base au lieu d'une transaction.
--lock-all-tables, -xFLUSH TABLES WITH READ LOCK tenu pendant tout l'export : les écritures de toutes les sessions attendent (ou échouent en 1205 au-delà de leur lock_wait_timeout), l'export voit toutes les bases au même instant. Privilège RELOAD. Instance en langage PostgreSQL : lecture dans une transaction, comme par défaut (voir 16.6.4).
--batch-bytes <n>Taille visée d'un INSERT multi-lignes (défaut 1 Mio).

Attention — un export --users est un fichier sensible : le vérificateur d'un compte (IDENTIFIED BY PASSWORD '*…') n'est pas le mot de passe, mais il en tient lieu. Le protocole d'authentification ne demande au client qu'une valeur que ce vérificateur permet de calculer : quiconque le lit peut se connecter sous ce compte avec un client modifié, sans jamais connaître le mot de passe. C'est aussi un double SHA-1 sans sel, qui se casse vite si le mot de passe est faible. Traitez un tel script comme un fichier de mots de passe : droits de lecture réservés au compte d'administration (sous Unix chmod 600, sous Windows une ACL restreinte), jamais dans un dépôt de sources ni un ticket, transfert chiffré, archive chiffrée si elle quitte la machine, suppression dès qu'il a servi. Après une fuite, changez les mots de passe des comptes concernés.

Ordre du script :

  1. En-tête (SET NAMES utf8mb4, contrôles des clés étrangères coupés).
  2. Comptes.
  3. Pour chaque base :
    1. séquences (avant les tables, une valeur par défaut pouvant en appeler une) : CREATE SEQUENCE puis SETVAL à la prochaine valeur non réservée ;
    2. tables (parentes avant enfants) avec leurs lignes ;
    3. vues (dans l'ordre de leurs dépendances) ;
    4. routines, puis endpoints de l'API REST (CREATE ENDPOINT, chapitre 24) ;
    5. déclencheurs (après les lignes : ils ne se déclenchent pas au chargement) ;
    6. événements.
  4. Droits des comptes.

Les valeurs sont écrites comme suit :

  • BLOB et colonnes binaires en hexadécimal (X'…') ;
  • chaînes échappées ;
  • dates et heures avec leurs fractions de seconde ;
  • nombres tels que le serveur les rend.

Une table disque est exportée avec son ENGINE déclaré (SHOW CREATE TABLE). Une table à versionnement système est exportée avec sa clause WITH SYSTEM VERSIONING et ses seules lignes courantes : l'historique n'est pas dans le script (utiliser BACKUP, chapitre 12).

Cohérence : par défaut, toute la lecture se fait dans une seule transaction. Le script reflète donc un instant unique, sans bloquer les autres sessions. Un DDL exécuté pendant l'export sur une table pas encore lue fait échouer l'export (1213) : relancez-le.

Durée : miraj-dump (export et restore) et miraj-backup lèvent pour leur propre session la limite de durée des instructions (max_statement_time, 300 s par défaut, chapitre 16) : la lecture d'une grosse table, un BACKUP ou un RESTORE long ne sont pas interrompus par l'erreur 1969.

19.3.2 Restauration#

miraj-dump restore lit le script au fil de l'eau, même pour plusieurs gigaoctets, et exécute ses instructions une à une. Les corps de routines, de déclencheurs et d'événements sont entourés de DELIMITER ;; dans le script, et l'outil comprend cette commande.

  • -d <base> choisit la base courante au départ.
  • --force continue après une erreur. Sinon, la restauration s'arrête à la première erreur, en indiquant la ligne du script.

-r s'écrit aussi --result-file, -d aussi --database.

miraj-cli connecté à un serveur découpe lui aussi le script (DELIMITER compris) et s'arrête à la première erreur (26.7) ; ouvert sur un dossier de données (--root), il n'interprète pas DELIMITER : utilisez alors miraj-dump restore … --root.

19.4 Quelle méthode choisir ?#

BesoinMéthode
Sauvegarde quotidienne rapide, restauration immédiateBACKUP DATABASE / miraj-backup
Sauvegarde complète planifiée sous Windows, sans scriptMiraj Server Manager (voir 22.10)
Récupérer quelques lignes d'hierRESTORE DATABASE copie FROM '…' sous un autre nom
Changer de machine ou de version, archivermiraj-dump --users
Garder aussi les comptesmiraj-dump --users (la copie physique ne les contient pas)
Serveur arrêtémiraj-backup … --root ou miraj-dump … --root
ClusterBACKUP sur le primaire ; restauration sur un nœud seul

Dans tous les cas, testez vos restaurations régulièrement : miraj-backup verify --deep contrôle une sauvegarde physique. Une restauration sous un autre nom suivie de quelques comparaisons contrôle l'ensemble de la chaîne.