This text is a work in progress—highly subject to change—and may not accurately describe any released version of the Apache™ Subversion® software. Bookmarking or otherwise referring others to this page is probably not such a smart idea. Please visit http://www.svnbook.com/ for stable versions of this book.

Maintenance d'un dépôt

Assurer la maintenance d'un dépôt Subversion peut être intimidant, certainement parce que les systèmes qui comprennent une base de données sont complexes. Le faire bien est une question de maîtrise des outils — connaître leur fonction, quand les utiliser et comment. Cette section vous présente les outils fournis par Subversion pour assurer l'administration du dépôt et décrit leur maniement pour réaliser des opérations telles que migrations de données, mises à jour, sauvegardes et nettoyages.

Boîte à outils de l'administrateur

Subversion fournit une poignée d'utilitaires pour créer, inspecter, modifier et réparer votre dépôt. Étudions de plus près chacun de ces outils. Ensuite, nous abordons rapidement quelques utilitaires inclus dans le gestionnaire de bases de données Berkeley DB qui fournissent des fonctionnalités spécifiques au magasin de données de votre dépôt qui ne sont pas assurées par les propres outils de Subversion.

svnadmin

Le programme svnadmin est le meilleur ami de l'administrateur de dépôts. En plus de fournir la possibilité de créer des dépôts Subversion, ce programme vous permet d'effectuer de nombreuses opérations de maintenance sur ces dépôts. La syntaxe de svnadmin est similaire à celle des autres programmes en ligne de commande de Subversion :

$ svnadmin help
usage général : svnadmin SOUS_COMMANDE DÉPÔT [ARGS & OPTIONS ...]
Entrer 'svnadmin help <sous-commande>' pour une aide spécifique.
Entrer 'svnadmin --version' pour avoir la version et les modules de stockages.

Sous-commandes disponibles :
   crashtest
   create
   deltify
…

