SVNBOOK Chap5 Repository Maintenance
De Framalang Wiki.
Cette page fait partie du projet Version control with subversion.
| Pseudo | Code | Rôle | Statut |
|---|---|---|---|
| Hotshot92 | Traduction | Fait | |
| SVN | 1ère Relecture | Fait | |
| Validation |
Sommaire |
Titre
Maintaining a Subversion repository can be daunting, mostly due to the complexities inherent in systems that have a database backend. Doing the task well is all about knowing the tools—what they are, when to use them, and how. This section will introduce you to the repository administration tools provided by Subversion and discuss how to wield them to accomplish tasks such as repository data migration, upgrades, backups, and cleanups.
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. Réussir nécessite principalement de connaître les outils - ceux dont on dispose, quand les utiliser et comment. Cette section vous présentera les outils fournis par Subversion pour assurer l'administration du dépôt et décrira leur maniement pour réaliser des opérations telles que migrations de données, mises à jour, sauvegardes et nettoyages.
Sous-titre 1
Subversion provides a handful of utilities useful for creating, inspecting, modifying, and repairing your repository. Let's look more closely at each of those tools. Afterward, we'll briefly examine some of the utilities included in the Berkeley DB distribution that provide functionality specific to your repository's database backend not otherwise provided by Subversion's own tools.
Subversion fournit une poignée d'utilitaires pour créer, inspecter, modifier et réparer votre dépôt. Regardons de plus près chacun de ces outils. Ensuite, nous aborderons 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
The svnadmin program is the repository administrator's best friend. Besides providing the ability to create Subversion repositories, this program allows you to perform several maintenance operations on those repositories. The syntax of svnadmin is similar to that of other Subversion command-line programs:
$ svnadmin help
general usage: svnadmin SUBCOMMAND REPOS_PATH [ARGS & OPTIONS ...]
Type 'svnadmin help <subcommand>' for help on a specific subcommand.
Type 'svnadmin --version' to see the program version and FS modules.
Available subcommands:
crashtest
create
deltify
…
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
…
Previously in this chapter (in the section called “Creating the Repository”), we were introduced to the svnadmin create subcommand. Most of the other svnadmin subcommands we will cover later in this chapter. And you can consult the section called “svnadmin” for a full rundown of subcommands and what each of them offers.
Plus tôt dans ce chapitre (dans la section "Créer un dépôt"), nous vous avons présenté la sous-commande svnadmin create. La plupart des autres sous-commandes svnadmin seront couvertes plus loin dans ce chapitre. Vous pouvez également consulter la section "svnadmin" pour une liste complète des sous-commandes et des fonctionnalités qu'elles apportent.
svnlook
svnlook is a tool provided by Subversion for examining the various revisions and transactions (which are revisions in the making) in a repository. No part of this program attempts to change the repository. svnlook is typically used by the repository hooks for reporting the changes that are about to be committed (in the case of the pre-commit hook) or that were just committed (in the case of the post-commit hook) to the repository. A repository administrator may use this tool for diagnostic purposes.
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 d'une procédure automatique pré-propagation) ou qui viennent d'être propagés (dans le cas d'une procédure automatique post-propagation). Un administrateur peut être amené à utiliser cet outil à des fins de diagnostic.
svnlook has a straightforward syntax:
$ svnlook help
general usage: svnlook SUBCOMMAND REPOS_PATH [ARGS & OPTIONS ...]
Note: any subcommand which takes the '--revision' and '--transaction'
options will, if invoked without one of those options, act on
the repository's youngest revision.
Type 'svnlook help <subcommand>' for help on a specific subcommand.
Type 'svnlook --version' to see the program version and FS modules.
…
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.
...
Most of svnlook's subcommands can operate on either a revision or a transaction tree, printing information about the tree itself, or how it differs from the previous revision of the repository. You use the --revision (-r) and --transaction (-t) options to specify which revision or transaction, respectively, to examine. In the absence of both the --revision (-r) and --transaction (-t) options, svnlook will examine the youngest (or HEAD) revision in the repository. So the following two commands do exactly the same thing when 19 is the youngest revision in the repository located at /var/svn/repos:
$ svnlook info /var/svn/repos $ svnlook info /var/svn/repos -r 19
La plupart des 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 transaction examiner, utilisez respectivement les options --revision (-r) et --transaction (-t). En l'absence des options --revision (-r) et --transaction (-t), svnlook examinera la révision la plus récente (ou 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
One exception to these rules about subcommands is the svnlook youngest subcommand, which takes no options and simply prints out the repository's youngest revision number:
$ svnlook youngest /var/svn/repos 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
- Keep in mind that the only transactions you can browse are uncommitted ones. Most repositories will have no such transactions because transactions are usually either committed (in which case, you should access them as revision with the --revision (-r) option) or aborted and removed.
- 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 comportent 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.
Output from svnlook is designed to be both human- and machine-parsable. Take, as an example, the output of the svnlook info subcommand:
$ svnlook info /var/svn/repos sally 2002-11-04 09:29:13 -0600 (Mon, 04 Nov 2002) 27 Added the usual Greek tree. $
La sortie de svnlook est conçue pour être à la fois lisible par un humain et traitable 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. $
The output of svnlook info consists of the following, in the order given:
- The author, followed by a newline
- The date, followed by a newline
- The number of characters in the log message, followed by a newline
- The log message itself, followed by a newline
This output is human-readable, meaning items such as the datestamp are displayed using a textual representation instead of something more obscure (such as the number of nanoseconds since the Tastee Freez guy drove by). But the output is also machine-parsable—because the log message can contain multiple lines and be unbounded in length, svnlook provides the length of that message before the message itself. This allows scripts and other wrappers around this command to make intelligent decisions about the log message, such as how much memory to allocate for the message, or at least how many bytes to skip in the event that this output is not the last bit of data in the stream.
La sortie de svnlook info est constituée des éléments suivants, par ordre d'apparition :
- l'auteur, suivi d'un saut de ligne
- la date, suivie d'un saut de ligne
- le nombre de caractères du message de propagation, suivi d'un saut de ligne
- le message de propagation lui-même, suivi d'un saut de 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 utilisant 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 can perform a variety of other queries: displaying subsets of bits of information we've mentioned previously, recursively listing versioned directory trees, reporting which paths were modified in a given revision or transaction, showing textual and property differences made to files and directories, and so on. See the section called “svnlook” for a full reference of svnlook's features.
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 versionnées 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 à la section "svnlook" pour la liste complète des fonctionnalités offertes par svnlook.
svndumpfilter
While it won't be the most commonly used tool at the administrator's disposal, svndumpfilter provides a very particular brand of useful functionality—the ability to quickly and easily modify streams of Subversion repository history data by acting as a path-based filter.
The syntax of svndumpfilter is as follows:
$ svndumpfilter help
general usage: svndumpfilter SUBCOMMAND [ARGS & OPTIONS ...]
Type "svndumpfilter help <subcommand>" for help on a specific subcommand.
Type 'svndumpfilter --version' to see the program version.
Available subcommands:
exclude
include
help (?, h)
Bien que ce ne soit pas l'outil le plus utilisé mis à disposition de l'administrateur, svndumpfilter fournit des fonctionnalités particulièrement singulières et utiles - 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)
There are only two interesting subcommands: svndumpfilter exclude and svndumpfilter include. They allow you to make the choice between implicit or explicit inclusion of paths in the stream. You can learn more about these subcommands and svndumpfilter's unique purpose later in this chapter, in the section called “Filtering Repository History”.
Il n'y a que deux sous-commandes intéressantes : svndumpfilter exclude et svndumpfilter include. Elles vous permettent de choisir entre l'inclusion implicite ou explicite des chemins dans le flux. Vous pouvez en apprendre plus sur ces sous-commandes et sur l'utilité si particulière de svndumpfilter plus loin dans ce chapitre, dans la section "Filtrer l'historique du dépôt".
svnsync
The svnsync program, which is new to the 1.4 release of Subversion, provides all the functionality required for maintaining a read-only mirror of a Subversion repository. The program really has one job—to transfer one repository's versioned history into another repository. And while there are few ways to do that, its primary strength is that it can operate remotely—the “source” and “sink” [32] repositories may be on different computers from each other and from svnsync itself.
Le programme svnsync, apparu dans la version 1.4 de Subversion, fournit toutes les fonctionnalités requises pour faire fonctionner un miroir en lecture seule d'un dépôt Subversion. Le programme n'a qu'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" [32] peuvent être sur deux ordinateurs différents et svnsync sur un troisième.
As you might expect, svnsync has a syntax that looks very much like every other program we've mentioned in this chapter:
$ svnsync help
general usage: svnsync SUBCOMMAND DEST_URL [ARGS & OPTIONS ...]
Type 'svnsync help <subcommand>' for help on a specific subcommand.
Type 'svnsync --version' to see the program version and RA modules.
Available subcommands:
initialize (init)
synchronize (sync)
copy-revprops
help (?, h)
$
We talk more about replicating repositories with svnsync later in this chapter (see the section called “Repository Replication”).
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
help (?, h)
$
Nous reviendrons en détail sur la réplication de dépôts avec svnsync plus loin dans ce chapitre (voir la section "Réplication de dépôt").
fsfs-reshard.py
While not an official member of the Subversion toolchain, the fsfs-reshard.py script (found in the tools/server-side directory of the Subversion source distribution) is a useful performance tuning tool for administrators of FSFS-backed Subversion repositories. FSFS repositories contain files that describe the changes made in a single revision, and files that contain the revision properties associated with a single revision. Repositories created in versions of Subversion prior to 1.5 keep these files in two directories—one for each type of file. As new revisions are committed to the repository, Subversion drops more files into these two directories—over time, the number of these files in each directory can grow to be quite large. This has been observed to cause performance problems on certain network-based filesystems.
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. Les dépôts FSFS contiennent des fichiers qui décrivent les changements apportés dans une seule révision et des fichiers qui contiennent les propriétés de révision associées à une seule révision. Les dépôts créés avec Subversion avant la version 1.5 conservent ces fichiers dans deux répertoires : un pour chaque type de fichiers. Au fur et à mesure des révisions propagées dans le dépôt, Subversion dépose de plus en plus de fichiers dans ces deux répertoires - au bout d'un certain temps, le nombre de fichiers dans chaque répertoire peut devenir particulièrement élevé. On a pu constater dans cette situation des problèmes de performances sur certains systèmes de fichiers en réseau.
Subversion 1.5 creates FSFS-backed repositories using a slightly modified layout in which the contents of these two directories are sharded, or scattered across several subdirectories. This can greatly reduce the time it takes the system to locate any one of these files, and therefore increases the overall performance of Subversion when reading from the repository. The number of subdirectories used to house these files is configurable, though, and that's where fsfs-reshard.py comes in. This script reshuffles the repository's file structure into a new arrangement that reflects the requested number of sharding subdirectories. This is especially useful for converting an older Subversion repository into the new Subversion 1.5 sharded layout (which Subversion will not automatically do for you) or for fine-tuning an already sharded repository.
Subversion en version 1.5 crée les dépôts FSFS en utilisant un schéma légèrement différent pour lequel ces deux répertoires sont répartis dans plusieurs sous-répertoires. Cela peut réduire de façon drastique le temps de recherche d'un de ces fichiers et, en conséquence, améliore la performance globale de Subversion pour la lecture du dépôt. Le nombre de sous-répertoires utilisés pour héberger ces fichiers est d'ailleurs configurable, et c'est là qu'intervient le script fsfs-reshard.py. Le script remanie la structure du dépôt pour se conformer au nombre de sous-répertoires demandés. C'est particulièrement utile pour convertir un vieux dépôt Subversion vers le nouveau schéma réparti de Subversion 1.5 (ce que Subversion ne fera pas automatiquement pour vous) ou pour modifier cette valeur dans un dépôt déjà réparti.
Berkeley DB utilities
If you're using a Berkeley DB repository, all of your versioned filesystem's structure and data live in a set of database tables within the db/ subdirectory of your repository. This subdirectory is a regular Berkeley DB environment directory and can therefore be used in conjunction with any of the Berkeley database tools, typically provided as part of the Berkeley DB distribution.
For day-to-day Subversion use, these tools are unnecessary. Most of the functionality typically needed for Subversion repositories has been duplicated in the svnadmin tool. For example, svnadmin list-unused-dblogs and svnadmin list-dblogs perform a subset of what is provided by the Berkeley db_archive utility, and svnadmin recover reflects the common use cases of the db_recover utility.
Si vous utilisez un dépôt avec une base Berkeley DB, toute la structure de votre système de fichiers versionnés ainsi que les données 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. La plupart 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.
However, there are still a few Berkeley DB utilities that you might find useful. The db_dump and db_load programs write and read, respectively, a custom file format that describes the keys and values in a Berkeley DB database. Since Berkeley databases are not portable across machine architectures, this format is a useful way to transfer those databases from machine to machine, irrespective of architecture or operating system. As we describe later in this chapter, you can also use svnadmin dump and svnadmin load for similar purposes, but db_dump and db_load can do certain jobs just as well and much faster. They can also be useful if the experienced Berkeley DB hacker needs to do in-place tweaking of the data in a BDB-backed repository for some reason, which is something Subversion's utilities won't allow. Also, the db_stat utility can provide useful information about the status of your Berkeley DB environment, including detailed statistics about the locking and storage subsystems.
For more information on the Berkeley DB tool chain, visit the documentation section of the Berkeley DB section of Oracle's web site, located at http://www.oracle.com/technology/documentation/berkeley-db/db/.
Cependant, il reste quelques utilitaires Berkeley DB que vous pourriez trouver utile. Les programmes db_dump et db_load écrivent et lisent 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 le vous permettront 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).
Sous-titre 2
Sometimes a user will have an error in her log message (a misspelling or some misinformation, perhaps). If the repository is configured (using the pre-revprop-change hook; see the section called “Implementing Repository Hooks”) to accept changes to this log message after the commit is finished, the user can “fix” her log message remotely using svn propset (see svn propset). However, because of the potential to lose information forever, Subversion repositories are not, by default, configured to allow changes to unversioned properties—except by an administrator.
Parfois un utilisateur se trompera 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 "Implémenter des procédures automatiques dans le dépôt") 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). 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.
If a log message needs to be changed by an administrator, this can be done using svnadmin setlog. This command changes the log message (the svn:log property) on a given revision of a repository, reading the new value from a provided file.
$ echo "Here is the new, correct log message" > newlog.txt $ svnadmin setlog myrepos newlog.txt -r 388
The svnadmin setlog command, by default, is still bound by the same protections against modifying unversioned properties as a remote client is—the pre- and post-revprop-change hooks are still triggered, and therefore must be set up to accept changes of this nature. But an administrator can get around these protections by passing the --bypass-hooks option to the svnadmin setlog command.
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 toujours des garde-fous pour empêcher de modifier des propriétés non suivies en versions de la même manière que pour 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.
WARNING
- Remember, though, that by bypassing the hooks, you are likely avoiding such things as email notifications of property changes, backup systems that track unversioned property changes, and so on. In other words, be very careful about what you are changing, and how you change it.
- 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 version, etc. En d'autres termes, faites particulièrement attention aux changements que vous apportez et à la manière dont vous le faites.
Sous-Titre 3
While the cost of storage has dropped incredibly in the past few years, disk usage is still a valid concern for administrators seeking to version large amounts of data. Every bit of version history information stored in the live repository needs to be backed up elsewhere, perhaps multiple times as part of rotating backup schedules. It is useful to know what pieces of Subversion's repository data need to remain on the live site, which need to be backed up, and which can be safely removed.
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 un 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.
Sous-sous-titre 4
To keep the repository small, Subversion uses deltification (or deltified storage) within the repository itself. Deltification involves encoding the representation of a chunk of data as a collection of differences against some other chunk of data. If the two pieces of data are very similar, this deltification results in storage savings for the deltified chunk—rather than taking up space equal to the size of the original data, it takes up only enough space to say, “I look just like this other piece of data over here, except for the following couple of changes.” The result is that most of the repository data that tends to be bulky—namely, the contents of versioned files—is stored at a much smaller size than the original full-text representation of that data. And for repositories created with Subversion 1.4 or later, the space savings are even better—now those full-text representations of file contents are themselves compressed.
Pour garder un dépôt petit, Subversion utilise la différenciation (ou le 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 avec un autre groupe de données. Si les deux groupes de données sont très similaires, la différenciation économisera 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. Et pour les dépôts créés avec Subversion en version 1.4 ou plus, l'espace économisé est encore plus important - les représentations textuelles des fichiers sont à présent elles-mêmes compressées.
POINT OF INTEREST
- Because all of the data that is subject to deltification in a BDB-backed repository is stored in a single Berkeley DB database file, reducing the size of the stored values will not immediately reduce the size of the database file itself. Berkeley DB will, however, keep internal records of unused areas of the database file and consume those areas first before growing the size of the database file. So while deltification doesn't produce immediate space savings, it can drastically slow future growth of the database.
- Comme toutes les données sujettes à différenciation dans un dépôt BDB sont stockées dans un unique fichier de la base de données, réduire la taille des données stockées ne réduira pas instantanément la taille du fichier de base de données lui-même. Le gestionnaire de base de données Berkeley DB gardera néanmoins une trace des zones non-utilisées du fichier de base de données et utilisera ces zones avant d'augmenter la taille du fichier de base de données. Ainsi, même si la différenciation n'économise pas immédiatement de la place, cela ralentit de façon drastique la croissance de la base de données.
Sous-sous-titre 5
Though they are uncommon, there are circumstances in which a Subversion commit process might fail, leaving behind in the repository the remnants of the revision-to-be that wasn't—an uncommitted transaction and all the file and directory changes associated with it. This could happen for several reasons: perhaps the client operation was inelegantly terminated by the user, or a network failure occurred in the middle of an operation. Regardless of the reason, dead transactions can happen. They don't do any real harm, other than consuming disk space. A fastidious administrator may nonetheless wish to remove them.
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.
You can use the svnadmin lstxns command to list the names of the currently outstanding transactions:
$ svnadmin lstxns myrepos 19 3a1 a45 $
Each item in the resultant output can then be used with svnlook (and its --transaction (-t) option) to determine who created the transaction, when it was created, what types of changes were made in the transaction—information that is helpful in determining whether the transaction is a safe candidate for removal! If you do indeed want to remove a transaction, its name can be passed to svnadmin rmtxns, which will perform the cleanup of the transaction. In fact, svnadmin rmtxns can take its input directly from the output of svnadmin lstxns!
$ svnadmin rmtxns myrepos `svnadmin lstxns myrepos` $
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` $
If you use these two subcommands like this, you should consider making your repository temporarily inaccessible to clients. That way, no one can begin a legitimate transaction before you start your cleanup. Example 5.1, “txn-info.sh (reporting outstanding transactions)” contains a bit of shell-scripting that can quickly generate information about each outstanding transaction in your repository.
Si vous utilisez ces deux sous-commandes de cette façon, 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 tant que le nettoyage n'est pas commencé. L'exemple 5.1 "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.
Example 5.1. txn-info.sh (reporting outstanding transactions)
#!/bin/sh
### Generate informational output for all outstanding transactions in
### a Subversion repository.
REPOS="${1}"
if [ "x$REPOS" = x ] ; then
echo "usage: $0 REPOS_PATH"
exit
fi
for TXN in `svnadmin lstxns ${REPOS}`; do
echo "---[ Transaction ${TXN} ]-------------------------------------------"
svnlook info "${REPOS}" -t "${TXN}"
done
Exemple 5.1 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
The output of the script is basically a concatenation of several chunks of svnlook info output (see the section called “svnlook”) and will look something like this:
$ txn-info.sh myrepos ---[ Transaction 19 ]------------------------------------------- sally 2001-09-04 11:57:19 -0500 (Tue, 04 Sep 2001) 0 ---[ Transaction 3a1 ]------------------------------------------- harry 2001-09-10 16:50:30 -0500 (Mon, 10 Sep 2001) 39 Trying to commit over a faulty network. ---[ Transaction a45 ]------------------------------------------- sally 2001-09-12 11:09:28 -0500 (Wed, 12 Sep 2001) 0 $
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 "svnlook"), et ressemblera à quelque chose comme ça :
$ 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 pourri ---[ Transaction a45 ]------------------------------------------- sally 2001-09-12 11:09:28 -0500 (mer. 12 sep. 2001) 0 $
A long-abandoned transaction usually represents some sort of failed or interrupted commit. A transaction's datestamp can provide interesting information—for example, how likely is it that an operation begun nine months ago is still active?
In short, transaction cleanup decisions need not be made unwisely. Various sources of information—including Apache's error and access logs, Subversion's operational logs, Subversion revision history, and so on—can be employed in the decision-making process. And of course, an administrator can often simply communicate with a seemingly dead transaction's owner (via email, e.g.) to verify that the transaction is, in fact, in a zombie state.
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.
Sous-sous-titre 6
Until recently, the largest offender of disk space usage with respect to BDB-backed Subversion repositories were the logfiles in which Berkeley DB performs its prewrites before modifying the actual database files. These files capture all the actions taken along the route of changing the database from one state to another—while the database files, at any given time, reflect a particular state, the logfiles contain all of the many changes along the way between states. Thus, they can grow and accumulate quite rapidly.
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.
Fortunately, beginning with the 4.2 release of Berkeley DB, the database environment has the ability to remove its own unused logfiles automatically. Any repositories created using svnadmin when compiled against Berkeley DB version 4.2 or later will be configured for this automatic logfile removal. If you don't want this feature enabled, simply pass the --bdb-log-keep option to the svnadmin create command. If you forget to do this or change your mind at a later time, simply edit the DB_CONFIG file found in your repository's db directory, comment out the line that contains the set_flags DB_LOG_AUTOREMOVE directive, and then run svnadmin recover on your repository to force the configuration changes to take effect. See the section called “Berkeley DB Configuration” for more information about database configuration.
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) sera 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 DB_LOG_AUTOREMOVE puis lancez svnadmin recover sur votre dépôt pour que le changement de configuration prenne effet. Reportez-vous à la section "Configuration de la base de données Berkeley DB" pour plus d'informations sur la configuration du gestionnaire de bases de données.
Without some sort of automatic logfile removal in place, logfiles will accumulate as you use your repository. This is actually somewhat of a feature of the database system—you should be able to recreate your entire database using nothing but the logfiles, so these files can be useful for catastrophic database recovery. But typically, you'll want to archive the logfiles that are no longer in use by Berkeley DB, and then remove them from disk to conserve space. Use the svnadmin list-unused-dblogs command to list the unused logfiles:
$ svnadmin list-unused-dblogs /var/svn/repos /var/svn/repos/log.0000000031 /var/svn/repos/log.0000000032 /var/svn/repos/log.0000000033 … $ rm `svnadmin list-unused-dblogs /var/svn/repos` ## disk space reclaimed!
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, et donc 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 la place. 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é !
WARNING
- BDB-backed repositories whose logfiles are used as part of a backup or disaster recovery plan should not make use of the logfile autoremoval feature. Reconstruction of a repository's data from logfiles can only be accomplished only when all the logfiles are available. If some of the logfiles are removed from disk before the backup system has a chance to copy them elsewhere, the incomplete set of backed-up logfiles is essentially useless.
- Les dépôts BDB qui utilisent les fichiers de journalisation pour les sauvegardes ou les rétablissements après incident ne devraient 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.
Sous-titre 4
As mentioned in the section called “Berkeley DB”, a Berkeley DB repository can sometimes be left in a frozen state if not closed properly. When this happens, an administrator needs to rewind the database back into a consistent state. This is unique to BDB-backed repositories, though—if you are using FSFS-backed ones instead, this won't apply to you. And for those of you using Subversion 1.4 with Berkeley DB 4.4 or later, you should find that Subversion has become much more resilient in these types of situations. Still, wedged Berkeley DB repositories do occur, and an administrator needs to know how to safely deal with this circumstance.
Comme indiqué dans la section "Bases de données Berkeley DB", un dépôt Berkeley DB peut se retrouver bloqué s'il n'est pas fermé 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.
To protect the data in your repository, Berkeley DB uses a locking mechanism. This mechanism ensures that portions of the database are not simultaneously modified by multiple database accessors, and that each process sees the data in the correct state when that data is being read from the database. When a process needs to change something in the database, it first checks for the existence of a lock on the target data. If the data is not locked, the process locks the data, makes the change it wants to make, and then unlocks the data. Other processes are forced to wait until that lock is removed before they are permitted to continue accessing that section of the database. (This has nothing to do with the locks that you, as a user, can apply to versioned files within the repository; we try to clear up the confusion caused by this terminology collision in the sidebar The Three Meanings of “Lock”.)
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 levé 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 significations de "verrou").
In the course of using your Subversion repository, fatal errors or interruptions can prevent a process from having the chance to remove the locks it has placed in the database. The result is that the backend database system gets “wedged.” When this happens, any attempts to access the repository hang indefinitely (since each new accessor is waiting for a lock to go away—which isn't going to happen).
If this happens to your repository, don't panic. The Berkeley DB filesystem takes advantage of database transactions, checkpoints, and prewrite journaling to ensure that only the most catastrophic of events [33] can permanently destroy a database environment. A sufficiently paranoid repository administrator will have made off-site backups of the repository data in some fashion, but don't head off to the tape backup storage closet just yet.
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. A ce moment là, toutes les tentatives d'accès au dépôt se solderont 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 [33] soient à même de détruire définitivement un environnement de base de données. Un administrateur suffisamment paranoïaque conservera 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.
Instead, use the following recipe to attempt to “unwedge” your repository:
- Make sure no processes are accessing (or attempting to access) the repository. For networked repositories, this also means shutting down the Apache HTTP Server or svnserve daemon.
- Become the user who owns and manages the repository. This is important, as recovering a repository while running as the wrong user can tweak the permissions of the repository's files in such a way that your repository will still be inaccessible even after it is “unwedged.”
- Run the command svnadmin recover /var/svn/repos. You should see output such as this:
Repository lock acquired. Please wait; recovering the repository may take some time... Recovery completed. The latest repos revision is 19.
This command may take many minutes to complete.
- Restart the server process.
Au lieu de ça, appliquez donc la recette suivante pour tenter de "faire repartir" votre dépôt :
- 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.
- 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.
- Lancez la commande svnadmin recover /var/svn/depot. Vous devriez voir 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.
- Redémarrez le processus serveur.
This procedure fixes almost every case of repository wedging. Make sure that you run this command as the user that owns and manages the database, not just as root. Part of the recovery process might involve re-creating from scratch various database files (shared memory regions, e.g.). Recovering as root will create those files such that they are owned by root, which means that even after you restore connectivity to your repository, regular users will be unable to access it.
If the previous procedure, for some reason, does not successfully unwedge your repository, you should do two things. First, move your broken repository directory aside (perhaps by renaming it to something like repos.BROKEN) and then restore your latest backup of it. Then, send an email to the Subversion users mailing list (at <users@subversion.tigris.org>) describing your problem in detail. Data integrity is an extremely high priority to the Subversion developers.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 par root. La procédure de rétablissement peut impliquer de récréer en repartant 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 devriez faire deux choses. D'abord, mettez de côté votre répertoire de dépôt cassé (par exemple en le renommant depot.CASSE) puis restaurez la dernière sauvegarde de votre dépôt. Ensuite, envoyez un mail à la liste de diffusion des utilisateurs de Subversion (<users@subversion.tigris.org>) 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.
Sous-titre 5
A Subversion filesystem has its data spread throughout files in the repository, in a fashion generally understood by (and of interest to) only the Subversion developers themselves. However, circumstances may arise that call for all, or some subset, of that data to be copied or moved into another repository.
Subversion provides such functionality by way of repository dump streams. A repository dump stream (often referred to as a “dump file” when stored as a file on disk) is a portable, flat file format that describes the various revisions in your repository—what was changed, by whom, when, and so on. This dump stream is the primary mechanism used to marshal versioned history—in whole or in part, with or without modification—between repositories. And Subversion provides the tools necessary for creating and loading these dump streams: the svnadmin dump and svnadmin load subcommands, respectively.
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.
WARNING
- While the Subversion repository dump format contains human-readable portions and a familiar structure (it resembles an RFC 822 format, the same type of format used for most email), it is not a plain-text file format. It is a binary file format, highly sensitive to meddling. For example, many text editors will corrupt the file by automatically converting line endings.
- 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 vont corrompre le fichier en convertissant les caractères de fin de ligne.
There are many reasons for dumping and loading Subversion repository data. Early in Subversion's life, the most common reason was due to the evolution of Subversion itself. As Subversion matured, there were times when changes made to the backend database schema caused compatibility issues with previous versions of the repository, so users had to dump their repository data using the previous version of Subversion and load it into a freshly created repository with the new version of Subversion. Now, these types of schema changes haven't occurred since Subversion's 1.0 release, and the Subversion developers promise not to force users to dump and load their repositories when upgrading between minor versions (such as from 1.3 to 1.4) of Subversion. But there are still other reasons for dumping and loading, including re-deploying a Berkeley DB repository on a new OS or CPU architecture, switching between the Berkeley DB and FSFS backends, or (as we'll cover later in this chapter in the section called “Filtering Repository History”) purging versioned data from repository history.
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 (comme par exemple entre la version 1.3 et la version 1.4) de Subversion. Mais il y a toujours des raisons pour décharger et recharger ses données, y compris 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 verrons dans ce chapitre à la section "Filtrer l'historique d'un dépôt") la purge de données suivies en version de l'historique du dépôt.
NOTE
- The Subversion repository dump format describes versioned repository changes only. It will not carry any information about uncommitted transactions, user locks on filesystem paths, repository or server configuration customizations (including hook scripts), and so on.
- 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.
Whatever your reason for migrating repository history, using the svnadmin dump and svnadmin load subcommands is straightforward. svnadmin dump will output a range of repository revisions that are formatted using Subversion's custom filesystem dump format. The dump format is printed to the standard output stream, while informative messages are printed to the standard error stream. This allows you to redirect the output stream to a file while watching the status output in your terminal window. For example:
$ svnlook youngest myrepos 26 $ svnadmin dump myrepos > dumpfile * Dumped revision 0. * Dumped revision 1. * Dumped revision 2. … * Dumped revision 25. * Dumped revision 26.
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.
At the end of the process, you will have a single file (dumpfile in the previous example) that contains all the data stored in your repository in the requested range of revisions. Note that svnadmin dump is reading revision trees from the repository just like any other “reader” process would (e.g., svn checkout), so it's safe to run this command at any time.
A la fin de la procédure, vous obtiendrez un fichier unique (nommé 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.
The other subcommand in the pair, svnadmin load, parses the standard input stream as a Subversion repository dump file and effectively replays those dumped revisions into the target repository for that operation. It also gives informative feedback, this time using the standard output stream:
$ svnadmin load newrepos < dumpfile
<<< Started new txn, based on original revision 1
* adding path : A ... done.
* adding path : A/B ... done.
…
------- Committed new rev 1 (loaded from original rev 1) >>>
<<< Started new txn, based on original revision 2
* editing path : A/mu ... done.
* editing path : A/D/G/rho ... done.
------- Committed new rev 2 (loaded from original rev 2) >>>
…
<<< Started new txn, based on original revision 25
* editing path : A/D/gamma ... done.
------- Committed new rev 25 (loaded from original rev 25) >>>
<<< Started new txn, based on original revision 26
* adding path : A/Z/zeta ... done.
* editing path : A/mu ... done.
------- Committed new rev 26 (loaded from original rev 26) >>>
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
* ajout de : A ... fait.
* ajout de : A/B ... fait.
…
------- Révision 1 propagée (commit) >>>
<<< Début d'une nouvelle transaction basée sur la révision 2
* édition de : A/mu ... fait.
* édition de : 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 de : A/D/gamma ... fait.
------- Révision 25 propagée (commit) >>>
<<< Début d'une nouvelle transaction basée sur la révision 26
* ajout de : A/Z/zeta ... fait.
* édition de : A/mu ... fait.
------- Révision 26 propagée (commit) >>>
The result of a load is new revisions added to a repository—the same thing you get by making commits against that repository from a regular Subversion client. Just as in a commit, you can use hook programs to perform actions before and after each of the commits made during a load process. By passing the --use-pre-commit-hook and --use-post-commit-hook options to svnadmin load, you can instruct Subversion to execute the pre-commit and post-commit hook programs, respectively, for each loaded revision. You might use these, for example, to ensure that loaded revisions pass through the same validation steps that regular commits pass through. Of course, you should use these options with care—if your post-commit hook sends emails to a mailing list for each new commit, you might not want to spew hundreds or thousands of commit emails in rapid succession at that list! You can read more about the use of hook scripts in the section called “Implementing Repository Hooks”.
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 pré-propagation et post-propagation (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 script post-propagation envoie des mails à une liste de diffusion pour chaque nouvelle propagation, vous ne voulez peut-être pas envoyer des centaines voire des milliers de mails de notification à la suite à cette liste ! Vous pouvez en apprendre davantage sur l'utilisation des procédures automatiques dans la section "Mettre en place des procédures automatiques".
Note that because svnadmin uses standard input and output streams for the repository dump and load processes, people who are feeling especially saucy can try things such as this (perhaps even using different versions of svnadmin on each side of the pipe):
$ svnadmin create newrepos$ svnadmin dump oldrepos
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 pourront tenter des choses du genre (peut-être même en utilisant différentes versions de svnadmin de chaque côté du symbole pipe) :
$ svnadmin create nouveau-depot$ svnadmin dump vieux-depot
By default, the dump file will be quite large—much larger than the repository itself. That's because by default every version of every file is expressed as a full text in the dump file. This is the fastest and simplest behavior, and it's nice if you're piping the dump data directly into some other process (such as a compression program, filtering program, or loading process). But if you're creating a dump file for longer-term storage, you'll likely want to save disk space by using the --deltas option. With this option, successive revisions of files will be output as compressed, binary differences—just as file revisions are stored in a repository. This option is slower, but it results in a dump file much closer in size to the original repository.
Par défaut, le fichier dump prendra 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 seront écrites en tant que différences binaires et compressées - de la même manière que sont stockés les 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.
We mentioned previously that svnadmin dump outputs a range of revisions. Use the --revision (-r) option to specify a single revision, or a range of revisions, to dump. If you omit this option, all the existing repository revisions will be dumped.
$ svnadmin dump myrepos -r 23 > rev-23.dumpfile $ svnadmin dump myrepos -r 100:200 > revs-100-200.dumpfile
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 seront affichées :
$ svnadmin dump mon-depot -r 23 > fichier-dump.rev-23 $ svnadmin dump mon-depot -r 100:200 > fichier-dump.revs-100-200
As Subversion dumps each new revision, it outputs only enough information to allow a future loader to re-create that revision based on the previous one. In other words, for any given revision in the dump file, only the items that were changed in that revision will appear in the dump. The only exception to this rule is the first revision that is dumped with the current svnadmin dump command.
By default, Subversion will not express the first dumped revision as merely differences to be applied to the previous revision. For one thing, there is no previous revision in the dump file! And second, Subversion cannot know the state of the repository into which the dump data will be loaded (if it ever is). To ensure that the output of each execution of svnadmin dump is self-sufficient, the first dumped revision is, by default, a full representation of every directory, file, and property in that revision of the repository.
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 est la première révision qui est déchargée par la commande svnadmin dump courante.
Par défaut, Subversion n'exprimera 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 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.
However, you can change this default behavior. If you add the --incremental option when you dump your repository, svnadmin will compare the first dumped revision against the previous revision in the repository—the same way it treats every other revision that gets dumped. It will then output the first revision exactly as it does the rest of the revisions in the dump range—mentioning only the changes that occurred in that revision. The benefit of this is that you can create several small dump files that can be loaded in succession, instead of one large one, like so:
$ svnadmin dump myrepos -r 0:1000 > dumpfile1 $ svnadmin dump myrepos -r 1001:2000 --incremental > dumpfile2 $ svnadmin dump myrepos -r 2001:3000 --incremental > dumpfile3
These dump files could be loaded into a new repository with the following command sequence:
$ svnadmin load newrepos < dumpfile1 $ svnadmin load newrepos < dumpfile2 $ svnadmin load newrepos < dumpfile3
Vous pouvez toujours modifier ce comportement par défaut. Si vous ajoutez l'option --incremental quand vous déchargez le dépôt, svnadmin comparera 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 affichera 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-dump.1 $ svnadmin dump mon-depot -r 1001:2000 --incremental > fichier-dump.2 $ svnadmin dump mon-depot -r 2001:3000 --incremental > fichier-dump.3
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-dump.1 $ svnadmin load nouveau-depot < fichier-dump.2 $ svnadmin load nouveau-depot < fichier-dump.3
Another neat trick you can perform with this --incremental option involves appending to an existing dump file a new range of dumped revisions. For example, you might have a post-commit hook that simply appends the repository dump of the single revision that triggered the hook. Or you might have a script that runs nightly to append dump file data for all the revisions that were added to the repository since the last time the script ran. Used like this, svnadmin dump can be one way to back up changes to your repository over time in case of a system crash or some other catastrophic event.
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-propagation 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.
The dump format can also be used to merge the contents of several different repositories into a single repository. By using the --parent-dir option of svnadmin load, you can specify a new virtual root directory for the load process. That means if you have dump files for three repositories—say calc-dumpfile, cal-dumpfile, and ss-dumpfile—you can first create a new repository to hold them all:
$ svnadmin create /var/svn/projects $
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. Cela signifie que si vous avez des fichiers dump pour trois dépôts -- disons fichier-dump-calc, fichier-dump-cal et fichier-dump-tab -- vous pouvez d'abord créer un nouveau dépôt pour les héberger tous :
$ svnadmin create /var/svn/projets $
Then, make new directories in the repository that will encapsulate the contents of each of the three previous repositories:
$ svn mkdir -m "Initial project roots" \
file:///var/svn/projects/calc \
file:///var/svn/projects/calendar \
file:///var/svn/projects/spreadsheet
Committed revision 1.
$
Lastly, load the individual dump files into their respective locations in the new repository:
$ svnadmin load /var/svn/projects --parent-dir calc < calc-dumpfile … $ svnadmin load /var/svn/projects --parent-dir calendar < cal-dumpfile … $ svnadmin load /var/svn/projects --parent-dir spreadsheet < ss-dumpfile … $
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 son répertoire respectif 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 tableur < fichier-dump-tab … $
We'll mention one final way to use the Subversion repository dump format—conversion from a different storage mechanism or version control system altogether. Because the dump file format is, for the most part, human-readable, it should be relatively easy to describe generic sets of changes—each of which should be treated as a new revision—using this file format. In fact, the cvs2svn utility (see the section called “Converting a Repository from CVS to Subversion”) uses the dump format to represent the contents of a CVS repository so that those contents can be copied into a Subversion repository.
Mentionnons une dernière façon d'utiliser les fichiers dump de Subversion - la conversion depuis un système de stockage différent ou depuis un autre système de suivi de versions. Comme le format des fichiers dump est, pour sa plus grande partie, lisible par un humain, il devrait être relativement facile de décrire des ensembles de modifications - chaque ensemble constituant une nouvelle révision - en utilisant ce format de fichier. En fait, l'utilitaire cvs2svn (voir la section "Convertir un dépôt CVS vers Subversion") utilise le format dump pour représenter le contenu d'un dépôt CVS, de manière à pouvoir copier ce contenu vers un dépôt Subversion.
Sous-titre 6
Since Subversion stores your versioned history using, at the very least, binary differencing algorithms and data compression (optionally in a completely opaque database system), attempting manual tweaks is unwise if not quite difficult, and at any rate strongly discouraged. And once data has been stored in your repository, Subversion generally doesn't provide an easy way to remove that data. [34] But inevitably, there will be times when you would like to manipulate the history of your repository. You might need to strip out all instances of a file that was accidentally added to the repository (and shouldn't be there for whatever reason). [35] Or, perhaps you have multiple projects sharing a single repository, and you decide to split them up into their own repositories. To accomplish tasks such as these, administrators need a more manageable and malleable representation of the data in their repositories—the Subversion repository dump format.
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, en option, dans un système de gestion de bases de données complètement opaque), il est malavisé 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 [34]. Mais, inévitablement, il y a des cas où vous voudrez 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) [35]. Ou peut-être avez-vous plusieurs projets qui partagent le même dépôt et vous déciderez de leur attribuer chacun le leur. Pour accomplir ce genre de tâches, les administrateurs ont besoin d'une représentation plus souple et plus facile à gérer de leurs données dans les dépôts : les fichiers dump Subversion.
As we described earlier in the section called “Migrating Repository Data Elsewhere”, the Subversion repository dump format is a human-readable representation of the changes that you've made to your versioned data over time. Use the svnadmin dump command to generate the dump data, and svnadmin load to populate a new repository with it. The great thing about the human-readability aspect of the dump format is that, if you aren't careless about it, you can manually inspect and modify it. Of course, the downside is that if you have three years' worth of repository activity encapsulated in what is likely to be a very large dump file, it could take you a long, long time to manually inspect and modify it.
Comme indiqué précédemment dans la section "Migrer les 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 version. Utilisez la commande svnadmin dump pour extraire les données et svnadmin 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.
That's where svndumpfilter becomes useful. This program acts as a path-based filter for repository dump streams. Simply give it either a list of paths you wish to keep or a list of paths you wish to not keep, and then pipe your repository dump data through this filter. The result will be a modified stream of dump data that contains only the versioned paths you (explicitly or implicitly) requested.
C'est là qu'intervient svndumpfilter. Ce programme agit comme un filtre sur les chemins pour les flux de déchargement/chargement dump 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 obtiendrez un flux modifié qui ne contient que les données versionnées des chemins que vous avez demandés (explicitement ou implicitement).
Let's look at a realistic example of how you might use this program. Earlier in this chapter (see the section called “Planning Your Repository Organization”), we discussed the process of deciding how to choose a layout for the data in your repositories—using one repository per project or combining them, arranging stuff within your repository, and so on. But sometimes after new revisions start flying in, you rethink your layout and would like to make some changes. A common change is the decision to move multiple projects that are sharing a single repository into separate repositories for each project.
Prenons un exemple concret d'utilisation de ce programme. Plus tôt dans ce chapitre (voir la section "Prévoir l'organisation de votre dépôt"), nous avons décrit le processus de décision pour 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.
Our imaginary repository contains three projects: calc, calendar, and spreadsheet. They have been living side-by-side in a layout like this:
/
calc/
trunk/
branches/
tags/
calendar/
trunk/
branches/
tags/
spreadsheet/
trunk/
branches/
tags/
To get these three projects into their own repositories, we first dump the whole repository:
$ svnadmin dump /var/svn/repos > repos-dumpfile * Dumped revision 0. * Dumped revision 1. * Dumped revision 2. * Dumped revision 3. … $
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 propres dépôts, 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. … $
Next, run that dump file through the filter, each time including only one of our top-level directories. This results in three new dump files:
$ svndumpfilter include calc < repos-dumpfile > calc-dumpfile … $ svndumpfilter include calendar < repos-dumpfile > cal-dumpfile … $ svndumpfilter include spreadsheet < repos-dumpfile > ss-dumpfile … $
Ensuite, nous passons ce fichier dump à travers le filtre, en 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 … $
At this point, you have to make a decision. Each of your dump files will create a valid repository, but will preserve the paths exactly as they were in the original repository. This means that even though you would have a repository solely for your calc project, that repository would still have a top-level directory named calc. If you want your trunk, tags, and branches directories to live in the root of your repository, you might wish to edit your dump files, tweaking the Node-path and Node-copyfrom-path headers so that they no longer have that first calc/ path component. Also, you'll want to remove the section of dump data that creates the calc directory. It will look something like the following:
Node-path: calc Node-action: add Node-kind: dir Content-length: 0
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 appelé calc. Si vous voulez que les répertoires trunk, tags et branches soient placés à la racine de votre dépôt, vous voudrez peut-être é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 voudrez également supprimer la section des données qui crée le répertoire calc. Elle ressemblera à quelque chose comme ça :
Node-path: calc Node-action: add Node-kind: dir Content-length: 0
WARNING
- If you do plan on manually editing the dump file to remove a top-level directory, make sure your editor is not set to automatically convert end-of-line characters to the native format (e.g., \r\n to \n), as the content will then not agree with the metadata. This will render the dump file useless.
- 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) puisque le contenu ne serait alors plus conforme aux métadonnées. Cela corromprait le fichier dump de manière irréversible.
All that remains now is to create your three new repositories, and load each dump file into the right repository, ignoring the UUID found in the dump stream:
$ svnadmin create calc
$ svnadmin load --ignore-uuid calc < calc-dumpfile
<<< Started new transaction, based on original revision 1
* adding path : Makefile ... done.
* adding path : button.c ... done.
…
$ svnadmin create calendar
$ svnadmin load --ignore-uuid calendar < cal-dumpfile
<<< Started new transaction, based on original revision 1
* adding path : Makefile ... done.
* adding path : cal.c ... done.
…
$ svnadmin create spreadsheet
$ svnadmin load --ignore-uuid spreadsheet < ss-dumpfile
<<< Started new transaction, based on original revision 1
* adding path : Makefile ... done.
* adding path : ss.c ... done.
…
$
Tout ce qu'il reste à faire maintenant, 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
* ajout de : Makefile ... fait.
* ajout de : 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
* ajout de : Makefile ... fait.
* ajout de : 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
* ajout de : Makefile ... fait.
* ajout de : tableur.c ... fait.
…
$
Both of svndumpfilter's subcommands accept options for deciding how to deal with “empty” revisions. If a given revision contains only changes to paths that were filtered out, that now-empty revision could be considered uninteresting or even unwanted. So to give the user control over what to do with those revisions, svndumpfilter provides the following command-line options:
- --drop-empty-revs
- Do not generate empty revisions at all—just omit them.
- --renumber-revs
- If empty revisions are dropped (using the --drop-empty-revs option), change the revision numbers of the remaining revisions so that there are no gaps in the numeric sequence.
- --preserve-revprops
- If empty revisions are not dropped, preserve the revision properties (log message, author, date, custom properties, etc.) for those empty revisions. Otherwise, empty revisions will contain only the original datestamp, and a generated log message that indicates that this revision was emptied by svndumpfilter.
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 pourrait être considérée comme inintéressante voire indésirable. Pour permettre à l'utilisateur de décider que faire de telles révisions, svndumpfilter fournit 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 contiendront que l'horodatage original et un message expliquant que c'est à cause de svndumpfilter que cette révision est vide.
While svndumpfilter can be very useful and a huge timesaver, there are unfortunately a couple of gotchas. First, this utility is overly sensitive to path semantics. Pay attention to whether paths in your dump file are specified with or without leading slashes. You'll want to look at the Node-path and Node-copyfrom-path headers.
… Node-path: spreadsheet/Makefile …
If the paths have leading slashes, you should include leading slashes in the paths you pass to svndumpfilter include and svndumpfilter exclude (and if they don't, you shouldn't). Further, if your dump file has an inconsistent usage of leading slashes for some reason, [36] you should probably normalize those paths so that they all have, or all lack, leading slashes.
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 devriez 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 [36], vous devriez probablement normaliser les chemins en adoptant une des deux conventions.
Also, copied paths can give you some trouble. Subversion supports copy operations in the repository, where a new path is created by copying some already existing path. It is possible that at some point in the lifetime of your repository, you might have copied a file or directory from some location that svndumpfilter is excluding, to a location that it is including. To make the dump data self-sufficient, svndumpfilter needs to still show the addition of the new path—including the contents of any files created by the copy—and not represent that addition as a copy from a source that won't exist in your filtered dump data stream. But because the Subversion repository dump format shows only what was changed in each revision, the contents of the copy source might not be readily available. If you suspect that you have any copies of this sort in your repository, you might want to rethink your set of included/excluded paths, perhaps including the paths that served as sources of your troublesome copy operations, too.
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.
Finally, svndumpfilter takes path filtering quite literally. If you are trying to copy the history of a project rooted at trunk/my-project and move it into a repository of its own, you would, of course, use the svndumpfilter include command to keep all the changes in and under trunk/my-project. But the resultant dump file makes no assumptions about the repository into which you plan to load this data. Specifically, the dump data might begin with the revision that added the trunk/my-project directory, but it will not contain directives that would create the trunk directory itself (because trunk doesn't match the include filter). You'll need to make sure that any directories that the new dump stream expects to exist actually do exist in the target repository before trying to load the stream into that repository.
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 que 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 pourront 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 devrez 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 cible, avant d'essayer de charger le flux de données à l'intérieur.
Sous-titre 7
There are several scenarios in which it is quite handy to have a Subversion repository whose version history is exactly the same as some other repository's. Perhaps the most obvious one is the maintenance of a simple backup repository, used when the primary repository has become inaccessible due to a hardware failure, network outage, or other such annoyance. Other scenarios include deploying mirror repositories to distribute heavy Subversion load across multiple servers, use as a soft-upgrade mechanism, and so on.
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.
As of version 1.4, Subversion provides a program for managing scenarios such as these—svnsync. This works by essentially asking the Subversion server to “replay” revisions, one at a time. It then uses that revision information to mimic a commit of the same to another repository. Neither repository needs to be locally accessible to the machine on which svnsync is running—its parameters are repository URLs, and it does all its work through Subversion's Repository Access (RA) interfaces. All it requires is read access to the source repository and read/write access to the destination repository.
Depuis la version 1.4, Subversion fournit un programme pour gérer de tels scénarios : svnsync. Il fonctionne essentiellement en demandant au serveur Subversion de parcourir 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 Repository Access (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
- When using svnsync against a remote source repository, the Subversion server for that repository must be running Subversion version 1.4 or later.
- 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.
Assuming you already have a source repository that you'd like to mirror, the next thing you need is an empty target repository that will actually serve as that mirror. This target repository can use either of the available filesystem data-store backends (see the section called “Choosing a Data Store”), but it must not yet have any version history in it. The protocol that svnsync uses to communicate revision information is highly sensitive to mismatches between the versioned histories contained in the source and target repositories. For this reason, while svnsync cannot demand that the target repository be read-only, [37] allowing the revision history in the target repository to change by any mechanism other than the mirroring process is a recipe for disaster.
Supposons que vous vouliez réaliser un miroir d'un de vos dépôts ; il vous faut alors disposer d'un dépôt cible vide qui servira de miroir. Ce dépôt cible peut utiliser n'importe quel magasin de données disponible (voir la section "Choisir un magasin de données") mais il ne doit avoir aucun historique. Le protocole utilisé par svnsync pour transmettre les informations de révision est particulièrement sensible aux divergences entre les historiques versionnés de la source et de la cible. Pour cette raison, bien que svnsync ne puisse pas exiger que le dépôt cible soit en lecture seule [37], autoriser des modifications d'historique sur le dépôt cible par un mécanisme externe autre que le processus de réplication mènera droit au désastre.
WARNING
- Do not modify a mirror repository in such a way as to cause its version history to deviate from that of the repository it mirrors. The only commits and revision property modifications that ever occur on that mirror repository should be those performed by the svnsync tool.
- Ne modifiez pas un 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.
Another requirement of the target repository is that the svnsync process be allowed to modify revision properties. Because svnsync works within the framework of that repository's hook system, the default state of the repository (which is to disallow revision property changes; see pre-revprop-change) is insufficient. You'll need to explicitly implement the pre-revprop-change hook, and your script must allow svnsync to set and change revision properties. With those provisions in place, you are ready to start mirroring repository revisions.
Une autre exigence concernant le dépôt cible 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) n'est pas suffisant. Vous devrez activer explicitement la procédure 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.
TIP
- It's a good idea to implement authorization measures that allow your repository replication process to perform its tasks while preventing other users from modifying the contents of your mirror repository at all.
- 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.
Let's walk through the use of svnsync in a somewhat typical mirroring scenario. We'll pepper this discourse with practical recommendations, which you are free to disregard if they aren't required by or suitable for your environment.
As a service to the fine developers of our favorite version control system, we will be mirroring the public Subversion source code repository and exposing that mirror publicly on the Internet, hosted on a different machine than the one on which the original Subversion source code repository lives. This remote host has a global configuration that permits anonymous users to read the contents of repositories on the host, but requires users to authenticate to modify those repositories. (Please forgive us for glossing over the details of Subversion server configuration for the moment—those are covered thoroughly in Chapter 6, Server Configuration.) And for no other reason than that it makes for a more interesting example, we'll be driving the replication process from a third machine—the one that we currently find ourselves using.
Examinons l'utilisation de svnsync dans un scénario classique de réplication. Nous saupoudrerons le discours de quelques recommandations pratiques que vous serez libre d'ignorer si elles ne sont pas nécessaires ou pas applicables à votre environnement.
Pour rendre service aux excellents développeurs de notre système de gestion de versions favori, nous allons répliquer le dépôt public qui contient le code source de Subversion 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 ça, nous piloterons la réplication depuis une troisième machine - en l'occurrence, celle que nous sommes en train d'utiliser.
First, we'll create the repository which will be our mirror. This and the next couple of steps do require shell access to the machine on which the mirror repository will live. Once the repository is all configured, though, we shouldn't need to touch it directly again.
$ ssh admin@svn.example.com \
"svnadmin create /var/svn/svn-mirror"
admin@svn.example.com's password: ********
$
At this point, we have our repository, and due to our server's configuration, that repository is now “live” on the Internet. Now, because we don't want anything modifying the repository except our replication process, we need a way to distinguish that process from other would-be committers. To do so, we use a dedicated username for our process. Only commits and revision property modifications performed by the special username syncuser will be allowed.
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: ********
$
A 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 utiliserons 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 seront autorisées.
We'll use the repository's hook system both to allow the replication process to do what it needs to do and to enforce that only it is doing those things. We accomplish this by implementing two of the repository event hooks—pre-revprop-change and start-commit. Our pre-revprop-change hook script is found in Example 5.2, “Mirror repository's pre-revprop-change hook script”, and basically verifies that the user attempting the property changes is our syncuser user. If so, the change is allowed; otherwise, it is denied.
Nous allons utiliser le système de procédures automatiques (hook) 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émenterons donc deux des procédures automatiques du dépôt : pre-revprop-change et start-commit. Notre script pre-revprop-change est présenté dans l'exemple 5.2 - "Procédure automatique pre-revprop-change du dépôt miroir" et, en gros, 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.
- Example 5.2. Mirror repository's pre-revprop-change hook script
#!/bin/sh USER="$3" if [ "$USER" = "syncuser" ]; then exit 0; fi echo "Only the syncuser user may change revision properties" >&2 exit 1
That covers revision property changes. Now we need to ensure that only the syncuser user is permitted to commit new revisions to the repository. We do this using a start-commit hook scripts such as the one in Example 5.3, “Mirror repository's start-commit hook script”.
- Exemple 5.2. 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 fournie dans l'exemple 5.3 "Procédure automatique start-commit d'un dépôt miroir"
- Example 5.3. Mirror repository's start-commit hook script
#!/bin/sh USER="$2" if [ "$USER" = "syncuser" ]; then exit 0; fi echo "Only the syncuser user may commit new revisions" >&2 exit 1
After installing our hook scripts and ensuring that they are executable by the Subversion server, we're finished with the setup of the mirror repository. Now, we get to actually do the mirroring.
- Exemple 5.3."Procédure automatique start-commit d'un 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.
The first thing we need to do with svnsync is to register in our target repository the fact that it will be a mirror of the source repository. We do this using the svnsync initialize subcommand. The URLs we provide point to the root directories of the target and source repositories, respectively. In Subversion 1.4, this is required—only full mirroring of repositories is permitted. In Subversion 1.5, though, you can use svnsync to mirror only some subtree of the repository, too.
$ svnsync help init initialize (init): usage: svnsync initialize DEST_URL SOURCE_URL Initialize a destination repository for synchronization from another repository. … $ svnsync initialize http://svn.example.com/svn-mirror \ http://svn.collab.net/repos/svn \ --sync-username syncuser --sync-password syncpass Copied properties for revision 0. $
La première chose à faire avec svnsync est d'enregistrer dans notre dépôt cible le fait qu'il sera un miroir du dépôt source. Pour ce faire nous utiliserons la sous-commande svnsync initialize. Nous fournirons des URL qui pointent vers les répertoires racines des dépôts cible et source, respectivement. Dans Subversion 1.4, c'est obligatoire - seule la réplication de dépôts complets est permise. Dans Subversion 1.5, cependant, vous pouvez aussi utiliser svnsync pour répliquer uniquement des sous-arborescence 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.collab.net/repos/svn \ --sync-username id-sync --sync-password mot-de-passe-sync Propriétés copiées pour la révision 0. $
Our target repository will now remember that it is a mirror of the public Subversion source code repository. Notice that we provided a username and password as arguments to svnsync—that was required by the pre-revprop-change hook on our mirror repository.
Notre dépôt cible se rappellera maintenant qu'il est un miroir du dépôt public du code source Subversion. 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
- In Subversion 1.4, the values given to svnsync's --username and --password command-line options were used for authentication against both the source and destination repositories. This caused problems when a user's credentials weren't exactly the same for both repositories, especially when running in noninteractive mode (with the --non-interactive option).
- This has been fixed in Subversion 1.5 with the introduction of two new pairs of options. Use --source-username and --source-password to provide authentication credentials for the source repository; use --sync-username and --sync-password to provide credentials for the destination repository. (The old --username and --password options still exist for compatibility, but we advise against using them.)
- Dans Subversion 1.4, les valeurs passé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 cible. Cela posait des problèmes quand ces valeurs n'étaient pas exactement les mêmes 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 cible (les vieilles options --username et --password existent encore pour assurer la compatibilité mais nous les déconseillons).
And now comes the fun part. With a single subcommand, we can tell svnsync to copy all the as-yet-unmirrored revisions from the source repository to the target. [38] The svnsync synchronize subcommand will peek into the special revision properties previously stored on the target repository, and determine both what repository it is mirroring as well as that the most recently mirrored revision was revision 0. Then it will query the source repository and determine what the latest revision in that repository is. Finally, it asks the source repository's server to start replaying all the revisions between 0 and that latest revision. As svnsync get the resultant response from the source repository's server, it begins forwarding those revisions to the target repository's server as new commits.
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 cible [38]. La sous-commande svnsync synchronize fouillera dans les propriétés de révision spéciales du dépôt cible pour déterminer aussi bien de quel dépôt source il est le miroir que la dernière révision qui a été répliquée, en l'occurrence la révision 0. Ensuite, elle interrogera le dépôt source pour savoir quelle est la dernière révision propagée dans ce dépôt. Enfin, elle demandera 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 recevra la réponse du dépôt source, elle commencera la retransmission des révisions vers le dépôt cible en tant que nouvelles propagations.
$ svnsync help synchronize synchronize (sync): usage: svnsync synchronize DEST_URL Transfer all pending revisions to the destination from the source with which it was initialized. … $ svnsync synchronize http://svn.example.com/svn-mirror Transmitting file data ........................................ Committed revision 1. Copied properties for revision 1. Transmitting file data .. Committed revision 2. Copied properties for revision 2. Transmitting file data ..... Committed revision 3. Copied properties for revision 3. … Transmitting file data .. Committed revision 23406. Copied properties for revision 23406. Transmitting file data . Committed revision 23407. Copied properties for revision 23407. Transmitting file data .... Committed revision 23408. Copied properties for revision 23408. $
$ svnsync help synchronize synchronize (sync): usage : svnsync synchronize URL_DEST Transfère toutes les révisions en attente vers la destination, à partir de la source avec laquelle elle a été initialisée. … $ svnsync synchronize http://svn.exemple.com/miroir-svn 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 23406 propagée. Propriétés copiées pour la révision 23406. Transmission des données . Révision 23407 propagée. Propriétés copiées pour la révision 23407. Transmission des données .... Révision 23408 propagée. Propriétés copiées pour la révision 23408. $
Of particular interest here is that for each mirrored revision, there is first a commit of that revision to the target repository, and then property changes follow. This is because the initial commit is performed by (and attributed to) the user syncuser, and it is datestamped with the time as of that revision's creation. Also, Subversion's underlying repository access interfaces don't provide a mechanism for setting arbitrary revision properties as part of a commit. So svnsync follows up with an immediate series of property modifications that copy into the target repository all the revision properties found for that revision in the source repository. This also has the effect of fixing the author and datestamp of the revision to match that of the source repository.
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 cible, 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 cible 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.
Also noteworthy is that svnsync performs careful bookkeeping that allows it to be safely interrupted and restarted without ruining the integrity of the mirrored data. If a network glitch occurs while mirroring a repository, simply repeat the svnsync synchronize command, and it will happily pick up right where it left off. In fact, as new revisions appear in the source repository, this is exactly what you to do to keep your mirror up to date.
A noter é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 exactement ce qu'il faut faire pour conserver votre miroir à jour.
Titre
svnsync Bookkeeping
Propriétés propres à svnsync
- svnsync needs to be able to set and modify revision properties on the mirror repository because those properties are part of the data it is tasked with mirroring. As those properties change in the source repository, those changes need to be reflected in the mirror repository, too. But svnsync also uses a set of custom revision properties—stored in revision 0 of the mirror repository—for its own internal bookkeeping. These properties contain information such as the URL and UUID of the source repository, plus some additional state-tracking information.
- svnsync a besoin de pouvoir définir et modifier des propriétés de révision dans le dépôt miroir car ces propriétés font partie intégrante des données à répliquer. Au fur et à mesure que ces propriétés changent dans le dépôt source, ces changements doivent également être répliqués dans le dépôt miroir. Mais svnsync utilise aussi un ensemble de propriétés de révision qui lui sont propres - stockées dans la révision 0 du dépôt miroir - à ses propres fins de journalisation. Ces propriétés contiennent des informations telles que l'URL et l'UUID du dépôt source, ainsi que quelques informations supplémentaires sur l'état du miroir.
- One of those pieces of state-tracking information is a flag that essentially just means “there's a synchronization in progress right now.” This is used to prevent multiple svnsync processes from colliding with each other while trying to mirror data to the same destination repository. Now, generally you won't need to pay any attention whatsoever to any of these special properties (all of which begin with the prefix svn:sync-). Occasionally, though, if a synchronization fails unexpectedly, Subversion never has a chance to remove this particular state flag. This causes all future synchronization attempts to fail because it appears that a synchronization is still in progress when, in fact, none is. Fortunately, recovering from this situation is as simple as removing the svn:sync-lock property which serves as this flag from revision 0 of the mirror repository:
$ svn propdel --revprop -r0 svn:sync-lock http://svn.example.com/svn-mirror property 'svn:sync-lock' deleted from repository revision 0 $
- Une de ces informations sur l'état du miroir est un drapeau indiquant, essentiellement, qu'"il y a une synchronisation en cours". Il est utilisé pour éviter que de multiples processus svnsync entrent en collision en essayant de répliquer les données vers le même dépôt cible. Quoi qu'il en soit, vous n'aurez généralement pas à vous soucier de ces propriétés spéciales (elles commencent toutes par le préfixe svn:sync-). Occasionnellement, cependant, si une synchronisation échoue accidentellement, Subversion ne pourra pas enlever ce drapeau indiquant l'état de la synchronisation. Cela fera échouer toute nouvelle tentative de synchronisation puisque le drapeau indique qu'une synchronisation est en cours, alors que ce n'est pas le cas. Heureusement, sortir de cette situation est aussi simple que supprimer la propriété svn:sync-lock de la révision 0 du dépôt miroir (c'est le fameux drapeau) :
$ svn propdel --revprop -r0 svn:sync-lock http://svn.exemple.com/miroir-svn Propriété 'svn:sync-lock' supprimée de la révision 0 du dépôt $
- That svnsync stores the source repository URL in a bookkeeping property on the mirror repository is the reason why you have to specify that URL only once, during svnsync init. Future synchronization operations against that mirror simply consult the special svn:sync-from-url property stored on the mirror itself to know where to synchronize from. This value is used literally by the synchronization process, though. So while from within CollabNet's network you can perhaps access our example source URL as http://svn/repos/svn (because that first svn magically gets .collab.net appended to it by DNS voodoo), if you later need to update that mirror from another machine outside CollabNet's network, the synchronization might fail (because the hostname svn is ambiguous). For this reason, it's best to use fully qualified source repository URLs when initializing a mirror repository rather than those that refer to only hostnames or IP addresses (which can change over time). But here again, if you need an existing mirror to start referring to a different URL for the same source repository, you can change the bookkeeping property which houses that information:
$ svn propset --revprop -r0 svn:sync-from-url NEW-SOURCE-URL \
http://svn.example.com/svn-mirror
property 'svn:sync-from-url' set on repository revision 0
$
- Le fait que svnsync stocke l'URL du dépôt source dans une propriété qui lui est dédiée au sein du dépôt cible est la raison pour laquelle vous n'avez à renseigner cette URL qu'une seule fois, pendant svnsync init. Les opérations suivantes de synchronisation de ce miroir se contentent de consulter la propriété svn:sync-from-url stockée dans le dépôt miroir lui-même pour déterminer la source de la synchronisation. Notez bien que cette valeur est utilisée telle quelle par le processus de synchronisation. Ainsi, depuis l'intérieur du réseau CollabNet vous pouvez peut-être accéder à notre URL source http://svn/depot/svn (parce que le premier svn se voit ajouter .collab.net par la magie du serveur DNS), mais, si vous devez mettre à jour le miroir plus tard depuis une machine en dehors du réseau CollabNet, la synchronisation risque d'échouer (parce que le nom de machine svn est ambigu). Pour cette raison, il est préférable d'utiliser le nom complet pour l'URL du dépôt source lors de l'initialisation de votre dépôt miroir plutôt que simplement le nom de machine ou l'adresse IP (qui peut varier au cours du temps). Là encore, si vous devez changer l'URL de la source (ayant le même contenu) d'un dépôt miroir existant, vous pouvez changer la propriété de journalisation qui stocke cette information :
$ svn propset --revprop -r0 svn:sync-from-url NOUVELLE-URL-SOURCE \
http://svn.exemple.com/miroir-svn
Propriété 'svn:sync-from-url' définie à la révision 0 du dépôt
$
- Another interesting thing about these special bookkeeping properties is that svnsync will not attempt to mirror any of those properties when they are found in the source repository. The reason is probably obvious, but basically boils down to svnsync not being able to distinguish the special properties it has merely copied from the source repository from those it needs to consult and maintain for its own bookkeeping needs. This situation could occur if, for example, you were maintaining a mirror of a mirror of a third repository. When svnsync sees its own special properties in revision 0 of the source repository, it simply ignores them.
- Un autre point intéressant concernant ces propriétés liées à la synchronisation est que svnsync n'essaiera pas de répliquer ces propriétés s'il les trouve dans le dépôt source. La raison est probablement évidente, mais est due en résumé au fait que svnsync n'est pas capable de distinguer les propriétés spéciales qu'il n'a fait que copier à partir du dépôt source de celles qu'il doit consulter et tenir à jour pour ses propres besoins. Cette situation peut arriver si, par exemple, vous hébergez le miroir du miroir d'un dépôt. Quand svnsync voit ses propres propriétés de syncrhonisation dans la révision 0 du dépôt source, il les ignore purement et simplement.
There is, however, one bit of inelegance in the process. Because Subversion revision properties can be changed at any time throughout the lifetime of the repository, and because they don't leave an audit trail that indicates when they were changed, replication processes have to pay special attention to them. If you've already mirrored the first 15 revisions of a repository and someone then changes a revision property on revision 12, svnsync won't know to go back and patch up its copy of revision 12. You'll need to tell it to do so manually by using (or with some additional tooling around) the svnsync copy-revprops subcommand, which simply rereplicates all the revision properties for a particular revision or range thereof.
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 saura pas qu'il faut revenir en arrière et modifier la copie de la révision 12. Vous devrez le lui indiquer manuellement en utilisant la sous-commande svnsync copy-revprops (ou à l'aide d'autres outils), ce qui re-répliquera toutes les propriétés de révision pour une révision particulière ou un ensemble de révisions.
$ svnsync help copy-revprops copy-revprops: usage: svnsync copy-revprops DEST_URL [REV[:REV2]] Copy the revision properties in a given range of revisions to the destination from the source with which it was initialized. … $ svnsync copy-revprops http://svn.example.com/svn-mirror 12 Copied properties for revision 12. $
That's repository replication in a nutshell. You'll likely want some automation around such a process. For example, while our example was a pull-and-push setup, you might wish to have your primary repository push changes to one or more blessed mirrors as part of its post-commit and post-revprop-change hook implementations. This would enable the mirror to be up to date in as near to real time as is likely possible.
$ svnsync help copy-revprops copy-revprops: usage : svnsync copy-revprops URL_DEST [REV[:REV2]] Copie les propriétés de révision pour l'intervalle donné vers la destination à partir de la source avec laquelle elle a été initialisée. … $ svnsync copy-revprops http://svn.exemple.com/miroir-svn 12 Propriétés copiées pour la révision 12. $
Voilà pour une 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-propagation et post-revprop-change. Ceci permettrait au miroir d'être à jour presque en temps réel.
Also, while it isn't very commonplace to do so, svnsync does gracefully mirror repositories in which the user as whom it authenticates has only partial read access. It simply copies only the bits of the repository that it is permitted to see. Obviously, such a mirror is not useful as a backup solution.
In Subversion 1.5, svnsync grew the ability to also mirror a subset of a repository rather than the whole thing. The process of setting up and maintaining such a mirror is exactly the same as when mirroring a whole repository, except that instead of specifying the source repository's root URL when running svnsync init, you specify the URL of some subdirectory within that repository. Synchronization to that mirror will now copy only the bits that changed under that source repository subdirectory. There are some limitations to this support, though. First, you can't mirror multiple disjoint subdirectories of the source repository into a single mirror repository—you'd need to instead mirror some parent directory that is common to both. Second, the filtering logic is entirely path-based, so if the subdirectory you are mirroring was renamed at some point in the past, your mirror would contain only the revisions since the directory appeared at the URL you specified. And likewise, if the source subdirectory is renamed in the future, your synchronization processes will stop mirroring data at the point that the source URL you specified is no longer valid.
En outre, et bien que ce ne soit pas très utilisé, svnsync sait répliquer des dépôts pour lesquels l'identifiant qu'il utilise pour s'authentifier n'a que des droits partiels en lecture. Il copie simplement les parties du dépôt qu'il est autorisé à voir. Un tel miroir n'est clairement pas une bonne solution de sauvegarde.
Dans 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-répertoire à l'intérieur du dépôt. La synchronisation du miroir ne copiera 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-répertoires 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-répertoire 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-répertoire 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.
As far as user interaction with repositories and mirrors goes, it is possible to have a single working copy that interacts with both, but you'll have to jump through some hoops to make it happen. First, you need to ensure that both the primary and mirror repositories have the same repository UUID (which is not the case by default). See the section called “Managing Repository UUIDs” later in this chapter for more about this.
Once the two repositories have the same UUID, you can use svn switch with the --relocate option to point your working copy to whichever of the repositories you wish to operate against, a process that is described in svn switch. There is a possible danger here, though, in that if the primary and mirror repositories aren't in close synchronization, a working copy up to date with, and pointing to, the primary repository will, if relocated to point to an out-of-date mirror, become confused about the apparent sudden loss of revisions it fully expects to be present, and it will throw errors to that effect. If this occurs, you can relocate your working copy back to the primary repository and then either wait until the mirror repository is up to date, or backdate your working copy to a revision you know is present in the sync repository, and then retry the relocation.
En ce qui concerne les interactions entre les utilisateurs et les dépôts ainsi que les miroirs, il est possible d'avoir une seule copie de travail qui interagisse avec un dépôt et son miroir, mais vous devrez faire quelques manipulations pour y arriver. D'abord, vous devez vous assurer que le dépôt source et le dépôt miroir ont bien le même identifiant unique UUID (ce qui n'est pas le cas par défaut). Reportez-vous à la section "Gérer les identifiants uniques (UUID) des dépôts" plus loin dans ce chapitre pour plus de détails à ce sujet.
Une fois que les deux dépôts ont le même identifiant unique, vous pouvez utiliser svn switch avec l'option --relocate pour faire pointer votre copie de travail vers le dépôt de votre choix ; cette procédure est décrite dans svn switch. Cette manoeuvre est potentiellement dangereuse si le miroir et le dépôt original ne sont pas étroitement synchronisés : une copie de travail à jour, pointant vers le dépôt source, que l'on ferait pointer vers un miroir non à jour, sera perdue devant l'absence soudaine de révisions qu'elle s'attend à trouver et elle renverra des erreurs dans ce sens. Si cela arrive, vous pouvez refaire pointer votre copie de travail vers le dépôt original et soit attendre que le dépôt miroir se mette à jour, soit faire revenir en arrière votre copie de travail jusqu'à un numéro de révision dont vous savez qu'il est présent dans le dépôt miroir, puis retenter le changement de dépôt.
Finally, be aware that the revision-based replication provided by svnsync is only that—replication of revisions. Only information carried by the Subversion repository dump file format is available for replication. As such, svnsync has the same sorts of limitations that the repository dump stream has, and does not include such things as the hook implementations, repository or server configuration data, uncommitted transactions, or information about user locks on repository paths.
Enfin, soyez conscient que la réplication, basée sur les révisions, fournie par svnsync n'est rien de plus que de la simple réplication de révisions. Seules les informations incluses dans le format de fichier dump des dépôts Subversion peuvent être répliquées. Ainsi, svnsync possède les mêmes limitations que les flux de chargement/déchargement Subversion, et n'inclut donc pas les procédures automatiques, la configuration du dépôt et du serveur, les transactions inachevées ni les informations relatives aux verrous posés par les utilisateurs sur les chemins du dépôt.
Sous-titre 8
Despite numerous advances in technology since the birth of the modern computer, one thing unfortunately rings true with crystalline clarity—sometimes things go very, very awry. Power outages, network connectivity dropouts, corrupt RAM, and crashed hard drives are but a taste of the evil that Fate is poised to unleash on even the most conscientious administrator. And so we arrive at a very important topic—how to make backup copies of your repository data.
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.
There are two types of backup methods available for Subversion repository administrators—full and incremental. A full backup of the repository involves squirreling away in one sweeping action all the information required to fully reconstruct that repository in the event of a catastrophe. Usually, it means, quite literally, the duplication of the entire repository directory (which includes either a Berkeley DB or FSFS environment). Incremental backups are lesser things: backups of only the portion of the repository data that has changed since the previous backup.
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 signifie de 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.
As far as full backups go, the naïve approach might seem like a sane one, but unless you temporarily disable all other access to your repository, simply doing a recursive directory copy runs the risk of generating a faulty backup. In the case of Berkeley DB, the documentation describes a certain order in which database files can be copied that will guarantee a valid backup copy. A similar ordering exists for FSFS data. But you don't have to implement these algorithms yourself, because the Subversion development team has already done so. The svnadmin hotcopy command takes care of the minutia involved in making a hot backup of your repository. And its invocation is as trivial as the Unix cp or Windows copy operations:
$ svnadmin hotcopy /var/svn/repos /var/svn/repos-backup
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/sauvegarde-du-depot
The resultant backup is a fully functional Subversion repository, able to be dropped in as a replacement for your live repository should something go horribly wrong.
When making copies of a Berkeley DB repository, you can even instruct svnadmin hotcopy to purge any unused Berkeley DB logfiles (see the section called “Purging unused Berkeley DB logfiles”) from the original repository upon completion of the copy. Simply provide the --clean-logs option on the command line.
$ svnadmin hotcopy --clean-logs /var/svn/bdb-repos /var/svn/bdb-repos-backup
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 "Purger les 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 /var/svn/sauvegarde-du-depot
Additional tooling around this command is available, too. The tools/backup/ directory of the Subversion source distribution holds the hot-backup.py script. This script adds a bit of backup management atop svnadmin hotcopy, allowing you to keep only the most recent configured number of backups of each repository. It will automatically manage the names of the backed-up repository directories to avoid collisions with previous backups and will “rotate off” older backups, deleting them so that only the most recent ones remain. Even if you also have an incremental backup, you might want to run this program on a regular basis. For example, you might consider using hot-backup.py from a program scheduler (such as cron on Unix systems), which can cause it to run nightly (or at whatever granularity of time you deem safe).
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érera automatiquement les noms des répertoires sauvegardés pour éviter les collisions avec les précédentes sauvegardes et éliminera 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 convienne mieux).
Some administrators use a different backup mechanism built around generating and storing repository dump data. We described in the section called “Migrating Repository Data Elsewhere” how to use svnadmin dump with the --incremental option to perform an incremental backup of a given revision or range of revisions. And of course, you can achieve a full backup variation of this by omitting the --incremental option to that command. There is some value in these methods, in that the format of your backed-up information is flexible—it's not tied to a particular platform, versioned filesystem type, or release of Subversion or Berkeley DB. But that flexibility comes at a cost, namely that restoring that data can take a long time—longer with each new revision committed to your repository. Also, as is the case with so many of the various backup methods, revision property changes that are made to already backed-up revisions won't get picked up by a nonoverlapping, incremental dump generation. For these reasons, we recommend against relying solely on dump-based backup approaches.
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 "Migrer les 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 plate-forme, à 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 seront pas prises en compte par l'utilisation de flux de dump incrémentaux ne se chevauchant pas. C'est pourquoi nous ne recommandons pas de se reposer uniquement sur le type de sauvegarde basé sur les fichiers dump.
As you can see, each of the various backup types and methods has its advantages and disadvantages. The easiest is by far the full hot backup, which will always result in a perfect working replica of your repository. Should something bad happen to your live repository, you can restore from the backup with a simple recursive directory copy. Unfortunately, if you are maintaining multiple backups of your repository, these full copies will each eat up just as much disk space as your live repository. Incremental backups, by contrast, tend to be quicker to generate and smaller to store. But the restoration process can be a pain, often involving applying multiple incremental backups. And other methods have their own peculiarities. Administrators need to find the balance between the cost of making the backup and the cost of restoring it.
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 fournira 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 consommera 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.
The svnsync program (see the section called “Repository Replication”) actually provides a rather handy middle-ground approach. If you are regularly synchronizing a read-only mirror with your main repository, in a pinch your read-only mirror is probably a good candidate for replacing that main repository if it falls over. The primary disadvantage of this method is that only the versioned repository data gets synchronized—repository configuration files, user-specified repository path locks, and other items that might live in the physical repository directory but not inside the repository's virtual versioned filesystem are not handled by svnsync.
Le programme svnsync (voir la section "Réplication de 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.
In any backup scenario, repository administrators need to be aware of how modifications to unversioned revision properties affect their backups. Since these changes do not themselves generate new revisions, they will not trigger post-commit hooks, and may not even trigger the pre-revprop-change and post-revprop-change hooks. [39] And since you can change revision properties without respect to chronological order—you can change any revision's properties at any time—an incremental backup of the latest few revisions might not catch a property modification to a revision that was included as part of a previous backup.
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'activeront pas les procédures automatiques post-propagation ni même éventuellement les procédures automatiques pre-revprop-change et post-revprop-change [39]. 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.
Generally speaking, only the truly paranoid would need to back up their entire repository, say, every time a commit occurred. However, assuming that a given repository has some other redundancy mechanism in place with relatively fine granularity (such as per-commit emails or incremental dumps), a hot backup of the database might be something that a repository administrator would want to include as part of a system-wide nightly backup. It's your data—protect it as much as you'd like.
En règle générale, seuls les plus paranoïaques auront 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 e-mails 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.
Often, the best approach to repository backups is a diversified one that leverages combinations of the methods described here. The Subversion developers, for example, back up the Subversion source code repository nightly using hot-backup.py and an off-site rsync of those full backups; keep multiple archives of all the commit and property change notification emails; and have repository mirrors maintained by various volunteers using svnsync. Your solution might be similar, but should be catered to your needs and that delicate balance of convenience with paranoia. And whatever you do, validate your backups from time to time—what good is a spare tire that has a hole in it? While all of this might not save your hardware from the iron fist of Fate, [40] it should certainly help you recover from those trying times.
Bien souvent, la meilleure approche de sauvegarde d'un dépôt consiste à ne pas mettre tous ses oeufs 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 mails 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êchera pas votre matériel de subir les affres du destin [40], cela vous aidera certainement à vous sortir de ces situations délicates.
Sous-titre 9
Subversion repositories have a universally unique identifier (UUID) associated with them. This is used by Subversion clients to verify the identity of a repository when other forms of verification aren't good enough (such as checking the repository URL, which can change over time). Most Subversion repository administrators rarely, if ever, need to think about repository UUIDs as anything more than a trivial implementation detail of Subversion. Sometimes, however, there is cause for attention to this detail.
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). La plupart des administrateurs de dépôt 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.
As a general rule, you want the UUIDs of your live repositories to be unique. That is, after all, the point of having UUIDs. But there are times when you want the repository UUIDs of two repositories to be exactly the same. For example, if you make a copy of a repository for backup purposes, you want the backup to be a perfect replica of the original so that, in the event that you have to restore that backup and replace the live repository, users don't suddenly see what looks like a different repository. When dumping and loading repository history (as described earlier in the section called “Migrating Repository Data Elsewhere”), you get to decide whether to apply the UUID encapsulated in the data dump stream to the repository in which you are loading the data. The particular circumstance will dictate the correct behavior.
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 aura des cas où vous voudrez 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 "Migrer les 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 iront dans le nouveau dépôt. Les circonstances vous imposeront la marche à suivre.
There are a couple of ways to set (or reset) a repository's UUID, should you need to. As of Subversion 1.5, this is as simple as using the svnadmin setuuid command. If you provide this subcommand with an explicit UUID, it will validate that the UUID is well-formed and then set the repository UUID to that value. If you omit the UUID, a brand-new UUID will be generated for your repository.
$ svnlook uuid /var/svn/repos
cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec
$ svnadmin setuuid /var/svn/repos # generate a new UUID
$ svnlook uuid /var/svn/repos
3c3c38fe-acc0-11dc-acbc-1b37ff1c8e7c
$ svnadmin setuuid /var/svn/repos \
cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec # restore the old UUID
$ svnlook uuid /var/svn/repos
cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec
$
Il y a plusieurs façons de faire pour attribuer (ou modifier) un UUID à un dépôt, le cas échéant. Avec Subversion 1.5, il suffit d'utiliser la commande svnadmin setuuid. Si vous fournissez un UUID explicite à cette sous-commande, elle validera le format de l'UUID et fixera l'identifiant unique du dépôt à cette valeur. Si vous omettez l'UUID, un nouvel UUID sera 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
$
For folks using versions of Subversion earlier than 1.5, these tasks are a little more complicated. You can explicitly set a repository's UUID by piping a repository dump file stub that carries the new UUID specification through svnadmin load --force-uuid REPOS-PATH.
$ svnadmin load --force-uuid /var/svn/repos <<EOF SVN-fs-dump-format-version: 2 UUID: cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec EOF $ svnlook uuid /var/svn/repos 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 $
Having older versions of Subversion generate a brand-new UUID is not quite as simple to do, though. Your best bet here is to find some other way to generate a UUID, and then explicitly set the repository's UUID to that value.
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.

