# 5.9. Sauvegarde et restauration de mongodb gros volumes

## 5.9.1. Préconisation

La documentation officielle de MongoDB présente différentes techniques de sauvegarde et restauration:
  - utilisation des outils mongodump/mongorestore (Cf. la section dédiée))
  - utilisation de Filesystem snapshots
  - réalisation de copies de disque.

La technique sélectionnée par VITAM est la troisième pour les raisons suivantes:

> - Le volume de donnée en production est important. Les outils mongodump et mongorestore ne sont pas conseillés dans ce cas de figure car ils necessitent un temps d’exécution trop important (sauvegarde / restauration des données et création d’indexes).
> - La technique des snapshots des disques dépend fortement des outils disponibles de l’environnement matériel.

Voir aussi

Pour plus d’information, veuillez-vous référer à la documentation officielle : mongodump et Filesystem Snapshots.

La sauvegarde et la restauration d’une base de forte volumétrie doit être anticipée lors du déploiement:
  - en limitant le volume de donnée, géré par un shard, à une taille raisonnable;
  - en prévoyant un espace disque de taille identique au volume géré ou au moyen d’ajouter un disque supplémentaire.

## 5.9.2. Sauvegarde d’un cluster Mongo shardé

1. Identifier dans chaque replicaSet les instances mongo Primary (le replicaset configserver, géré par les composants vitam-mongoc, et le replicaset de chaque shard, géré par le composant vitam-mongod)
2. Arrêter proprement les services mongo
3. Réaliser la copie compressée (tar.gz, zip, …) du dossier /vitam/data/mongoc/db (pour l’instance Primary du configserver) ou du dossier /vitam/data/mongod/db (pour l’instance Primary d’un shard), pour chaque replicaset identifié précédemment, en veillant à respecter le nommage des sauvegardes : configsrv, shard0, shard1, …
4. Stocker les copies sur un disque séparé et sécurisé

## 5.9.3. Restauration d’un cluster Mongo shardé

Note

La documentation officielle est consultable ici: Restore sharded cluster.

1. Si le cluster existant n’est pas utilisé pour restaurer la sauvegarde, déployer un nouveau cluster mongo vide, avec les mêmes caractéristiques que l’existant (configuration et nombre de shards). Il est conseillé d’utiliser l’ansiblerie VITAM, en modifiant l’inventaire, et en exécutant le playbook d’initialisation du cluster Mongo (`ansible-vitam/mongodb_data.yml`)

2. Arrêter le cluster mongodb

3. Modifier la configuration des services vitam-mongoc (chaque membre du replicaset configserver) pour désactiver la replication et le sharding, en commentant dans le fichier /vitam/conf/mongoc/mongoc.conf les lignes suivantes

       replication:
         replSetName: configsvr # name of the replica set
         enableMajorityReadConcern: true

       sharding:
         clusterRole: configsvr # role du shard

4. Modifier la configuration des services vitam-mongod (chaque membre du replicaset de chaque shard), en commentant dans le fichier /vitam/conf/mongod/mongod.conf les lignes suivantes

       replication:
         replSetName: shardX # name of the replica set
         enableMajorityReadConcern: true

       sharding:
         clusterRole: shardsvr # role du shard

5. Si les services vitam-mongoc et vitam-mongod sont dans une zone réseau privée et sécurisée, il est plus simple de désactiver l’authentification en commentant la partie sécurité dans les fichiers de configuration modifiés précédemment. Sinon, dans la suite de la procédure, un chapitre permet de tenir compte de cette contrainte. Pour désactiver la sécurité, commenter les lignes suivantes

       security:
         authorization: enabled
         clusterAuthMode: keyFile
         keyFile: "/vitam/conf/mongoc/keyfile"

6. Copier et décompresser les sauvegardes, en respectant chaque nom de fichier vers la machine destinataire (configsrv, shard0, shard1, …), dans le dossier /vitam/data/mongoX de chaque instance mongo, c’est à dire de l’ensemble des membres de chaque replicaset

7. Démarrer tous les services mongo en commençant par les services vitam-mongoc puis les services vitam-mongod, ou réutiliser le playbook ansible (start_mongo.yml) en limitant aux machines des groupes hosts_mongoc_data et hosts_mongod_data (paramètre –limit)

