AccessBackUp : Un gestionnaire de sauvegarde de base de données Access (ou autre fichier)

www.vbfrance.com/code.aspx?ID=33732

Documentation : AccessBackup.html

Code source : AccessBackup.vbproj.html

Par Patrice Dargenton

http://patrice.dargenton.free.fr/CodesSources/index.html

Date de mise à jour : 25/05/2013

 

Comment faire régulièrement des copies de sauvegarde d'une base MS-Access partagée sur un lecteur réseau ? il suffit de créer une tâche planifiée de copie sur le serveur, c'est tout ! mais que se passe-t-il si la base est en cours d'utilisation ? comment conserver les versions successives des copies ? AccessBackUp adresse précisément ce genre de tâche, et il peut archiver en fait tout type de fichier. De plus, c'est un programme DotNet qui tourne tel quel sur un Windows Serveur 2003 sans installation particulière à faire, pas d'impact sur vôtre configuration donc. Voici la liste des fonctionnalités assurées par AccessBackUp :

- Gestion de deux niveaux de sécurité :

   1°) Niveau fréquent (par exemple toutes les heures) : copie instantanée temporaire de la base MS-Access ;

   2°) Niveau + rare (par exemple une fois par jour) : copie instantanée en vue d'archivage définitif de la base MS-Access ;

- Gestion des bases en cours d'utilisation (copie incertaine ou sinon copie fiable si personne n'est connecté) ;

- Gestion du mot de passe des bases MS-Access ;

- Gestion du compactage (avec réparation, le cas échéant) des bases MS-Access (DAO.DBEngine.CompactDatabase fonctionne en DotNet standard via l'adaptateur DAO) ;

- Gestion de la compression des sauvegardes au format standard .zip ;

- Gestion des roulements (pour conserver par exemple les 10 dernières versions) ;

- Gestion de la numérotation des archives définitives ;

- Paramétrage complet en ligne de commande ;

- Fichier log pour laisser la trace des sauvegardes effectuées ;

- Et bien sûr il fonctionne sans session ouverte sur le serveur.

 

Mots clés : MS-Access, DotNet, VB .Net, Sauvegardes, Compactage, Compression, Zip, Versions, Roulement, Archives, Snapshot, Sauvegarde en continue, Sauvegarde à chaud, CDP : Continuous data protection : sauvegarde de données en continue, Hot backup.

 

 

Tables des matières

Algorithme. 2

Remarques. 2

Copie instantanée d'une base de données en cours d'utilisation. 2

Transvaser les données d'une base de données à une autre. 2

Paramètres utilisables dans la ligne de commande. 3

Limitations. 4

Composants requis. 5

Composants d'accès aux données : ADO.. 5

Autres solutions à envisager 5

Réplication. 5

Transvaser les données en ligne. 5

SQL Server 6

Historique des versions. 6

Version 1.04 du 25/05/2013. 6

Version 1.03 du 16/03/2013. 6

Version 1.02 du 01/11/2009. 6

Version 1.01 du 10/09/2005 Première version. 6

Liens utiles. 6

 

 

Algorithme

1°) Selon l'extension du fichier, on vérifie si la source à sauvegarder est une base MS-Access. Dans ce cas, on regarde combien d'utilisateurs sont actuellement connectés. Si personne n'est connecté, la copie est fiable, sinon la copie est incertaine, mais en tout cas on vérifie qu'aucun utilisateur n'a laissé la base dans un état suspect ;

2°) S'il y a déjà eu une copie de sauvegarde, on vérifie si les dates de dernière écriture sont identiques, au quel cas il est inutile de faire une nouvelle sauvegarde ;

3°) Si c'est une base MS-Access fermée, on la compacte ;

4°) On fait une copie de sauvegarde ;

5°) Si c'est une base MS-Access ouverte, on la compacte la copie ;

6°) On compresse la copie au format Zip ;

7°) On fait une copie de roulement pour conserver les n dernières versions successives (la plus ancienne étant supprimée) ;

8°) On fait une archive définitive selon la fréquence demandée.

 

 

Remarques

- AccessBackup peut aussi servir à sauver une base de données qui serait stockée en RAM, pour des raisons de performance : cela permet d'avoir ainsi la performance et la sécurité ;

