Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Meine MySQL-Datenbank ist beschädigt... Was mache ich jetzt?

Wie werden MySQL-Tabellen beschädigt? Es gibt viele Möglichkeiten, Datendateien zu beschädigen. Beschädigungen sind häufig auf Fehler in der zugrunde liegenden Plattform zurückzuführen, auf die sich MySQL zum Speichern und Abrufen von Daten verlässt – Festplatten-Subsystem, Controller, Kommunikationskanäle, Treiber, Firmware oder andere Hardwarefehler. Datenbeschädigung kann auch auftreten, wenn der MySQL-Server-Daemon plötzlich neu gestartet wird oder Ihr Server aufgrund eines Absturzes anderer Betriebssystemkomponenten neu gestartet wird. Wenn die Datenbankinstanz gerade dabei war, Daten auf die Festplatte zu schreiben, könnte sie die Daten teilweise schreiben, was zu einer anderen Seitenprüfsumme als erwartet führen kann. Es gab auch Bugs in MySQL, so dass selbst wenn die Server-Hardware in Ordnung ist, MySQL selbst eine Beschädigung verursachen kann.

Wenn MySQL-Daten beschädigt werden, lautet die Empfehlung normalerweise, sie aus der letzten Sicherung wiederherzustellen, zum DR-Server zu wechseln oder den betroffenen Knoten herunterzufahren, wenn Sie einen Galera-Cluster haben, um Daten sofort von anderen Knoten bereitzustellen. In einigen Fällen ist dies nicht möglich - wenn das Backup nicht vorhanden ist, der Cluster nie eingerichtet wurde, Ihre Replikation sehr lange ausgefallen ist oder das DR-Verfahren nie getestet wurde. Auch wenn Sie über ein Backup verfügen, möchten Sie möglicherweise einige Maßnahmen ergreifen, um eine Wiederherstellung zu versuchen, da es möglicherweise weniger Zeit in Anspruch nimmt, wieder online zu gehen.

MyISAM, das Böse und Hässliche

InnoDB ist fehlertoleranter als MyISAM. InnoDB verfügt über auto_recovery-Funktionen und ist im Vergleich zur älteren MyISAM-Engine viel sicherer.

MyISAM-Tabellen können leicht beschädigt werden, wenn viele Schreibvorgänge und viele Sperren auf dieser Tabelle stattfinden. Die Speicher-Engine „schreibt“ Daten in den Dateisystem-Cache, was einige Zeit dauern kann, bevor sie auf die Festplatte geleert werden. Wenn Ihr Server plötzlich neu startet, gehen daher einige unbekannte Datenmengen im Cache verloren. Das ist ein üblicher Weg, um MyISAM-Daten zu beschädigen. Die Empfehlung lautet, von MyISAM auf InnoDB zu migrieren, aber es kann Fälle geben, in denen dies nicht möglich ist.

Primum non nocere, die Sicherung

Bevor Sie versuchen, beschädigte Tabellen zu reparieren, sollten Sie zuerst Ihre Datenbankdateien sichern. Ja, es ist bereits kaputt, aber dies dient dazu, das Risiko möglicher weiterer Schäden zu minimieren, die durch eine Wiederherstellungsoperation verursacht werden können. Es gibt keine Garantie dafür, dass Ihre Maßnahmen unberührte Datenblöcke nicht beschädigen. Das Erzwingen einer InnoDB-Wiederherstellung mit Werten über 4 kann Datendateien beschädigen, also stellen Sie sicher, dass Sie dies mit einer vorherigen Sicherung und idealerweise auf einer separaten physischen Kopie der Datenbank tun.

Führen Sie die folgenden Schritte aus, um alle Dateien aus all Ihren Datenbanken zu sichern:

Stoppen Sie den MySQL-Server

service mysqld stop

Geben Sie den folgenden Befehl für Ihr Datenverzeichnis ein.

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

Nachdem wir eine Sicherungskopie des Datenverzeichnisses haben, können wir mit der Fehlerbehebung beginnen.

Identifizierung von Datenkorruption