8. Pour chacune des instances mongoc et mongod, se connecter au serveur avec le client mongo, et exécuter les opérations suivantes :

   > 1. Si l’authentification est activée, il faut créer un `systemUser` (pré-requis: il faut un utilisateur ayant un role « root ») de manière à disposer des droits pour exécuter les prochaines opérations. Pour cela exécuter les commandes suivantes :

   >    >     use admin
   >    >     // Authenticate as root user
   >    >     db.auth("rootUser", "rootUserPassword")
   >    >     // Create system user
   >    >     db.createUser({user: "systmUser", pwd: "systemUserPassword", roles: [ "__system" ]})
   >    >     // Authenticate as system user
   >    >     db.auth("systmUser", "systemUserPassword")

   > 2. Supprimer la base de données `local`

   >    >     // Drop local database
   >    >     use local
   >    >     db.dropDatabase()

   > 3. Pour les machines mongoc uniquement, et si la restauration est réalisée sur des nouvelles machines hébergeant les services vitam-mongod, modifier la configuration des instances mongoc (configserver): mettre à jour la collection `shards` en spécifiant les nouvelles ips des machines :

   >    >     use config
   >    >     // spécifier les shards pour chaque mongoc
   >    >     // Example
   >    >     db.shards.updateOne({ "_id" : "shard0"},  { $set : { "host" : "shard0/ip_member0-1:27019,ip-member0-2:27019,ip-member0-3:27019"}})
   >    >     db.shards.updateOne({ "_id" : "shard1"},  { $set : { "host" : "shard1/ip_member1-1:27019,ip-member1-2:27019,ip-member1-3:27019"}})
   >    >     db.shards.updateOne({ "_id" : "shard2"},  { $set : { "host" : "shard2/ip_member2-1:27019,ip_member2-2:27019,ip_member2-3:27019"}})

   > 4. Pour les machines mongod uniquement, et si la restauration est réalisée sur des nouvelles machines hébergeant les services vitam-mongoc, modifier la configuration des instances mongod (les shards): mettre à jour la collection `system.version` en spécifiant les nouvelles ips des machines :

   >    >     use admin
   >    >     db.system.version.deleteOne( { "_id": "minOpTimeRecovery" } )
   >    >     // spécifier les mongoc pour chaque shard
   >    >     // Example
   >    >     db.system.version.updateOne({ "_id" : "shardIdentity" },{ $set :{ "configsvrConnectionString" : "configserver/ip_member_1:27018,ip_member_2:27018,ip_member_3:27018"}})

   > 5. Si un utilisateur ayant un role `__system` a été créé à l’étape (6.1), il faut le supprimer

   >    >     // Remove system user
   >    >     use admin
   >    >     // Authenticate as root user
   >    >     db.auth("rootUser", "rootUserPassword")
   >    >     db.removeUser("systmeUser")

9. Arrêter l’ensemble des services mongo et réactiver la replication et le sharding (et l’authentification si désactivée) dans les fichiers de configuration de chacune des instances

10. Démarrer l’ensemble des services mongoc et mongod (en respectant l’ordre déjà spécifié précédemment)

11. Activer les `replicaSet` pour chacun des mongoc et mongod (shards) en exécutant, avec le client mongo, le script init-replica-config.js disponible sur chacune des machines dont le paramètre mongo_rs_bootstrap est spécifié dans l’inventaire ansible. Aussi depuis chacune de ces machines, il faut exécuter le script en modifiant le paramètre host de manière à l’exécuter sur chaque membre du replicaSet

    >     // Sur un des mongoc
    >     > mongo --host {{ ip_service }} --port {{ mongodb.mongoc_port }} {{ vitam_defaults.folder.root_path }}/app/mongoc/init-replica-config.js
    >     // Pour chaque shards et sur un des shards d'un replicaset
    >     > mongo --host {{ ip_service }} --port {{ mongodb.mongod_port }} {{ vitam_defaults.folder.root_path }}/app/mongod/init-replica-config.js

Avertissement

Chaque membre Secondary activé effectue une synchronisation initiale pour reprendre l’ensemble des commandes opérées sur le membre Primary. En fonction du volume de données géré par shard, ainsi que des performances des machines et du réseau, cette opération peut s’exécuter en un temps important, durant lequel les performances du cluster seront affaiblies.

1. Démarrer les services vitam-mongos

2. Test de la restauration

   > - Un document accessible depuis un shards devrait être accessible depuis `mongos` (faire la requête de test sur chaque shard)
   > - Tester aussi les collections non shardées
   > - Il est conseillé d’exécuter une requête `count` sur chacune des collections avant la sauvegarde pour vérifier lors de la restauration le bon compte.

Note

L’ansiblerie VITAM déploie dans chacune des instances mongoc et mongod des scripts préparés restore-mongoc.js et restore-mongod.js respectivement

> - {{ vitam_defaults.folder.root_path }}/app/mongoc/restaure-mongoc.js
> - {{ vitam_defaults.folder.root_path }}/app/mongod/restaure-mongod.js

Toutes les informations sur les adresses ip et numéros de ports de toutes les instances du cluster mongodb sont automatiquement renseignés dans ces scripts

Pour exécuter ces deux scripts, il faut lancer la commande suivante que vous pouvez automatiser dans un playbook:

     // Sur mongoc
    > mongo {{ ip_service }}:{{ mongodb.mongos_port }}/admin {{ mongo_credentials }} {{ vitam_defaults.folder.root_path }}/app/mongoc/restore-mongoc.js
     // Sur mongod
    > mongo {{ ip_service }}:{{ mongodb.mongos_port }}/admin {{ mongo_credentials }} {{ vitam_defaults.folder.root_path }}/app/mongod/restore-mongod.js