Au début de ce chapitre (dans la section intitulée « Création d'un dépôt »), nous vous avons présenté la sous-commande svnadmin create. Beaucoup d'autres sous-commandes svnadmin sont couvertes plus loin dans ce chapitre. Vous pouvez également consulter Guide de référence de svnadmin : administration des dépôts Subversion pour une liste complète des sous-commandes et des fonctionnalités qu'elles apportent.

svnlook

svnlook est un outil de Subversion pour examiner les différentes révisions et transactions (qui sont des révisions en cours de création) dans un dépôt. Aucune modification n'est faite au dépôt par cet outil. svnlook est généralement utilisé par les procédures automatiques du dépôt pour signaler les changements qui vont être propagés (dans le cas de la procédure automatique pre-commit) ou qui viennent d'être propagés (dans le cas de la procédure automatique post-commit). Un administrateur peut être amené à utiliser cet outil à des fins de diagnostic.

La syntaxe de svnlook est particulièrement simple :

$ svnlook help
usage général : svnlook SOUS_COMMANDE CHEMIN_DÉPÔT [ARGS & OPTIONS...]
Note : Quand --revision ou --transaction ne sont pas précisées, les sous-
       commandes qui en ont besoin utilisent la révision la plus récente.
Entrer 'svnlook help <sous-commande>' pour une aide spécifique.
Entrer 'svnlook --version' pour avoir la version et les modules de stockage.
…

Beaucoup de sous-commandes svnlook peuvent être appliquées soit à une révision soit à une arborescence de transaction, affichant les informations à propos de l'arborescence elle-même ou les différences par rapport à la révision précédente du dépôt. Pour spécifier quelle révision ou quelle transaction examiner, utilisez respectivement les options --revision (-r) et --transaction (-t). En l'absence des options --revision (-r) ou --transaction (-t), svnlook examine la révision la plus récente (la révision HEAD) du dépôt. Ainsi, les deux commandes suivantes font exactement la même chose si la révision la plus récente du dépôt situé à l'emplacement /var/svn/depot porte le numéro 19 :

$ svnlook info /var/svn/depot
$ svnlook info /var/svn/depot -r 19

Signalons une exception à ces règles concernant les sous-commandes : la sous-commande svnlook youngest ne prend aucune option et affiche simplement le numéro de la révision la plus récente du dépôt :

$ svnlook youngest /var/svn/depot
19
$
[Note] Note

Gardez à l'esprit que les seules transactions que vous pouvez examiner sont celles qui n'ont pas été propagées. La plupart des dépôts ne comporte pas de transactions de ce type parce que les transactions sont habituellement soit propagées (auquel cas vous devriez y avoir accès sous la forme de révisions via l'option --revision (-r)), soit annulées et supprimées.

La sortie de svnlook est conçue pour être à la fois lisible par un humain et analysable par une machine. Prenons, par exemple, la sortie de la sous-commande svnlook info :

$ svnlook info /var/svn/depot
sally
2002-11-04 09:29:13 -0600 (lun. 04 nov. 2002)
27
J'ai ajouté le traditionnel
Arbre grec.
$

La sortie de svnlook info est constituée des éléments suivants, par ordre d'apparition :

  1. L'auteur, suivi d'un passage à la ligne.

  2. La date, suivie d'un passage à la ligne.

  3. Le nombre de caractères du message de propagation, suivi d'un passage à la ligne.

  4. Le message de propagation lui-même, suivi d'un passage à la ligne.

Cette sortie est lisible par un humain, ce qui veut dire que les éléments tels que la date sont représentés par du texte simple au lieu d'un obscur code (comme le nombre de nanosecondes depuis le passage aux nouveaux francs). Mais cette sortie est aussi analysable par une machine — parce que le message de propagation peut comporter plusieurs lignes et n'est pas limité en taille, svnlook affiche la longueur du message avant le message lui-même. Cela permet aux scripts et autres utilitaires faisant appel à cette commande de prendre des décisions opportunes à propos du message de propagation, comme savoir combien de mémoire allouer pour le message ou au moins savoir combien d'octets sauter dans le cas où les données affichées par svnlook ne sont pas les dernières données du flux.

svnlook peut répondre à un tas d'autres requêtes : afficher des sous-ensembles des informations précédemment citées, lister récursivement les arborescences suivies en versions des répertoires, lister les chemins modifiés lors de telle révision ou transaction, afficher les différences de contenu et de propriétés pour les fichiers et répertoires,  etc. Reportez-vous à Guide de référence de svnlook : outil d'exploration du contenu d'un dépôt Subversion pour la liste complète des fonctionnalités offertes par svnlook.

svndumpfilter

Bien que ce ne soit pas l'outil qu'un administrateur utilise le plus, svndumpfilter fournit une fonctionnalité d'un genre très particulier qui est d'une grande utilité : la possibilité de modifier rapidement et facilement des flux de l'historique du dépôt Subversion en agissant en tant que filtre sur les chemins.

La syntaxe de svndumpfilter est la suivante :

$ svndumpfilter help
usage général : svndumpfilter SOUS_COMMANDE [ARGS & OPTIONS ...]
Entrer 'svndumpfilter help <sous-commande>' pour l'aide spécifique.
Entrer 'svndumpfilter - -version' pour avoir le numéro de version du programme.

Sous-commandes disponibles :
   exclude
   include
   help (?, h)

Il n'y a que deux sous-commandes intéressantes : svndumpfilter exclude et svndumpfilter include. Elles vous permettent de choisir entre l'inclusion implicite et l'inclusion explicite des chemins dans le flux. Vous en saurez plus sur ces sous-commandes et sur l'utilité si particulière de svndumpfilter plus loin dans ce chapitre, dans la section intitulée « Filtrage de l'historique d'un dépôt ».

svnrdump

Le programme svnrdump est, pour faire simple, essentiellement une variante qui fonctionne avec un réseau des sous-commandes svnadmin dump et svnadmin load.

$ svnrdump help
usage général : svnrdump SOUS_COMMANDE DÉPÔT [-r BAS[:HAUT]]
Entrer 'svnrdump help <sous-commande>' pour une aide spécifique.
Entrer 'svnrdump - -version' pour la version et les modules d'accès (RA).

Sous-commandes disponibles :
   dump
   load
   help (?, h)

$

Nous entrerons dans le détail de l'utilisation des commandes svnrdump et svnadmin plus loin dans ce chapitre (voir la section intitulée « Migration des données d'un dépôt »).

svnsync

Le programme svnsync fournit toutes les fonctionnalités requises pour faire fonctionner un miroir en lecture seule d'un dépôt Subversion. Ce programme a une et une seule fonction : transférer l'historique d'un dépôt vers un autre dépôt. Et, bien qu'il y ait différentes manières de faire, sa force réside dans sa capacité de travailler à distance : les dépôts « source » et « destination » peuvent être sur deux ordinateurs différents et svnsync sur un troisième.

Comme vous vous en doutez, svnsync possède une syntaxe très proche des autres programmes déjà mentionnés dans ce chapitre :

$ svnsync help
usage général : svnsync SOUS_COMMANDE DÉPÔT [ARGS & OPTIONS ...]
Entrer 'svnsync help <sous-commande>' pour une aide spécifique.
Entrer 'svnsync - -version' pour la version et les modules d'accès (RA).

Sous-commandes disponibles :
   initialize (init)
   synchronize (sync)
   copy-revprops
   info
   help (?, h)
$

Nous revenons en détail sur la réplication de dépôts avec svnsync plus loin dans ce chapitre (voir la section intitulée « Réplication d'un dépôt »).

fsfs-reshard.py

Bien qu'il ne fasse pas officiellement partie des outils Subversion, le script fsfs-reshard.py (situé dans le répertoire tools/server-side du code source de Subversion) est un outil particulièrement utile à l'administrateur pour optimiser les performances de dépôts Subversion utilisant un magasin de données FSFS. Comme indiqué dans la note Répartition des fichiers stockant les révisions, les dépôts FSFS contiennent des fichiers qui décrivent les changements apportés dans chaque révision. Parfois ces fichiers sont conservés dans un même répertoire, parfois ils sont répartis (sharded en anglais, d'où le nom du script) dans plusieurs répertoires. La bonne nouvelle, c'est que le nombre de répertoires utilisés pour conserver ces fichiers est configurable. Et c'est ici que fsfs-reshard.py joue son rôle.

fsfs-reshard.py remanie la structure du dépôt pour se conformer au nombre de sous-répertoires demandés et met à jour la configuration du dépôt pour conserver cette modification. Utilisé en combinaison avec svnadmin upgrade , c'est particulièrement utile pour convertir un dépôt Subversion pre-1.5 vers le dernier schéma réparti de Subversion (ce que Subversion ne fait pas automatiquement pour vous). Vous pouvez aussi ajuster finement cette valeur dans un dépôt déjà réparti.

Utilitaires Berkeley DB

Si vous utilisez un dépôt avec une base Berkeley DB, à la fois les données et la structure de votre système de fichiers suivis en version résident dans un ensemble de tables de la base de données qui sont situées dans le sous-répertoire db/ de votre dépôt. Ce sous-répertoire est un répertoire d'environnement classique de base de données Berkeley DB et n'importe quel outil de base de données Berkeley, généralement fourni avec la distribution Berkeley, peut y être utilisé.

Pour un usage quotidien, ces outils ne sont pas nécessaires. Beaucoup des fonctionnalités dont les dépôts Subversion ont besoin ont été dupliquées dans l'outil svnadmin. Par exemple, svnadmin list-unused-dblogs et svnadmin list-dblogs fournissent un sous-ensemble des fonctionnalités offertes par l'utilitaire db_archive de Berkeley DB et svnadmin recover reproduit les utilisations courantes de l'utilitaire db_recover.

Cependant, il reste quelques utilitaires Berkeley DB que vous pourriez trouver utiles. Les programmes db_dump et db_load fonctionnent avec, pour la lecture et l'écriture respectivement, un format de fichier personnalisé qui décrit les clés et les valeurs d'une base de données Berkeley DB. Puisque les bases de données Berkeley DB ne sont pas portables d'une architecture de machine à une autre, ce format est utile pour transférer les bases de données entre deux machines, indépendamment de l'architecture et du système d'exploitation. Comme nous le décrivons plus loin dans ce chapitre, vous pouvez aussi utiliser svnadmin dump et svnadmin load pour faire la même chose, mais db_dump et db_load peuvent accomplir certaines tâches tout aussi bien et beaucoup plus vite. Ils peuvent aussi être utiles si un expert Berkeley DB, pour une raison ou pour une autre, doit manipuler les données directement dans la base de données d'un dépôt BDB (les utilitaires Subversion ne vous le permettent pas). De plus, l'utilitaire db_stat peut fournir des informations utiles sur l'état de votre environnement Berkeley DB, y compris des statistiques détaillées concernant les sous-systèmes de verrouillage et de stockage.

Pour davantage d'informations sur la suite d'outils Berkeley DB, consultez la documentation en ligne sur le site Internet d'Oracle, dans la section Berkeley DB : http://www.oracle.com/technology/documentation/berkeley-db/db/ (ce site est en anglais).

Correction des messages de propagation

Il arrive qu'un utilisateur se trompe dans son message de propagation (une faute d'orthographe ou une coquille, par exemple). Si le dépôt est configuré (en utilisant la procédure automatique pre-revprop-change, voir la section intitulée « Mise en place des procédures automatiques ») pour accepter les modifications de ce message après la fin de la propagation, l'utilisateur peut corriger son message à distance en utilisant svn propset (voir svn propset (pset, ps)). Cependant, en raison de la possibilité de perte d'information irrémédiable, les dépôts Subversion ne sont pas configurés, par défaut, pour autoriser les modifications de propriétés non suivies en versions — sauf de la part d'un administrateur.

Si un administrateur est amené à changer un message de propagation, il peut le faire avec svnadmin setlog. Cette commande change le message de propagation (la propriété svn:log) d'une révision donnée du dépôt, la nouvelle valeur étant lue dans un fichier.

$ echo "Voici le nouveau message de propagation, en version corrigée" > nouveau-message.txt
$ svnadmin setlog mon-depot nouveau-message.txt -r 388

La commande svnadmin setlog, par défaut, possède les mêmes garde-fous pour empêcher de modifier des propriétés non suivies en versions qu'un client distant (les procédures automatiques pre- et post-revprop-change sont toujours activées et doivent donc être configurées afin d'accepter ce type de changement. Mais un administrateur peut contourner ces protections en passant l'option --bypass-hooks à la commande svnadmin setlog.

[Avertissement] Avertissement

Souvenez-vous cependant que, en contournant les procédures automatiques, vous êtes susceptible de ne pas activer certaines actions telles que la notification par email du changement des propriétés, la sauvegarde par les systèmes qui surveillent les propriétés non suivies en versions, etc. En d'autres termes, faites particulièrement attention aux changements que vous apportez et à la manière dont vous le faites.

Gestion de l'espace disque

Bien que le coût de stockage ait diminué de manière drastique ces dernières années, l'utilisation de l'espace disque reste une des préoccupations de l'administrateur qui doit suivre en versions de grandes quantités de données. Chaque élément de l'historique de chaque donnée stockée dans un dépôt actif doit être sauvegardé ailleurs, peut-être même de nombreuses fois dans le cas de sauvegardes tournantes. Il est utile de savoir quelles données d'un dépôt Subversion doivent rester sur le site de production, lesquelles doivent être sauvegardées et lesquelles peuvent être supprimées sans risque.

Économie d'espace disque

Pour garder un dépôt petit, Subversion utilise la différenciation (ou « stockage différentiel ») à l'intérieur du dépôt lui-même. La différenciation implique l'encodage de la représentation d'un groupe de données sous la forme d'un ensemble de différences par rapport à un autre groupe de données. Si les deux groupes de données sont très similaires, la différenciation économise de l'espace pour le groupe différencié — au lieu de prendre le même espace que les données originales, le groupe occupe juste l'espace nécessaire pour dire : « je ressemble à l'autre groupe de données là-bas, sauf pour les deux ou trois changements qui suivent ». Au final, l'espace occupé par l'ensemble des données du dépôt (c'est-à-dire le contenu des fichiers suivis en versions) est beaucoup plus petit que la représentation textuelle originale de ces données.

Le stockage sous forme différenciée a fait partie de l'architecture conceptuelle de Subverson dès le début de sa conception ; et il a subi des améliorations au cours des ans. Les dépôts créés avec la version 1.4 ou ultérieure de Subversion bénéficient de la compression du contenu des fichiers « pleins-textes ». Les dépôts créés avec la version 1.6 ou ultérieure de Subversion économisent davantage d'espace disque grace au partage de représentation, une fonctionnalité qui permet à plusieurs fichiers ou révisions de fichiers dont le contenu est identique de faire référence à une seule instance partagée de ce contenu plutôt que chacun n'en conserve sa propre copie.

[Note] Note

Comme toutes les données susceptibles de faire l'objet d'une différenciation dans un dépôt BDB sont stockées dans un seul fichier de la base Berkeley DB, la réduction de la taille des données stockées ne se répercute pas immédiatement sur la taille du fichier de base de données lui-même. Cependant, le gestionnaire Berkeley DB garde trace en interne des enregistrements inutilisés du fichier de la base de données et les consommera en premier lorsque la taille de la base de données augmente. Ainsi, alors que la différenciation ne produit pas instantanément de gain d'espace, cela peut réduire drastiquement le rythme de croissance de la base de données.

Suppression des transactions mortes

Bien que rares, il y a des circonstances dans lesquelles le déroulement d'une propagation Subversion peut mal se terminer, laissant derrière elle dans le dépôt des restes de cette tentative de propagation : une transaction inachevée et toutes les modifications de fichiers et de répertoires associées. Il peut y avoir plusieurs raisons à cet échec : l'utilisateur a peut-être brutalement interrompu l'opération côté client ou bien une coupure réseau s'est peut-être produite au milieu de l'opération. Quoi qu'il en soit, des transactions mortes peuvent apparaître. Elles ne sont pas dangereuses mais elles consomment inutilement de l'espace disque. Un administrateur consciencieux se doit néanmoins de les supprimer.

Vous pouvez utiliser la commande svnadmin lstxns pour obtenir la liste des noms des transactions non encore réglées :

$ svnadmin lstxns mon-depot
19
3a1
a45
$

Chaque élément de la sortie de cette commande peut être passé en argument de svnlook (avec l'option --transaction (-t)) pour déterminer qui est à l'origine de la transaction, quand elle a eu lieu et quels types de changements ont été effectués — ces informations sont très utiles pour savoir si on peut supprimer la transaction sans arrière pensée ! Si vous décidez effectivement de supprimer la transaction, son nom peut être passé à svnadmin rmtxns qui fera le nettoyage adéquat. En fait, svnadmin rmtxns peut directement prendre en entrée la sortie de svnadmin lstxns !

 
$ svnadmin rmtxns mon-depot `svnadmin lstxns mon-depot`
$

Si vous utilisez ces deux sous-commandes ainsi, vous devriez envisager de rendre votre dépôt temporairement indisponible pour les clients. De cette manière, personne ne peut initier une transaction légitime avant que le nettoyage n'ait commencé. L'exemple Exemple 5.3, « txn-info.sh (lister les transactions inachevées) » contient quelques lignes de script shell qui peuvent produire les informations relatives à chaque transaction inachevée de votre dépôt.

Exemple 5.3. txn-info.sh (lister les transactions inachevées)

#!/bin/sh

### Produit les informations relatives à toutes les transactions
### inachevées d'un dépôt Subversion

DEPOT="${1}"
if [ "x$DEPOT" = x ] ; then
  echo "utilisation: $0 CHEMIN_VERS_LE_DEPOT"
  exit
fi

for TXN in `svnadmin lstxns ${DEPOT}`; do
  echo "---[ Transaction ${TXN} ]-------------------------------------------"
  svnlook info "${DEPOT}" -t "${TXN}"
done

La sortie produite par ce script est, en bref, la concaténation des différents groupes d'informations fournis par svnlook info (voir la section intitulée « svnlook ») et ressemble à ceci :

$ txn-info.sh mon-depot
---[ Transaction 19 ]-------------------------------------------
sally
2001-09-04 11:57:19 -0500 (mar. 04 sep. 2001)
0
---[ Transaction 3a1 ]-------------------------------------------
harry
2001-09-10 16:50:30 -0500 (lun. 10 sep. 2001)
39
Tentative de propagation dans un réseau capricieux
---[ Transaction a45 ]-------------------------------------------
sally
2001-09-12 11:09:28 -0500 (mer. 12 sep. 2001)
0
$

Une transaction initiée depuis longtemps correspond en général à une propagation qui a été interrompue ou qui a échoué. L'horodatage de la transaction peut fournir des informations intéressantes — par exemple, quelle est la probabilité qu'une transaction commencée il y a neuf mois soit toujours active ?

En résumé, la décision de supprimer une transaction ne doit pas être prise à la légère. D'autres sources d'informations (comme les journaux d'Apache sur les erreurs et les accès, les journaux opérationnels de Subversion, l'historique des révisions Subversion, etc.) peuvent aider à la prise de décision. Et bien sûr, l'administrateur peut toujours entrer en contact (par email, par exemple) avec l'auteur d'une transaction qui semble abandonnée pour vérifier que c'est bien le cas.

Purge des fichiers de journalisation inutilisés de Berkeley DB

Jusqu'à il y a peu, les plus gros consommateurs d'espace disque pour les dépôts Subversion basés sur BDB étaient les fichiers de journalisation dans lesquels le gestionnaire Berkeley DB effectue les pré-écritures avant de modifier la base de données elle-même. Ces fichiers recensent toutes les actions menées pour modifier la base de données, étape par étape ; alors que les fichiers de la base de données, à un instant donné, ne reflètent qu'un état particulier, les fichiers de journalisation contiennent l'ensemble de tous les changements opérés entre chaque état successif. Ainsi, ils peuvent grossir assez rapidement.

Heureusement, à partir de la version 4.2 de Berkeley DB, l'environnement de la base de données est capable de supprimer ses propres fichiers non utilisés automatiquement. Tout dépôt créé en utilisant svnadmin compilé avec la version 4.2 de Berkeley DB (ou suivantes) est configuré pour supprimer automatiquement les fichiers de journalisation. Si vous ne voulez pas activer cette fonctionnalité, passez simplement l'option --bdb-log-keep à la commande svnadmin create. Si vous oubliez de le faire ou si vous changez d'avis plus tard, éditez simplement le fichier DB_CONFIG qui se trouve dans le répertoire db de votre dépôt, commentez la ligne qui contient la directive set_flags DB_LOG_AUTOREMOVE puis lancez svnadmin recover sur votre dépôt pour que le changement de configuration prenne effet. Reportez-vous à la section intitulée « Configuration de la base de données Berkeley DB » pour plus d'informations sur la configuration du gestionnaire de bases de données.

Sans suppression automatique des fichiers de journalisation, les journaux vont s'accumuler au fur et à mesure de l'utilisation de votre dépôt. Cela peut être considéré comme une fonctionnalité du gestionnaire de bases de données — vous devez être capable de recréer entièrement votre base de données en utilisant uniquement vos fichiers de journalisation, c'est pourquoi ceux-ci sont utiles pour le rétablissement de la base après une catastrophe. Mais en général, vous voudrez archiver les fichiers de journalisation qui ne sont plus utilisés par la base de données et ensuite les enlever du disque pour conserver de l'espace libre. Utilisez la commande svnadmin list-unused-dblogs pour avoir la liste des fichiers de journalisation inutilisés :

$ svnadmin list-unused-dblogs /var/svn/depot
/var/svn/depot/log.0000000031
/var/svn/depot/log.0000000032
/var/svn/depot/log.0000000033
…
$ rm `svnadmin list-unused-dblogs /var/svn/depot`
## espace disque récupéré !
[Avertissement] Avertissement

Les dépôts BDB qui utilisent les fichiers de journalisation pour les sauvegardes ou les rétablissements après incident ne doivent pas activer la suppression automatique des fichiers de journalisation. La reconstruction des données d'un dépôt à partir des fichiers de journalisation ne peut être effectuée que si tous les fichiers de journalisation sont accessibles. Si quelques fichiers de journalisation sont supprimés du disque avant que le système de sauvegarde n'ait pu les copier ailleurs, l'ensemble incomplet des fichiers de journalisation est totalement inutile.

Tasser le système de fichiers FSFS

Comme nous l'avons indiqué dans l'encadré Répartition des fichiers stockant les révisions, les dépôts FSFS Subversion créent, par défaut, un fichier sur le disque pour chaque nouvelle révision ajoutée au dépôt. La gestion de ces milliers de fichiers sur le serveur Subversion, même lorsqu'ils sont répartis dans différents répertoires, peut être la source de pertes de performances.

Le premier problème est que le système d'exploitation doit référencer ces fichiers sur une courte période de temps. Cela conduit à une mauvaise utilisation du cache disque et, en conséquence, à plus de temps pour les recherches sur les gros disques. C'est pour cette raison que Subversion est pénalisé lorsqu'il accède à vos données suivies en versions.

Le deuxième problème est un peu plus subtil. En raison de la manière dont la plupart des systèmes de fichiers alloue l'espace disque, chaque fichier utilise sur le disque plus de place qu'il n'en prend réellement. Cette quantité d'espace disque nécessaire pour stocker un seul fichier peut atteindre de 2 à 16 kilooctets par fichier, en fonction du type de système de fichiers. Cela se traduit directement par un gachis d'espace disque à chaque révision pour les dépôts FSFS. L'effet est d'autant plus sensible pour les dépôts qui ont de petites révisions, puisque le surplus d'espace nécessaire pour stocker le fichier de révision dépasse rapidement la taille des données effectivement stockées.

Afin de résoudre ce problème, Subversion 1.6 introduit la commande svnadmin pack. En « tassant » (pack en anglais) tous les fichiers d'un dépôt fragmenté dans un seul fichier et en supprimant les fichiers correspondants à chaque révision, svnadmin pack remplace la fragmentation par un seul fichier. Ainsi,le cache du système de fichiers est plus performant et le temps d'accès aux fichiers est réduit.

Subversion peut tasser des dépôts fragmentés qui ont été mis à niveau vers le système de fichiers 1.6 ou ultérieur (voir svnadmin upgrade dans Guide de référence de svnadmin : administration des dépôts Subversion). Pour le faire, lancez simplement svnadmin pack sur le dépôt:

 
$ svnadmin pack /var/svn/depot
Packing shard 0...done.
Packing shard 1...done.
Packing shard 2...done.
…
Packing shard 34...done.
Packing shard 35...done.
Packing shard 36...done.
$

Comme le processus de tassage obtient les verrous nécessaires avant de faire son travail, vous pouvez lancer la commande sur un dépôt en service, ou même comme action dans la procédure automatique post-commit. Tasser un dépôt déjà tassé est autorisé, mais n'aura aucun effet sur l'utilisation de l'espace disque par le dépôt.

La commande svnadmin pack n'a aucun effet sur un dépôt BDB.

Rétablissement de bases de données Berkeley DB

Comme indiqué dans la section intitulée « Berkeley DB », un dépôt Berkeley DB peut se retrouver bloqué s'il n'est pas arrêté proprement. Quand cela arrive, un administrateur doit faire revenir la base de données en arrière jusque dans un état cohérent. Ceci ne concerne cependant que les dépôts BDB (si vous utilisez FSFS, vous n'êtes pas concerné). Et pour ceux qui utilisent Subversion 1.4 avec Berkeley DB version 4.4 ou plus, vous constaterez que Subversion est devenu beaucoup plus résilient face à ce type de problème. Certes, mais des plantages de dépôts Berkeley DB arrivent encore et un administrateur doit savoir comment réagir dans de telles circonstances.

Pour protéger les données du dépôt, le gestionnaire Berkeley DB utilise un mécanisme de verrouillage. Ce mécanisme s'assure que les éléments de la base de données ne sont pas modifiés en même temps par plusieurs utilisateurs et que chaque processus voit les données dans un état cohérent lors de la lecture de la base de données. Quand un processus a besoin de modifier quelque chose dans la base de données, il vérifie d'abord l'existence d'un verrou sur les données concernées. Si les données ne sont pas verrouillées, le processus les verrouille, effectue les changements qu'il veut puis déverrouille les données. Les autres processus sont obligés d'attendre que le verrou soit libéré avant d'être autorisés à accéder aux données de cette zone (ceci n'a rien à voir avec les verrous que vous, utilisateur, pouvez appliquer sur les fichiers suivis en versions dans le dépôt ; nous essayons de lever l'ambiguïté créée par l'emploi de cette terminologie commune dans l'encadré Les trois types de « verrous »).

Au cours de l'utilisation de votre dépôt Subversion, des erreurs fatales ou des interruptions peuvent empêcher un processus de supprimer des verrous qu'il a placés dans la base de données. Cela conduit à des plantages du magasin de données. Lorsque cela arrive, toutes les tentatives d'accès au dépôt se soldent par un échec (puisque chaque nouvel arrivant attend que le verrou se libère, ce qui n'est pas prêt d'arriver).

Si cela arrive à votre dépôt, ne paniquez pas. Le système de fichiers Berkeley DB tire parti des transactions de la base de données, des points de contrôle et de la journalisation préalable à toute écriture pour garantir que seuls les événements les plus catastrophiques[55] soient à même de détruire définitivement un environnement de base de données. Un administrateur suffisamment paranoïaque conserve des sauvegardes des données du dépôt dans un endroit distinct, mais attendez un peu avant de vous diriger vers l'armoire de rangement des sauvegardes.

Appliquez plutôt la recette suivante pour tenter de « faire repartir » votre dépôt :

  1. Assurez-vous qu'aucun processus n'accède au dépôt (ou ne tente de le faire). Pour les dépôts en réseau, cela implique d'arrêter le serveur HTTP Apache ou le démon svnserve.

  2. Prenez l'identité de l'utilisateur qui possède et gère le dépôt. C'est important, puisque rétablir un dépôt avec un autre utilisateur peut modifier les droits d'accès des fichiers du dépôt de telle manière que votre dépôt soit toujours inaccessible même après la remise en service.

  3. Lancez la commande svnadmin recover /var/svn/depot. Vous devriez obtenir une sortie du genre :

     
    Verrou du dépôt acquis.
    Patientez ; le rétablissement du dépôt peut être long...
    
    Fin du rétablissement.
    La dernière révision du dépôt est 19
    
    

    Cette commande peut durer plusieurs minutes.

  4. Redémarrez le processus serveur.

Cette procédure fonctionne dans presque tous les cas de plantage. Faites attention à ce qu'elle soit lancée par l'utilisateur qui possède et gère la base de données, pas nécessairement root. La procédure de rétablissement peut impliquer de récréer en partant de zéro certains fichiers de la base de données (de la mémoire partagée, par exemple). Un rétablissement par root créerait ces fichiers avec root comme propriétaire, ce qui veut dire que même après que vous ayez rétabli l'accès à votre dépôt, les utilisateurs de base n'y auront pas accès.

Si la procédure précédente, pour une raison ou pour une autre, ne fait pas repartir votre dépôt, vous devez faire deux choses. D'abord, mettez de côté votre répertoire de dépôt cassé (par exemple en le renommant depot.CASSÉ) puis restaurez la dernière sauvegarde de votre dépôt. Ensuite, envoyez un email à la liste de diffusion des utilisateurs de Subversion () et décrivez votre problème en détail. L'intégrité des données fait partie des sujets à très haute priorité pour les développeurs Subversion.

Migration des données d'un dépôt

Un système de fichiers Subversion a ses données réparties dans les fichiers du dépôt d'une manière que seuls les développeurs Subversion eux-mêmes comprennent (et s'y intéressent). Il peut cependant y avoir des circonstances qui obligent à copier ou déplacer l'ensemble (ou une partie) des données d'un dépôt à un autre.

Subversion fournit cette fonctionnalité par le biais des flux de déchargement du dépôt. Un flux de déchargement de dépôt (« fichier dump » ou dump file en anglais, quand il est stocké dans un fichier sur le disque) est un format de fichier portable, contenant des données brutes, qui décrit les différentes révisions de votre dépôt — ce qui a été modifié, par qui, quand, etc. Ce fichier dump est le principal mécanisme utilisé pour réorganiser des historiques de versions — en partie ou en totalité, avec ou sans modification — entre des dépôts. Et Subversion fournit les outils nécessaires à la création et au chargement de ces fichiers dump : les sous-commandes svnadmin dump et svnadmin load respectivement.

[Avertissement] Avertissement

Bien que le format des fichiers dump de Subversion contienne des parties lisibles par les humains et une structure familière (elle ressemble au format décrit par la RFC 822, utilisé pour la plupart des emails), ce n'est pas un format de fichier purement textuel. C'est un format de fichier binaire, très sensible aux modifications faites à son contenu. Par exemple, de nombreux éditeurs de textes corrompent le fichier en convertissant les caractères de fin de ligne.

Il existe de nombreuses raisons de décharger et recharger les données d'un dépôt Subversion. Aux premiers temps de Subversion, la principale raison était l'évolution de Subversion lui-même. Au fur et à mesure que Subversion gagnait en maturité, des changements faits sur les schémas des magasins de données sous-jacents entraînaient des problèmes de compatibilité avec les versions précédentes du dépôt, ce qui obligeait les utilisateurs à décharger les données de leurs dépôts en utilisant la version précédente de Subversion puis à recharger ces données dans un dépôt tout neuf créé avec la nouvelle version de Subversion. Il n'y a pas eu de changement de schéma de ce type depuis la version 1.0 de Subversion et les développeurs ont promis de ne pas forcer les utilisateurs à décharger et recharger leurs dépôts lors du passage d'une version mineure à une autre (par exemple entre la version 1.3 et la version 1.4) de Subversion. Mais il existe néanmoins des raisons de décharger et recharger ses données, comme le redéploiement d'un dépôt Berkeley DB sur un nouveau système d'exploitation ou sur une architecture CPU différente, la migration du magasin de données de Berkeley DB à FSFS et réciproquement ou (comme nous le voyons dans ce chapitre à la section intitulée « Filtrage de l'historique d'un dépôt ») la purge de données suivies en version de l'historique du dépôt.

[Note] Note

Le format de déchargement des dépôts Subversion ne décrit que l'évolution des éléments suivis en version. Il ne contient pas d'information sur les transactions inachevées, les verrous utilisateurs sur les chemins du système de fichiers, la configuration personnalisée du dépôt ou du serveur (y compris les procédures automatiques) et ainsi de suite.

Le format de déchargement des dépôts permet la conversion depuis un système de stockage différent ou depuis un autre système de gestion de versions. Comme le format du fichier est, pour sa plus grande partie, lisible par un humain, il doit être relativement facile de décrire des ensembles de modifications génériques (chacun étant traité comme une nouvelle révision) en utilisant ce format de fichier. En fait, l'utilitaire cvs2svn (voir la section intitulée « Conversion d'un dépôt CVS vers Subversion ») utilise le format dump pour décrire le contenu d'un dépôt CVS afin de pouvoir le copier dans un dépôt Subversion.

Pour le moment, nous nous concentrons sur la migration de données d'un dépôt entre différents dépôts Subversion et cela fait l'objet des sections qui suivent.

Migration des données d'un dépôt à l'aide de svnadmin

Quelle que soit la raison pour laquelle vous voulez migrer votre historique de dépôt, l'utilisation des sous-commandes svnadmin dump et svnadmin load est simplissime. svnadmin dump affiche un intervalle de révisions du dépôt, chacune utilisant le format des fichiers dump Subversion. Le fichier dump est envoyé sur la sortie standard tandis que les messages d'information sont envoyés sur la sortie d'erreur. Ceci vous permet de rediriger le flux standard vers un fichier tout en visualisant ce qui se passe dans votre terminal. Par exemple :

$ svnlook youngest mon-depot
26
$ svnadmin dump mon-depot > fichier-dump
* Révision 0 déchargée.
* Révision 1 déchargée.
* Révision 2 déchargée.
…
* Révision 25 déchargée.
* Révision 26 déchargée.

À la fin de la procédure, vous obtiendrez un fichier unique (fichier-dump dans l'exemple précédent) qui contient toutes les données stockées dans votre dépôt pour l'intervalle de révisions demandé. Notez que svnadmin dump lit les arborescences des révisions du dépôt de la même manière que tout autre processus « lecteur » (par exemple svn checkout), vous pouvez donc sans risque lancer cette commande à n'importe quel moment.

La commande jumelle, svnadmin load, recherche dans l'entrée standard la structure d'un fichier dump Subversion puis insère les révisions déchargées dans le dépôt de destination spécifié. Elle fournit elle aussi des informations sur le déroulement de l'opération, cette fois en utilisant la sortie standard :

$ svnadmin load nouveau-depot < fichier-dump
<<< Début d'une nouvelle transaction basée sur la révision 1
       * édition du chemin : A ... fait.
       * édition du chemin : A/B ... fait.
       …
  ------- Révision 1 propagée (commit) >>>

  <<< Début d'une nouvelle transaction basée sur la révision 2
       * édition du chemin : A/mu ... fait.
       * édition du chemin : A/D/G/rho ... fait.

  ------- Révision 2 propagée (commit) >>>

  …

  <<< Début d'une nouvelle transaction basée sur la révision 25
       * édition du chemin : A/D/gamma ... fait.

  ------- Révision 25 propagée (commit) >>>

  <<< Début d'une nouvelle transaction basée sur la révision 26
       * édition du chemin : A/Z/zeta ... fait.
       * édition du chemin : A/mu ... fait.

  ------- Révision 26 propagée (commit) >>>

Le résultat d'un chargement est l'ajout de nouvelle révisions à un dépôt — comme si vous faisiez des propagations vers ce dépôt avec un client Subversion classique. De la même manière que pour une propagation, vous pouvez utiliser les procédures automatiques pour effectuer des actions particulières avant et après chaque propagation faite par la procédure de chargement. En passant les options --use-pre-commit-hook et --use-post-commit-hook (respectivement) à svnadmin load, vous demandez à Subversion d'exécuter les procédures automatiques pre-commit et post-commit (respectivement) pour chaque révision chargée. Un exemple d'utilisation de ces options est de s'assurer que les révisions chargées passent par les mêmes étapes de validation qu'une propagation normale. Bien sûr, utilisez ces options avec prudence — si votre procédure automatique post-commit envoie des emails à une liste de diffusion pour chaque nouvelle propagation, vous ne voulez peut-être pas envoyer des centaines voire des milliers d'emails de notification à la suite vers cette liste ! Vous pouvez en apprendre davantage sur l'utilisation des procédures automatiques dans la section intitulée « Mise en place des procédures automatiques ».

Notez que puisque svnadmin utilise l'entrée et la sortie standards pour le déchargement et le rechargement, les administrateurs les plus intrépides peuvent tenter des choses du genre (peut-être même en utilisant différentes versions de svnadmin de chaque côté de la barre verticale |) :

$ svnadmin create nouveau-depot
$ svnadmin dump vieux-depot | svnadmin load nouveau-depot

Par défaut, un fichier dump prend beaucoup de place (beaucoup plus que le dépôt lui-même). C'est parce que, par défaut, chaque version de chaque fichier est écrite en entier dans le fichier dump. C'est le comportement le plus simple et le plus rapide et cela convient bien si vous redirigez le flux de données directement vers un autre processus (comme un programme de compression, de filtrage ou de chargement). Mais si vous créez un fichier dump dans une optique de stockage à long terme, vous voudrez sans doute économiser de l'espace disque en utilisant l'option --deltas. Avec cette option, les révisions successives des fichiers sont écrites en tant que différences binaires et compressées (de la même manière que pour le stockage des fichiers dans le dépôt). Cette option ralentit le processus mais le fichier résultant a une taille beaucoup plus proche de celle du dépôt original.

Nous avons mentionné auparavant que svnadmin dump affiche un intervalle de révisions. Pour spécifier une révision unique ou un intervalle à décharger, utilisez l'option --revision (-r). Si vous omettez cette option, toutes les révisions existantes sont affichées :

$ svnadmin dump mon-depot -r 23 > rev-23.fichier-dump
$ svnadmin dump mon-depot -r 100:200 > revs-100-200.fichier-dump

Au fur et à mesure que Subversion décharge chaque nouvelle révision, il n'affiche que le minimum d'informations nécessaire à un futur chargement pour re-générer la révision à partir de la précédente. En d'autres termes, pour n'importe quelle révision du fichier dump, seuls les éléments ayant subi une modification dans cette révision apparaissent dans le fichier dump. La seule exception à cette règle concerne la première révision qui est déchargée par la commande svnadmin dump courante.

Par défaut, Subversion n'exprime pas la première révision déchargée sous forme de différences à appliquer à la révision précédente. En effet, il n'y a pas de révision précédente dans le fichier dump ! Et puis Subversion ne peut pas connaître l'état du dépôt dans lequel les données vont être chargées (si jamais elles le sont). Pour s'assurer que la sortie de chaque exécution de svnadmin dump est auto-suffisante, la première révision déchargée est, par défaut, une représentation complète de chaque répertoire, de chaque fichier et de chaque propriété de cette révision du dépôt.

Vous pouvez toujours modifier ce comportement par défaut. Si vous ajoutez l'option --incremental quand vous déchargez le dépôt, svnadmin compare la première révision déchargée à la révision précédente du dépôt (de la même manière qu'il traite toutes les autres révisions qui sont déchargées). Il affiche alors la première révision de la même manière que le reste des révisions dans l'intervalle demandé (en ne mentionnant que les changements contenus dans cette révision). L'avantage est que vous pouvez créer plusieurs petits fichiers dump qui peuvent être chargés les uns à la suite des autres au lieu d'un unique gros fichier. Par exemple :

 
$ svnadmin dump mon-depot -r 0:1000 > fichier-dump1
$ svnadmin dump mon-depot -r 1001:2000 --incremental > fichier-dump2
$ svnadmin dump mon-depot -r 2001:3000 --incremental > fichier-dump3

Ces fichiers dump peuvent maintenant être chargés dans un nouveau dépôt avec la séquence de commandes suivante :

 
$ svnadmin load nouveau-depot < fichier-dump1
$ svnadmin load nouveau-depot < fichier-dump2
$ svnadmin load nouveau-depot < fichier-dump3

Une autre astuce consiste à utiliser l'option --incremental pour ajouter un nouvel intervalle de révisions à un fichier dump existant. Par exemple, vous pouvez avoir une procédure automatique post-commit qui ajoute simplement à un fichier dump le contenu de la révision qui a déclenché la procédure. Ou alors vous pouvez avoir un script qui tourne la nuit pour ajouter à un fichier dump les données de toutes les révisions qui ont eu lieu depuis le dernier lancement du script. Ainsi, svnadmin dump est une manière de réaliser des sauvegardes des changements de votre dépôt au fil du temps, dans l'éventualité d'un plantage système ou de toute autre événement catastrophique.

Les fichiers dump peuvent aussi être utilisés pour fusionner le contenu de différents dépôts en un seul dépôt. En utilisant l'option --parent-dir de svnadmin load, vous pouvez spécifier un nouveau répertoire racine virtuel pour la procédure de chargement. Ainsi, si vous avez des fichiers dump pour trois dépôts (disons fichier-dump-calc, fichier-dump-cal et fichier-dump-tab) vous pouvez commencer par créer un nouveau dépôt pour les héberger tous :

$ svnadmin create /var/svn/projets
$

Ensuite, créez dans le dépôt les nouveaux répertoires qui vont encapsuler le contenu de chacun des trois dépôts précédents :

$ svn mkdir -m "Racines initiales des projets" \
      file:///var/svn/projets/calc \
      file:///var/svn/projets/calendrier \
      file:///var/svn/projets/tableur
Révision 1 propagée.
$

Enfin, chargez chaque fichier dump dans le répertoire correspondant du nouveau dépôt :

$ svnadmin load /var/svn/projets --parent-dir calc < fichier-dump-calc
…
$ svnadmin load /var/svn/projets --parent-dir calendrier < fichier-dump-cal
…
$ svnadmin load /var/svn/projets --parent-dir spreadsheet < fichier-dump-tab
…
$

Migration des données d'un dépôt en utilisant svnrdump

Dans Subversion 1.7, la commande svnrdump a rejoint la trousse à outils Subversion. Elle est plutôt spécialisée en tant que version réseau de svnadmin dump et svnadmin load, que nous avons vu en détail dans la section intitulée « Migration des données d'un dépôt à l'aide de svnadmin ». svnrdump dump génère un flux dump à partir d'un dépôt distant, en l'affichant sur la sortie standard ; svnrdump load lit un flux depuis l'entrée standard et le charge dans un dépôt distant. En utilisant svnrdump, vous pouvez générer des dumps incrémentaux tout comme vous le feriez avec svnadmin dump. Vous pouvez même décharger une sous-arborescence d'un dépôt (ce que ne peut pas faire svnadmin dump).

La principale différence est que vous n'avez pas besoin d'avoir un accès direct au dépôt avec svnrdump car elle utilise les mêmes protocoles définis par Repository Access (RA) que le client texte interactif Subversion. Ainsi, vous serez peut-être amené à fournir des éléments d'authentification. Aussi, vous actions à distance sont soumises aux droits qui vous sont octroyés par la configuration du serveur Subversion.

[Note] Note

svnrdump dump requiert que le serveur soit en version 1.4 au moins. Elle génère des flux dump du type de ceux générés lorsque vous spécifiez l'option --deltas à svnadmin dump. Ce n'est pas significatif pour l'utilisation courante de cette commande mais peut vous impacter si vous avez en tête de transformer le flux dump de sortie.

[Note] Note

Comme elle modifie les propriétés de révisions après avoir propagé les nouvelles révisions, svnrdump load requiert que le dépôt cible soit configuré afin d'autoriser les modifications de propriétés via la procédure automatique pre-revprop-change. Reportez-vous à pre-revprop-change dans Partie II, « Guide de référence des commandes Subversion » pour plus de détails.

Comme vous pouvez vous y attendre, vous pouvez utiliser svnadmin et svnrdump de concert. Vous pouvez, par exemple, utililser svnrdump dump pour générer un flux dump depuis un dépôt distant et rediriger ce flux vers svnadmin load pour copier tout l'historique de ce dépôt vers un dépôt local. Vous pouvez tout aussi bien effectuer l'inverse, copier l'historique d'un dépôt local vers un distant.

[Astuce] Astuce

Si vous utiliser des URL de type file://, svnrdump peut alors accéder à des dépôts locaux, mais il le fera en utilisant la couche d'abstraction Repository Access (RA) de Subversion ; vous obtiendrez de bien meilleures performances en utilisant svnadmin dans de tels cas de figure.

Filtrage de l'historique d'un dépôt

Puisque Subversion stocke votre historique du suivi de versions en utilisant, au minimum, des algorithmes de différenciation binaire et de la compression de données (le tout, potentiellement, dans un système de gestion de bases de données complètement opaque), il est maladroit, et en tous cas fortement déconseillé, d'essayer de le modifier manuellement, sachant qu'en plus c'est assez difficile. Et une fois que des données ont été stockées dans votre dépôt, Subversion ne fournit généralement pas de moyen simple pour enlever ces données[56]. Mais, inévitablement, il y a des cas où vous voulez manipuler l'historique de votre dépôt. Par exemple pour supprimer tous les occurrences d'un fichier qui a été accidentellement ajouté au dépôt (alors qu'il ne devrait pas y être)[57]. Ou bien lorsque vous avez plusieurs projets qui partagent le même dépôt et que vous décidez de leur attribuer chacun le leur. Pour accomplir ce genre de tâches, les administrateurs ont besoin d'une représentation des données de leurs dépôts plus souple et plus facile à gérer : les fichiers dump Subversion.