Das Fehlerprotokoll ist Ihr bester Freund. Wenn Daten beschädigt werden, finden Sie normalerweise relevante Informationen (einschließlich Links zur Dokumentation) im Fehlerprotokoll. Wenn Sie nicht wissen, wo es sich befindet, überprüfen Sie my.cnf und die Variable log_error. Weitere Einzelheiten finden Sie in diesem Artikel https://dev.mysql.com/doc/refman/8.0/en/error-log-destination-configuration. html. Was Sie auch wissen sollten, ist Ihr Speicher-Engine-Typ. Sie finden diese Informationen im Fehlerprotokoll oder in information_schema.

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

Die wichtigsten Tools/Befehle zur Diagnose von Problemen mit Datenbeschädigung sind CHECK TABLE, REPAIR TABLE und myisamchk. Der mysqlcheck-Client übernimmt die Tabellenpflege:Er prüft, repariert (MyISAM), optimiert oder analysiert Tabellen, während MySQL läuft.

mysqlcheck -uroot -p <DATABASE>

Ersetzen Sie DATABASE durch den Namen der Datenbank und TABLE durch den Namen der Tabelle, die Sie überprüfen möchten:

mysqlcheck -uroot -p <DATABASE> <TABLE>

Mysqlcheck überprüft die angegebene Datenbank und Tabellen. Wenn eine Tabelle die Prüfung besteht, zeigt mysqlcheck OK für die Tabelle an.

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

Datenkorruptionsprobleme können auch mit Berechtigungsproblemen zusammenhängen. In einigen Fällen kann das Betriebssystem den Einhängepunkt aufgrund von R/W-Problemen in den schreibgeschützten Modus umschalten oder dies kann durch einen Benutzer verursacht werden, der versehentlich den Besitz der Datendateien geändert hat. In solchen Fällen finden Sie entsprechende Informationen im Fehlerprotokoll.

