Come posso riparare una tabella InnoDB?

Noi (apparentemente) abbiamo mal eseguito il nostro motore di database Solaris MySQL ieri sera. Almeno alcune delle tabelle InnoDB sono danneggiate, con errori di data / ora non corretti nel log delle transazioni e un errore specifico sull’indice corrotto.

Sappiamo degli strumenti disponibili per le riparazioni delle tabelle MyISAM, ma non riesco a trovare nulla per InnoDB.

Nota a margine: il tentativo di ottimizzare una tabella (nel mio tentativo di ribuild l’indice danneggiato) causa l’arresto anomalo del server del database.

Prima di tutto, fermate il server e visualizzate il disco . Non ha senso avere un solo colpo a questo. Allora dai un’occhiata qui .

ferma la tua applicazione … o ferma il tuo schiavo in modo che non vengano aggiunte nuove righe

create table  like ; insert  select * from ; truncate table ; insert  select * from ; 

riavvia il tuo server o slave

La seguente soluzione è stata ispirata dal suggerimento di Sandro sopra.

Attenzione : mentre ha funzionato per me, ma non posso dire se funzionerà per te.

Il mio problema era il seguente: leggere alcune righe specifiche da una tabella (chiamiamo questa tabella broken ) avrebbe fatto crashare MySQL. Anche SELECT COUNT(*) FROM broken lo ucciderebbe. Spero che tu abbia una PRIMARY KEY su questo tavolo (nel seguente esempio, è id ).

  1. Assicurati di avere un backup o un’istantanea del server MySQL danneggiato (nel caso tu voglia tornare al punto 1 e provare qualcos’altro!)
  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. Ripetere il passaggio 3 fino a quando non si blocca il DB (è ansible utilizzare LIMIT 100000 e quindi utilizzare valori inferiori, fino a quando non si utilizza LIMIT 1 anomalo sul DB).
  5. Vedi se hai tutto (puoi confrontare SELECT MAX(id) FROM broken con il numero di righe in broken_repair ).
  6. A questo punto, apparentemente avevo tutte le mie file (eccetto quelle che sono state probabilmente troncate selvaggiamente da InnoDB). Se ti perdi alcune righe, potresti provare ad aggiungere un OFFSET al LIMIT .

In bocca al lupo!

Vedi questo articolo: http://www.unilogica.com/mysql-innodb-recovery/ (It’s in portuguese)

Vengono spiegati come usare innodb_force_recovery e innodb_file_per_table . Ho scoperto questo dopo aver bisogno di recuperare un database in crash con un singolo ibdata1 .

Usando innodb_file_per_table, tutte le tabelle in InnoDB creeranno un file tabella separato, come MyISAM.

Passo 1.

Arresta il server MySQL

Passo 2.

aggiungi questa linea a my.cnf (in windows si chiama my.ini)

 set-variable=innodb_force_recovery=6 

Passaggio 3.

elimina ib_logfile0 e ib_logfile1

Passaggio 4.

Avvia il server MySQL

Passaggio 5.

Esegui questo comando:

 mysqlcheck --database db_name table_name -uroot -p 

Dopo aver corretto con successo la tabella innodb arrestata, non dimenticare di rimuovere # set-variable = innodb_force_recovery = 6 da my.cnf e quindi riavviare nuovamente il server MySQL.