Developpez.com

Télécharger gratuitement le magazine des développeurs, le bimestriel des développeurs avec une sélection des meilleurs tutoriels

Developpez.com - 4D
X

Choisissez d'abord la catégorieensuite la rubrique :


Récupération d'un fichier de données endommagé

Date de publication : Juin 2005

Par Thang NGUYEN (Quality Assurance, 4D Inc.)
 

L'intégrité des données est un des éléments les plus importants dans une base de données. Dans cette note technique, nous allons aborder la façon de récupérer des données lorsque une corruption intervient en nous concentrant sur quatre façons : en utilisant 4D Tools, en réindexant un fichier de données, en restockant les enregistrements, en exportant les données dans un nouveau fichier de données.

I. Résumé
II. Récupérer des données endommagées avec 4D Tools
Vérification du fichier de données
Réparation des données en utilisant la réparation rapide
Réparer la base en utilisant la Récupération par marqueur d'enregistrements
Re-indexer le fichier de données
Charger et restocker les enregistrements
III. Exporter les données dans un nouveau fichier de données
IV. Bases exemples


I. Résumé

L'intégrité des données est un des éléments les plus importants dans une base de données. Vous pouvez avoir sécurisé vos données au maximum et vous être préparé à toutes éventualités, des événements malheureux comme une interruption de l'alimentation électrique, un "crash" système ou un "crash" de l'application, peuvent endommager les données. Dans cette note technique, nous allons aborder la façon de récupérer des données lorsque une corruption intervient. Il y a différentes façons de vérifier et de réparer les données, mais cette note technique va se concentrer sur quatre façons :

  • en utilisant 4D Tools ;
  • en réindexant un fichier de données ;
  • en restockant les enregistrements ;
  • en exportant les données dans un nouveau fichier de données.
info Note : avant d'utiliser ces différentes procédures ; faites une sauvegarde de votre base de données. Notez aussi que certains des exemples fournis dans cette note technique sont utilisés comme outils de diagnostic. Leur utilisation ne garantit pas la récupération des données. Nous vous recommandons toujours d'utiliser en priorité la copie de sauvegarde générée par 4D Backup ou les fonctionnalités de sauvegarde incorporées dans 4D 2004, avec intégration du fichier d'historique. Lorsque que cela vous est impossible, et seulement dans ce cas-là, vous pouvez utilisez les techniques décrites dans la présente note.

II. Récupérer des données endommagées avec 4D Tools


Vérification du fichier de données

4D Tools est un programme utilitaire fournit avec 4ème Dimension. 4D Tools possède plusieurs fonctionnalités de diagnostic qui détectent et réparent les dommages survenus dans une base de données. En fonction du degré de corruption des données, 4D Tools pourra réparer. Détecter et fixer les problèmes est une procédure simple.

1 - Lancez 4D Tools et ouvrez le fichier de Structure de votre base.

2 - Sélectionnez le fichier de données associé (endommagé).

3 - Sélectionnez ensuite l'onglet "Maintenance". Il y a trois options utilisées pour vérifier les données. Les options sont : "Vérifier tout", "Vérifier enregistrements...", "Vérifier index...".

Pictures 0516x0444



Lorsque vous utilisez l'option "Vérifier tout", 4D Tools commence immédiatement à vérifier le fichier de données. Le programme vérifie l'intégrité de tous les enregistrements et de tous les index. Cette option est plus approfondie mais elle est aussi plus lente que les deux autres options.

Nous recommandons de choisir cette option pour une maintenance régulière de votre base de données, ou si 4D a détecté un problème dans votre base de données qu'il ne peut pas réparer.

L'option "Vérifier enregistrements..." restreint la vérification aux données des enregistrements. De plus, vous pouvez choisir des tables spécifiques que vous voulez vérifiez. Cette option est utile lorsque vous souhaitez effectuer une vérification rapide de certaines tables dans une grosse base de données. Choisissez cette option seulement si vous voulez vérifier les enregistrements ou seulement ceux de tables spécifiques.

L'option "Vérifier index..." restreint la vérification des données aux index. De plus, vous pouvez choisir des index spécifiques. Choisissez cette option seulement si vous voulez vérifier les index ou certains index bien précis de la base de données.


Réparation des données en utilisant la réparation rapide

Si une des options précédentes renvoie une erreur, l'étape suivante est la réparation du fichier de données. Sélectionnez l'onglet "Réparation". Il y a trois options utilisées pour réparer les données. Ces options sont "Réparer tout", "Réparer enregistrements..." et "Réparer index...".

Pictures 0590x0508



