wake-up-neo.com

MySQL enthält eine falsche Schlüsseldatei für die tmp-Tabelle, wenn mehrere Joins erstellt werden

Ich komme nicht oft hierher, um Hilfe zu holen, aber ich bin ziemlich frustriert und ich hoffe, jemand hat es schon einmal erlebt.

Immer wenn ich versuche, Datensätze mit mehr als einem Join aus einer Tabelle abzurufen, erhalte ich den folgenden Fehler:

#126 - Incorrect key file for table '/tmp/#sql_64d_0.MYI'; try to repair it

Diese Abfrage erzeugt also den Fehler:

SELECT * FROM `core_username`
INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`)
INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`)
ORDER BY `core_username`.`name` ASC LIMIT 1

Aber dieser wird nicht:

SELECT * FROM `core_username`
INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`)
ORDER BY `core_username`.`name` ASC LIMIT 1

Und dieser wird auch nicht:

SELECT * FROM `core_username`
INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`)
ORDER BY `core_username`.`name` ASC LIMIT 1

Was könnte das verursachen? Ich weiß nicht wirklich, wie man eine tmp-Tabelle repariert, aber ich glaube nicht, dass das das Problem ist, da es jedes Mal eine neue tmp-Tabelle ist. Die Benutzername-Tabelle ist ziemlich groß (derzeit 233.718 Datensätze), aber ich bezweifle, dass dies irgendetwas damit zu tun hat.

Jede Hilfe wäre sehr dankbar.

[~ # ~] update [~ # ~] : Nach einigen weiteren Tests scheint der Fehler nur dann aufzutreten, wenn ich versuche, die Ergebnisse zu ordnen. Das heißt, diese Abfrage gibt mir das, was ich erwarte:

SELECT * FROM `core_username`
INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`)
INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`)
LIMIT 1

Aber wenn ich das hinzufüge:

ORDER BY `core_username`.`name` ASC

Der Fehler wird ausgelöst. Dies geschieht nur auf dem speziellen Webserver, den ich gerade benutze. Wenn ich die Datenbank herunterlade und das Gleiche auf meinem localhost sowie auf anderen Servern versuche, funktioniert es einwandfrei. Die MySQL-Version ist 5.0.77.

Da ich das weiß, bin ich ziemlich sicher, dass die zu erstellende tmp-Tabelle viel zu groß ist und MySQL-Chokes wie in diesem Blog-Beitrag beschrieben . Ich bin mir aber immer noch nicht sicher, wie die Lösung aussehen würde ...

57

Manchmal, wenn dieser Fehler bei temporären Tabellen auftritt:

#126 - Incorrect key file for table '/tmp/#sql_64d_0.MYI'; try to repair it

Es kann sein, weil die /tmp Ordner hat nicht mehr genügend Speicherplatz. Bei einigen Linux-Installationen wird /tmp befindet sich in einer eigenen Partition und hat nicht viel Speicherplatz - große MySQL-Abfragen füllen diese.

Sie können df -h um zu prüfen, ob \tmp befindet sich in einer eigenen Partition und gibt an, wie viel Speicherplatz ihm zugewiesen ist.

Wenn es sich in einer eigenen Partition befindet und wenig Speicherplatz zur Verfügung steht, können Sie entweder:

(a) ändere/tmp so, dass seine Partition mehr Platz hat (entweder durch Neuzuteilen oder Verschieben auf die Hauptpartition - z. B. siehe hier )
(b) Ändern der MySQL-Konfiguration, sodass ein anderer temporärer Ordner auf einer anderen Partition verwendet wird, z. /var/tmp

102
codeulike

Überprüfen Sie den verfügbaren Speicherplatz in MySQL tmpdir (in Ihrem Fall/tmp), während Sie die Abfragen ausführen, da er bei der Arbeit mit großen Tabellen Hunderte von MB aufnehmen kann. So etwas hat bei mir funktioniert:

$ while true; do df -h /tmp; sleep .5; done
20
Francesc Rosàs

führe das aus

REPAIR TABLE `core_username`,`core_site`,`core_person`;

oder mach das:

select * from (
 SELECT * FROM `core_username`
 INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`)
 INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`)
 LIMIT 1)
ORDER BY `name` ASC
6
Pentium10

Möglicherweise hilft das Ausführen von "ANALYZE TABLE".

Wir hatten dieses Problem plötzlich auf einer großen Tabelle (~ 100 Millionen Zeilen) und MySQL versuchte, mit/tmp eine temporäre Tabelle von über 1 GB zu schreiben, was fehlschlug, da/tmp auf ~ 600 Millionen beschränkt war.