Comme indiqué précédemment dans la section intitulée « Migration des données d'un dépôt », le format des fichiers dump Subversion est une représentation lisible par les humains des modifications apportées au cours du temps aux données suivies en versions. Utilisez la commande svnadmin dump ou svnrdump dump pour extraire les données et svnadmin load ou svnrdump load pour les charger dans un nouveau dépôt. Le gros atout de l'aspect « lisible par les humains » des fichiers dump est que, si vous y tenez, vous pouvez en inspecter le contenu et le modifier. Bien sûr, la contrepartie est que, si vous avez un fichier dump d'un dépôt actif depuis plusieurs années, cela vous prendra un certain temps pour en inspecter manuellement le contenu et le modifier, un temps certain même.

C'est là qu'intervient svndumpfilter. Ce programme agit comme un filtre sur les chemins pour les flux de déchargement/chargement d'un dépôt. Vous n'avez qu'à lui fournir une liste de chemins que vous voulez conserver ou une liste de chemins que vous voulez éliminer et ensuite rediriger le flux de dump de vos données à travers ce filtre. Vous obtenez un flux modifié qui ne contient que les données suivies en versions des chemins que vous avez demandés (explicitement ou implicitement).

Prenons un exemple concret d'utilisation de ce programme. Précédemment dans ce chapitre (voir la section intitulée « Stratégies d'organisation d'un dépôt »), nous avons décrit le processus de décision permettant de choisir l'organisation des données de votre dépôt (utiliser un dépôt par projet ou les combiner, comment organiser les répertoires au sein du dépôt, etc.). Mais il peut arriver qu'après un certain nombre de révisions vous repensiez votre organisation et vouliez la modifier. Une modification classique est de déplacer plusieurs projets qui partagent le même dépôt vers des dépôts propres à chacun d'eux.