L'utilisation d'une option en particulier dépend des problèmes rencontrés. Si les problèmes sont à la fois sur les enregistrements et les index, alors le choix de l'option "Réparer tout" est le plus approprié. 4D commence par réparer le fichier de données. Cette option est la plus approfondie mais aussi la plus lente, particulièrement si le data est gros.

D'un autre côté, si un problème particulier se rapporte aux enregistrements seulement, alors il sera plus efficace de lancer "Réparer enregistrements...". De plus vous pouvez choisir les tables que vous souhaitez réparer. Cette option est pratique pour réparer seulement les parties endommagées dans une grosse base. Choisissez cette option si vous êtes sûr que seulement les enregistrements de la base sont endommagés.

L'option "Réparer index..." ne devrait être choisie que si vous êtes sûr que seulement les index dans la base sont endommagés. Cette option restreint la réparation aux index. De plus, vous pouvez choisir les index que vous souhaitez réparer. Cette option est utile pour réparer seulement les index endommagés dans une grosse base de données.


Réparer la base en utilisant la Récupération par marqueur d'enregistrements

Avant de procéder à la "Récupération par marqueur d'enregistrements", vous devez avoir essayer de réindexer votre base de données et de charger et restocker les enregistrements d'abord. Pour plus d'informations concernant la réindexation, allez à la partie "Réindexer la base de données" dans cette note technique.

Quand votre fichier de données est sérieusement endommagé et ne peut pas être réparé par les options de réparation rapide ou en ré-indexant votre base de données, utilisez l'option "Récupération par marqueur d'enregistrements". Lorsque vous choisissez cette option, un nouveau data sera créé plutôt que de réparer l'ancien data. Ainsi, en utilisant cette option, vérifiez que vous avez suffisamment d'espace disque.

Qu'est-ce que la récupération par marqueur d'enregistrements ?

Les enregistrements de 4ème Dimension ont une longueur variable. Chaque enregistrement est marqué par un "tag". Ce marqueur d'enregistrement est un numéro unique suivi par la taille de l'enregistrement (cette valeur est aussi appelée "check sum"). Ce marqueur est comme un résumé de l'enregistrement contenant les informations essentielles, qui peuvent être utilisées pour le retrouver dans la table d'adresses.

Si la table d'adresses est endommagée, 4D Tools utilise ce marqueur, stocké dans l'en-tête de chaque enregistrement.

Lorsque l'on lance la récupération par analyse des marqueurs d'enregistrements, 4D Tools se positionne au début du fichier de données, compare la taille de l'enregistrement avec la taille indiquée par le marqueur. Si les valeurs sont identiques, 4D Tools récupère l'enregistrement pour le placer dans le nouveau fichier de données, sinon l'enregistrement n'est pas récupéré.

Une fois tous les enregistrements corrects recopiés dans le nouveau fichier de données, 4D Tools reconstruit les index.

Pour lancer la récupération par marqueur d'enregistrements, choisissez l'option "Récupérer" dans la partie "Récupération par marqueur d'enregistrement". Une fenêtre apparaîtra, proposant la création d'un nouveau fichier de données.

Pictures 0555x0369



Après avoir saisi un nouveau nom de données, sélectionnez le bouton "Enregistrer" et 4D Tools commencera la récupération par marqueur d'enregistrements. Dans les cas sévères, où l'utilisation de 4D Tools ne résout pas le problème, une approche plus agressive nécessite d'être utilisée.

info Note : Quand le fichier de données consiste en plusieurs segments, vous pouvez créer plusieurs segments lorsque vous créer un nouveau fichier de données, autrement 4D Tools s'arrêtera et demandera un nouveau segment au milieu de la "Récupération par marqueurs d'enregistrements".

Re-indexer le fichier de données

La première étape pour réindexer le fichier de données est de

1 - faire une copie du fichier de structure.

2 - Ouvrez une copie de la structure avec un nouveau fichier de données.

3 - Supprimez tous les liens et allez sur chaque table, et décochez tous les index,

4 - Refermez la base.

5 - Relancez la structure dupliquée avec le fichier de données d'origine puis fermer la base de données.

Vous obtiendrez ainsi un fichier de données non-indexées.

6 - Lancez votre fichier de structure d'origine avec le fichier de données d'origine. En faisant ceci, 4D réindexera votre fichier de données.


Charger et restocker les enregistrements

Il peut arriver que vous lanciez votre base de données et que des recherches sur vos données provoquent un "crash". Mais si vous utilisez 4D Tools, celui-ci vous dit que votre base de données ne présente pas de problèmes. Que pouvez-vous faire ?

