Perché le tabelle MySQL si arrestano in modo anomalo? Come lo prevengo?


9

Sono l'amministratore di un sito Moodle che ha danneggiato la sua tabella Users ed è diventato inutilizzabile.

Fortunatamente, un semplice ha REPAIR TABLE mdl_userfatto di nuovo funzionare. Il fatto è che non so perché si sia effettivamente schiantato e reso inutilizzabile, e voglio assicurarmi di essere meglio preparato la prossima volta.

Non sono un DBA di grande esperienza, sono solo uno sviluppatore che fa molte cose, quindi per favore abbi pazienza.

Potrei semplicemente ripristinare un backup, ma immagino ci siano modi per prevenire gli arresti anomali.

Queste tabelle sono utf8_general_ci e utilizzano MyISAM.

Perché una tabella MySQL si arresta in modo anomalo? Cosa posso fare per evitare che ciò accada?

Risposte:


11

È piuttosto facile che una tabella MyISAM si blocchi.

Nell'intestazione di ogni tabella MyISAM è presente un contatore che tiene traccia di quanti handle di file aperti sono presenti sulla tabella.

Se avvii mysql e il numero nell'intestazione non corrisponde al numero di handle di file effettivi, mysqld considera la tabella come bloccata.

Se un semplice lo REPAIR TABLE mdl_userfa funzionare di nuovo ogni volta senza perdita di dati, ciò può indicare che hai un sito molto trafficato su cui scrive mdl_user.

Se dozzine di tabelle lo richiedono REPAIR TABLE, convertirò tutte le tabelle in InnoDB. Tuttavia, se la mdl_usertabella è l'unica tabella con questo problema, c'è qualcosa che puoi fare (per questo esempio, supponiamo che sia il database moodle);

Se vuoi che tutte le tabelle vengano lasciate come MyISAM

PASSAGGIO 01: Creare uno script di tabella di riparazione

echo "REPAIR TABLE moodle.mdl_user;" > /var/lib/mysql/MoodleStartUp.sql

PASSAGGIO 02: Dichiarare lo script di riparazione come file di avvio

Aggiungi questo a /etc/my.cnf

[mysqld]
init-file=/var/lib/mysql/MoodleStartUp.sql

PASSAGGIO 03: riavviare mysql

Ogni riavvio di mysql attiverà lo Script tabella riparazioni

Se vuoi che tutte le tabelle diventino InnoDB

Esegui questo codice per creare uno script di conversione in blocco delle tabelle MyISAM in InnoDB e visualizzalo

MYSQL_USER=root
MYSQL_PASS=password
MYSQL_CONN="-u${MYSQL_USER} -p ${MYSQL_PASS}"
echo "SET SQL_LOG_BIN = 0;" > /root/ConvertMyISAMToInnoDB.sql
mysql ${MYSQL_CONN} -A --skip-column-names -e"SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') InnoDBConversionSQL FROM information_schema.tables WHERE engine='MyISAM' AND table_schema NOT IN ('information_schema','mysql','performance_schema') ORDER BY (data_length+index_length)" > /root/ConvertMyISAMToInnoDB.sql
less /root/ConvertMyISAMToInnoDB.sql

Una volta che sei soddisfatto del contenuto dello script di conversione, eseguilo

mysql ${MYSQL_CONN} < /root/ConvertMyISAMToInnoDB.sql

AGGIORNAMENTO 2012-03-15 14:00 EDT

@Kevin , Durante l'utilizzo di MyISAM, cosa succede se rimanere senza spazio su disco è il tuo problema?

Ecco qualcosa da considerare: secondo la guida allo studio di certificazione MySQL 5.0 ,

inserisci qui la descrizione dell'immagine

bulletpoint # 11 dice quanto segue alle pagine 408.409 Sezione 29.2:

Se si esaurisce lo spazio su disco durante l'aggiunta di righe a una tabella MyISAM, non si verifica alcun errore. Il server sospende l'operazione fino a quando non diventa disponibile spazio, quindi completa l'operazione.

Quando esaurisci lo spazio su disco, non arrestare o eliminare mysql. Il conteggio degli handle di file aperti in qualsiasi MyISAM attualmente utilizzato non sarà cancellato. Pertanto, la tabella MyISAM è contrassegnata come bloccata. Se riesci a liberare spazio su disco nel volume di dati con mysqld ancora in esecuzione, mysqld si salverà una volta reso disponibile lo spazio su disco.


Risposta eccellente. Non conoscevo i bit degli handle di file e hai già risolto come posso prevenire (o riparare automaticamente) nel caso qualcosa vada storto. Qualche suggerimento per la sicurezza se il sito in effetti scrive molto su mdl_user (o su qualsiasi altra tabella)?
AeroCross

Dovresti fare tre cose: 1) aumentare la RAM, 2) aumentare max_connections, 3) passare a InnoDB.
RolandoMySQLDBA

Noob qui. Dove devo "eseguire" questo codice? Da un file caricato sul server o da qualche riga di comando?
UncaughtTypeError

0

Gestisco anche un sito moodle su mysql e la causa più comune di corruzione della tabella per noi è a corto di spazio su disco.


@RolandoMySQLDBA - sì, lo spazio su disco è sicuramente il problema (relativo ad altri processi e alla filosofia di gestione in generale). Sfortunatamente, non vediamo che il problema si risolva da solo quando lo spazio è libero, o non si risolve da solo in modo abbastanza tempestivo. La mia risposta è stata solo quella di sottolineare che con la nostra istanza di moodle / mysql, i problemi di spazio su disco possono causare arresti anomali delle tabelle, indipendentemente da cosa dovrebbe fare mysql / myisam.
Kevin,

-3

Ho trovato una buona riga per convertire tutte le tabelle in InnoDB:

mysql -u root -p dbName -e "show table status where Engine='MyISAM';" | 
    awk 'NR>1 {print "ALTER TABLE "$1" ENGINE = InnoDB;"}'  | 
    mysql -u root -p dbName

Il codice potrebbe essere ok per questo, ma non risponde alla domanda della prima parte (Perché una tabella MySQL si arresta in modo anomalo?). Se vuoi dire che risponde alla seconda parte (Come prevenirlo?), Aggiungi qualche spiegazione in più, per favore.
ypercubeᵀᴹ

Aggiungi anche maggiori dettagli. L'esecuzione di questo convertirà tutte le tabelle in un database? O l'intero server? Cosa succederà se una tabella non riesce a convertire e viene visualizzato un errore? È possibile che finiamo con alcune tabelle convertite e alcune lasciate in MyiSAM? In generale, quali altre cose un DBA dovrebbe considerare prima di eseguire questo?
ypercubeᵀᴹ
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.