Notre dépôt imaginaire contient trois projets : calc, calendrier et tableur. Ils se trouvent côte à côte comme ceci :


/
   calc/
      trunk/
      branches/
      tags/
   calendrier/
      trunk/
      branches/
      tags/
   tableur/
      trunk/
      branches/
      tags/

Pour placer ces trois projets dans leur dépôts propres, nous commençons par décharger tout le dépôt :

$ svnadmin dump /var/svn/depot > fichier-dump-depot
* Révision 0 déchargée.
* Révision 1 déchargée.
* Révision 2 déchargée.
* Révision 3 déchargée.
…
$

Ensuite, nous passons ce fichier dump à travers le filtre, en n'incluant à chaque fois qu'un seul répertoire racine. Nous obtenons trois nouveaux fichiers dump :

 
$ svndumpfilter include calc < fichier-dump-depot > fichier-dump-calc
…
$ svndumpfilter include calendrier < fichier-dump-depot > fichier-dump-cal
…
$ svndumpfilter include tableur < fichier-dump-depot > fichier-dump-tab
…
$

C'est le moment de prendre une décision. Chacun de vos fichiers dump générera un dépôt valide, mais il conservera les chemins exactement comme ils étaient dans le dépôt original. Cela veut dire que même si vous obtenez un dépôt propre à votre projet calc ce dépôt aura toujours un répertoire racine calc. Si vous voulez que les répertoires trunk, tags et branches soient placés à la racine de votre dépôt, vous devez alors éditer les fichiers dump, en modifiant les en-têtes Node-path et Node-copyfrom-path pour qu'ils ne contiennent plus de référence au répertoire calc/. Vous devez également supprimer la section des données qui crée le répertoire calc. Elle ressemble à ceci :

