11. Administration du serveur
Ce chapitre s'adresse aux administrateurs qui exploitent miraj-server, le serveur réseau de MIRAJ. Il couvre le démarrage et l'arrêt, la configuration (ligne de commande et fichier XML), l'organisation du dossier de données, la durabilité, la sécurité opérationnelle, la supervision, la sauvegarde et les réglages de performance.
11.1 Démarrage et arrêt du serveur#
11.1.1 Commande de base#
miraj-server.exe --root D:\donnees --lang fr --log--root désigne le dossier de données du serveur (un dossier par base, plus un sous-dossier miraj pour les comptes et les journaux internes). En son absence, le serveur utilise un dossier data relatif au répertoire courant.
Pour le dépannage et la maintenance des comptes (voir 11.5.3), le serveur dispose d'un mode dédié :
miraj-server.exe --root D:\donnees --reset-accounts [--key-dir <dossier>]11.1.2 Arrêt du serveur#
miraj-server n'a pas de séquence d'arrêt propre : que l'arrêt vienne d'un Ctrl-C, de la fermeture du processus ou d'une coupure de la machine, aucun point de sauvegarde final n'est écrit avant la sortie. Tout arrêt doit donc être traité, du point de vue de l'administrateur, comme un arrêt brutal : c'est le journal d'écriture (WAL) et sa reprise au redémarrage qui garantissent l'intégrité des données (voir 11.4), pas une phase d'extinction soignée du serveur. C'est différent de l'usage embarqué de MIRAJ (bibliothèque miraj.dll ou API Rust native) : là, la fermeture de l'instance (Miraj::drop) écrit tout avant de rendre la main. Rien dans le code actuel du serveur n'introduit de traitement particulier sur signal d'arrêt : à vérifier de nouveau dans une version ultérieure si ce point évolue.
11.1.3 Options de ligne de commande#
Toutes les options sont facultatives ; les valeurs par défaut sont celles appliquées quand ni le fichier miraj_config.xml ni la ligne de commande ne les changent (voir 11.2 pour l'ordre de priorité).
| Option | Valeur par défaut | Description |
|---|---|---|
--root <dossier> | data | Dossier de données du serveur. |
--config <fichier> | <root>\miraj_config.xml | Chemin explicite du fichier de configuration XML (voir 11.2). |
--port <port> | 7007 | Port TCP d'écoute. |
--bind <adresse> | 127.0.0.1 | Adresse d'écoute. Un avertissement est émis si une adresse non locale est choisie (voir 11.5.4). |
--lang <code> | en | Langue des messages d'erreur des sessions : en, fr, zh, hi, es, ar, pt, ru, de, ja. |
--log | désactivé | Tient à jour <root>\miraj\server.log (connexions, erreurs SQL, pannes internes ; voir 11.6). |
--result-buffer <Mo> | 64 | Mémoire gardée par connexion pour un client lent à lire son résultat. |
--write-timeout <secondes> | 60 | Attente maximale d'un client qui ne lit plus son résultat avant déconnexion. |
--connect-timeout <secondes> | 10 | Attente maximale de la poignée de main d'un client. |
--idle-timeout <secondes> | 28800 (8 h) | Attente maximale d'une commande d'un client déjà connecté. |
--key-dir <dossier> | profil du compte qui lance le serveur | Dossier de la clé du coffre des comptes, hors du dossier de données (voir 11.5.1). |
--lock-wait-timeout <secondes> | 50 | Attente maximale d'un verrou de table explicite (LOCK TABLES) avant l'erreur 1205. |
--deferred-update ON|OFF | ON | Mise à jour différée : un UPDATE admissible d'une ligne désignée par sa clé ne la prend pas et est réévalué au COMMIT, si bien que deux transactions qui modifient la même ligne valident toutes les deux (voir 9.2). Valeur initiale de la variable deferred_update des sessions ; OFF : l'UPDATE prend sa ligne tout de suite. |
--concurrency mvocc|pessimistic | mvocc | Modèle de concurrence. pessimistic rétablit l'ancien modèle à verrous de ligne ; option temporaire, le temps de comparer les deux modèles. |
--lob-threshold <octets> | 8192 | Taille à partir de laquelle une valeur BLOB quitte la table et rejoint le magasin .bmrj. |
--lob-cache <Mo> | 128 | Taille du cache de lecture des BLOB déportés. |
--event-scheduler ON|OFF|DISABLED | OFF | État du planificateur d'événements au démarrage ; DISABLED interdit SET GLOBAL event_scheduler = ON ensuite. |
--parallel-threads <n> | un fil par cœur | Fils que toutes les requêtes du serveur peuvent occuper en tout (édition Standard ; sans effet en édition Express, avec avertissement). |
--save-policy relaxed|statement|periodic | relaxed | Politique de durabilité (voir 11.4.1). |
--save-interval <millisecondes> | 5000 | Intervalle du vidage périodique de fond (politiques relaxed et periodic). |
--slow-query-log | désactivé | Active le journal des requêtes lentes. |
--slow-query-log-file <fichier> | <root>\miraj\slow.log | Fichier du journal des requêtes lentes ; le préciser active aussi le journal. |
--long-query-time <secondes> | 10 | Durée au-delà de laquelle une instruction est considérée comme une requête lente. |
--max-statement-time <secondes> | 0 (sans limite) | Durée au-delà de laquelle une instruction est abandonnée (valeur initiale de la variable de session max_statement_time). |
--secure-file-priv <dossier> | vide (LOAD_FILE désactivé) | Seul dossier lisible par LOAD_FILE, pour les comptes ayant le privilège FILE. Ne doit ni contenir ni se trouver dans le dossier de données ou celui des clés. |
--backup-dir <dossier> | vide (BACKUP / RESTORE refusés) | Seul dossier où BACKUP DATABASE écrit et d'où RESTORE DATABASE lit ; créé s'il n'existe pas. Ne doit ni contenir ni se trouver dans le dossier de données ou celui des clés (voir 11.7 et chapitre 18). |
--tls-cert <fichier.pem> / --tls-key <fichier.pem> | absent | Certificat et clé privée TLS proposés à la poignée de main client. |
--require-tls | désactivé | Refuse les clients qui ne se connectent pas en TLS (erreur 3159). |
--cluster-config <cluster.toml> | cluster.toml à côté de l'exécutable | Édition Cluster : configuration du nœud dans une réplication multi-nœud (voir 11.1.4). |
--reset-accounts | — | Recrée le coffre des comptes avec le seul root local (voir 11.5.3). Utilisable avec --root et --key-dir. |
--help / -h / /? | — | Affiche l'usage et quitte. |
Remarque de terminologie : le nom des options en ligne de commande utilise des tirets (
--long-query-time), celui des clés XML et des variables de session des soulignés (long_query_time) ; ce chapitre respecte cette convention à chaque endroit.
11.1.4 Réplication (édition Cluster)#
L'édition Cluster ajoute la réplication multi-nœud : un nœud primaire écrit, des nœuds secondaires reçoivent son journal en continu et le rejouent en lecture seule. Les clients se connectent à un secondaire sur son port client habituel (7007 par défaut) ; toute tentative d'écriture y échoue en erreur
- Les nœuds communiquent entre eux sur un port distinct, en TLS mutuel (certificat signé par l'autorité du cluster). La configuration se fait par
--cluster-config:
[node]
id = "n1" # identifiant stable du nœud
listen = "0.0.0.0:7107" # port entre nœuds (pas celui des clients)
advertise = "10.0.0.1:7107" # adresse annoncée aux autres nœuds
[cluster]
name = "gestium-prod"
seeds = ["10.0.0.1:7107", "10.0.0.2:7107"]
tls_cert = "node.pem" # chemins relatifs au fichier
tls_key = "node-key.pem"
tls_ca = "cluster-ca.pem"
ack = "written" # ou "durable" : le secondaire vide son
# journal sur disque avant d'accuser
journal_retention_mb = 1024 # au-delà, un secondaire absent est
# réamorcé à son retourAu premier démarrage, tous les nœuds sont secondaires. Le rôle primaire se désigne une fois par :
SET GLOBAL cluster_role = 'primary';les autres nœuds rejoignent alors le primaire (copie des bases puis flux du journal). La promotion d'un secondaire utilise la même commande ; un ancien primaire relancé après une bascule est mis à l'écart (@@cluster_role = 'FENCED', lecture seule) jusqu'à ce qu'on le fasse rejoindre le nouveau primaire :
SET GLOBAL cluster_role = 'secondary';ses écritures non répliquées sont alors mises de côté dans <root>\miraj\quarantaine. Suivi de la réplication :
SHOW CLUSTER STATUS;
SELECT * FROM information_schema.MIRAJ_NODES;
SELECT * FROM information_schema.MIRAJ_REPLICATION;
SELECT @@read_only, @@cluster_role, @@cluster_epoch, @@cluster_primary;11.2 Fichier de configuration miraj_config.xml#
MIRAJ accepte une configuration par fichier XML, sur le modèle d'un fichier .cnf/.ini classique. Trois niveaux se combinent, dans cet ordre de priorité croissante :
- valeur par défaut interne ;
- valeur du fichier
miraj_config.xml; - argument de la ligne de commande (priorité la plus forte).
Le fichier lu est <root>\miraj_config.xml par défaut, ou le chemin donné par --config. Une variable absente ou en commentaire garde sa valeur par défaut. Extrait :
<?xml version="1.0" encoding="UTF-8"?>
<miraj>
<!-- Langue des messages d'erreur des sessions (en, fr) -->
<!-- <language>en</language> -->
<!-- Politique de sauvegarde (relaxed, statement, periodic) -->
<!-- <save_policy>relaxed</save_policy> -->
<!-- Adresse d'écoute du serveur -->
<!-- <bind>127.0.0.1</bind> -->
<!-- Port TCP d'écoute du serveur -->
<!-- <port>7007</port> -->
<!-- Fichier <dossier>/miraj/server.log tenu à jour -->
<!-- <log>false</log> -->
</miraj>Pour appliquer une valeur, décommentez la ligne et changez la valeur ; le reste du fichier (les autres variables en commentaire) n'a pas besoin d'être modifié.
Un second fichier, miraj_default.xml, est régénéré à chaque démarrage du serveur : il liste toutes les variables reconnues avec leur valeur par défaut courante. C'est un fichier de référence, jamais relu par le serveur — ne pas y écrire ses propres réglages, ils seraient effacés au prochain démarrage. Utilisez-le pour retrouver, version après version, la liste complète des clés disponibles et leur valeur par défaut.
Les clés du fichier XML recouvrent les mêmes réglages que les options de ligne de commande : language, save_policy, save_interval, checkpoint_interval, lock_wait_timeout, deferred_update, concurrency, key_dir, lob_threshold, lob_cache, event_scheduler, parallel_threads, slow_query_log, slow_query_log_file, long_query_time, max_statement_time, secure_file_priv, bind, port, log, result_buffer, write_timeout, connect_timeout, idle_timeout, tls_cert, tls_key, require_tls.
checkpoint_interval (60000 ms, soit 60 s, par défaut) n'a pas d'équivalent en ligne de commande : c'est l'intervalle entre deux points de sauvegarde (voir 11.4.2), réglable uniquement par ce fichier.
Usage recommandé : le fichier XML convient à un réglage permanent, propre à une instance (un dossier de données), qu'on ne veut pas répéter à chaque lancement dans un script ou un service Windows ; la ligne de commande reste utile pour un réglage ponctuel (diagnostic, script de test) qui doit l'emporter sur le fichier.
11.3 Organisation du dossier de données#
<dossier racine>/
miraj_config.xml configuration (si présente)
miraj_default.xml référence des valeurs par défaut, régénéré au démarrage
<base>/
<table>.mrj une table = un fichier (format MIRA v2)
<table>.bmrj magasin des BLOB longs de la table (créé au premier dépôt)
journal.mrl journal d'écriture (WAL) de la base
miraj/
accounts.mra coffre chiffré des comptes
server.log journal serveur, si --log est actif
slow.log journal des requêtes lentes, si activé
quarantaine/ écritures non répliquées d'un nœud FENCED (édition Cluster)Points pratiques pour l'administration :
- Chaque base est un sous-dossier du dossier racine ; chaque table un fichier
.mrjdans ce sous-dossier. Créer ou supprimer une base revient à créer ou supprimer ce sous-dossier (fait par le serveur lui-même viaCREATE DATABASE/DROP DATABASE, jamais à la main pendant que le serveur tourne). - Un BLOB qui dépasse
--lob-threshold(8192 octets par défaut) est déposé dans le fichier.bmrjde sa table plutôt que dans le.mrj; ce fichier n'apparaît qu'après le premier dépôt d'un BLOB de cette taille. Les deux fichiers doivent être copiés ensemble : un.mrjsans son.bmrjassocié perd ses valeurs BLOB déportées. Après un abaissement de--lob-threshold, les valeurs déjà stockées qui atteignent le nouveau seuil rejoignent le.bmrjà l'ouverture de la base (la table est réécrite au point de sauvegarde suivant). Sur le primaire d'un cluster, ce déplacement passe par le journal, dans un plafond de 256 Mio par table (voir 12.7) : au-delà, les valeurs restent dans la table, lisibles, et une ligneAVERTISSEMENTest écrite dans le journal du serveur. journal.mrlest le journal d'écriture de la base : il permet de rejouer les écritures postérieures au dernier point de sauvegarde de chaque table en cas d'arrêt brutal (voir 11.4). Ne jamais le supprimer ou le modifier à la main.- Le coffre des comptes
miraj/accounts.mraest propre au dossier de données ; sa clé de déchiffrement est rangée ailleurs (voir 11.5.1). Copier un dossier de données sans sa clé rend le coffre illisible au redémarrage. - Sauvegarde : à l'arrêt du serveur (voir 11.1.2 et 11.7), une copie simple du dossier racine (bases,
miraj/, fichiers de configuration) suffit à en obtenir une image cohérente, à condition de copier aussi la clé du coffre des comptes si elle est nécessaire à la restauration (voir 11.5.1 et 11.7).
11.4 Durabilité et reprise après incident#
11.4.1 Politiques de sauvegarde (save_policy)#
MIRAJ écrit chaque instruction de modification dans le journal (WAL) de la base concernée avant de considérer l'instruction terminée ; la façon dont ce journal atteint le disque dépend de la politique choisie :
| Politique | Comportement | Perte maximale tolérée en cas d'arrêt brutal du processus | Perte maximale tolérée en cas de coupure de la machine |
|---|---|---|---|
relaxed (par défaut) | Le journal est écrit dans son fichier avant que l'instruction ne rende la main, sans attendre le disque ; un fil de fond le vide sur disque toutes les --save-interval ms (5000 par défaut). | Aucune (le fichier a déjà reçu l'écriture du système d'exploitation). | Les écritures du dernier intervalle --save-interval. |
statement | Comme relaxed, en attendant en plus le vidage sur disque à la fin de chaque instruction d'écriture. | Aucune. | Aucune. |
periodic | Rien n'est écrit avant le passage du fil de fond (toutes les --save-interval ms). | Les écritures des dernières --save-interval ms. | Les écritures des dernières --save-interval ms. |
Ces trois politiques peuvent aussi être choisies par session, sans changer le réglage du serveur :
SET SESSION save_policy = 'statement';(une quatrième valeur, manual, existe en interne mais est refusée en politique de serveur : elle n'écrirait jamais rien tant que la session ne l'ordonne pas, ce qui n'a pas de sens comme politique par défaut).
Comment choisir :
statementmaximise la sécurité (aucune perte possible, y compris lors d'une coupure de courant) au prix d'une latence d'écriture par instruction liée au disque — à retenir pour des données qu'aucune perte, même minime, ne peut affecter.relaxed(le réglage par défaut) offre un bon compromis : aucune perte en cas d'arrêt du seul processus serveur (le plus fréquent en pratique), et une fenêtre de perte bornée par--save-intervalseulement en cas de coupure de la machine elle-même.periodicréduit encore la latence d'écriture en échange d'une fenêtre de perte identique dans les deux cas (processus ou machine) — à réserver à des charges où le débit d'écriture prime sur la garantie de durabilité stricte.
Dans tous les cas, le journal lui-même reste cohérent : ce qui peut être perdu, ce sont les toutes dernières écritures non encore vidées, jamais l'intégrité du fichier.
11.4.2 Points de sauvegarde (checkpoints)#
Un point de sauvegarde consolide l'état courant des tables et permet de tronquer le journal d'écriture d'autant. Il se déclenche automatiquement :
- toutes les
checkpoint_intervalmillisecondes (60 000 ms, soit 60 s, par défaut — réglable uniquement viamiraj_config.xml, voir 11.2) ; - quand le journal dépasse 64 Mo ;
- à la fermeture propre d'une instance embarquée (
Miraj::drop).
11.4.3 Reprise après un arrêt brutal#
Au démarrage, le serveur ouvre les fichiers de table de chaque base puis rejoue les enregistrements du journal postérieurs au LSN (numéro de séquence du journal) déjà présent dans chaque fichier .mrj. Les écritures de fichiers sont atomiques (fichier temporaire, vidage, puis remplacement — sous Windows via MoveFileExW avec MOVEFILE_WRITE_THROUGH), et le magasin de BLOB (.bmrj) est toujours vidé sur disque avant le journal et le fichier de table qui le référencent : un arrêt brutal peut au pire laisser des octets de BLOB orphelins dans le .bmrj, jamais une référence sans contenu. D'après le dossier technique du projet, ce mécanisme a été validé par 120 arrêts brutaux aléatoires du processus pendant des écritures, sans incohérence observée.
Comme rappelé en 11.1.2, miraj-server ne dispose pas d'un arrêt propre : c'est précisément ce mécanisme de reprise, et non une séquence d'extinction, qui garantit l'intégrité des données à chaque redémarrage.
11.5 Sécurité opérationnelle#
11.5.1 Coffre des comptes et gestion de la clé#
Les comptes (utilisateurs, mots de passe, privilèges, rôles) sont gardés dans un coffre chiffré et authentifié par AES-256-GCM, <root>\miraj\accounts.mra — jamais journalisé, écrit de façon atomique, protégé contre la restauration d'une copie ancienne par un numéro de génération croissant.
La clé de 32 octets qui protège ce coffre est rangée hors du dossier de données :
- sous Windows, elle est chiffrée par DPAPI pour le compte qui lance le serveur, dans
%LOCALAPPDATA%\MIRAJ\keys; - sur les autres systèmes, dans un fichier aux droits
0600; --key-dir <dossier>(ou la clé XMLkey_dir) permet de choisir un autre emplacement, par exemple pour partager la clé entre plusieurs services ou la ranger sur un support distinct du dossier de données.
Conséquence pour la sauvegarde et le déploiement : copier uniquement le dossier de données ne suffit pas à pouvoir rouvrir les comptes sur une autre machine ou sous un autre compte Windows ; il faut aussi transférer la clé (ou son dossier --key-dir), en la protégeant au moins aussi bien qu'un mot de passe administrateur.
11.5.2 Comptes sans mot de passe et écoute réseau#
Un compte root local, sans mot de passe, existe dès la création du dossier de données ; c'est le seul compte qui gère les autres comptes. Le serveur écoute par défaut sur la boucle locale (127.0.0.1) : ce réglage protège implicitement un compte encore sans mot de passe contre un accès distant. Choisir une adresse d'écoute non locale (--bind) déclenche un avertissement, et le serveur signale les comptes sans mot de passe qui deviendraient alors joignables à distance. En pratique, avant d'ouvrir l'écoute au-delà de la boucle locale, donnez un mot de passe à root :
ALTER USER 'root'@'localhost' IDENTIFIED BY 'un mot de passe robuste';11.5.3 --reset-accounts : procédure de secours#
Un coffre des comptes altéré, supprimé ou dont la clé est absente/illisible empêche le démarrage du serveur. La procédure de secours locale est :
miraj-server.exe --root D:\donnees --reset-accounts [--key-dir <dossier>]Cette commande recrée le coffre avec pour seul compte le root local, sans mot de passe, puis se termine (elle ne démarre pas le serveur réseau). Elle doit être exécutée localement, avec un accès au dossier de données et, implicitement, un accès équivalent à celui de la clé. Après un --reset-accounts :
- tous les comptes et privilèges précédemment définis sont perdus (seul
rootlocal subsiste) ; recréez les comptes applicatifs et redonnez les privilèges nécessaires ; - redonnez sans attendre un mot de passe à
rootavant de relancer le serveur en écoute non locale (voir la commandeALTER USERci-dessus).
N'utilisez cette procédure qu'en dernier recours (coffre corrompu, clé perdue, compte administrateur bloqué sans autre accès) : elle ne restaure rien, elle repart d'un état vierge de comptes.
11.5.4 Recommandations pour un déploiement en production#
- Conservez l'écoute sur la boucle locale (
127.0.0.1, valeur par défaut) tant qu'un pare-feu ou un tunnel applicatif ne protège pas un accès plus large ; ne choisissez une adresse non locale qu'après avoir sécurisé tous les comptes par mot de passe. - Activez TLS (
--tls-cert/--tls-key) et envisagez--require-tlsdès que les clients se connectent au travers d'un réseau qui n'est pas physiquement isolé. - Séparez la clé du coffre des comptes (
--key-dir) du support de sauvegarde du dossier de données, ou documentez clairement qu'elle doit être copiée à part lors d'une restauration. - Laissez
secure_file_privvide (valeur par défaut,LOAD_FILEdésactivé) sauf besoin explicite ; si vous l'activez, pointez-le vers un dossier dédié, distinct du dossier de données et du dossier des clés. - Démarrez systématiquement avec
--log(voir 11.6) pour conserver une trace des erreurs SQL et des incidents internes. - Gardez à l'esprit l'absence d'arrêt propre (11.1.2) : prévoyez la politique de sauvegarde (11.4.1) en fonction de la perte de données que vous pouvez tolérer en cas de coupure, plutôt que de compter sur une extinction soignée du service.
11.6 Supervision#
11.6.1 SHOW STATUS et SHOW VARIABLES#
SHOW VARIABLES; -- réglages courants de la session/du serveur
SHOW VARIABLES LIKE 'save_%';
SHOW STATUS; -- compteurs d'activité
SHOW STATUS LIKE 'Miraj_%';SHOW VARIABLES restitue les mêmes valeurs que SELECT @@nom pour chaque variable ; c'est ce que lisent à la connexion les outils clients courants (consoles graphiques, connecteurs).
SHOW STATUS expose notamment, à ce jour :
| Variable | Signification |
|---|---|
Miraj_parallel_queries | Nombre de requêtes ayant utilisé l'exécution parallèle (édition Standard). |
Miraj_parallel_queries_serialized | Requêtes retombées en exécution série faute de fils disponibles. |
Miraj_parallel_workers | Fils du budget de parallélisme configuré. |
Miraj_parallel_workers_busy | Fils actuellement occupés. |
Slow_queries | Nombre de requêtes consignées dans le journal des requêtes lentes. |
Max_statement_time_exceeded | Nombre d'instructions abandonnées pour dépassement de max_statement_time. |
Cette liste s'enrichira au fil des versions ; consultez SHOW STATUS sans filtre pour la liste complète de l'instance en service.
11.6.2 information_schema#
information_schema (lecture seule) donne une vue structurée utile à l'administration, notamment : SCHEMATA, TABLES, COLUMNS, STATISTICS, VIEWS, TABLE_CONSTRAINTS, KEY_COLUMN_USAGE, REFERENTIAL_CONSTRAINTS, ainsi que les tables de privilèges USER_PRIVILEGES, SCHEMA_PRIVILEGES, TABLE_PRIVILEGES, APPLICABLE_ROLES, ENABLED_ROLES. Un compte ne voit, dans SHOW DATABASES, SHOW TABLES et information_schema, que ce qu'il a le privilège d'atteindre.
En édition Cluster, information_schema.MIRAJ_NODES et information_schema.MIRAJ_REPLICATION complètent SHOW CLUSTER STATUS pour le suivi de la réplication (voir 11.1.4).
Tables propres à MIRAJ pour la concurrence : MIRAJ_CONCURRENCY (filigrane de purge, transaction la plus ancienne), MIRAJ_VERSIONS (versions en attente, par table) et MIRAJ_DEFERRED_UPDATE (mise à jour différée, une ligne de compteurs cumulés depuis le démarrage) :
SELECT INTENTS_RECORDED, ROWS_APPLIED, COMMIT_FAILURES, FAILED_READ_VALIDATION,
NORMAL_KEY, NORMAL_TRIGGER
FROM information_schema.MIRAJ_DEFERRED_UPDATE;INTENTS_RECORDED compte les UPDATE différés, ROWS_APPLIED les lignes écrites au COMMIT, IMAGES_MATERIALIZED les UPDATE différés rattrapés par une écriture ordinaire de la même transaction ; COMMIT_FAILURES les COMMIT refusés d'une transaction qui avait des UPDATE différés, détaillés par cause (FAILED_WITNESS : ligne changée de sorte que le WHERE ou une colonne lue par un déclencheur AFTER UPDATE ne vaut plus ; FAILED_ROW_GONE, FAILED_CONCURRENT_WRITER, FAILED_WARNING, FAILED_TABLE_REDEFINED, FAILED_ERROR, FAILED_READ_VALIDATION : la transaction avait lu une ligne modifiée depuis) ; ENGINE_RETRIES les instructions en auto-validation rejouées par le moteur après un conflit ; les colonnes NORMAL_* les UPDATE d'une session à ON qui n'ont pas pu être différés, par raison (SESSION, FORM, TABLE, TRIGGER, KEY, ROW_COUNT, ROW, CALCULATION). Un FAILED_READ_VALIDATION élevé signale des transactions qui lisent une ligne avant de la mettre à jour (voir 9.2).
11.6.3 Journalisation#
--log(oulogdans le fichier XML) tient à jour<root>\miraj\server.log: ce fichier ne reçoit, horodatées, que les erreurs SQL renvoyées aux clients (avec la commande en cause), les pannes internes (paniques capturées, jamais transmises à l'appelant) et les problèmes de fonctionnement du serveur. Les requêtes qui réussissent n'y apparaissent pas ; les connexions et les erreurs sont en revanche aussi affichées sur la sortie standard.--slow-query-log(ouslow_query_log/slow_query_log_file) consigne dans<root>\miraj\slow.log(ou le fichier choisi) chaque instruction plus longue que--long-query-timesecondes, avec le volume envoyé au client (Bytes_sent).SET GLOBAL log_output = 'TABLE'bascule ce journal vers la tablemiraj.slow_log;FLUSH SLOW LOGSrouvre le fichier après une rotation externe.
11.7 Sauvegarde et restauration#
Le serveur sauvegarde une base à chaud, sans l'arrêter. Démarrez-le avec un dossier de sauvegardes (--backup-dir, voir 11.1.3), puis :
BACKUP DATABASE gestion TO 'gestion-2026-09-24';
RESTORE DATABASE gestion_copie FROM 'gestion-2026-09-24';La copie est cohérente, avec toutes les transactions validées jusqu'à un instant et aucune au-delà. Les écritures ne sont suspendues que quelques millisecondes. L'outil miraj-backup pilote ces instructions depuis une tâche planifiée, et miraj-dump exporte une base en script SQL portable, comptes compris. Tout est détaillé au chapitre 18.
Ces sauvegardes ne contiennent pas le coffre des comptes. Exportez les comptes avec miraj-dump --users, ou copiez à froid le sous-dossier miraj\ et la clé du coffre (voir ci-dessous).
Copie à froid du dossier complet, pour un changement de machine avec les comptes, par exemple :
- Arrêtez le serveur. Comme rappelé en 11.1.2,
miraj-servern'offre pas de séquence d'arrêt propre : traitez chaque arrêt comme un arrêt brutal. C'est la reprise par journal (11.4.3) qui garantit un dossier cohérent au prochain démarrage. - Copiez le dossier de données (
--root) dans son intégralité : bases (.mrj,.bmrj,journal.mrl), sous-dossiermiraj\(comptes, journaux internes) et fichiers de configuration XML éventuels. - Copiez séparément la clé du coffre des comptes si elle est nécessaire à la restauration sur une autre machine ou sous un autre compte Windows (voir 11.5.1) : elle n'est pas dans le dossier de données.
- Pour restaurer, replacez ce dossier (et la clé, si nécessaire) à l'emplacement attendu, puis redémarrez le serveur normalement.
Pour une base intégrée (usage via miraj.dll ou l'API Rust, hors serveur réseau), la fermeture normale de l'instance (Miraj::drop) écrit tout avant de rendre la main : une sauvegarde à froid après cette fermeture n'a pas à se soucier d'un arrêt brutal.
11.8 Performance : réglages à connaître#
Ce chapitre reste orienté administration ; pour le détail technique de l'exécution parallèle et ses limites, voir roadmap.md et docs/LIMITES.md.
L'exécution parallèle (édition Standard uniquement — l'édition Express, compilée sans la fonctionnalité Cargo parallel, exécute chaque requête sur le seul fil de sa session) répartit sur plusieurs fils les lectures volumineuses : filtres, projections, agrégation, tri, DISTINCT, jointures INNER/LEFT, et la lecture sous-jacente des UPDATE/DELETE/INSERT ... SELECT — avec, dans tous les cas, les mêmes résultats et le même ordre qu'en exécution série.
Deux réglages contrôlent ce parallélisme :
--parallel-threads <n>(serveur) : fixe le nombre total de fils que toutes les requêtes du serveur peuvent occuper ensemble. Par défaut, un fil par cœur de la machine. À réduire si le serveur partage la machine avec d'autres services, ou à ajuster si des mesures montrent une contention entre requêtes concurrentes.max_parallel_degree(variable de session) : borne le degré de parallélisme d'une session donnée, dans la limite du budget serveur ci-dessus. Utile pour réserver l'essentiel des fils à un traitement interactif tout en laissant un traitement de fond (import, recalcul en masse) se dérouler avec un degré plus faible, ou l'inverse.
EXPLAIN affiche le degré de parallélisme retenu pour une requête donnée, ce qui permet de vérifier qu'un réglage a l'effet attendu avant de le généraliser.
Pour la volumétrie des BLOB, --lob-threshold et --lob-cache (voir 11.1.3 et 11.3) influent aussi sur la performance : un seuil plus bas déporte plus de valeurs hors des fichiers de table (utile si les lignes doivent rester compactes en mémoire), un cache plus grand réduit les lectures répétées de BLOB volumineux au prix de la mémoire qu'il occupe.