## 5.9.4. Cas particulier de l’offre froide

Dans le cas particulier d’une offre de stockage froide, les fichiers backup zip sont stockés dans des bandes magnétiques.

La procédure de backup du mongo de l’offre froide est très importante, car, la base de donnée est l’unique référentiel de l’ensemble des fichiers écris dans les bandes magnétiques.

Avertissement

Si les données du cluster mongodb de l’offre froide sont perdues, toutes les informations enregistrées sur les bandes magnétiques sont inutilisables. Pour cette raison, il est impératif de stocker les sauvegardes du cluster mongo de l’offre froide dans une bande magnétique.

### 5.9.4.1. Sauvegarde

#### 5.9.4.1.1. Script de sauvegarde du cluster mongodb

Un playbook, ayant les tâches ci-dessous, a été mis en place pour faire un backup du mongodb de l’offre froide:

> 1. Détection des noeuds mongodb `Primary` (confiserver et shards)
> 2. Arrêt de VITAM
> 3. Copie et ajout d’un fichier de description des instances en cours
> 4. Compression du dossier db de chaque instance `Primary` (configserver et shards)
> 5. Démarrage de VITAM
> 6. Envoi des fichiers zip (via CURL) vers l’offre froide (composant offer sur url d’admin spécifique au traitement du backup) qui seront sauvegardés sur une bande magnétique

Pour exécuter le playbook :

Prudence

Le playbook ci-dessous est à exécuter uniquement sur un VITAM ayant une offre froide `**tapeLibrary**`

    ansible-playbook ansible-vitam-exploitation/backup_mongodb_tape_offer.yml -i environments/hosts.<environnement> --ask-vault-pass

#### 5.9.4.1.2. Sauvegarde des fichiers backup dans l’offre froide

Lors de l’envoi des fichiers vers l’offre froide, cette dernière va procéder au traitement suivant:

- Réception du fichier zip dans une zone temporaire
- Copie du fichier dans une zone d’écriture sur bande magnétique
- Création d’un ordre spécifique pour écrire le fichier backup zip sur une bande magnétique ayant un tag `backup`
- Le worker « TapeDriveWorker » (Thread executé dans la jvm offer) qui va exécuter la tâche consigne son ordre d’écriture dans le fichier log `offer_tape_backup_DATE.log`, en détaillant les informations : `code de la bande magnétique`, `mongoc` ou `mongod (shard(i)`, `date`.

Note

Lors de la lecture depuis une bande magnétique, on accède aux fichiers sans connaître leur nom et leur type. Si on perd le cluster mongodb, le fichier de log `offer_tape_backup_DATE.log` sera l’unique moyen d’accéder rapidement au nom du fichier sauvegardé associé au code de la bande magnétique où il a été enregistré. Le nom `DATE-disk-mongod-shard01_.zip` que l’on récupère depuis le fichier log `offer_tape_backup_DATE.log` nous renseigne sur la date et le fait que ce soit un backup du `shard01`.

Avertissement

Après chaque sauvegarde, le fichier `offer_tape_backup_DATE.log` doit être copié dans un lieu sûr, pour le besoin de restauration en cas de perte du site. Dans le cas de la perte du site, si ce fichier n’est pas disponible, la lecture de toutes les bandes magnétiques sera l’unique moyen pour récupérer les fichiers de backup.

### 5.9.4.2. Restauration

#### 5.9.4.2.1. Accès aux fichiers de l’offre froide

Sur l’offre froide, toutes les écritures des fichiers backup du mongodb de l’offre, sont tracées dans le fichier log `offer_tape_backup_DATE.log`

Pour récupérer une sauvegarde, il convient donc de consulter les lignes de log ayant comme information:

> - Le code de la bande magnétique sur laquelle est écrit le fichier
> - Le nom du fichier de la forme `DATE-disk-mongod-shard01_.zip`

Pour restaurer une date donnée

    - Repérer dans le fichier log ``offer_tape_backup_DATE.log`` tous les fichiers backup ``(mongoc et mongod)`` zip correspondant à cette date ainsi que les bandes magnétiques sur lesquelles les fichiers sont stockés
    - Manuellement, charger les bandes magnétiques sur une ``tape-library`` pour lire les fichiers
    - La lecture des fichiers doit être réalisée en spécifiant les noms avec la nomenclature adéquate (le nom se retrouve aussi à l'intérieur du fichier zip dans un fichier descriptif)
    - Copier et décompresser chacun de ces fichiers dans l'instance mongo correspondante. Par exemple le fichier ayant pour nom ``DATE-disk-mongod-shard01_.zip`` est à copier et à décompresser dans tous les membres mongo du shard ``shard01``

#### 5.9.4.2.2. Restaurer le cluster mongodb

Une fois tous les fichiers copiés et décompressés dans les instances mongo correspondantes, il faut suivre la procédure de restauration décrite ci-dessus paragraphe Restauration d’un cluster Mongo shardé.