[[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 .

MySQL-Client

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

Fehlerprotokolleintrag

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.

InnoDB-Tabelle wird wiederhergestellt

Wenn Sie die InnoDB-Speicher-Engine für eine Datenbanktabelle verwenden, können Sie den InnoDB-Wiederherstellungsprozess ausführen.
Um die automatische Wiederherstellung zu aktivieren, muss die Option innodb_force_recovery aktiviert sein. Innodb_force_recovery erzwingt den Start von InnoDB und verhindert gleichzeitig, dass Hintergrundoperationen ausgeführt werden, sodass Sie Ihre Tabellen sichern können.

Öffnen Sie dazu my.cnf und fügen Sie die folgende Zeile zum Abschnitt [mysqld] hinzu:

[mysqld]
innodb_force_recovery=1
service mysql restart

Sie sollten bei innodb_force_recovery=1 beginnen, die Änderungen an der Datei my.cnf speichern und dann den MySQL-Server mit dem entsprechenden Befehl für Ihr Betriebssystem neu starten. Wenn Sie Ihre Tabellen mit einem innodb_force_recovery-Wert von 3 oder weniger sichern können, sind Sie relativ sicher. In vielen Fällen müssen Sie auf 4 hochgehen und wie Sie bereits wissen, kann dies Daten beschädigen.

[mysqld]
innodb_force_recovery=1
service mysql restart

Wechseln Sie bei Bedarf auf den höheren Wert, sechs ist das Maximum und am gefährlichsten.

Sobald Sie Ihre Datenbank starten können, geben Sie den folgenden Befehl ein, um alle Datenbanken in die Datei databases.sql zu exportieren:

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

Starten Sie mysql und versuchen Sie dann, die betroffene(n) Datenbank(en) mit dem Befehl DROP DATABASE zu löschen. Wenn MySQL eine Datenbank nicht löschen kann, können Sie sie mit den folgenden Schritten manuell löschen, nachdem Sie den MySQL-Server gestoppt haben.

service mysqld stop

Wenn Sie eine Datenbank nicht löschen konnten, geben Sie die folgenden Befehle ein, um sie manuell zu löschen.

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

Stellen Sie sicher, dass Sie die internen Datenbankverzeichnisse nicht löschen.
Wenn Sie fertig sind, kommentieren Sie die folgende Zeile in [mysqld] aus, um den InnoDB-Wiederherstellungsmodus zu deaktivieren.

#innodb_force_recovery=...

Speichern Sie die Änderungen in der Datei my.cnf und starten Sie dann den MySQL-Server

service mysqld start

Geben Sie den folgenden Befehl ein, um die Datenbanken aus der in Schritt 5 erstellten Sicherungsdatei wiederherzustellen:

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

MyISAM reparieren

Wenn mysqlcheck einen Fehler für eine Tabelle meldet, geben Sie den Befehl mysqlcheck mit dem Flag -repair ein, um ihn zu beheben. Die mysqlcheck-Reparaturoption funktioniert, während der Server läuft.

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

Wenn der Server heruntergefahren ist und mysqlcheck Ihre Tabelle aus irgendeinem Grund nicht reparieren kann, haben Sie immer noch die Möglichkeit, mit myisamchk eine Wiederherstellung direkt an Dateien durchzuführen. Bei myisamchk müssen Sie sicherstellen, dass der Server die Tabellen nicht geöffnet hat.

Beenden Sie MySQL

service mysqld stop
cd /var/lib/mysql

Wechseln Sie in das Verzeichnis, in dem sich die Datenbank befindet.

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

Geben Sie den folgenden Befehl ein, um alle Tabellen in einer Datenbank zu überprüfen:

myisamchk *.MYI

Wenn der vorherige Befehl nicht funktioniert, können Sie versuchen, temporäre Dateien zu löschen, die möglicherweise verhindern, dass myisamchk ordnungsgemäß ausgeführt wird. Wechseln Sie dazu zurück in das Verzeichnis data dir und führen Sie dann den folgenden Befehl aus:

ls */*.TMD

Wenn .TMD-Dateien aufgelistet sind, löschen Sie sie:

rm */*.TMD

Führen Sie dann myisamchk erneut aus.

Um zu versuchen, eine Tabelle zu reparieren, führen Sie den folgenden Befehl aus und ersetzen Sie TABLE durch den Namen der Tabelle, die Sie reparieren möchten:

myisamchk --recover <TABLE>

Starten Sie den MySQL-Server neu

service mysqld start

So vermeiden Sie Datenverlust

Es gibt mehrere Dinge, die Sie tun können, um das Risiko nicht wiederherstellbarer Daten zu minimieren. Erstmal Backups. Das Problem mit Backups ist, dass sie manchmal übersehen werden können. Für cron-geplante Backups schreiben wir normalerweise Wrapper-Skripte, die Probleme im Backup-Protokoll erkennen, aber das schließt keine Fälle ein, in denen das Backup überhaupt nicht gestartet wurde. Cron kann manchmal hängen bleiben und oft ist keine Überwachung darauf eingestellt. Ein weiteres potenzielles Problem könnte der Fall sein, wenn das Backup nie eingerichtet wurde. Es empfiehlt sich, Berichte von einem separaten Tool auszuführen, das den Sicherungsstatus analysiert und Sie über fehlende Sicherungszeitpläne informiert. Sie können dafür ClusterControl verwenden oder Ihre eigenen Programme schreiben.

ClusterControl-Betriebssicherungsbericht

Um die Auswirkungen einer möglichen Datenbeschädigung zu verringern, sollten Sie immer geclusterte Systeme in Betracht ziehen. Es ist nur eine Frage der Zeit, wann die Datenbank abstürzt oder beschädigt wird, daher ist es gut, eine Kopie zu haben, zu der Sie wechseln können. Es könnte sich um eine Master / Slave-Replikation handeln. Der wichtige Aspekt hierbei ist eine sichere automatische Wiederherstellung, um die Komplexität der Umstellung zu minimieren und die Wiederherstellungszeit (RTO) zu minimieren.

Automatische Wiederherstellungsfunktionen von ClusterControl