IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

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

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 lorsqu’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. ♪

Article lu   fois.

L'auteur

Site personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

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 lorsqu’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.

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 cela vous est impossible, et seulement dans ce cas-là, vous pouvez utiliser 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 fourni avec 4e 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érifier. 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 essayé 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 4e 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.

Lorsqu’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.

Note : Quand le fichier de données consiste en plusieurs segments, vous pouvez créer plusieurs segments lorsque vous créez 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 ».

Réindexer le fichier de données

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

  1. Faites 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çons 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'enregistrement 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.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
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èrement 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 a 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

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

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.