Come si identifica la corruzione della tabella InnoDB?


24

Ho alcune tabelle che sono partizionate e hanno diversi indici su uno slave replicato. Dopo aver copiato lo snapshot (verificato sicuro) su un nuovo slave e aver aggiornato mysqld dalla 5.1.42 alla 5.5.15 e aver riavviato la replica, visualizzo gli arresti anomali di InnoDB con il messaggio di errore "Puntatore non valido ..."

Questi errori si sono verificati su 2 server con hardware e O / S diversi. Dopo l'esecuzione:

ALTER TABLE .... COALESCE PARTION n;

il problema scompare per quel tavolo.

La mia domanda ha una portata più ampia, tuttavia, ed è "Come si identifica la corruzione della tabella InnoDB?" o riformulato "Come si valuta lo stato della tabella InnoDB?" È "CHECK TABLE" l'unico strumento disponibile per identificare i problemi pre-crash?

Non sono sicuro che sia importante, ma gli arresti anomali si sono verificati in esecuzione: Versione: socket '5.5.15-55-log': porta '/opt/mysql.sock': 3306 Percona Server (GPL), Release rel21.0, Revision 158


2
Ciao Randy! Penso che le risposte qui siano credibili: InnoDB ha identificato la propria corruzione. Forse dovresti riformulare la tua domanda, perché ciò che fai causerebbe la corruzione di InnoDB?
Morgan Tocker,

Risposte:


18

Morgan dà un suggerimento nel suo commento che InnoDB verifica costantemente la presenza di pagine danneggiate facendo checksum sulle pagine che legge. Se InnoDB rileva una mancata corrispondenza del checksum, arresta in modo anomalo il server.

Se si desidera accelerare tale processo (anziché attendere che InnoDB legga la pagina danneggiata), è possibile utilizzare innochecksum:

Poiché la mancata corrispondenza del checksum causerà l'arresto deliberato di InnoDB di un server in esecuzione, può essere preferibile utilizzare questo strumento piuttosto che attendere che un server nell'utilizzo della produzione incontri le pagine danneggiate.

Un avvertimento interessante:

innochecksum non può essere utilizzato su file tablespace che il server ha già aperto. Per tali file, è necessario utilizzare CHECK TABLE per controllare le tabelle all'interno del tablespace.