- Sur une application de base de données MS-Access, qui est attachée à une base distincte pour les données, aucune connexion n'est ouverte s'il n'y a pas de formulaire ouvert (les tables attachées ne sont pas ouvertes). En revanche, le moindre contrôle dépendant sur un formulaire provoque l'ouverture d'une connexion durant toute la durée d'affichage du formulaire. Cependant, un formulaire indépendant n'ouvre aucune connexion sur la base attachée, ce qui permet de faire une interface pour les attaches, les sauvegardes, le compactage (lequel requiert une connexion interne en mode exclusif), ...

 

 

Copie instantanée d'une base de données en cours d'utilisation

Est-ce que la copie d'une base en cours d'utilisation est fiable, ses données sont-elles intègres ? Je ne pense pas que cela pose de problème particulier dans la mesure où lorsqu'un utilisateur place la base dans un état suspect (par exemple un verrouillage lors d'une écriture, une transaction, ...), alors un flag est signalé en regard de chaque utilisateur connecté répertorié dans les connexions en cours à la base : il s'agit de la valeur du champ "SUSPECTED_STATE" renvoyée lors de la lecture de l'état des connexions à la base de chaque utilisateur, en utilisant le paramètre JET_SCHEMA_USERROSTER. Si l'état est suspect, alors aucune sauvegarde n'est effectuée à ce moment là. Les copies n'ont donc lieu que si aucun des utilisateurs connectés n'a placé la base dans un état suspect.

De toute façon, on effectue ces sauvegardes en plus des sauvegardes certainement fiables (où personne n'est connecté), lesquelles étant certes moins fréquentes selon l'utilisation de la base, il s'agit donc ensuite d'un arbitrage entre "fraîcheur" et fiabilité des données. Quoi qu'il en soit, je ne compte pas réutiliser une base incertaine telle quelle, je préfère dans ce cas transvaser les données, pour être sûr que la base ne soit pas corrompue :

 

 

Transvaser les données d'une base de données à une autre

Il y a deux méthodes pour y parvenir : la première méthode utilise des requêtes SQL d'insertion entre les tables d'une base source vers la base de destination, dans laquelle les tables équivalentes sont attachées à la base source. La seule difficulté est que les relations d'intégrité référentielle entre les données doivent être basées sur des champs mnémoniques de type texte, ou en tout cas pas du type NumAuto (si la performance est cruciale, on peut cependant rattacher des liens NumAuto à partir de liens mnémoniques redondants, ou bien alors peut être désactiver l'intégrité référentielle dans la copie).

La seconde méthode consiste à utiliser mon utilitaire de synchronisation de base de données DBToFile, qui fonctionne aussi avec des requêtes SQL, mais qui assure automatiquement la mise à jour des identifiants NumAuto. Cette synchronisation s'effectue via un fichier texte (ou éventuellement binaire) contenant l'ensemble des données à transférer, cela permet donc de répliquer la base sans avoir à modifier sa structure. Pour plus d'info, voir :

http://patrice.dargenton.free.fr/dbtofile/index.html

Dans le cas d'un simple transfert des données de toute une base, la programmation de DBToFile est assez simple : il n'y a qu'une série ordonnée de Select * à préciser.

 

Dans l'un ou l'autre des cas, le transvasement des données est une technique probablement beaucoup plus lente que la copie directe de la base.

 

 

Paramètres utilisables dans la ligne de commande

 

Syntaxe : Paramètre Valeur : séparés par un espace, ainsi que les autres paramètres.