Une des façon la plus rapide et la plus efficace pour savoir si votre fichier de données est endommagé et savoir quels enregistrements sont à l'origine du problème est de charger chaque enregistrement et de le restocker. Quand un enregistrement est endommagé, le charger causera un comportement inattendu. Il n'y a pas de garantie que la procédure ci-dessous puisse détecter la corruption, mais en utilisant ce code, 4D chargera et restockera l'enregistrement. La méthode indiquée ci-dessous est une procédure écrite par Hugo Fournier (4D Inc.). Cette méthode boucle sur tous les enregistrements de la base et vérifie si l'enregistement est corrompu. Cette méthode va créer un fichier d'historique, à côté de la structure de la base, "LogEnregistrements". Le fichier "LogEnregistrements" vous indiquera tous les enregistrements qui ont été restockés avec succès.



    C_BLOB($Blob;$BlobBuffer)
    C_BOOLEEN($Boolean;$BooleanBuffer)
    C_DATE($Date;$DateBuffer)
    C_ENTIER($Integer;$IntegerBuffer)
    C_ENTIER LONG($Longint;$LongintBuffer)
    C_IMAGE($Picture;$PictureBuffer)
    C_REEL($Real;$RealBuffer)
    C_ALPHA(20;$String;$AlphaBuffer)
    C_TEXTE($Text;$TextBuffer)
    C_HEURE($Time;$TimeBuffer)
    C_ENTIER LONG($j)
    C_TEXTE($tableName)
    C_HEURE($vhDoc)

    $vhDoc:=Creer document("LogEnregistrements")      ` Création d'un nouveau document

    Si (OK=1)
       Boucle ($j;1;Nombre de tables)
          TOUT SELECTIONNER(Table($j)->)
          Boucle ($k;1;Nombre de champs(Table($j)))
             Au cas ou
                : (Type(Champ($j;$k)->)=Est un champ alpha)
                   TOUT SELECTIONNER(Table($j)->)

                   Boucle ($i;1;Enregistrements trouves(Table($j)->))
                      $AlphaBuffer:=Champ($j;$k)->
                      Champ($j;$k)->:=$string
                      STOCKER ENREGISTREMENT(Table($j)->)
                      Champ($j;$k)->:=$AlphaBuffer
                      STOCKER ENREGISTREMENT(Table($j)->)
                      $tableName:=Nom de la table($j)
                      ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Champ : "
                         + Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))      ` On écrit dans le document
                      ENREGISTREMENT SUIVANT(Table($j)->)
                   Fin de boucle

                : (Type(Champ($j;$k)->)=Est un texte )
                   TOUT SELECTIONNER(Table($j)->)

                   Boucle ($i;1;Enregistrements trouves(Table($j)->))
                      $TextBuffer:=Champ($j;$k)->
                      Champ($j;$k)->:=$Text
                      STOCKER ENREGISTREMENT(Table($j)->)
                      Champ($j;$k)->:=$TextBuffer
                      STOCKER ENREGISTREMENT(Table($j)->)
                      $tableName:=Nom de la table($j)
                      ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Champ : "
                         +Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))
                      ENREGISTREMENT SUIVANT(Table($j)->)
                   Fin de boucle

                : (Type(Champ($j;$k)->)=Est un entier)
                   TOUT SELECTIONNER(Table($j)->)

                   Boucle ($i;1;Enregistrements trouves(Table($j)->))
                      $IntegerBuffer:=Champ($j;$k)->
                      Champ($j;$k)->:=$Integer
                      STOCKER ENREGISTREMENT(Table($j)->)
                      Champ($j;$k)->:=$IntegerBuffer
                      STOCKER ENREGISTREMENT(Table($j)->)
                      $tableName:=Nom de la table($j)
                      ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Champ : "
                         +Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))
                      ENREGISTREMENT SUIVANT(Table($j)->)
                   Fin de boucle

                : (Type(Champ($j;$k)->)=Est un entier long )
                   TOUT SELECTIONNER(Table($j)->)

                   Boucle ($i;1;Enregistrements trouves(Table($j)->))
                      $LongintBuffer:=Champ($j;$k)->
                      Champ($j;$k)->:=$Longint
                      STOCKER ENREGISTREMENT(Table($j)->)
                      Champ($j;$k)->:=$LongintBuffer
                      STOCKER ENREGISTREMENT(Table($j)->)
                      $tableName:=Nom de la table($j)
                      ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Champ : "
                         +Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))
                      ENREGISTREMENT SUIVANT(Table($j)->)
                   Fin de boucle

                : (Type(Champ($j;$k)->)=Est un booléen )
                   TOUT SELECTIONNER(Table($j)->)

                   Boucle ($i;1;Enregistrements trouves(Table($j)->))
                      $BooleanBuffer:=Champ($j;$k)->
                      Champ($j;$k)->:=$Boolean
                      STOCKER ENREGISTREMENT(Table($j)->)
                      Champ($j;$k)->:=$BooleanBuffer
                      STOCKER ENREGISTREMENT(Table($j)->)
                      $tableName:=Nom de la table($j)
                      ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Champ : "
                         +Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))
                      ENREGISTREMENT SUIVANT(Table($j)->)
                   Fin de boucle

                : (Type(Champ($j;$k)->)=Est une date )
                   TOUT SELECTIONNER(Table($j)->)

                   Boucle ($i;1;Enregistrements trouves(Table($j)->))
                      $DateBuffer:=Champ($j;$k)->
                      Champ($j;$k)->:=$Date
                      STOCKER ENREGISTREMENT(Table($j)->)
                      Champ($j;$k)->:=$DateBuffer
                      STOCKER ENREGISTREMENT(Table($j)->)
                      $tableName:=Nom de la table($j)
                      ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Champ : "
                         +Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))
                      ENREGISTREMENT SUIVANT(Table($j)->)
                   Fin de boucle

                : (Type(Champ($j;$k)->)=Est une heure )
                   TOUT SELECTIONNER(Table($j)->)

                   Boucle ($i;1;Enregistrements trouves(Table($j)->))
                      $TimeBuffer:=Champ($j;$k)->
                      Champ($j;$k)->:=$Time
                      STOCKER ENREGISTREMENT(Table($j)->)
                      Champ($j;$k)->:=$TimeBuffer
                      STOCKER ENREGISTREMENT(Table($j)->)
                      $tableName:=Nom de la table($j)
                      ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Champ : "
                         +Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))
                      ENREGISTREMENT SUIVANT(Table($j)->)
                   Fin de boucle

                : (Type(Champ($j;$k)->)=Est une image )
                   TOUT SELECTIONNER(Table($j)->)

                   Boucle ($i;1;Enregistrements trouves(Table($j)->))
                      $PictureBuffer:=Champ($j;$k)->
                      Champ($j;$k)->:=$Picture
                      STOCKER ENREGISTREMENT(Table($j)->)
                      Champ($j;$k)->:=$PictureBuffer
                      STOCKER ENREGISTREMENT(Table($j)->)
                      $tableName:=Nom de la table($j)
                      ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Field : "
                         +Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))
                      ENREGISTREMENT SUIVANT(Table($j)->)
                   Fin de boucle

                : (Type(Champ($j;$k)->)=Est un numérique )
                   TOUT SELECTIONNER(Table($j)->)

                   Boucle ($i;1;Nombre de champs(Table($j)))
                      $RealBuffer:=Champ($j;$k)->
                      Champ($j;$k)->:=$Real
                      STOCKER ENREGISTREMENT(Table($j)->)
                      Champ($j;$k)->:=$RealBuffer
                      STOCKER ENREGISTREMENT(Table($j)->)
                      $tableName:=Nom de la table($j)
                      ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Champ : "
                         +Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))
                      ENREGISTREMENT SUIVANT(Table($j)->)
                   Fin de boucle

                : (Type(Champ($j;$k)->)=Est un BLOB )
                   TOUT SELECTIONNER(Table($j)->)

                   Boucle ($i;1;Enregistrements trouves(Table($j)->))
                      $BlobBuffer:=Champ($j;$k)->
                      Champ($j;$k)->:=$Blob
                      STOCKER ENREGISTREMENT(Table($j)->)
                      Champ($j;$k)->:=$BlobBuffer
                      STOCKER ENREGISTREMENT(Table($j)->)
                      $tableName:=Nom de la table($j)
                      ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Champ : "
                         +Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))
                      ENREGISTREMENT SUIVANT(Table($j)->)
                   Fin de boucle

                : (Type(Champ($j;$k)->)=Est une sous table )
                   `ne rien faire
             Fin de cas
          Fin de boucle
       Fin de boucle

       ENVOYER PAQUET($vhDoc;"Tous les enregistrements sont OK"+Caractere(13))
       FERMER DOCUMENT($vhDoc)      ` Close the document
    Sinon
       ALERTE("Impossible de créer le fichier \"LogEnregistrements\".")
    Fin de si



