Warum stürzen MySQL-Tabellen ab? Wie verhindere ich das?

9

Ich bin der Administrator einer Moodle- Site, deren Benutzertabelle beschädigt und unbrauchbar geworden ist.

Zum Glück hat ein einfacher REPAIR TABLE mdl_useres wieder funktioniert. Die Sache ist, dass ich nicht weiß, warum es tatsächlich abgestürzt ist und es unbrauchbar gemacht hat, und ich möchte sicherstellen, dass ich beim nächsten Mal besser vorbereitet bin.

Ich bin kein durch und durch erfahrener DBA - ich bin nur ein Entwickler, der eine Menge Sachen macht, also bitte nehmen Sie mit mir Kontakt auf.

Ich könnte einfach ein Backup wiederherstellen, aber ich denke, es gibt Möglichkeiten, Abstürze zu verhindern.

Diese Tabellen sind utf8_general_ci und verwenden MyISAM.

Warum stürzt eine MySQL-Tabelle ab? Was kann ich tun, um dies zu verhindern?

AeroCross
quelle

Antworten:

11

Es ist ziemlich leicht, dass eine MyISAM-Tabelle abstürzt.

In der Kopfzeile jeder MyISAM-Tabelle befindet sich ein Zähler, der verfolgt, wie viele offene Dateihandles für die Tabelle vorhanden sind.

Wenn Sie mysql starten und die Nummer im Header nicht mit der Anzahl der tatsächlichen Dateihandles übereinstimmt, behandelt mysqld die Tabelle als abgestürzt.

Wenn eine einfache Funktion REPAIR TABLE mdl_userjedes Mal ohne Datenverlust wieder funktioniert, kann dies darauf hinweisen, dass Sie über eine Website mit sehr hohem Datenverkehr verfügen, auf die geschrieben wird mdl_user.

Wenn Dutzende von Tabellen dies erfordern REPAIR TABLE, würde ich alle Tabellen in InnoDB konvertieren. Wenn die mdl_userTabelle jedoch die einzige Tabelle mit diesem Problem ist, können Sie Folgendes tun (in diesem Beispiel beispielsweise die Datenbank moodle).

Wenn Sie möchten, dass alle Tabellen als MyISAM verbleiben

SCHRITT 01: Erstellen Sie ein Reparaturtabellenskript

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

SCHRITT 02: Deklarieren Sie das Reparaturskript als Startdatei

Fügen Sie dies zu /etc/my.cnf hinzu

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

SCHRITT 03: Starten Sie MySQL neu

Jeder Neustart von MySQL löst das Repair Table Script aus

Wenn Sie möchten, dass alle Tabellen zu InnoDB werden

Führen Sie diesen Code aus, um ein Massenkonvertierungsskript von MyISAM-Tabellen in InnoDB zu erstellen, und zeigen Sie es an

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

Wenn Sie mit dem Inhalt des Konvertierungsskripts zufrieden sind, führen Sie es aus

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

UPDATE 2012-03-15 14:00 EDT

@ Kevin , was ist, wenn Sie MyISAM verwenden, wenn Ihnen der Speicherplatz ausgeht?

Folgendes ist zu beachten: Laut MySQL 5.0 Certification Study Guide ,

Geben Sie hier die Bildbeschreibung ein

Aufzählungspunkt Nr. 11 besagt Folgendes auf den Seiten 408.409, Abschnitt 29.2:

Wenn Ihnen beim Hinzufügen von Zeilen zu einer MyISAM-Tabelle nicht genügend Speicherplatz zur Verfügung steht, tritt kein Fehler auf. Der Server unterbricht den Vorgang, bis Speicherplatz verfügbar ist, und schließt den Vorgang dann ab.

Wenn Ihnen der Speicherplatz ausgeht, fahren Sie mysql nicht einfach herunter oder beenden Sie es. Die Anzahl der geöffneten Dateihandles in einem derzeit verwendeten MyISAM wurde nicht gelöscht. Daher ist die MyISAM-Tabelle als abgestürzt markiert. Wenn Sie Speicherplatz im Datenvolumen freigeben können, während mysqld noch ausgeführt wird, wird mysqld aktiviert, sobald Speicherplatz verfügbar ist.

RolandoMySQLDBA
quelle
Hervorragende Resonanz. Ich kannte das Bit der Dateihandles nicht und Sie haben bereits gelöst, wie ich verhindern (oder automatisch reparieren) kann, falls etwas schief geht. Irgendwelche Vorschläge zur Sicherheit, wenn die Site tatsächlich viele Schreibvorgänge in mdl_user (oder eine andere Tabelle) ausführt?
AeroCross
Sie sollten drei Dinge tun: 1) RAM erhöhen, 2) max_connections erhöhen, 3) zu InnoDB wechseln.
RolandoMySQLDBA
Noob hier. Wo "starte" ich diesen Code? Von einer auf den Server hochgeladenen Datei oder von einer Befehlszeile?
UncaughtTypeError
0

Ich verwalte auch eine Moodle-Site auf MySQL, und die häufigste Ursache für Tabellenkorruption ist, dass uns der Speicherplatz ausgeht.

Kevin
quelle
@ RolandoMySQLDBA - Ja, Speicherplatz ist sicherlich das Problem (im Zusammenhang mit einigen anderen Prozessen und der Verwaltungsphilosophie im Allgemeinen). Leider sehen wir nicht, dass sich das Problem von selbst löst, wenn der Speicherplatz gelöscht wird, oder es löst sich nicht rechtzeitig genug. Meine Antwort war nur, um darauf hinzuweisen, dass bei unserer Moodle / MySQL-Instanz Speicherplatzprobleme zu Tabellenabstürzen führen können, unabhängig davon, was MySQL / Myisam tun soll.
Kevin
-3

Ich habe eine gute Zeile gefunden, um alle Tabellen in InnoDB zu konvertieren:

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
Dmitry
quelle
Der Code mag dafür in Ordnung sein, beantwortet aber nicht die Frage des ersten Teils (Warum stürzt eine MySQL-Tabelle ab?). Wenn Sie meinen, dass es den zweiten Teil beantwortet (Wie kann man das verhindern?), Fügen Sie bitte weitere Erklärungen hinzu.
Ypercubeᵀᴹ
Fügen Sie auch weitere Details hinzu. Konvertiert das Ausführen alle Tabellen in einer Datenbank? Oder der ganze Server? Was passiert, wenn eine Tabelle nicht konvertiert werden kann und eine Fehlermeldung angezeigt wird? Ist es möglich, dass einige Tabellen konvertiert und einige in MyiSAM verbleiben? Welche anderen Dinge sollte ein DBA im Allgemeinen beachten, bevor er dies ausführt?
Ypercubeᵀᴹ