Come riparo una tabella InnoDB?
Domanda
Abbiamo (apparentemente) eseguito male il nostro motore di database MySQL Solaris ieri sera. Almeno alcune delle tabelle di InnoDB sono danneggiate, con errori di timestamp fuori servizio nel registro delle transazioni e un errore specifico sull'indice corrotto.
Conosciamo gli strumenti disponibili per le riparazioni della tabella MyISAM, ma non troviamo nulla per InnoDB.
Nota a margine: il tentativo di ottimizzare una tabella (nel mio tentativo di ricostruire l'indice danneggiato) provoca l'arresto anomalo del server di database.
Soluzione
Prima di tutto arresta il server e immagini il disco . Non ha senso solo sparare a questo. Dai un'occhiata qui .
Altri suggerimenti
interrompe l'applicazione ... o interrompe lo slave in modo che non vengano aggiunte nuove righe
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>;
riavvia il tuo server o slave
La seguente soluzione è stata ispirata dal suggerimento di Sandro sopra.
Avviso : mentre ha funzionato per me, ma non so dire se funzionerà per te.
Il mio problema era il seguente: la lettura di alcune righe specifiche da una tabella (chiamiamo questa tabella broken
) causava l'arresto anomalo di MySQL. Anche SELEZIONA COUNT (*) DA rotto
lo ucciderebbe. Spero che tu abbia un PRIMARY KEY
su questa tabella (nel seguente esempio, è id
).
- Assicurati di avere un backup o un'istantanea del server MySQL guasto (nel caso in cui desideri tornare al passaggio 1 e provare qualcos'altro!)
-
CREA TABELLA broken_repair COME Rotto;
-
INSERISCI rotto_repair SELEZIONA * DA rotto DOVE ID NON IN (SELEZIONA ID DA broken_repair) LIMIT 1;
- Ripeti il ??passaggio 3 fino a quando non si blocca il DB (puoi usare
LIMIT 100000
e quindi usare valori più bassi, fino a quandoLIMIT 1
non blocca il DB). - Verifica se hai tutto (puoi confrontare
SELEZIONA MAX (id) DA rotto
con il numero di righe inbroken_repair
). - A questo punto, apparentemente avevo tutte le mie righe (tranne quelle che probabilmente erano state troncate selvaggiamente da InnoDB). Se perdi alcune righe, puoi provare ad aggiungere un
OFFSET
alLIMIT
.
Buona fortuna!
Ecco la soluzione fornita da MySQL: http://dev.mysql.com/doc/refman /5.5/en/forcing-innodb-recovery.html
Vedi questo articolo: http://www.unilogica.com/mysql-innodb-recovery / (è in portoghese)
Viene spiegato come utilizzare innodb_force_recovery e innodb_file_per_table . L'ho scoperto dopo aver bisogno di ripristinare un database bloccato con un singolo ibdata1 .
Usando innodb_file_per_table, tutte le tabelle in InnoDB creeranno un file di tabella separato, come MyISAM.
Passaggio 1.
Arresta il server MySQL
Passaggio 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 correttamente la tabella innodb bloccata, non dimenticare di rimuovere # set-variabile = innodb_force_recovery = 6 da my.cnf e quindi riavviare nuovamente il server MySQL.