Cette méthode est disponible sous la forme d'un fichier de méthode 4D, "VerifEnreg.C4D" à importer dans votre base pour l'utiliser (Mode Structure, Nouvelle Méthode, Menu Méthode, ligne Importer la méthode...).


III. Exporter les données dans un nouveau fichier de données

Si votre fichier de données est sévéremment endommagé et si d'utiliser les procédures précédentes n'est pas suffisant, la dernière solution est d'exporter toutes vos données dans un nouveau fichier. L'export peut prendre beaucoup de temps en fonction de la taille de vos données. Lorsque vous exportez, il y à une "bonne" façon et une "mauvaise". Vous pourriez être tenté d'utiliser les commandes ENVOYER ENREGISTREMENT et RECEVOIR ENREGISTREMENT pour exporter et importer toutes vos données. Mais lorsque vous utilisez ces commandes, la plupart du temps, le problème présent dans l'enregistrement sera exporté puis réimporté, chaque enregistrement étant exporté comme une entité entière. Vous pouvez utiliser l'import/export en standard dans 4D. Lorsque vous exportez vos données, vérifiez que vous le faites avec délimiteur Tabulation et en fichier texte ou XML. Vous pouvez exporter vos données en texte ou XML à partir du Mode Utilisation.

Pictures 0584x0417



