web-dev-qa-db-fra.com

Comment réparer une table InnoDB?

Nous avons (apparemment) mal exécuté notre moteur de base de données Solaris MySQL hier soir. Au moins certaines des tables InnoDB sont corrompues, avec des erreurs d'horodatage en panne dans le journal des transactions et une erreur spécifique concernant l'index corrompu.

Nous connaissons les outils disponibles pour les réparations de tables MyISAM, mais nous ne trouvons rien pour InnoDB.

Note latérale: la tentative d'optimisation d'une table (dans ma tentative de reconstruction de l'index corrompu) provoque le crash du serveur de base de données.

33
lefticus

Tout d'abord arrêtez le serveur et créez une image du disque. Il ne sert à rien d'avoir un seul coup à ce sujet. Alors jetez un oeil ici .

26
Jon Topper

arrêtez votre application ... ou arrêtez votre esclave afin qu'aucune nouvelle ligne ne soit ajoutée

create table <new table> like <old table>;
insert <new table> select * from <old table>;
truncate table  <old table>;
insert <old table> select * from <new table>;

redémarrez votre serveur ou esclave

21
Sandro Frattura

La solution suivante a été inspirée par l'astuce de Sandro ci-dessus.

Attention: alors que cela a fonctionné pour moi, mais je ne peux pas dire si cela fonctionnera pour vous.

Mon problème était le suivant: lire certaines lignes spécifiques d'une table (appelons cette table broken) plantait MySQL. Même SELECT COUNT(*) FROM broken le tuerait. J'espère que vous avez un PRIMARY KEY Sur cette table (dans l'exemple suivant, c'est id).

  1. Assurez-vous d'avoir une sauvegarde ou un instantané du serveur MySQL cassé (juste au cas où vous voudriez revenir à l'étape 1 et essayer autre chose!)
  2. CREATE TABLE broken_repair LIKE broken;
  3. INSERT broken_repair SELECT * FROM broken WHERE id NOT IN (SELECT id FROM broken_repair) LIMIT 1;
  4. Répétez l'étape 3 jusqu'à ce qu'il plante la base de données (vous pouvez utiliser LIMIT 100000 Puis utiliser des valeurs inférieures, jusqu'à ce que l'utilisation de LIMIT 1 Plante la base de données).
  5. Voyez si vous avez tout (vous pouvez comparer SELECT MAX(id) FROM broken avec le nombre de lignes dans broken_repair).
  6. À ce stade, j'avais apparemment toutes mes lignes (sauf celles qui étaient probablement sauvagement tronquées par InnoDB). Si vous manquez quelques lignes, vous pouvez essayer d'ajouter un OFFSET au LIMIT.

Bonne chance!

6
jpetazzo
4
freytag

Voir cet article: http://www.unilogica.com/mysql-innodb-recovery/ (C'est en portugais)

On explique comment utiliser innodb_force_recovery et innodb_file_per_table . J'ai découvert cela après avoir besoin de récupérer une base de données en panne avec un seul ibdata1 .

En utilisant innodb_file_per_table, toutes les tables dans InnoDB créeront un fichier de table séparé, comme MyISAM.

0
Ragen Dazs