«Cannot commit index» или как выкачать данные из частично восстановленной (несогласованной) базы данных
Alexey Kovyazin, dernière mise à jour le 30 mars 2014
Après avoir corrigé les corruptions, il est fréquent de voir l’erreur « Cannot commit index » lors de l’étape de restauration. Dans Firebird 2.0 et versions ultérieures, cela apparaît comme un avertissement et la base de données ne sera pas mise en ligne ; dans Firebird 1.0-1.5 et InterBase, cela se produit comme une erreur très désagréable qui arrête le processus de restauration (il est impressionnant de voir cette erreur à la fin de la restauration d’une base de données de 200 Go).
La raison de l’erreur « Cannot commit index.. » est évidente : la corruption affecte l’intégrité référentielle de la base de données, et les enregistrements disparaissent de manière magique (du point de vue du serveur).
Par exemple, vous avez une table « Customers » et une table associée « Orders » référencée par une clé étrangère. Sans corruption, il n’est pas possible de violer la clé étrangère et de supprimer un enregistrement de Customers sans d’abord supprimer toutes les commandes qui se réfèrent à un client particulier. La corruption affecte le fichier de base de données à bas niveau et supprime directement les enregistrements. Quelle belle surprise pour le serveur de voir des liens non résolus vers les enregistrements maîtres depuis les enregistrements de clés étrangères.
Ici, je dois ajouter une astuce concernant le processus de restauration : le moteur restaure toutes les tables avec des index non activés (ce qui rend le remplissage des tables avec des enregistrements beaucoup plus rapide), puis commence à activer (c’est-à-dire construire) les index un par un. Cela signifie que toutes les données sont déjà dans la base de données lorsque le processus de restauration commence l’étape de création des index et que vous voyez l’erreur « Cannot commit index.. ».
Eh bien, le premier réflexe lorsque vous voyez l’erreur « Cannot commit index » est de supprimer la contrainte de clé étrangère appropriée afin de permettre à la restauration de se terminer. La question est de savoir ce que nous allons faire avec une base de données incohérente mais restaurée avec succès : la clé étrangère supprimée peut être une partie importante de la logique métier.
Il y a 2 approches ici : recréer les données manquantes ou supprimer les données incohérentes. Voyons ce que cela signifie sur l’exemple Customers-Orders ci-dessus.
Recréation des données manquantes
Donc, vous avez décidé que vous devez recréer les Customers manquants pour les Orders incohérents. De cette façon, vous devez déterminer les ID perdus. Habituellement, j’utilise une requête SQL comme celle-ci (je pense qu’il sera facile de l’adapter à votre cas) :
SELECT O.Customer_ID FROM ORDERS O WHERE NOT EXISTS ( SELECT C.Customer_ID FROM CUSTOMERS C WHERE O.Customer_ID=C.Customer_ID)
Après cela, vous pouvez insérer manuellement des enregistrements avec la liste des clés primaires manquantes, puis relancer la sauvegarde/restauration.
Pompage des données cohérentes
Si vous pensez qu’il est acceptable de perdre des enregistrements incohérents, vous pouvez pomper toutes les données de la base partiellement restaurée vers une base vide et simplement ignorer les enregistrements incohérents, en utilisant l’approche suivante :
-
Téléchargez l’outil gratuit IBDataPump http://www.clevercomponents.com/demo/datapump/IBPump.zip
-
Créez uniquement la base de données de métadonnées à partir de la sauvegarde de la base réparée (après IBFirstAID) en utilisant la commande
gbak -c -m -user SYSDBA -pass masterkey Disk:\Path\backup.fbk Disk:\Path\fresh.fdb
-
Exécutez IBDataPump et définissez la base partiellement réparée comme Source, et la nouvelle base vide comme cible
-
Cliquez sur les onglets suivants, cliquez sur les boutons appropriés et sur le 3ème onglet cliquez sur « Pump ». Attendez la fin (cela peut être un long processus, pour avoir une idée, vous pouvez vérifier la dynamique de croissance de la taille de la base cible).
-
En conséquence, vous aurez une base fresh.fdb avec des relations de clés étrangères cohérentes - c’est tout à fait correct.
Si la base de données a une boucle avec des clés étrangères, IBDataPump vous avertira et vous donnera une liste de ces contraintes - une ou plusieurs d’entre elles doivent être supprimées avant que le pompage soit disponible.
Bien sûr, il y a eu des cas où le pompage nécessite une approche spéciale, et si vous rencontrez une telle situation, veuillez contacter notre support.