Node-path: calc
Node-action: add
Node-kind: dir
Content-length: 0

[Avertissement] Avertissement

Si vous envisagez d'éditer à la main le fichier dump pour enlever un répertoire à la racine, assurez-vous que votre éditeur n'est pas configuré pour convertir les caractères de fin de ligne vers le format natif (par exemple de \r\n vers \n), sinon le contenu ne serait plus conforme aux métadonnées. Cela corromprait le fichier dump de manière irréversible.

Tout ce qu'il reste à faire à présent, c'est de créer vos trois nouveaux dépôts et de charger chaque fichier dump dans le bon dépôt, en ignorant l'UUID contenu dans chaque flux dump :

$ svnadmin create calc
$ svnadmin load --ignore-uuid calc < fichier-dump-calc
<<< Début d'une nouvelle transaction basée sur la révision 1
     * édition du chemin : Makefile ... fait.
     * édition du chemin : bouton.c ... fait.
…
$ svnadmin create calendrier
$ svnadmin load --ignore-uuid calendrier < fichier-dump-cal
<<< Début d'une nouvelle transaction basée sur la révision 1
     * édition du chemin : Makefile ... fait.
     * édition du chemin : cal.c ... fait.
…
$ svnadmin create tableur
$ svnadmin load --ignore-uuid tableur < fichier-dump-tab
<<< Début d'une nouvelle transaction basée sur la révision 1
     * édition du chemin : Makefile ... fait.
     * édition du chemin : tableur.c ... fait.
…
$

Les deux sous-commandes svndumpfilter possèdent des options pour décider comment traiter les révisions « vides ». Si une révision donnée ne contient que des modifications concernant des chemins qui ont été filtrés, cette révision dorénavant vide peut être considérée comme inintéressante voire indésirable. Pour permettre à l'utilisateur de décider que faire de telles révisions, svndumpfilter propose les options suivantes :

--drop-empty-revs

Ne générer aucune révision vide ; elles sont tout simplement ignorées.

--renumber-revs