Quindi sì, per una tabella online CHECK TABLEè probabilmente lo strumento (o come sottolineato in un'altra risposta mysqlcheck se si desidera fare più di un singolo database alla volta).

Se riesci a chiudere il tuo database, puoi forzarlo usando i checksum innochecksum

Aneddoto : su un tablespace innodb di 29 GB (con innodb_file_per_table=1), questo script ha richiesto circa 2 minuti

#!/bin/bash
for i in $(ls /var/lib/mysql/*/*.ibd)
do
  innochecksum -v $i
done

Come bonus, però, poiché stai eseguendo Percona, hanno implementato un nuovo metodo per un checksum innodb veloce . Non l'ho mai usato, ma potrebbe accelerare il processo.


1
Ci proverò qui, sembra essere la soluzione che @randymelder sta cercando +1
marcio

2
Il server Percona ha alcune altre belle funzionalità. Vedi innodb_corrupt_table_action percona.com/doc/percona-server/5.5/reliability/… (!!)
Morgan Tocker,

@DTest: innochecksum è la strada da percorrere. Questo è un custode. +1 !!!
RolandoMySQLDBA

@DTest: Tanto di cappello oggi su questo !!!!
RolandoMySQLDBA

@MorganTocker Interessante. Dovrò recuperare il mio vuoto di conoscenza e fare qualche ricerca su percona
Derek Downey,

6

ATTENZIONE: prima di provare una di queste istruzioni si consiglia vivamente di verificare che sia presente un backup integro del database nelle mani, per ogni evenienza. (grazie a @Nick per l'avvertimento)

Prova a usare il mysqlcheckcomando. Su un terminale:

mysqlcheck -u username -p --databases database1 database2

Questo comando mostrerà un elenco di tutte le tabelle e uno stato che ti dirà se c'era qualche tipo di corruzione:

table1  OK
table2  OK
table3  OK
tableN  OK

Con quello in mano saprai già quali tavoli devi riparare. Nel caso in cui desideri riparare tutto in una volta:

mysqlcheck -u username -p --auto-repair --databases database1 database2 

Maggiori informazioni su mysqlcheck: http://dev.mysql.com/doc/refman/5.0/en/mysqlcheck.html

Nota: hai taggato la tua domanda con . Non avevo idea di cosa fosse, quindi ho cercato su Google. Sembra essere un fork di MySQL, ma non ho motivo di credere che i comandi siano incompatibili (dita incrociate).


Qualcuno mi ha indicato questa guida che contiene istruzioni più specifiche per il recupero del database InnoDB per situazioni più critiche in cui l'intero database non si avvia: http://www.softwareprojects.com/resources/programming/t-how-to-fix-mysql -database-MyISAM-innodb-1634.html


1
mysqlcheck è sinonimo di 'check table ...' -1
randomx


Non vero. In primo luogo, mysqlcheck è un'utilità della riga di comando e CHECK TABLE è un'istruzione SQL (è come confrontare l'arancione con i limoni). Inoltre, NON È possibile controllare un intero database con CHECK TABLE senza includere TUTTI i nomi delle tabelle nell'istruzione SQL ( non sarebbe anche molto produttivo)
marcio

E mysqlcheck ha un'opzione per - riparare automaticamente le tabelle che sono danneggiate mentre CHECK TABLE controlla solo se le tabelle sono corrotte o meno, ma non può effettuare alcuna riparazione.
marcio,

2
@randymelder - Sbagli a dire che mysqlcheck è sinonimo di CHECK TABLE. La documentazione si è collegato a stati: " mysqlcheckutilizza le istruzioni SQL CHECK TABLE, REPAIR TABLE, ANALYZE TABLE, e OPTIMIZE TABLEin un modo conveniente per l'utente determina quali istruzioni per l'uso per l'operazione che si desidera eseguire, e quindi invia le dichiarazioni al server da eseguire.. " Questo non è un sinonimo; questa è un'interfaccia utente per una raccolta di istruzioni.
Nick Chammas,

6

Secondo la Guida allo studio di certificazione MySQL 5.0, Pagina 443.444 Sezione 30.4 :

Puoi controllare le tabelle di InnoDB usando il comando CHECK TABLE o usando un programma client per emettere l'istruzione per te. Tuttavia, se una tabella InnoDB presenta problemi, non è possibile correggerla utilizzando REPAIR TABLE perché tale istruzione si applica solo a MyISAM.

Se un controllo di tabella indica che una tabella InnoDB presenta problemi, dovresti essere in grado di ripristinare la tabella in uno stato coerente scaricandola con mysqldump, rilasciandola e ricreandola da quel dump.

In caso di arresto anomalo di un server MySQL o dell'host su cui viene eseguito, alcune tabelle InnoDB potrebbero richiedere riparazioni. Normalmente, è sufficiente riavviare il server perché il motore di archiviazione InnoDB esegue il ripristino automatico come parte della sequenza di avvio. In rari casi, il server potrebbe non avviarsi a causa del fallimento del ripristino automatico di InnoDB. In tal caso, utilizzare la seguente procedura:

  • Riavviare il server con l'opzione --innodb_force_recovery impostata su un valore nella rabbia da 1 a 6. Questi valori indicano livelli crescenti di cautela per evitare un arresto anomalo e livelli crescenti di tolleranza per possibili incoerenze nelle tabelle recuperate. Un buon valore per iniziare è 4.

  • Quando si avvia il server con --innodb_force_recovery impostato su un valore diverso da zero, InnoDB considera il tablespace come di sola lettura. Di conseguenza, è necessario scaricare le tabelle InnoDB con mysqldump e quindi rilasciarle mentre l'opzione è attiva. Quindi riavviare il server senza l'opzione --innodb_force_recovery. Quando viene visualizzato il server, ripristinare le tabelle InnoDB dai file di dump.

  • Se i passaggi precedenti falliscono, è necessario ripristinare le tabelle InnoDB da un backup precedente.

Leggi i documenti MySQL su InnoDB Forced Recovery  


3
FWIW, la guida alla certificazione ha una risposta politicamente corretta :) Se CONTROLLA TABELLA su una tabella InnoDB e in realtà è corrotta, non tornerà mai come "corrotta", causerà l'arresto anomalo del server. La dichiarazione è quasi obsoleta in InnoDB, perché ogni volta che leggi le pagine di InnoDB verifica la corruzione (tramite i checksum delle pagine).
Morgan Tocker,

2

Mi chiedo cosa succede se qualcuno utilizza i dati InnoDB creati tramite il plug-in InnoDB e passa quindi a un'altra versione di InnoDB. Ciò potrebbe creare una possibile corruzione della pagina agli occhi di mysqld.

Nota cosa dice la documentazione MySQL sul formato di file InnoDB su questa possibilità:

In generale, una versione più recente di InnoDB può creare una tabella o un indice che non può essere letto o scritto in modo sicuro con una versione precedente di InnoDB senza il rischio di arresti anomali, blocchi, risultati errati o corruzioni. Il plug-in InnoDB introduce un nuovo meccanismo per proteggere da queste condizioni e per aiutare a preservare la compatibilità tra i file di database e le versioni di InnoDB.

Vorrei eliminare i dati sullo slave. In effetti, userei semplicemente la forza bruta ottenendo un dump logico (mysqldump) dei dati:

  • Rilascia tutti i database usando InnoDB sullo slave
  • Spegni mysql sullo schiavo
  • Elimina ibdata1, ib_logfile0 e ib_logfile1 sullo slave
  • Avviare mysql sullo slave, lasciando ricreare ibdata1, ib_logfile0 e ib_logfile1
  • mysqldump i dati dal master allo slave

La mia risposta originale è considerata "vecchia scuola". Tuttavia, in questo caso, esaminerei sicuramente i formati di file utilizzati da .ibd e / o ibdata1.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.