Mysql
 sql >> Database >  >> RDS >> Mysql

Il mio database MySQL è danneggiato... Cosa devo fare ora?

In che modo le tabelle MySQL vengono danneggiate? Ci sono molti modi per rovinare i file di dati. Spesso, la corruzione è dovuta a difetti della piattaforma sottostante, su cui MySQL fa affidamento per archiviare e recuperare i dati:sottosistema del disco, controller, canali di comunicazione, driver, firmware o altri errori hardware. Il danneggiamento dei dati può verificarsi anche se il demone del server MySQL si riavvia improvvisamente o il server si riavvia a causa di un arresto anomalo di altri componenti del sistema operativo. Se l'istanza del database stava scrivendo i dati sul disco, potrebbe scrivere i dati parzialmente, il che potrebbe finire con un checksum della pagina diverso dal previsto. Ci sono stati anche dei bug in MySQL, quindi anche se l'hardware del server è ok, MySQL stesso può causare danni.

Di solito, quando i dati MySQL vengono danneggiati, la raccomandazione è di ripristinarli dall'ultimo backup, passare al server DR o rimuovere il nodo interessato se si dispone di un cluster Galera per servire immediatamente i dati da altri nodi. In alcuni casi non è possibile:se il backup non è presente, il cluster non è mai stato configurato, la replica è inattiva da molto tempo o la procedura di ripristino di emergenza non è mai stata testata. Anche se disponi di un backup, potresti comunque voler intraprendere alcune azioni per tentare il ripristino poiché potrebbe volerci meno tempo per tornare online.

MyISAM, il brutto e il cattivo

InnoDB è più tollerante ai guasti di MyISAM. InnoDB ha funzionalità di ripristino automatico ed è molto più sicuro rispetto al vecchio motore MyISAM.

Le tabelle MyISAM possono essere facilmente danneggiate quando si verificano molte scritture e molti blocchi si verificano su quella tabella. Il motore di archiviazione "scrive" i dati nella cache del filesystem, operazione che potrebbe richiedere del tempo prima che vengano scaricati sul disco. Pertanto, se il tuo server si riavvia improvvisamente, una quantità sconosciuta di dati nella cache viene persa. Questo è un modo normale per corrompere i dati di MyISAM. La raccomandazione è di migrare da MyISAM a InnoDB, ma potrebbero esserci casi in cui ciò non è possibile.

Primum non nocere, il backup

Prima di tentare di riparare le tabelle danneggiate, è necessario eseguire prima il backup dei file di database. Sì, è già rotto ma questo per ridurre al minimo il rischio di possibili ulteriori danni che potrebbero essere causati da un'operazione di ripristino. Non vi è alcuna garanzia che qualsiasi azione intrapresa non danneggi i blocchi di dati non toccati. Forzare il ripristino di InnoDB con valori maggiori di 4 può danneggiare i file di dati, quindi assicurati di farlo con un backup precedente e, idealmente, su una copia fisica separata del database.

Per eseguire il backup di tutti i file di tutti i database, segui questi passaggi:

Arresta il server MySQL

service mysqld stop

Digita il seguente comando per la tua datadir.

cp -r /var/lib/mysql /var/lib/mysql_bkp

Dopo aver ottenuto una copia di backup della directory dei dati, siamo pronti per iniziare la risoluzione dei problemi.

Identificazione del danneggiamento dei dati

Il registro degli errori è il tuo migliore amico. Di solito, quando si verifica un danneggiamento dei dati, troverai le informazioni rilevanti (compresi i collegamenti alla documentazione) nel registro degli errori. Se non sai dove si trova, controlla my.cnf e la variabile log_error, per maggiori dettagli consulta questo articolo https://dev.mysql.com/doc/refman/8.0/en/error-log-destination-configuration. html. Quello che dovresti anche sapere è il tuo tipo di motore di archiviazione. Puoi trovare queste informazioni nel registro degli errori o in information_schema.

mysql> select table_name,engine from information_schema.tables where table_name = '<TABLE>' and table_schema = '<DATABASE>';

