Contexte
Lors d'une formation sur PingDirectory, le 'lab' sur la sauvegarde / restauration est très simple : on lance une sauvegarde avec l'utilitaire backup, puis une sauvegarde avec restore, sans avoir modifié les données. Trouvant l'exercice peut représentatif, j'ai testé la restauration en ayant au préalable supprimé des entrées. Et, ô surprise, les données n'ont pas été restaurées.
Il ne s'agit pas d'un problème sur le produit, mais d'un problème de processus.
Les tests réalisés et la marche à suivre sont décrits dans la suite de cet article.
Test sur un seul serveur
Installation
Sur le premier serveur, on installe l'annuaire :
/opt/ds/setup --acceptLicense --no-prompt --script-friendly \
--localHostName $(hostname -f) \
--ldapPort 1389 \
--ldapsPort 1636 \
--httpsPort 1443 \
--rootUserDN cn=dmanager \
--rootUserPassword MyStrongPassw0rd \
--maxHeapSize 512m \
--enableStartTLS \
--generateSelfSignedCertificate \
--baseDN dc=example,dc=com \
--sampleData 2000
On peut chercher les entrées commençant par user.20 :
bin/ldapsearch -b dc=example,dc=com uid=user.20* dn
dn: uid=user.20,ou=People,dc=example,dc=com
dn: uid=user.200,ou=People,dc=example,dc=com
dn: uid=user.201,ou=People,dc=example,dc=com
dn: uid=user.204,ou=People,dc=example,dc=com
dn: uid=user.206,ou=People,dc=example,dc=com
dn: uid=user.205,ou=People,dc=example,dc=com
dn: uid=user.207,ou=People,dc=example,dc=com
dn: uid=user.202,ou=People,dc=example,dc=com
dn: uid=user.203,ou=People,dc=example,dc=com
dn: uid=user.208,ou=People,dc=example,dc=com
dn: uid=user.209,ou=People,dc=example,dc=com
dn: uid=user.2000,ou=People,dc=example,dc=com
# Result Code: 0 (success)
# Number of Entries Returned: 12
Lancement d'une sauvegarde
On lance ensuite une sauvegarde avec l'utilitaire backup :
mkdir /opt/dirbackups
/opt/ds/bin/backup --port 1389 --bindDN cn=dmanager --bindPassword MyStrongPassw0rd \
--backupAll --backupDirectory /opt/dirbackups
[18/Mar/2018:11:28:36 +0000] severity="NOTICE" msgCount=0 msgID=10944792 message="Starting backup for backend schema"
[18/Mar/2018:11:28:36 +0000] severity="NOTICE" msgCount=1 msgID=10944792 message="Starting backup for backend encryption-settings"
[18/Mar/2018:11:28:36 +0000] severity="SEVERE_WARNING" msgCount=2 msgID=1880228562 message="The encryption settings database backup does not include the '/opt/ds/config/encryption-settings.pin' file that holds the key used to protect the encryption settings definitions. This file should be backed up separately (e.g., by manually copying it to a safe place) to ensure that it will be available if it becomes necessary to restore the encryption settings database from a backup"
[18/Mar/2018:11:28:36 +0000] severity="NOTICE" msgCount=3 msgID=10944792 message="Starting backup for backend alarms"
[18/Mar/2018:11:28:36 +0000] severity="NOTICE" msgCount=4 msgID=10944792 message="Starting backup for backend ads-truststore"
[18/Mar/2018:11:28:36 +0000] severity="NOTICE" msgCount=5 msgID=10944792 message="Starting backup for backend alerts"
[18/Mar/2018:11:28:36 +0000] severity="NOTICE" msgCount=6 msgID=10944792 message="Starting backup for backend userRoot"
[18/Mar/2018:11:28:36 +0000] severity="NOTICE" msgCount=7 msgID=8847446 message="Archived: 00000000.jdb"
[18/Mar/2018:11:28:36 +0000] severity="NOTICE" msgCount=8 msgID=10944792 message="Starting backup for backend replicationChanges"
[18/Mar/2018:11:28:36 +0000] severity="NOTICE" msgCount=9 msgID=10944792 message="Starting backup for backend adminRoot"
[18/Mar/2018:11:28:36 +0000] severity="NOTICE" msgCount=10 msgID=10944792 message="Starting backup for backend config"
[18/Mar/2018:11:28:36 +0000] severity="NOTICE" msgCount=11 msgID=10944792 message="Starting backup for backend tasks"
[18/Mar/2018:11:28:36 +0000] severity="NOTICE" msgCount=12 msgID=10944795 message="The backup process completed successfully"
Backup task 2018031811283603 has been successfully completed
Suppression d'entrées
Pour vérifier que la restauration fonctionne, on se place dans le cas où l'on a supprimé des entrées.
On supprime donc les entrées de user.200 à user.209, via un fichier ldif
cat ldif/del.ldif
uid=user.200,ou=People,dc=example,dc=com
uid=user.201,ou=People,dc=example,dc=com
uid=user.204,ou=People,dc=example,dc=com
uid=user.206,ou=People,dc=example,dc=com
uid=user.205,ou=People,dc=example,dc=com
uid=user.207,ou=People,dc=example,dc=com
uid=user.202,ou=People,dc=example,dc=com
uid=user.203,ou=People,dc=example,dc=com
uid=user.208,ou=People,dc=example,dc=com
uid=user.209,ou=People,dc=example,dc=com
/opt/ds/bin/ldapdelete -f ldif/del.ldif
On vérifie dans l'annuaire :
bin/ldapsearch -b dc=example,dc=com uid=user.20* dn
dn: uid=user.20,ou=People,dc=example,dc=com
dn: uid=user.2000,ou=People,dc=example,dc=com
# Result Code: 0 (success)
# Number of Entries Returned: 2
Restauration de la sauvegarde
Heureusement, nous avons une sauvegarde.
On va réaliser une restauration des données avec l'utilitaire restore, en mode offline.
On arrête l'annuaire :
bin/stop-server
Puis on restaure, à partir de la dernière sauvegarde, et du backend userRoot (celui qui contient les données) :
bin/restore --backupDirectory /opt/dirbackups/userRoot
[11:48:17] The console logging output is also available in '/opt/ds/logs/tools/restore.log'
[11:48:17] restore was run with the following arguments: --configClass com.unboundid.directory.server.extensions.ConfigFileHandler --configFile /opt/ds/config/config.ldif --backupDirectory /opt/dirbackups/userRoot
[11:48:17] Restored: .environment-online-backup (size 0)
[11:48:17] Restored: 00000000.jdb (size 3708137)
[11:48:17] Restored: 00000001.jdb (size 1545)
[11:48:17] The restore process completed successfully
On redémarre ensuite l'annuaire :
bin/start-server
On vérifie dans l'annuaire que l'on a récupéré toutes les données :
bin/ldapsearch -b dc=example,dc=com uid=user.20* dn
dn: uid=user.20,ou=People,dc=example,dc=com
dn: uid=user.200,ou=People,dc=example,dc=com
dn: uid=user.201,ou=People,dc=example,dc=com
dn: uid=user.204,ou=People,dc=example,dc=com
dn: uid=user.206,ou=People,dc=example,dc=com
dn: uid=user.205,ou=People,dc=example,dc=com
dn: uid=user.207,ou=People,dc=example,dc=com
dn: uid=user.202,ou=People,dc=example,dc=com
dn: uid=user.203,ou=People,dc=example,dc=com
dn: uid=user.208,ou=People,dc=example,dc=com
dn: uid=user.209,ou=People,dc=example,dc=com
dn: uid=user.2000,ou=People,dc=example,dc=com
# Result Code: 0 (success)
# Number of Entries Returned: 12
Conclusion
En mode standalone, il est facile de récupérer des données
Au sein d'une topologie de réplication
Pour ce second test, nous allons ajouter une instance, et créer une topologie de réplication comprenant les 2 annuaires
Installation du second annuaire :
/opt/ds/setup --acceptLicense --no-prompt --script-friendly \
--localHostName $(hostname -f) \
--ldapPort 1389 \
--ldapsPort 1636 \
--httpsPort 1443 \
--rootUserDN cn=dmanager \
--rootUserPassword MyStrongPassw0rd \
--maxHeapSize 512m \
--enableStartTLS \
--generateSelfSignedCertificate \
--baseDN dc=example,dc=com \
--addBaseEntry
Mise en place de la réplication entre les 2 annuaires
On va tout d'abord ajouter une "location" pour les annuaires, sur chaque machine :
bin/dsconfig create-location --location-name france
bin/dsconfig set-global-configuration-prop --set location:france
On crée ensuite l'agrément de réplication :
/opt/ds/bin/dsreplication enable \
--host1 ping1.arciam.fr --port1 1389 \
--bindDN1 "cn=dmanager" --bindPassword1 MyStrongPassw0rd \
--replicationPort1 18989 \
--host2 ping2.arciam.fr --port2 1389 \
--bindDN2 "cn=dmanager" --bindPassword2 MyStrongPassw0rd \
--replicationPort2 18989 \
--baseDN dc=example,dc=com --adminUID admin \
--adminPassword MyStrongPassw0rd --no-prompt --ignoreWarnings
Vérification de la réplication
On utilise dsreplication avec l'option status :
/opt/ds/bin/dsreplication status -h localhost -p 1389 --adminUID admin -w MyStrongPassw0rd --no-prompt --displayservertable
--- Replication Servers: dc=example,dc=com ---
Server : Location : Priority (1) : Status
----------------------:----------:--------------:----------
ping1.arciam.fr:18989 : france : 5 : Available
ping2.arciam.fr:18989 : france : 5 (*) : Available
[1] WAN Gateway Priority. WAN gateways are marked with a *. To minimize WAN utilization, the
server with the WAN Gateway role is the only server in a location that exchanges updates with
remote locations.
--- Replication Status for dc=example,dc=com: Enabled ---
Server : Location : Entries : Conflict Entries : Backlog (1) : Rate (2)
---------------------:----------:---------:------------------:-------------:---------
ping1.arciam.fr:1389 : france : 2004 : 0 : 0 : 0
ping2.arciam.fr:1389 : france : 3 : 0 : 0 : 0
On constate donc que le deuxième serveur est en retard. On va l'initialiser, en se connectant sur ce serveur.
bin/dsreplication initialize --adminUID admin \
--adminPassword MyStrongPassw0rd --baseDN dc=example,dc=com \
--hostSource ping1.arciam.fr --portSource 1389 \
--hostDestination ping2.arciam.fr --portDestination 1389 \
--no-prompt
On peut alors vérifier le statut de la réplication :
/opt/ds/bin/dsreplication status -h localhost -p 1389 --adminUID admin -w MyStrongPassw0rd --no-prompt --displayservertable
--- Replication Status for dc=example,dc=com: Enabled ---
Server : Location : Entries : Conflict Entries : Backlog (1) : Rate (2)
---------------------:----------:---------:------------------:-------------:---------
ping1.arciam.fr:1389 : france : 2004 : 0 : 0 : 0
ping2.arciam.fr:1389 : france : 2004 : 0 : 0 : 0
Sauvegarde et suppression des entrées
Comme dans la première configuration, on lance une sauvegarde, puis on va supprimer les entrées user.200 à user.209.
Suite à la suppression, on peut constater que les entrées ont bien été supprimées sur les 2 serveurs :
/opt/ds/bin/dsreplication status -h localhost -p 1389 --adminUID admin -w MyStrongPassw0rd --no-prompt --displayservertable
--- Replication Status for dc=example,dc=com: Enabled ---
Server : Location : Entries : Conflict Entries : Backlog (1) : Rate (2)
---------------------:----------:---------:------------------:-------------:---------
ping1.arciam.fr:1389 : france : 1994 : 0 : 0 : 0
ping2.arciam.fr:1389 : france : 1994 : 0 : 0 : 0
Restauration sur le serveur 1
Nous allons procéder à la restauration, telle que l'on a fait lors de l'étape précédent, après arrêt de l'annuaire.
Une fois l'annuaire arrêté, on peut vérifier l'état de la réplication :
--- Replication Status for dc=example,dc=com: Enabled ---
Server : Location : Entries : Conflict Entries : Backlog (1) : Rate (2)
---------------------:----------:---------:------------------:-------------:---------
ping1.arciam.fr:1389 : N/A : N/A : N/A : N/A : 0
ping2.arciam.fr:1389 : france : 1994 : 0 : 0 : 0
Le premier annuaire n'est pas disponible, l'autre contient toujours les données
bin/restore --backupDirectory /opt/dirbackups/userRoot
[13:39:05] The console logging output is also available in '/opt/ds/logs/tools/restore.log'
[13:39:05] restore was run with the following arguments: --configClass com.unboundid.directory.server.extensions.ConfigFileHandler --configFile /opt/ds/config/config.ldif --backupDirectory /opt/dirbackups/userRoot
[13:39:05] Restored: .environment-online-backup (size 0)
[13:39:05] Restored: 00000002.jdb (size 2155059)
[13:39:05] Restored: 00000003.jdb (size 6402)
[13:39:05] The restore process completed successfully
On peut ensuite redémarrer l'annuaire, via bin/start-server
, et vérifier si on a récupéré nos entrées :
bin/ldapsearch -b dc=example,dc=com uid=user.20* dn
dn: uid=user.20,ou=People,dc=example,dc=com
dn: uid=user.2000,ou=People,dc=example,dc=com
# Result Code: 0 (success)
# Number of Entries Returned: 2
Seules 2 entrées sont présentes. Est-ce que la restauration n'aurait pas fonctionné ?
Si on regarde l'état de la réplication, on a :
--- Replication Status for dc=example,dc=com: Enabled ---
Server : Location : Entries : Conflict Entries : Backlog (1) : Rate (2) : A.O.B.C. (3) : Generation ID : Server ID : Replica ID
---------------------:----------:---------:------------------:-------------:----------:--------------:---------------:-----------:-----------
ping1.arciam.fr:1389 : france : 1994 : 0 : 0 : 0 : 0 seconds : 2857013720 : 8488 : 11115
ping2.arciam.fr:1389 : france : 1994 : 0 : 0 : 0 : 0 seconds : 2857013720 : 14618 : 17447
En redémarrant, même après une sauvegarde, l'instance d'annuaire est allé récupérer les données auprès de l'annuaire ayant le dernier Generation ID.
En regardant le fichier de logs errors ou replication, on voit le message suivant :
[18/Mar/2018:13:40:25.235 +0000] instanceName="ping1.arciam.fr:1389" threadID=-1 category=REP
LICATION severity=NOTICE msgID=118947963 msg="Replica dc=example,dc=com detected that there a
re updates originating from this replica present in the replication topology that are missing
from this replica. This can usually occur after a replica has been restored from backup. The
replica will not accept updates from external clients until these updates have been applied
locally. The change number of the last update at this replica: <>, and in the topology: 00000
162394BA3CE2B6B0000000A"
Conclusion
Si on doit restaurer les données dans une architecture répliquée, il est nécessaire d'arrêter la réplication, restaurer sur un des serveurs, puis remettre en route la réplication.
Procédure de sauvegarde dans une architecture répliquée
Comme vu ci-dessus, il est nécessaire de désactiver la réplication, en utilisant l'option pre-external-initialization de l'utilitaire dsreplication :
/opt/ds/bin/dsreplication pre-external-initialization --hostname ping1.arciam.fr \
--port 1389 --baseDN dc=example,dc=com --adminUID admin \
--adminPassword MyStrongPassw0rd --no-prompt
Ceci arrête la réplication pour le domaine.
On peut ensuite restaurer les données.
On va ensuite arrêter le premier serveur, lancer la restauration, puis redémarrer :
/opt/ds/bin/stop-server /opt/ds/bin/restore --backupDirectory /opt/dirbackups/userRoot /opt/ds/bin/start-server
Dans les messages de démarrage, on note :
[18/Mar/2018:14:04:03.841 +0000] category=REPLICATION severity=NOTICE msgID=15138895 msg="The following error has been received: <Replication server (23703) at ping1.arciam.fr:1389 is waiting for replicas in domain dc=example,dc=com to be reinitialized. Replication will not resume in this domain until the initialization is complete and dsreplication post-external-initialization has been executed>"
On vérifie que les données sont présentes :
bin/ldapsearch -b dc=example,dc=com uid=user.20* dn
dn: uid=user.20,ou=People,dc=example,dc=com
dn: uid=user.200,ou=People,dc=example,dc=com
dn: uid=user.201,ou=People,dc=example,dc=com
dn: uid=user.204,ou=People,dc=example,dc=com
dn: uid=user.206,ou=People,dc=example,dc=com
dn: uid=user.205,ou=People,dc=example,dc=com
dn: uid=user.207,ou=People,dc=example,dc=com
dn: uid=user.202,ou=People,dc=example,dc=com
dn: uid=user.203,ou=People,dc=example,dc=com
dn: uid=user.208,ou=People,dc=example,dc=com
dn: uid=user.209,ou=People,dc=example,dc=com
dn: uid=user.2000,ou=People,dc=example,dc=com
# Result Code: 0 (success)
# Number of Entries Returned: 12
Si on vérifie l'état de la réplication, on constate bien que notre serveur est à un niveau différent :
--- Replication Status for dc=example,dc=com: Enabled (pending external initialization) ---
Server : Location : Entries : Conflict Entries : Backlog : Recent Change Rate : Oldest Backlog Change Age : Generation ID : Server ID : Replica ID
---------------------:----------:---------:------------------:---------:--------------------:---------------------------:---------------:-----------:-----------
ping1.arciam.fr:1389 : france : 2004 : 0 : 0 : 0 : 0 seconds : 2857013720 : 900 : 23703
ping2.arciam.fr:1389 : france : 1994 : 0 : 0 : 0 : 0 seconds : 2320536041 : 614 : 1053
On peut alors remettre en route la réplication, en réinitialisant les serveurs du domaine.
/opt/ds/bin/dsreplication initialize --hostSource ping1.arciam.fr --portSource 1389 \
--hostDestination ping2.arciam.fr --portDestination 1389 \
--adminUID admin --adminPassword MyStrongPassw0rd --baseDN dc=example,dc=com --no-prompt
On vérifie l'état de la réplication :
--- Replication Status for dc=example,dc=com: Enabled --- Server : Location : Entries : Conflict Entries : Backlog : Recent Change Rate : Oldest Backlog Change Age : Generation ID : Server ID : Replica ID ---------------------:----------:---------:------------------:---------:--------------------:---------------------------:---------------:-----------:----------- ping1.arciam.fr:1389 : france : 2004 : 0 : 0 : 0 : 0 seconds : 2857013720 : 900 : 23703 ping2.arciam.fr:1389 : france : 2004 : 0 : 0 : 0 : 0 seconds : 2857013720 : 614 : 1053
Dernière étape, lancer l'utilitaire dsreplication avec l'option post-external-initialization :
bin/dsreplication post-external-initialization --hostname ping1.arciam.fr \ --port 1389 --baseDN dc=example,dc=com --adminUID admin \ --adminPassword MyStrongPassw0rd --no-prompt
Si on ajoute une entrée sur l'annuaire 2, on peut vérifier qu'elle est ajoutée sur l'annuaire 1 :
--- Replication Status for dc=example,dc=com: Enabled --- Server : Location : Entries : Conflict Entries : Backlog : Recent Change Rate : Oldest Backlog Change Age : Generation ID : Server ID : Replica ID ---------------------:----------:---------:------------------:---------:--------------------:---------------------------:---------------:-----------:----------- ping1.arciam.fr:1389 : france : 2005 : 0 : 0 : 0 : 0 seconds : 2857013720 : 900 : 23703 ping2.arciam.fr:1389 : france : 2005 : 0 : 0 : 0 : 0 seconds : 2857013720 : 614 : 1053
Synthèse
Si on veut restaurer une sauvegarde dans une architecture d'annuaires répliqués, il est nécessaire de suivre un processus spécifique.
Dans ce cas, il ne suffit pas de restaurer sur une machine, puisqu'au démarrage elle va reprendre ses données à partir des autres annuaires.
La démarche est donc la suivante :
- lancer l'utilitaire dsreplication avec l'option pre-external-initialization pour stopper la réplication dans le domaine
- arrêter l'annuaire qui doit être restauré
- lancer la restauration
- redémarrer l'annuaire
- lancer l'initialisation de la réplication dans le domaine
- lancer l'utilitaire dsreplication avec l'option post-external-initialization pour remettre en route la réplication dans le domaine