(s'il n'y a qu'un argument, alors c'est le chemin de la base à sauvegarder, c'est le seul paramètre obligatoire)

 

Résumé :

- CheminSrc

- DossierSauvegardes

- DossierSauvegardesIncert

- SuffixeArchive

- SuffixeCopie

- SuffixeBdOuverte

- SuffixeBdOuverteCompactee

- SuffixeBdFermee

- FormatVersionsRoulement

- FormatVersionsArch

- PeriodeArchJours

- NbVersionsRoulement

- CheminTrace

- MotDePasse

- CompactRepair

 

CheminSrc : Chemin du fichier source à sauvegarder, par exemple :

            C:\Tmp\MaBase.mdb ou

            \\Serveur\Donnees\MaBasePartagee.mdb

            "\\Serveur\Mon dossier\Ma base partagée.mdb"

            \\Serveur\Donnees\MonDocument.doc

 

DossierSauvegardes : Sous-dossier où placer les sauvegardes (relatif à l'emplacement de la source), ou sinon chemin complet du dossier des sauvegardes. On peut aussi laisser vide. Exemples :

            \Bak (ou Bak)

            C:\Sauvegardes

            \\Serveur\Sauvegardes

            "\\Serveur\Mes sauvegardes"

 

DossierSauvegardesIncert : On peut choisir de séparer les sauvegardes incertaines dans un dossier distinct, sinon le même dossier sera utilisé

SuffixeArchive : Suffixe des fichiers d'archive à conserver, par exemple : Arch

SuffixeCopie : Suffixe pour la copie (autre que base MS-Access), par exemple : _Copie

SuffixeBdOuverte : Suffixe pour la base ouverte non compactée (utile pour conserver sa date d'écriture), par exemple : Arch

SuffixeBdOuverteCompactee : Suffixe pour la base ouverte compactée, par exemple : _CopieIncert ou _CopieNonSure

SuffixeBdFermee : Suffixe pour la base fermée (et compactée), par exemple : _CopieFiable

FormatVersionsRoulement : Format numérique pour conserver les n versions précédentes, par exemple

            0 pour conserver au maximum les 9 versions précédentes

            00 pour conserver au maximum les 99 versions précédentes

FormatVersionsArch : Format numérique pour conserver les n versions d'archives définitives

            000 pour conserver au moins 999 versions (en cas de dépassement, le tri des fichiers ne sera pas parfait, mais cela ne pose pas d'autre problème)

PeriodeArchJours : Période d'archivage : Nombre de jours d'intervalle pour faire une nouvelle archive définitive

NbVersionsRoulement : Nombre de versions distinctes récentes conservées (par exemple les 5 dernières versions)

CheminTrace : Chemin du fichier de conservation des traces d'exécution, le cas échéant (laisser vide pour ne pas activer le traçage). On peut aussi indiquer seulement un sous-dossier où se trouve AccessBackup. Utile lorsque AccessBackup est lancé depuis une tâche planifiée sans ouverture de session. Exemples :

            Trace.txt

            \Trace\Trace.txt

            C:\Tmp\Log.txt

 

- MotDePasse : Mot de passe de la base MS-Access : Si la base n'a pas de mot de passe, cela fonctionnera aussi, mais attention car la base compactée elle sera protégée !

 

CompactRepair : pour pouvoir réparer une base corrompue sans requérir une version complète de MS-Access (syntaxe : CompactRepair C:\MaBd.mdb, CompactRepair remplace CheminSrc dans ce cas). Cet argument doit être utilisé si AccessBackup indique que la base est ouverte en mode exclusif ("Base ouverte exclusivement"), et que la base est inaccessible (depuis une application par exemple). MS-Access affiche le message suivant lorsque l'on tente d'ouvrir la base : "La base de données ‘xxx.mdb’ doit être réparée ou n'est pas un fichier de base de données. Vous ou un autre utilisateur avez peut-être quitté Microsoft Access de manière inattendue alors qu'une base de données Microsoft Access était ouverte. Essayer de réparer la base de données ? Oui Non".

 

 

Limitations

 

Au moment de faire la copie directe du fichier de base de données, le fichier est verrouillé, pas au sens d'une base de données, mais au sens de l'accès disque à un fichier quelconque : à ce moment là, une tentative d'écriture, de verrouillage ou d'ouverture en mode exclusif (par exemple pour effectuer un compactage) peut échouer, au quel cas il faudra prévoir un traitement d'erreur : de toute façon, toute application de base de données doit gérer les erreurs, quelque soit le type d'accès demandé, ce n'est pas vraiment une exigence particulière qui est recommandée ici.

 

Si on ouvre une base MS-Access en mode exclusif (option de la boite de dialogue d'ouverture d'une base sous MS-Access), alors AccessBackup ne peut pas la compacter ; mais, si on ouvre cette fois la base en mode lecture seule et exclusif, cette fois AccessBackup peut la compacter. Cependant, il ne peut pas terminer le processus car on ne peut pas remplacer la base d'origine par la copie compactée (mais on peut faire une copie fiable de la base, contrairement au mode exclusif tout court dans lequel on ne peut faire aucune copie).

 

Dans tous les cas, aucune boite de dialogue n'est affichée sur le serveur, car le programme doit fonctionner sans qu'une session soit ouverte : si une erreur survient, on peut consulter la trace des messages dans le fichier dédié à cela, si le traçage est activé. Sinon, si une session est ouverte, un minuteur permet d'avoir le temps de lire les messages.

 

 

Composants requis

 

AccessBackup requiert que les composants suivants soient installés :

- Plateforme .Net 2 (Framework DotNet) : c'est un composant optionnel proposé par Windows Update, mais il est pré-installé en standard avec Windows 2003 Serveur ;

- Composants d'accès aux données : ADO en version 2.6 minimum pour fonctionner en DotNet :

 

Composants d'accès aux données : ADO

On peut laisser la liaison précoce (ou anticipée, c'est-à-dire à la compilation) : l'exécutable fonctionne normalement avec une version différente d'ADO que celle utilisée à la compilation : l'adaptateur DotNet pour ADODB est compatible au niveau binaire, de façon ascendante et descendante. Pour vérifier cela, j'ai fait un test avec Adodb.dll sous .Net en liaison précoce, avec une version ADO 2.8 au moment de compiler l'exe, puis j'ai réinstallé un Windows XP vide (XP SR1A) pour pouvoir tester l'exe avec une version antérieur d'Ado : la 2.7, et cela fonctionne : moralité, pour certaine dll, on n'est pas obligé d'utiliser la liaison tardive pour être sûr que ça marchera partout (mais les tests sont difficiles !). En fait je crois qu'il faut regarder à la rubrique Reference dans le fichier .vbproj si les variables VersionMajor et VersionMinor sont précisées (d'ailleurs le typelib de la dll est : "ADO 2.0 ActiveX Data Object 2.0" : 2.0 et non 2.6, 2.7 ou 2.8). Je n'ai pas encore testé avec ADO 2.6 sous Windows 2000.

Note : Par rapport à DAO, ADO possède des fonctionnalités en plus, comme par exemple ouvrir une connexion en mode exclusif.

 

Liens ADO :

- Déploiement du MDAC :

            www.codeproject.com/KB/install/DeployingFrameworkMdac.aspx

Bootstrapper : permet de tout installer depuis le msi :

            www.microsoft.com/fr-fr/download/details.aspx?id=5072

- Pour installer les composants d'accès aux données (Microsoft Data Access Components : MDAC), vous pouvez les télécharger gratuitement sur le site de Microsoft France (MDAC_TYP.EXE, actuellement en version 2.8 : 5.447 Mo) :

            www.microsoft.com/downloads/details.aspx?displaylang=fr&FamilyID=6c050fe3-c795-4b7d-b037-185d0506396c

 

 

Autres solutions à envisager

Réplication

La réplication peut servir à la sauvegarde, dans ce cas on bénéficie d'une certaine automatisation du processus. Dommage que la réplication implique une modification de la structure de la base de données (des champs sont ajoutés aux tables concernés). Je n'ai jamais testé en pratique.

 

Transvaser les données en ligne

On peut aussi transvaser les données, mais pour effectuer la sauvegarde cette fois (au lieu de la restauration) : cette méthode peut être envisagée alors même que la base est en cours d'utilisation, il n'est pas besoin d'attendre que tout le monde se déconnecte, ni d'ouvrir la base en mode exclusif. Le seul problème qui peut arriver, c'est de capturer un instantané complet, et non un instantané en cours de modification (même dans ce cas, on ne devrait en principe jamais violer l'intégrité référentielle), sinon on peut verrouiller la base en écriture. Ensuite, il suffit de faire des copies de la copie, il n'y a plus de problème d'utilisateurs connectés.

DBToFile pourrait servir dans ce cadre d'utilisation, mais sur un serveur une installation serait requise, à savoir : VB6/ActiveX, contrairement à une solution pure DotNet. Note : pour le moment DBToFile ne gère pas le verrouillage exclusif au moment de la sauvegarde, il pourrait donc en théorie y avoir un risque dans le cas multi-utilisateur.

 

SQL Server

Une base de données de type serveur est plus adaptée lorsque le nombre d'utilisateurs simultanés devient élevé (disons à partir de 20 ou 30), et il intègre son propre mécanisme de sauvegarde. Cependant, si vous avez moins de 20 utilisateurs simultanés, MS-Access gère nativement le verrouillage pessimiste sans avoir à écrire une seule ligne de code, il suffit d'activer la propriété correspondante des formulaires concernés, c'est tout. Concrètement, cela permet de verrouiller un enregistrement (ou le cas échéant une page d'enregistrements physiquement contigus), dès qu'un utilisateur commence une modification, il n'y a donc aucune chance de conflit d'écriture, aucune gestion d'erreur supplémentaire à écrire au moment de valider cette modification. En DotNet 1 et 2, ADO.Net ne gère pas les curseurs coté serveur, de sorte que cette fonctionnalité est très difficile à programmer, il faut écrire des tartines de code, rien que pour afficher un message idiot à la fin du type : "ha ben j'ai pas pu effectuer certaines modifs à cause de conflits d'écriture entre plusieurs utilisateurs", message souvent incompréhensible pour les utilisateurs. Dans les situations où il y a peu d'utilisateurs simultanés, c'est quand même plus simple d'empêcher les conflits ! Et avec MS-Access, vous pouvez afficher des instances simultanées d'un même formulaire en mode enregistrement unique ou en mode feuille de données, et en mode sous-formulaire ou en formulaire principal dans une autre fenêtre (ce qui m'a servi pas plus tard qu'hier), c'est encore loin d'être possible en DotNet ! (il y a cependant des fonctionnalités de programmation assez intéressantes dans la nouvelle version de SQL Server).

 

 

Historique des versions

 

Version 1.04 du 25/05/2013

- Compilation en mode 32 bits, de façon à éviter le problème avec la requête du moteur JET concernant le nombre d'utilisateurs connectés, qui ne passe pas en mode 64 bits (on obtient l'erreur ADODB.Connection n°3706 : "Impossible de trouver le fournisseur. Il est peut-être mal installé.", dans la fonction iNbUtilisateurs)

 

Version 1.03 du 16/03/2013

- Argument CompactRepair pour pouvoir réparer une base corrompue sans requérir une version complète de MS-Access (syntaxe : CompactRepair C:\MaBd.mdb, CompactRepair remplace CheminSrc dans ce cas).

 

Version 1.02 du 01/11/2009

- Si un seul argument, alors c'est le chemin de la base à sauvegarder ;

- Gestion du mot de passe MS-Access ;

- Code Designer à part ;

- Version DotNet2 de ICSharpCode.SharpZipLib.dll ;

- Passage en VB 2008.

 

Version 1.01 du 10/09/2005 Première version

 

 

Liens utiles

 

- Détecter les fichiers ouverts sur un serveur

  www.codeproject.com/Articles/10760/An-app-to-see-who-has-files-open-on-a-network-serv

 

DBToFile

  http://patrice.dargenton.free.fr/dbtofile/index.html

 

SqlServer Backup/Restore Utility

  www.codeproject.com/Articles/37072/SqlServer-Backup-Restore-Utility

 

- Securely backup your SQL Server database and other files to a remote machine

  www.codeproject.com/KB/database/BackupUtility.aspx

 

Compactage BDD avec JetComp

  www.vbfrance.com/code.aspx?ID=43977

 

- Compact and Repair an Access Database Programmatically Using C#

  www.codeproject.com/KB/database/CompactAndRepair.aspx

 

- Web service method to backup database from mobile device using SQL Backup Command and asynchronous method calls

  www.codeproject.com/KB/vb/Backup_DB_from_Mobile_Dev.aspx

 

 

Note : AccessBackup a été testé depuis 2005, mais je ne peux cependant pas être tenu pour responsable pour l'utilisation que vous ferez de ce logiciel. Quoi qu'il en soit, prévenez moi si vous avez un problème, cela pourrait me concerner aussi !