Gli strumenti/comandi principali per diagnosticare problemi di danneggiamento dei dati sono CHECK TABLE, REPAIR TABLE e myisamchk. Il client mysqlcheck esegue la manutenzione delle tabelle:controlla, ripara (MyISAM), ottimizza o analizza le tabelle mentre MySQL è in esecuzione.

mysqlcheck -uroot -p <DATABASE>

Sostituisci DATABASE con il nome del database e sostituisci TABLE con il nome della tabella che vuoi controllare:

mysqlcheck -uroot -p <DATABASE> <TABLE>

Mysqlcheck controlla il database e le tabelle specificati. Se una tabella supera il controllo, mysqlcheck mostra OK per la tabella.

employees.departments                              OK
employees.dept_emp                                 OK
employees.dept_manager                             OK
employees.employees                                OK
Employees.salaries
Warning  : Tablespace is missing for table 'employees/salaries'
Error    : Table 'employees.salaries' doesn't exist in engine
status   : Operation failed
employees.titles                                   OK

I problemi di danneggiamento dei dati possono anche essere correlati a problemi di autorizzazione. In alcuni casi, il sistema operativo può cambiare il punto di montaggio in modalità di sola lettura a causa di problemi di R/W o ciò può essere causato da un utente che ha accidentalmente cambiato la proprietà dei file di dati. In questi casi, troverai le informazioni rilevanti nel registro degli errori.

[[email protected] employees]# ls -rtla
...
-rw-rw----. 1 mysql mysql  28311552 05-10 06:24 titles.ibd
-rw-r-----. 1 root  root  109051904 05-10 07:09 salaries.ibd
drwxr-xr-x. 7 mysql mysql      4096 05-10 07:12 ..
drwx------. 2 mysql mysql      4096 05-10 07:17 .

Client MySQL

MariaDB [employees]> select count(*) from salaries;
ERROR 1932 (42S02): Table 'employees.salaries' doesn't exist in engine

Voce del registro errori

2018-05-10  9:15:38 140703666226944 [ERROR] InnoDB: Failed to find tablespace for table `employees`.`salaries` in the cache. Attempting to load the tablespace with space id 9
2018-05-10  9:15:38 140703666226944 [ERROR] InnoDB: Operating system error number 13 in a file operation.
2018-05-10  9:15:38 140703666226944 [ERROR] InnoDB: The error means mysqld does not have the access rights to the directory.
2018-05-10  9:15:38 140703666226944 [ERROR] InnoDB: Cannot open datafile for read-only: './employees/salaries.ibd' OS error: 81
2018-05-10  9:15:38 140703666226944 [ERROR] InnoDB: Operating system error number 13 in a file operation.
2018-05-10  9:15:38 140703666226944 [ERROR] InnoDB: The error means mysqld does not have the access rights to the directory.
2018-05-10  9:15:38 140703666226944 [ERROR] InnoDB: Could not find a valid tablespace file for `employees/salaries`. Please refer to http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting-datadict.html for how to resolve the issue.

Recupero della tabella InnoDB

Se stai utilizzando il motore di archiviazione InnoDB per una tabella di database, puoi eseguire il processo di ripristino di InnoDB.
Per abilitare il ripristino automatico, MySQL richiede che l'opzione innodb_force_recovery sia abilitata. Innodb_force_recovery forza l'avvio di InnoDB impedendo l'esecuzione di operazioni in background, in modo da poter eseguire il dump delle tabelle.

Per fare ciò apri my.cnf e aggiungi la seguente riga alla sezione [mysqld]:

[mysqld]
innodb_force_recovery=1
service mysql restart

Dovresti iniziare da innodb_force_recovery=1, salvare le modifiche nel file my.cnf, quindi riavviare il server MySQL utilizzando il comando appropriato per il tuo sistema operativo. Se sei in grado di scaricare le tue tabelle con un valore innodb_force_recovery di 3 o meno, allora sei relativamente al sicuro. In molti casi dovrai salire fino a 4 e come già sai questo può corrompere i dati.