Es stellte sich heraus, dass die Statistiken für die InnoDB-Tabelle ziemlich veraltet waren. Nach dem Ausführen von "ANALYZE TABLE ..." wurden die Statistiken aktualisiert und das Problem behoben. Mit der genaueren Statistik konnte MySQL die Abfrage korrekt optimieren und die große tmp-Datei wurde nicht mehr benötigt.

Wir führen jetzt "mysqlcheck -Aa" in regelmäßigen Abständen aus, um alle Tabellenstatistiken auf dem neuesten Stand zu halten.

4
Roger Lucas

Ich hatte dieses Problem mit einer Abfrage in einer Tabelle, die über 500.000 Datensätze verfügte. Es gab mir den gleichen genauen Fehlertyp, der auf eine .MYI-Datei im Verzeichnis/tmp zeigte, die bei der Überprüfung nur selten vorhanden war. Ich hatte bereits die Größe der Heap- und temporären Dateien in der Datei /etc/my.cnf erhöht.

Das Problem mit der Abfrage war, dass sie in der Tat eine ORDER-Klausel am Ende enthielt. Wenn sie weggelassen wurde, funktionierte die Abfrage fehlerfrei. Es hatte auch ein Limit. Ich habe versucht, mir die letzten 5 Datensätze in der Tabelle anzusehen. In der ORDER-Klausel war sie erstickt und gab den Fehler aus.

Was geschah, war, dass mysqld eine interne temporäre Tabelle mit ALLEN Datensätzen aus der riesigen Tabelle erstellte, um die ORDER anzuwenden.

Die Art und Weise, wie ich das umgehen konnte, bestand darin, eine zusätzliche WHERE-Bedingung anzuwenden, die die Datensätze vom Riesentisch auf eine kleinere Menge beschränkt. Ich hatte bequemerweise ein Datum/Uhrzeit-Feld, aus dem herausgefiltert werden konnte.

Ich hoffe das hilft jemandem.

3
ClickWhisperer

Unter Unix verwendet MySQL den Wert der Umgebungsvariablen TMPDIR als Pfadnamen des Verzeichnisses, in dem temporäre Dateien gespeichert werden sollen. Wenn TMPDIR nicht festgelegt ist, verwendet MySQL die Systemstandardeinstellung/tmp,/var/tmp oder/usr/tmp.

Unter Windows, Netware und OS2 überprüft MySQL die Werte der Umgebungsvariablen TMPDIR, TEMP und TMP nacheinander. Für den ersten gefundenen Wert verwendet MySQL diesen und überprüft die verbleibenden Werte nicht. Wenn kein TMPDIR, TEMP oder TMP festgelegt ist, verwendet MySQL den Windows-Systemstandard, der normalerweise C:\windows\temp lautet.

Wenn das Dateisystem, das Ihr temporäres Dateiverzeichnis enthält, zu klein ist, Sie können die Option --tmpdir verwenden, um mit mysqld ein Verzeichnis in einem Dateisystem anzugeben, in dem genügend Speicherplatz vorhanden ist.

In MySQL 5.0 kann die Option --tmpdir auf eine Liste mehrerer Pfade gesetzt werden, die im Round-Robin-Verfahren verwendet werden. Pfade sollten unter Unix durch Doppelpunkte („:“) und unter Windows, NetWare und OS/2 durch Semikolonzeichen („;“) getrennt werden.

2
Jaydeep Dave

Ich habe das gleiche Problem.

Hier ist meine Lösung: 1. Verwenden Sie nicht "select *". Wählen Sie einfach das gewünschte Feld aus. 2. Teilen Sie die Abfrage. Wenn das ausgewählte Feld zu groß ist, kann es zu einer Aufteilung in eine Abfrage kommen. Sie können das Ergebnis später "array_merge ()", wenn die Variable, die das Ergebnis enthält, nicht geändert werden soll.

In meinem Fall habe ich die Abfrage in 5 Abfragen aufgeteilt und sie dann mithilfe von PHP in einem Array zusammengeführt.

Das Problem liegt auf dem MySQL-Server. Es ist nur eine Sache, die Anwendungsentwickler (wie wir ich) nicht beherrschen.

1
Ahmad

Ich hatte ein ähnliches Problem. In meinem eigenen Fall ist das Problem aufgrund eines falschen Besitzers/einer falschen Erlaubnis aufgetreten. Ich musste nur den Besitzer in meinem Datenverzeichnis in mysql user ändern und das Problem wurde behoben.

0
Lateef
0
DarckBlezzer