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

Thang NGUYEN

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

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

- Auteur : Thang NGUYEN

- Parution : 1 juin 2005

- Licence : 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.

Sommaire

- 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

- Ré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 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… ».

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… ».

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.

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.

1. C_BLOB($Blob;$BlobBuffer)

2. C_BOOLEEN($Boolean;$BooleanBuffer)

3. C_DATE($Date;$DateBuffer)

4. C_ENTIER($Integer;$IntegerBuffer)

5. C_ENTIER LONG($Longint;$LongintBuffer)

6. C_IMAGE($Picture;$PictureBuffer)

7. C_REEL($Real;$RealBuffer)

8. C_ALPHA(20;$String;$AlphaBuffer)

9. C_TEXTE($Text;$TextBuffer)

10. C_HEURE($Time;$TimeBuffer)

11. C_ENTIER LONG($j)

12. C_TEXTE($tableName)

13. C_HEURE($vhDoc)

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

17. Si (OK=1)

18. Boucle ($j;1;Nombre de tables)

19. TOUT SELECTIONNER(Table($j)->)

20. Boucle ($k;1;Nombre de champs(Table($j)))

21. Au cas ou

22. : (Type(Champ($j;$k)->)=Est un champ alpha)

23. TOUT SELECTIONNER(Table($j)->)

25. Boucle ($i;1;Enregistrements trouves(Table($j)->))

26. $AlphaBuffer:=Champ($j;$k)->

27. Champ($j;$k)->:=$string

28. STOCKER ENREGISTREMENT(Table($j)->)

29. Champ($j;$k)->:=$AlphaBuffer

30. STOCKER ENREGISTREMENT(Table($j)->)

31. $tableName:=Nom de la table($j)

32. ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Champ : "

33. + Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))      ` On écrit dans le document

34. ENREGISTREMENT SUIVANT(Table($j)->)

35. Fin de boucle

37. : (Type(Champ($j;$k)->)=Est un texte )

38. TOUT SELECTIONNER(Table($j)->)

40. Boucle ($i;1;Enregistrements trouves(Table($j)->))

41. $TextBuffer:=Champ($j;$k)->

42. Champ($j;$k)->:=$Text

43. STOCKER ENREGISTREMENT(Table($j)->)

44. Champ($j;$k)->:=$TextBuffer

45. STOCKER ENREGISTREMENT(Table($j)->)

46. $tableName:=Nom de la table($j)

47. ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Champ : "

48. +Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))

49. ENREGISTREMENT SUIVANT(Table($j)->)

50. Fin de boucle

52. : (Type(Champ($j;$k)->)=Est un entier)

53. TOUT SELECTIONNER(Table($j)->)

55. Boucle ($i;1;Enregistrements trouves(Table($j)->))

56. $IntegerBuffer:=Champ($j;$k)->

57. Champ($j;$k)->:=$Integer

58. STOCKER ENREGISTREMENT(Table($j)->)

59. Champ($j;$k)->:=$IntegerBuffer

60. STOCKER ENREGISTREMENT(Table($j)->)

61. $tableName:=Nom de la table($j)

62. ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Champ : "

63. +Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))

64. ENREGISTREMENT SUIVANT(Table($j)->)

65. Fin de boucle

67. : (Type(Champ($j;$k)->)=Est un entier long )

68. TOUT SELECTIONNER(Table($j)->)

70. Boucle ($i;1;Enregistrements trouves(Table($j)->))

71. $LongintBuffer:=Champ($j;$k)->

72. Champ($j;$k)->:=$Longint

73. STOCKER ENREGISTREMENT(Table($j)->)

74. Champ($j;$k)->:=$LongintBuffer

75. STOCKER ENREGISTREMENT(Table($j)->)

76. $tableName:=Nom de la table($j)

77. ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Champ : "

78. +Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))

79. ENREGISTREMENT SUIVANT(Table($j)->)

80. Fin de boucle

82. : (Type(Champ($j;$k)->)=Est un booléen )

83. TOUT SELECTIONNER(Table($j)->)

85. Boucle ($i;1;Enregistrements trouves(Table($j)->))

86. $BooleanBuffer:=Champ($j;$k)->

87. Champ($j;$k)->:=$Boolean

88. STOCKER ENREGISTREMENT(Table($j)->)

89. Champ($j;$k)->:=$BooleanBuffer

90. STOCKER ENREGISTREMENT(Table($j)->)

91. $tableName:=Nom de la table($j)

92. ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Champ : "

93. +Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))

94. ENREGISTREMENT SUIVANT(Table($j)->)

95. Fin de boucle

97. : (Type(Champ($j;$k)->)=Est une date )

98. TOUT SELECTIONNER(Table($j)->)

100. Boucle ($i;1;Enregistrements trouves(Table($j)->))

101. $DateBuffer:=Champ($j;$k)->

102. Champ($j;$k)->:=$Date

103. STOCKER ENREGISTREMENT(Table($j)->)

104. Champ($j;$k)->:=$DateBuffer

105. STOCKER ENREGISTREMENT(Table($j)->)

106. $tableName:=Nom de la table($j)

107. ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Champ : "

108. +Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))

109. ENREGISTREMENT SUIVANT(Table($j)->)

110. Fin de boucle

112. : (Type(Champ($j;$k)->)=Est une heure )

113. TOUT SELECTIONNER(Table($j)->)

115. Boucle ($i;1;Enregistrements trouves(Table($j)->))

116. $TimeBuffer:=Champ($j;$k)->

117. Champ($j;$k)->:=$Time

118. STOCKER ENREGISTREMENT(Table($j)->)

119. Champ($j;$k)->:=$TimeBuffer

120. STOCKER ENREGISTREMENT(Table($j)->)

121. $tableName:=Nom de la table($j)

122. ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Champ : "

123. +Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))

124. ENREGISTREMENT SUIVANT(Table($j)->)

125. Fin de boucle

127. : (Type(Champ($j;$k)->)=Est une image )

128. TOUT SELECTIONNER(Table($j)->)

130. Boucle ($i;1;Enregistrements trouves(Table($j)->))

131. $PictureBuffer:=Champ($j;$k)->

132. Champ($j;$k)->:=$Picture

133. STOCKER ENREGISTREMENT(Table($j)->)

134. Champ($j;$k)->:=$PictureBuffer

135. STOCKER ENREGISTREMENT(Table($j)->)

136. $tableName:=Nom de la table($j)

137. ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Field : "

138. +Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))

139. ENREGISTREMENT SUIVANT(Table($j)->)

140. Fin de boucle

142. : (Type(Champ($j;$k)->)=Est un numérique )

143. TOUT SELECTIONNER(Table($j)->)

145. Boucle ($i;1;Nombre de champs(Table($j)))

146. $RealBuffer:=Champ($j;$k)->

147. Champ($j;$k)->:=$Real

148. STOCKER ENREGISTREMENT(Table($j)->)

149. Champ($j;$k)->:=$RealBuffer

150. STOCKER ENREGISTREMENT(Table($j)->)

151. $tableName:=Nom de la table($j)

152. ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Champ : "

153. +Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))

154. ENREGISTREMENT SUIVANT(Table($j)->)

155. Fin de boucle

157. : (Type(Champ($j;$k)->)=Est un BLOB )

158. TOUT SELECTIONNER(Table($j)->)

160. Boucle ($i;1;Enregistrements trouves(Table($j)->))

161. $BlobBuffer:=Champ($j;$k)->

162. Champ($j;$k)->:=$Blob

163. STOCKER ENREGISTREMENT(Table($j)->)

164. Champ($j;$k)->:=$BlobBuffer

165. STOCKER ENREGISTREMENT(Table($j)->)

166. $tableName:=Nom de la table($j)

167. ENVOYER PAQUET($vhDoc;"OK "+"Table : "+$tableName+" "+"Champ : "

168. +Chaine($k)+" "+"Enreg. : "+Chaine($i)+Caractere(13))

169. ENREGISTREMENT SUIVANT(Table($j)->)

170. Fin de boucle

172. : (Type(Champ($j;$k)->)=Est une sous table )

173. `ne rien faire

174. Fin de cas

175. Fin de boucle

176. Fin de boucle

178. ENVOYER PAQUET($vhDoc;"Tous les enregistrements sont OK"+Caractere(13))

179. FERMER DOCUMENT($vhDoc)      ` Close the document

180. Sinon

181. ALERTE("Impossible de créer le fichier \"LogEnregistrements\".")

182. 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.

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