[mysqld]
innodb_force_recovery=1
service mysql restart

Se necessario, passare al valore più alto, sei è il massimo e il più pericoloso.

Una volta che sei in grado di avviare il tuo database, digita il seguente comando per esportare tutti i database nel file databases.sql:

mysqldump --all-databases --add-drop-database --add-drop-table > dump.sql

Avvia mysql, quindi prova a eliminare il database o i database interessati utilizzando il comando DROP DATABASE. Se MySQL non è in grado di eliminare un database, puoi eliminarlo manualmente utilizzando i passaggi seguenti dopo aver arrestato il server MySQL.

service mysqld stop

Se non sei riuscito a eliminare un database, digita i seguenti comandi per eliminarlo manualmente.

cd /var/lib/mysql
rm -rf <DATABASE>

Assicurati di non eliminare le directory interne del database.
Al termine, commenta la seguente riga in [mysqld] per disabilitare la modalità di ripristino di InnoDB.

#innodb_force_recovery=...

Salva le modifiche nel file my.cnf, quindi avvia il server MySQL

service mysqld start

Digita il seguente comando per ripristinare i database dal file di backup creato nel passaggio 5:

mysql> tee import_database.log
mysql> source dump.sql

Riparazione di MyISAM

Se mysqlcheck segnala un errore per una tabella, digita il comando mysqlcheck con il flag -repair per risolverlo. L'opzione di riparazione mysqlcheck funziona mentre il server è attivo e in esecuzione.

mysqlcheck -uroot -p -r <DATABASE> <TABLE>

Se il server è inattivo e per qualsiasi motivo mysqlcheck non può riparare la tua tabella, hai comunque la possibilità di eseguire il ripristino direttamente sui file usando myisamchk. Con myisamchk, devi assicurarti che il server non abbia le tabelle aperte.

Ferma MySQL

service mysqld stop
cd /var/lib/mysql

Passa alla directory in cui si trova il database.

cd /var/lib/mysql/employees
myisamchk <TABLE>

Per controllare tutte le tabelle in un database, digita il seguente comando:

myisamchk *.MYI

Se il comando precedente non funziona, puoi provare a eliminare i file temporanei che potrebbero impedire il corretto funzionamento di myisamchk. Per fare ciò, torna alla directory data dir, quindi esegui il comando seguente:

ls */*.TMD

Se sono elencati file .TMD, eliminali:

rm */*.TMD

Quindi esegui nuovamente myisamchk.

Per tentare di riparare una tabella, eseguire il comando seguente, sostituendo TABLE con il nome della tabella che si desidera riparare:

myisamchk --recover <TABLE>

Riavvia il server MySQL

service mysqld start

Come evitare la perdita di dati

Ci sono diverse cose che puoi fare per ridurre al minimo il rischio di dati irrecuperabili. Innanzitutto i backup. Il problema con i backup è che a volte possono essere trascurati. Per i backup pianificati cron, di solito scriviamo script wrapper che rilevano problemi nel registro di backup, ma che non includono i casi in cui il backup non è stato avviato affatto. Cron a volte può bloccarsi e spesso non è impostato alcun monitoraggio. Un altro potenziale problema potrebbe essere il caso in cui il backup non è mai stato impostato. È buona norma eseguire i report da uno strumento separato che analizzerà lo stato del backup e informerà l'utente sulle pianificazioni di backup mancanti. Puoi usare ClusterControl per questo o scrivere i tuoi programmi.

Rapporto di backup operativo di ClusterControl

Per ridurre l'impatto del possibile danneggiamento dei dati, dovresti sempre considerare i sistemi in cluster. È solo questione di tempo quando il database si arresta in modo anomalo o viene danneggiato, quindi è bene avere una copia a cui puoi passare. Potrebbe essere la replica Master/Slave. L'aspetto importante qui è avere un ripristino automatico sicuro per ridurre al minimo la complessità del passaggio e ridurre al minimo il tempo di ripristino (RTO).

Caratteristiche di ripristino automatico di ClusterControl