Sélectionnez la ligne Exporter.. dans le menu Fichier. Lorsque le dialogue d'export apparaît, choisissez la table et les champs que vous voulez exporter. Sélectionnez le format dans lequel vous voulez exporter. Vous pouvez choisir d'exporter tous les enregistrements ou seulement la sélection. Cliquez alors sur le bouton Export.

L'avantage de cette méthode est que, pour chaque champ, 4D convertit la valeur en texte. En faisant cela, si la valeur peut être convertie, la corruption est éliminée.


IV. Bases exemples

Téléchargez les bases exemples :

Base exemple Win

Base exemple Mac

__________________________________________________
Copyright © 1985-2009 4D SA - Tous droits réservés
Tous les efforts ont été faits pour que le contenu de cette note technique présente le maximum de fiabilité possible.
Néanmoins, les différents éléments composant cette note technique, et le cas échéant, le code, sont fournis sans garantie d'aucune sorte. L'auteur et 4D S.A. déclinent donc toute responsabilité quant à l'utilisation qui pourrait être faite de ces éléments, tant à l'égard de leurs utilisateurs que des tiers.
Les informations contenues dans ce document peuvent faire l'objet de modifications sans préavis et ne sauraient en aucune manière engager 4D SA. La fourniture du logiciel décrit dans ce document est régie par un octroi de licence dont les termes sont précisés par ailleurs dans la licence électronique figurant sur le support du Logiciel et de la Documentation afférente. Le logiciel et sa documentation ne peuvent être utilisés, copiés ou reproduits sur quelque support que ce soit et de quelque manière que ce soit, que conformément aux termes de cette licence.
Aucune partie de ce document ne peut être reproduite ou recopiée de quelque manière que ce soit, électronique ou mécanique, y compris par photocopie, enregistrement, archivage ou tout autre procédé de stockage, de traitement et de récupération d'informations, pour d'autres buts que l'usage personnel de l'acheteur, et ce exclusivement aux conditions contractuelles, sans la permission explicite de 4D SA.
4D, 4D Calc, 4D Draw, 4D Write, 4D Insider, 4ème Dimension ®, 4D Server, 4D Compiler ainsi que les logos 4e Dimension, sont des marques enregistrées de 4D SA.
Windows,Windows NT,Win 32s et Microsoft sont des marques enregistrées de Microsoft Corporation.
Apple, Macintosh, Power Macintosh, LaserWriter, ImageWriter, QuickTime sont des marques enregistrées ou des noms commerciaux de Apple Computer,Inc.
Mac2Win Software Copyright © 1990-2002 est un produit de Altura Software,Inc.
4D Write contient des éléments de "MacLink Plus file translation", un produit de DataViz, Inc,55 Corporate drive,Trumbull,CT,USA.
XTND Copyright 1992-2002 © 4D SA. Tous droits réservés.
XTND Technology Copyright 1989-2002 © Claris Corporation.. Tous droits réservés ACROBAT © Copyright 1987-2002, Secret Commercial Adobe Systems Inc.Tous droits réservés. ACROBAT est une marque enregistrée d'Adobe Systems Inc.
Tous les autres noms de produits ou appellations sont des marques déposées ou des noms commerciaux appartenant à leurs propriétaires respectifs.
__________________________________________________
 



Valid XHTML 1.1!Valid CSS!

Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
Contacter le responsable de la rubrique 4D