Si les révisions vides sont ignorées (avec l'option --drop-empty-revs), changer les numéros de révision restants pour qu'il n'y ait pas de trous dans la séquence de numérotation.

--preserve-revprops

Si les révisions vides ne sont pas ignorées, garder les propriétés de la révision (message de propagation, auteur, date, propriétés personnalisées, etc.) pour ces révisions vides. Autrement les révisions vides ne contiennent que l'horodatage original et un message expliquant que c'est à cause de svndumpfilter que cette révision est vide.

Alors que svndumpfilter peut s'avérer très utile et permet de gagner énormément de temps, il est affublé malheureusement de deux chausse-trappes. D'abord, cet utilitaire est extrêmement sensible à la sémantique des chemins. Prêtez attention à la manière dont sont spécifiés les chemins dans votre fichier dump, avec ou sans barre oblique (/) initiale. Regardez pour cela les en-têtes Node-path et Node-copyfrom-path.

…
Node-path: tableur/Makefile
…

Si les chemins ont une barre oblique initiale, vous devez inclure des barres obliques au début de chaque chemin que vous indiquez à svndumpfilter include et svndumpfilter exclude (et s'ils n'en ont pas, n'incluez pas de barre oblique au début). Pour aller plus loin, si votre fichier dump contient à la fois des chemins avec et des chemins sans barre oblique initiale, pour quelque raison que ce soit[58], vous devrez probablement normaliser les chemins en adoptant une des deux conventions.

En outre, les chemins qui ont été copiés peuvent vous donner quelques soucis. Subversion supporte les opérations de copie dans le dépôt, c'est-à-dire quand un nouveau chemin est créé par la copie d'un autre chemin qui existe déjà. Il est possible qu'à un certain moment de la vie de votre dépôt, vous ayez copié un fichier ou un répertoire d'un endroit que svndumpfilter a exclu vers un endroit qui est inclus. Pour rendre les données du dump cohérentes, svndumpfilter doit bien inclure l'ajout du nouveau chemin — y compris le contenu de tous les fichiers créés par la copie — mais en tant que copie d'un chemin source qui n'existe pas dans le flux des données filtrées. Mais puisque le format dump de Subversion ne contient que ce qui a été modifié dans chaque révision, le contenu de la source de la copie risque de ne pas être disponible. Si vous êtes susceptible d'avoir la moindre copie de ce type dans votre dépôt, vous devrez peut-être repenser votre ensemble de chemins à inclure/exclure, pour y inclure aussi les chemins qui ont servi de sources à des opérations de copie qui vous posent problème.

Enfin, svndumpfilter effectue un filtrage des chemins pour le moins littéral. Si vous essayez de copier l'historique d'un projet dont la racine est trunk/mon-projet et de le déplacer dans son propre dépôt, vous utiliserez évidemment la commande svndumpfilter include pour conserver tous les changements dans et sous trunk/mon-projet. Mais le fichier dump résultant ne fait aucune hypothèse sur le dépôt dans lequel vous allez charger ces données. En particulier, les données déchargées peuvent commencer par la révision qui a ajouté le répertoire trunk/mon-projet mais ne pas contenir les directives pour créer le répertoire trunk lui-même (parce que trunk ne correspond pas au filtre utilisé). Vous devez vous assurer que tous les répertoires à la présence desquels le flux de données déchargées s'attend existent réellement dans le dépôt destination, avant d'essayer de charger le flux de données à l'intérieur.

Réplication d'un dépôt

Divers scénarios montrent l'intérêt d'avoir un dépôt Subversion dont l'historique des versions est exactement le même que celui d'un autre dépôt. Le plus évident est probablement celui de maintenir un dépôt de secours, utilisé quand le dépôt principal est inaccessible en raison d'un problème matériel, d'une coupure réseau ou de tout autre souci de ce type. D'autres scénarios comprennent le déploiement de dépôts redondants pour distribuer la charge sur plusieurs serveurs, les mises à niveau transparentes et d'autres encore.

Subversion fournit un programme pour gérer de tels scénarios : svnsync. Il fonctionne essentiellement en demandant au serveur Subversion de « rejouer » les révisions, une par une. Il utilise ces informations sur les révisions pour répéter une propagation identique sur un autre dépôt. Aucun des deux dépôts n'a besoin d'être accessible localement sur la machine où svnsync tourne : ses paramètres sont des URL de dépôt et tout le travail est effectué via les interfaces d'accès au dépôt (Repository Access en anglais, ou RA) de Subversion. Tout ce dont il a besoin est un accès en lecture au dépôt source et un accès en lecture/écriture au dépôt de destination.

[Note] Note

Quand vous utilisez svnsync sur un dépôt source distant, le serveur Subversion de ce dépôt doit être en version 1.4 ou supérieure.

Réplication avec svnsync

Supposons que vous avez un dépôt source que vous voulez répliquer ; il vous faut alors disposer d'un dépôt destination qui servira de miroir. Ce dépôt cible peut utiliser n'importe quel magasin de données disponible (voir la section intitulée « Choix du magasin de données »), les couches d'abstraction de Subversion s'assurent que ces détails ne vous impactent pas. Par défaut, ce dépôt ne doit comporter aucun historique (nous aborderons une exception à cette règle plus loin dans cette section).

Le protocole utilisé par svnsync pour transmettre les informations de révision est particulièrement sensible aux divergences entre les historiques suivies en versions de la source et de la destination. Pour cette raison, bien que svnsync ne puisse pas exiger que le dépôt destination soit en lecture seule[59], autoriser des modifications d'historique sur le dépôt destination par un mécanisme externe autre que le processus de réplication mène droit au désastre.

[Avertissement] Avertissement

Ne modifiez pas le dépôt miroir de sorte que son historique de version diffère de celui du dépôt source. Les seules propagations et modifications de propriétés de révisions qui doivent avoir lieu sur ce dépôt miroir sont celles effectuées par l'outil svnsync.

Une autre exigence concernant le dépôt destination est que le processus svnsync doit être autorisé à modifier les propriétés de révision. Comme svnsync fonctionne dans le cadre du système des procédures automatiques du dépôt, l'état par défaut du dépôt (qui consiste à interdire les modifications des propriétés de révision, voir pre-revprop-change dans Guide de référence des procédures automatiques de Subversion) n'est pas suffisant. Vous devez activer explicitement la procédure automatique pre-revprop-change et votre script doit autoriser svnsync à définir et à modifier les propriétés de révision. Une fois ces dispositions prises, vous êtes parés pour commencer la réplication des révisions du dépôt.

[Astuce] Astuce

Il est de bon ton de mettre un place un contrôle d'accès pour autoriser le processus de réplication de votre dépôt à faire ce qu'il a à faire tout en interdisant aux autres utilisateurs de modifier le contenu de votre dépôt miroir.

Examinons maintenant l'utilisation de svnsync dans un scénario classique de réplication. Nous saupoudrons le discours de quelques recommandations pratiques que vous êtes libre d'ignorer si elles ne sont pas nécessaires ou pas applicables à votre environnement.

nous allons répliquer le dépôt public qui contient le code source de ce livre et mettre ce miroir à disposition sur Internet, sur une machine différente de celle qui héberge le dépôt original. Cet hôte distant possède une configuration globale qui autorise les accès anonymes en lecture mais requiert une authentification pour modifier les dépôts (pardonnez-nous de passer rapidement sur les détails de la configuration du serveur Subversion pour le moment, mais ces aspects sont traités en profondeur dans le Chapitre 6, Configuration du serveur.). Et pour rendre l'exemple plus intéressant, et uniquement pour cela, nous piloterons la réplication depuis une troisième machine — en l'occurrence, celle que nous sommes en train d'utiliser.

Dans un premier temps, nous allons créer le dépôt qui servira de miroir. Cette étape et les deux suivantes requièrent l'accès à la ligne de commande de la machine sur laquelle le miroir sera hébergé. Toutefois, une fois que ce dépôt sera complètement configuré, nous n'aurons plus besoin d'y avoir accès directement.

 
$ ssh admin@svn.exemple.com \
      "svnadmin create /var/svn/miroir-svn"
admin@svn.exemple.com's password: ********
$

À ce stade, nous disposons d'un dépôt et, en raison de la configuration de notre serveur, ce dépôt est accessible directement depuis Internet. Maintenant, puisque nous ne voulons pas que quoi que ce soit modifie notre dépôt en dehors du processus de réplication, nous devons trouver un moyen de distinguer ce processus des autres prétendants aux propagations. Pour ce faire, nous utilisons un identifiant d'utilisateur dédié à notre processus. Seules les propagations et les modifications de propriétés de révisions effectuées par l'identifiant spécial id-sync sont autorisées.

Nous allons utiliser le système de procédures automatiques du dépôt à la fois pour autoriser le processus de réplication à faire ce qu'il doit faire et pour garantir qu'il soit le seul à le faire. Nous implémentons donc deux des procédures automatiques du dépôt : pre-revprop-change et start-commit. Le script pre-revprop-change est présenté dans l'Exemple 5.4, « Procédure automatique pre-revprop-change du dépôt miroir » et, pour résumer, vérifie que l'utilisateur qui essaie de modifier les propriétés est bien notre utilisateur id-sync. Si c'est bien le cas, la modification est autorisée ; sinon, elle est refusée.

Exemple 5.4. Procédure automatique pre-revprop-change du dépôt miroir

#!/bin/sh

USER="$3"

if [ "$USER" = "id-sync" ]; then exit 0; fi

echo "Seul l'utilisateur id-sync est autorisé à modifier les propriétés de révision." >&2
exit 1

Voilà pour les modifications des propriétés de révision. Maintenant nous devons nous assurer que seul l'utilisateur id-sync est autorisé à propager de nouvelles révisions dans le dépôt. Ce que nous allons faire en utilisant une procédure automatique start-commit telle que celle présentée dans l'Exemple 5.5, « Procédure automatique start-commit du dépôt miroir ».

Exemple 5.5. Procédure automatique start-commit du dépôt miroir

#!/bin/sh

USER="$2"

if [ "$USER" = "id-sync" ]; then exit 0; fi

echo "Seul l'utilisateur id-sync est autorisé à effectuer des propagations." >&2
exit 1

Après avoir installé nos procédures automatiques et s'être assuré qu'elles sont exécutables par le serveur Subversion, nous en avons terminé avec l'installation de notre dépôt miroir. Maintenant, nous allons effectivement lancer la réplication.

La première chose à faire avec svnsync est d'enregistrer dans notre dépôt destination le fait qu'il sera un miroir du dépôt source. Nous utilisons donc la sous-commande svnsync initialize. Nous fournissons des URL qui pointent vers les répertoires racines des dépôts destination et source, respectivement. Dans Subversion 1.4, c'est obligatoire — seule la réplication de dépôts complets est permise. Depuis Subversion 1.5, cependant, vous pouvez aussi utiliser svnsync pour répliquer uniquement des sous-arborescences du dépôt.

$ svnsync help init
initialize (init): usage : svnsync initialize DEST_URL SOURCE_URL

Initialise un dépôt destination pour être synchronisé à partir
d'un autre dépôt.
…
$ svnsync initialize http://svn.exemple.com/miroir-svn \
                     http://svn.code.sf.net/p/svnbook/source \
                     --sync-username id-sync --sync-password mdp-sync
Propriétés copiées pour la révision 0.
$

Notre dépôt destination se souviendra maintenant qu'il est un miroir du dépôt public du code source de ce livre. Notez que nous avons fourni un identifiant et un mot de passe en arguments à svnsync — c'était exigé par la procédure automatique pre-revprop-change de notre dépôt miroir.

[Note] Note

Dans Subversion 1.4, les valeurs assignées aux options --username et --password de svnsync étaient utilisées pour l'authentification à la fois par le dépôt source et par le dépôt destination. Cela posait des problèmes quand ces l'utilisateur n'avait pas exactement les mêmes éléments pour les deux dépôts, particulièrement quand le mode non-interactif était utilisé (avec l'option --non-interactive).Ce problème a été résolu dans la version 1.5 de Subversion avec l'introduction de deux nouvelles paires d'options. Utilisez --source-username et --source-password pour vous authentifier auprès du dépôt source ; utilisez --sync-username et --sync-password pour vous authentifier auprès du dépôt destination (les vieilles options --username et --password existent encore pour assurer la compatibilité mais nous en déconseillons l'usage).

Abordons maintenant la partie amusante. En une seule sous-commande, nous pouvons demander à svnsync de copier toutes les révisions qui n'ont pas encore été répliquées du dépôt source vers le dépôt destination[60]. La sous-commande svnsync synchronize fouille dans les propriétés de révision spéciales du dépôt destination pour déterminer la dernière révision qui a été répliquée, en l'occurrence la révision 0. Ensuite, elle interroge le dépôt source pour savoir quelle est la dernière révision propagée dans ce dépôt. Enfin, elle demande au dépôt source de commencer à envoyer toutes les révisions entre la révision 0 et la dernière révision. Au moment où svnsync reçoit la réponse du dépôt source, elle commence la retransmission des révisions vers le dépôt destination en tant que nouvelles propagations.

$ svnsync help synchronize
synchronize (sync): Usage : svnsync synchronize URL_DEST [URL_SOURCE]

Tranfère toutes les révisions en attente vers la destination à partir
de la source avec laquelle elles ont été initialisées.
…
$ svnsync synchronize http://svn.exemple.com/miroir-svn \
                      http://svn.code.sf.net/p/svnbook/source
Transmission des données ........................................
Révision 1 propagée.
Propriétés copiées pour la révision 1.
Transmission des données ..
Révision 2 propagée.
Propriétés copiées pour la révision 2.
Transmission des données .....
Révision 3 propagée.
Propriétés copiées pour la révision 3.
…
Transmission des données ..
Révision 4063 propagée.
Propriétés copiées pour la révision 4063.
Transmission des données .
Révision 4064 propagée.
Propriétés copiées pour la révision 4064.
Transmission des données ....
Révision 4065 propagée.
Propriétés copiées pour la révision 4065.
$

Il est intéressant de noter ici que, pour chaque révision répliquée, il y a d'abord propagation de la révision dans le dépôt destination, puis des changements de propriétés ont lieu. C'est parce que la propagation initiale est effectuée par (et donc attribuée à) l'utilisateur id-sync et qu'elle est horodatée lors de la création de la nouvelle révision. Et aussi parce que les interfaces d'accès au dépôt Subversion n'autorisent pas la définition de propriétés de révision au sein d'une propagation. C'est pourquoi svnsync fait suivre la réplication par une série de modifications de propriétés qui copient dans le dépôt destination toutes les propriétés de révision trouvées dans le dépôt source pour cette révision. Cela a également pour effet de corriger l'auteur et l'horodatage de la révision pour être cohérent avec le dépôt source.

Notez également que svnsync documente tout ce qu'il fait en détail, afin de pouvoir être interrompu ou redémarré sans remettre en cause l'intégrité des données répliquées. Si une panne réseau survient pendant la réplication d'un dépôt, relancez simplement la commande svnsync synchronize et elle reprendra tranquillement là où elle s'était arrêtée. En fait, au fur et à mesure que de nouvelles révisions apparaissent dans le dépôt source, c'est précisément ce qu'il faut faire pour conserver votre miroir à jour.

[Avertissement] Avertissement

Parmi les informations stockées par le mirroir, svnsync enregistre l'URL source avec laquelle il a été initialisé. Ainsi, les appels suivants à svnsync ne requièrent pas de fournir l'URL source dans la ligne de commande. Cependant, pour plus de sécurité, nous recommandons que vous continuyez à le faire. En fonction de la manière dont il a été déployé, il peut s'avérer risqué pour svnsync de faire confiance à l'URL source qu'il récupère dépôt mirroir et depuis laquelle il récupère les données suivies en versions.

Le procédé est cependant peu élégant. Comme les propriétés des révisions Subversion peuvent être modifiées n'importe quand dans la vie du dépôt et comme elles ne conservent pas de trace des modifications effectuées, les processus de réplication doivent faire particulièrement attention à ces propriétés. Si vous avez déjà répliqué les quinze premières révisions d'un dépôt et que quelqu'un modifie une propriété de révision concernant la révision 12, svnsync ne sait pas qu'il faut revenir en arrière et modifier la copie de la révision 12. Vous devez le lui indiquer manuellement en utilisant la sous-commande svnsync copy-revprops (ou à l'aide d'autres outils), ce qui re-réplique toutes les propriétés de révision pour une révision particulière ou un ensemble de révisions.

copy-revprops: usage :

    1. svnsync copy-revprops URL_DEST [URL_SOURCE]
    2. svnsync copy-revprops URL_DEST REV[:REV2]

…
$ svnsync copy-revprops http://svn.exemple.com/mirroir-svn 12
Propriétés copiées pour la révision 12.
$

C'en est fini pour la présentation rapide de la réplication de dépôt. Vous voudrez sûrement automatiser un certain nombre de choses autour de ce processus. Par exemple, alors que notre exemple présentait une mise en place « tirer-et-pousser », vous êtes susceptible de vouloir que ce soit le dépôt source qui pousse les modifications vers un ou plusieurs miroirs prédéfinis lors de l'exécution des procédures automatiques post-commit et post-revprop-change. Ceci permettrait au miroir d'être à jour presque en temps réel.

Réplication partielle avec svnsync

svnsync n'est pas limitée à la copie intégrale de tout ce qui se trouve dans le dépôt. Elle peut aussi prendre en compte toute une variation de réplications partielles. Par exemple, bien que ce ne soit pas une situation très courante, svnsync sait répliquer des dépôts pour lesquels l'identifiant qu'elle utilise pour s'authentifier n'a que des droits partiels en lecture. Elle copie simplement les parties du dépôt qu'elle est autorisée à voir. Un tel miroir n'est clairement pas une bonne solution de sauvegarde..

Avec Subversion 1.5, svnsync a acquis la capacité de répliquer uniquement un sous-ensemble d'un dépôt plutôt que le dépôt entier. La procédure pour configurer et assurer la maintenance d'un tel miroir est exactement la même que pour répliquer un dépôt entier, excepté lors du passage de l'URL du dépôt source à svnsync init : vous spécifiez l'URL d'un sous-dossier à l'intérieur du dépôt. La synchronisation du miroir ne copie que les modifications relatives à l'arborescence sous le répertoire indiqué. Notez quand même quelques restrictions sur cette fonction : premièrement, vous ne pouvez pas répliquer plusieurs sous-dossiers disjoints du dépôt source vers un unique dépôt miroir — vous devez dans ce cas répliquer un répertoire parent qui est commun à tous les répertoires que vous voulez répliquer ; deuxièmement, la logique de filtrage est entièrement basée sur le chemin d'accès donc, si le sous-dossier que vous répliquez a été renommé par le passé, votre miroir ne contiendra que les révisions depuis lesquelles il a le nom indiqué dans l'URL que vous avez spécifiée. Et, de la même manière, si le sous-dossier source est renommé dans le futur, le processus de synchronisation ne répliquera plus les données à partir du moment où l'URL que vous avez spécifiée ne sera plus valide.

Une astuce rapide pour la création de mirroirs

Nous avons mentionné le coût de mise en place d'un mirroir pour un dépôt existant. Pour beaucoup, le coût apparent de transmettre des milliers (voire des millions) de révisions de l'historique vers un nouveau dépôt mirroir avec svnsync est le point d'arrêt final. Heureusement, Subversion 1.7 offre une porte de sortie avec la nouvelle option --allow-non-empty de svnsync initialize. Cette option vous permet d'initialiser un dépôt comme mirroir d'un autre en courtcircuitant la vérification que le dépôt à initialiser possède bien un historique vide. À la lecture de nos précédents avertissements sur la sensibilité du processus de réplication, vous devriez pressentir que cette option à n'utiliser qu'avec la plus grande prudence. Mais elle est terriblement efficace si vous avez les droits d'accès au dépôt source et que vous pouvez faire une copie physique du dépôt, puis initialiser cette copie en tant que nouveau mirroir :

$ svnadmin hotcopy /chemin/vers/depot /chemin/vers/depot-mirroir
$ ### créer le fichier /chemin/vers/depot-mirroir/hooks/pre-revprop-change
$ svnsync initialize file:///chemin/vers/depot-mirroir \
                     file:///chemin/vers/depot
svnsync: E000022: Le dépôt destination contient déjà des révisions ; utilisez
éventuellement l'option --allow-non-empty si ces révisions correspondent à
leurs contreparties dans le dépôt source
$ svnsync initialize --allow-non-empty file:///chemin/vers/depot-mirroir \
                                       file:///chemin/vers/depot
Propriétés copiées pour la révision 32042.
$

Les administrateurs qui utilisent une version antérieure à Subversion 1.7 (et qui n'ont donc pas accès à l'option --allow-non-emptyde svnsync initialize) peuvent atteindre le même résultat en manipulant précautionneusement la propriété de la révision r0 sur la copie du dépôt qui a vocation à devenir un mirroir. Utilisez svnadmin setrevprop pour créer les mêmes propriétés de journalisation que svnsync aurait créées.

Autour des réplications

Nous avons vu deux façons de répliquer l'historique des révisions d'un dépôt vers un autre. Regardons maintenant les choses du point de vue de l'utilisateur. Comment les réplications et les diverses situations qui y font appel affectent-elles les clients Subversion ?

Tant que l'on considère les interactions relatives aux dépôts et mirroirs, une copie de travail unique peut interagir avec les deux, mais vous devrez jongler un peu pour y arriver. D'abord, vous devez vous assurer que le dépôt primaire et le mirroir possèdent bien le même UUID (ce qui n'est pas le cas par défaut). Reportez-vous à la section intitulée « Gestion des identifiants uniques (UUID) des dépôts » plus loin dans ce chapitre pour en savoir davantage.

Une fois que les dépôts possèdent le même UUID, vous pouvez utiliser svn relocate pour faire pointer votre copie de travail vers le dépôt avec lequel vous souhaitez travailler ; cette procédure est décrite dans svn relocate dans Partie II, « Guide de référence des commandes Subversion ». Un danger vous guette ici cependant, car si les dépôts ne sont pas parfaitement synchrones, une copie de travail à jour et pointant vers le dépôt principal sera, si vous la faites pointer vers un mirroir obsolète, déboussolée par la perte apparente et soudaine des révisions qu'elle s'attend à trouver dans le dépôt. Elle renverra des erreurs pour vous le signaler. Si jamais cela survient, vous pouvez refaire pointer votre copie de travail vers le dépôt primaire et, soit attendre que le dépôt mirroir se mette à jour, soit remonter dans le temps votre copie de travail vers une révision dont vous savez qu'elle figure dans le dépôt mirroir, puis tenter à nouveau de faire pointer votre copie de travail vers ce mirroir.

Enfin, soyez conscient que la réplication des révisions fournie par svnsync n'est que cela  : une réplication de révisions. Seules les informations pouvant être contenues dans le format de fichier dump des dépôts Subversion peuvent être répliquées. Ainsi, les outils tels que svnsync (et svnrdump que nous avons vu dans la section intitulée « Migration des données d'un dépôt en utilisant svnrdump ») possèdent les mêmes limites intrinsèques aux fichiers dump. Ils ne répliquent pas les procédures automatiques, les transactions non propagées ou les verrous posés par les utilisateurs sur les chemins du dépôt.

Sauvegarde d'un dépôt

En dépit des nombreux progrès de la technologie depuis l'avènement de l'informatique moderne, une chose reste certaine : le pire n'est jamais très loin. L'alimentation électrique tombe en panne, les réseaux subissent des coupures, les mémoires vives crament, les disques durs flanchent, et ce même pour le plus consciencieux des administrateurs. Nous en venons donc maintenant à un sujet très important : comment réaliser des copies de sauvegarde des données de votre dépôt.

Les administrateurs de dépôts Subversion disposent de deux méthodes de sauvegarde : la complète et l'incrémentale. Une sauvegarde complète d'un dépôt implique de récupérer d'un seul coup toutes les informations nécessaires pour reconstruire complètement ce dépôt dans le cas d'une catastrophe. Habituellement, cela consiste à dupliquer, littéralement, la totalité du répertoire du dépôt (ce qui inclut l'environnement Berkeley DB ou FSFS). Les sauvegardes incrémentales sont plus restreintes : elles ne sauvegardent que les données du dépôt qui ont changé depuis la sauvegarde précédente.

Pour ce qui concerne les sauvegardes complètes, l'approche naïve pourrait sembler satisfaisante. Mais à moins d'interdire temporairement tout accès au dépôt, une simple copie récursive du répertoire risque de créer une sauvegarde corrompue. Dans le cas d'une base de données Berkeley DB, la documentation décrit un certain ordre de copie des fichiers qui garantit une copie de sauvegarde valide. Un ordre similaire existe avec les données FSFS. Mais vous n'avez pas à implémenter ces algorithmes vous-même, puisque l'équipe de développement de Subversion l'a déjà fait pour vous. La commande svnadmin hotcopy prend soin de tout ça afin de réaliser une copie à chaud de votre dépôt. Et son invocation est aussi triviale que la commande Unix cp ou qu'une copie sous Windows :

$ svnadmin hotcopy /var/svn/depot /var/svn/depot-sauvegarde

La sauvegarde générée est un dépôt Subversion totalement fonctionnel, capable de prendre immédiatement la place de votre dépôt en production si les choses tournent au vinaigre.

Lors de la copie d'un dépôt Berkeley DB, vous pouvez même ordonner à svnadmin hotcopy de purger les fichiers de journalisation inutilisés (voir la section intitulée « Purge des fichiers de journalisation inutilisés de Berkeley DB ») du dépôt original une fois la copie terminée. Ajoutez simplement l'option --clean-logs à la ligne de commande :

$ svnadmin hotcopy --clean-logs /var/svn/depot-bdb /var/svn/depot-bdb-sauvegarde

Des outils additionnels existent également autour de cette commande. Le répertoire tools/backup du code source de Subversion contient le script hot-backup.py. Ce script ajoute de la gestion de sauvegardes par-dessus svnadmin hotcopy, permettant de ne garder que les dernières sauvegardes (le nombre de sauvegardes à conserver est configurable) de chaque dépôt. Il gère automatiquement les noms des répertoires sauvegardés pour éviter les collisions avec les précédentes sauvegardes et élimine par rotation les sauvegardes les plus anciennes. Même si vous réalisez aussi des sauvegardes incrémentales, cette commande vous servira peut-être régulièrement. Par exemple, vous pouvez utiliser hot-backup.py dans un outil permettant le lancement différé de commandes (tel que cron sur les systèmes Unix) afin de le lancer toutes les nuits (ou à tout autre intervalle de temps qui vous convient mieux).

Quelques administrateurs utilisent un autre mécanisme de sauvegarde basé sur la génération et le stockage de flux dump des dépôts. Nous avons décrit dans la section intitulée « Migration des données d'un dépôt » comment utiliser svnadmin dump avec l'option --incremental pour réaliser une sauvegarde incrémentale d'une révision ou d'un intervalle de révisions donné. Et bien sûr, vous pouvez réaliser une sauvegarde complète en omettant l'option --incremental dans la commande. Cette méthode comporte certains avantages, entre autres que le format de vos informations sauvegardées est flexible (il n'est pas lié à une plateforme, à un type de magasin de données ou à une version particulière de Subversion ou de Berkeley DB). Mais cette flexibilité a un coût, à savoir le temps de restauration des données, qui en plus augmente avec chaque nouvelle révision propagée dans le dépôt. Aussi, comme c'est le cas pour un tas d'autres méthodes de sauvegarde, les modifications sur les propriétés de révision qui sont effectuées après une sauvegarde de ladite révision ne sont pas prises en compte par l'utilisation de flux de dump incrémentaux ne se chevauchant pas. C'est pourquoi nous recommandons de ne pas se reposer uniquement sur le type de sauvegarde basé sur les fichiers dump.

À partir de Subversion 1.8, svnadmin hotcopy accepte l'option --incremental et gère la copie à chaud des dépôts FSFS. Dans le mode de copie à chaud incrémentale, les données des révisions qui ont déjà été copiées vers le dépôt de destination ne seront pas copiées à nouveau. Lorsque l'option --incremental est utilisée avec svnadmin hotcopy, Subversion ne copie que les nouvelles révisions, les révisions dont la taille a changé et celles dont l'horodatage a été modifié depuis la précédente opération de copie à chaud. De plus, les performances de svnadmin hotcopy --incremental ne sont limitées que par les entrées/sorties disques, au contraire de svnsync ou svnadmin dump --incremental. En conséquence, les copies à chaud incrémentales peuvent vous faire économiser beaucoup de temps lors de la sauvegarde d'un gros dépôt.

Comme vous pouvez le constater, chaque type de sauvegarde a ses avantages et ses inconvénients. La méthode la plus facile est de loin la sauvegarde à chaud complète, qui fournit toujours une copie conforme et fonctionnelle de votre dépôt. En cas d'accident sur votre dépôt de production, vous pouvez effectuer une restauration à partir de votre sauvegarde par une simple copie récursive de répertoire. Malheureusement, si vous maintenez plusieurs sauvegardes de votre dépôt, chaque sauvegarde consomme autant d'espace disque que votre dépôt en production. Les sauvegardes incrémentales, en revanche, sont plus rapides à réaliser et prennent moins de place. Mais le processus de restauration peut s'avérer pénible, avec souvent plusieurs sauvegardes incrémentales à appliquer. D'autres méthodes ont leurs propres bizarreries. Les administrateurs doivent trouver le juste milieu entre le coût des sauvegardes et le coût de la restauration.

Le programme svnsync (voir la section intitulée « Réplication d'un dépôt ») fournit en fait une approche médiane assez pratique. Si vous synchronisez régulièrement un miroir en lecture seule avec votre dépôt principal, ce miroir en lecture seule se révèle être un bon candidat pour prendre le relais du dépôt défaillant en cas de besoin. Le principal inconvénient de cette méthode est que seules les données suivies en versions sont synchronisées — les fichiers de configuration du dépôt, les verrous utilisateurs sur les chemins ou d'autres éléments stockés physiquement dans le répertoire du dépôt mais pas dans le système de fichiers virtuel du dépôt ne sont pas pris en charge par svnsync.

Quelle que soit la méthode de sauvegarde utilisée, les administrateurs doivent savoir comment les modifications des propriétés non suivies en versions des révisions sont prises en compte (ou pas). Puisque ces modifications elles-mêmes ne créent pas de nouvelles révisions, elles n'activent pas les procédures automatiques post-commit ni même éventuellement les procédures automatiques pre-revprop-change et post-revprop-change[61]. Et puisque vous pouvez modifier les propriétés de révision sans respecter l'ordre chronologique (vous pouvez changer n'importe quelle propriété de révision à n'importe quel moment), une sauvegarde incrémentale des dernières révisions pourrait ne pas intégrer la modification d'une propriété de révision qui faisait partie d'une sauvegarde précédente.

En règle générale, seuls les plus paranoïaques ont besoin de sauvegarder le dépôt entier, disons, à chaque propagation. Cependant, en considérant qu'un dépôt donné possède des mécanismes de redondance autres avec une certaine granularité (tels que des courriels envoyés à chaque propagation ou des fichiers dumps incrémentaux), réaliser une copie à chaud de la base de données, dans le cadre des sauvegardes nocturnes quotidiennes des systèmes, est une bonne pratique d'administration. Ce sont vos données, protégez-les autant que vous le voulez.

Bien souvent, la meilleure approche de sauvegarde d'un dépôt consiste à ne pas mettre tous ses œufs dans le même panier, en utilisant une combinaison des méthodes décrites ici. Les développeurs Subversion, par exemple, sauvegardent le code source de Subversion chaque nuit en utilisant hot-backup.py et effectuent une copie distante par rsync de ces sauvegardes complètes ; ils conservent plusieurs archives de tous les emails de notification des propagations et des changements de propriétés ; ils ont également des miroirs maintenus par divers volontaires qui utilisent svnsync. Votre solution peut ressembler à cela, mais elle doit être adaptée à vos besoins et maintenir l'équilibre entre commodité et paranoïa. Et quoi que vous fassiez, vérifiez la validité de vos sauvegardes de temps en temps (à quoi servirait une roue de secours crevée ?). Bien que tout ceci n'empêche pas votre matériel de subir les affres du destin[62], cela vous aidera certainement à vous sortir de ces situations délicates.

Gestion des identifiants uniques (UUID) des dépôts

Chaque dépôt Subversion possède un identifiant unique (Universally Unique IDentifier en anglais ou UUID). Cet UUID est utilisé par les clients Subversion pour vérifier l'identité d'un dépôt quand les autres formes de vérification ne sont pas satisfaisantes (telles que l'URL du dépôt qui peut varier avec le temps). En général, les administrateurs de dépôts n'ont jamais (ou très rarement) à se préoccuper des UUID autrement que comme d'un détail d'implémentation bas niveau de Subversion. Parfois, cependant, il faut prêter attention à ce détail.

En règle générale, les UUID de vos dépôts de production doivent être uniques. C'est le but, après tout, des UUID. Mais il y a des cas où vous voulez que les UUID de deux dépôts soient identiques. Par exemple, quand vous faites une copie de sauvegarde d'un dépôt, vous voulez que cette sauvegarde soit une réplique exacte de l'original afin que, dans le cas où vous restaureriez la sauvegarde pour remplacer le dépôt de production, ceci soit transparent pour les utilisateurs. Quand vous déchargez et chargez l'historique d'un dépôt (comme décrit précédemment dans la section intitulée « Migration des données d'un dépôt »), vous devez décider si vous incluez l'UUID dans le flux de données déchargées (le fichier dump) qui va dans le nouveau dépôt. Les circonstances vous imposeront la marche à suivre.

Il y a plusieurs façons de faire pour attribuer (ou modifier) un UUID à un dépôt, le cas échéant. Depuis Subversion 1.5, il suffit d'utiliser la commande svnadmin setuuid. Si vous fournissez un UUID explicite à cette sous-commande, elle valide le format de l'UUID et fixe l'identifiant unique du dépôt à cette valeur. Si vous omettez l'UUID, un nouvel UUID est généré automatiquement pour votre dépôt.

$ svnlook uuid /var/svn/depot
cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec  
$ svnadmin setuuid /var/svn/depot   # créer un nouvel UUID
$ svnlook uuid /var/svn/depot
3c3c38fe-acc0-11dc-acbc-1b37ff1c8e7c 
$ svnadmin setuuid /var/svn/depot \
           cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec  # restaure l'ancien UUID
$ svnlook uuid /var/svn/depot
cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec
$

Pour ceux qui utilisent une version de Subversion antérieure à 1.5, ces tâches sont un peu plus compliquées. Vous pouvez attribuer explicitement un UUID en redirigeant le flux d'un fichier dump qui comporte le nouvel UUID avec la commande svnadmin load --force-uuid CHEMIN-DU-DEPOT.

 
$ svnadmin load --force-uuid /var/svn/depot <<EOF
SVN-fs-dump-format-version: 2

UUID: cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec
EOF
$ svnlook uuid /var/svn/depot
cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec
$

Faire générer un nouvel UUID à une ancienne version de Subversion n'est pas aussi simple. La meilleure façon de faire est certainement de trouver un moyen de générer un UUID puis d'affecter explicitement cet UUID au dépôt.



[55] Par exemple, disque dur + gros aimant à côté = désastre.

[56] C'est d'ailleurs pour cela que vous utilisez un système de gestion de versions, non ?

[57] Des suppressions délibérées et avisées de données suivies en versions peuvent effectivement être justifiées par des cas d'utilisation réels. C'est pourquoi une fonctionnalité « d'oblitération » est une des fonctionnalités les plus demandées pour Subversion et les développeurs de Subversion espèrent pouvoir la fournir bientôt.

[58] Bien que svnadmin dump ait une politique cohérente concernant la barre oblique initiale (aussi appelée « slash » — il ne l'inclut pas), d'autres programmes qui génèrent des fichiers dump sont susceptibles de ne pas être aussi cohérents.

[59] En fait, le dépôt ne peut pas être complètement en lecture seule, sinon svnsync lui-même aurait du mal à y copier l'historique des révisions.

[60] Nous avertissons le lecteur que, bien qu'il lui suffise de quelques secondes pour lire ce paragraphe et l'exemple qui suit, le temps nécessaire pour réaliser une opération de réplication est, disons, un peu plus long.

[61] La commande svnadmin setlog peut être utilisée de manière à contourner les procédures automatiques.

[62] Vous savez, le fameux « concours de circonstances », celui auquel vous êtes arrivé premier.