Anhang A. Probleme und häufige Fehler

Inhaltsverzeichnis

A.1. Wie man feststellt, was Probleme verursacht
A.2. Einige gebräuchliche Fehler bei der Benutzung von MySQL
A.2.1. Access denied-Fehler
A.2.2. MySQL server has gone away-Fehler
A.2.3. Can't connect to [local] MySQL server-Fehler
A.2.4. Host '...' is blocked-Fehler
A.2.5. Too many connections-Fehler
A.2.6. Some non-transactional changed tables couldn't be rolled back-Fehler
A.2.7. No free memory-Fehler
A.2.8. Packet too large-Fehler
A.2.9. Kommunikationsfehler / Abgebrochene Verbindung
A.2.10. The table is full-Fehler
A.2.11. Can't create/write to file-Fehler
A.2.12. Command out of sync-Fehler in Client
A.2.13. User ignored-Fehler
A.2.14. Table 'xxx' doesn't exist-Fehler
A.2.15. Can't initialize charset xxx-Fehler.
A.2.16. File Not Found
A.3. Installationsbezogene Themen
A.3.1. Probleme beim Linken mit der MySQL-Client-Bibliothek
A.3.2. Wie man MySQL als normaler Benutzer laufen läßt
A.3.3. Probleme mit Dateirechten
A.4. Administrationsbezogene Themen
A.4.1. Was zu tun ist, wenn MySQL andauernd abstürzt
A.4.2. Wie ein vergessenes Passwort zurückgesetzt wird
A.4.3. Wie MySQL mit vollen Festplatten umgeht
A.4.4. Wohin MySQL temporäre Dateien speichert
A.4.5. Wie Sie die MySQL-Socket-Datei /tmp/mysql.sock schützen oder ändern
A.4.6. Zeitzonen-Probleme
A.5. Anfragenbezogene Themen
A.5.1. Groß-/Kleinschreibung beim Suchen
A.5.2. Probleme bei der Benutzung von DATE-Spalten
A.5.3. Probleme mit NULL-Werten
A.5.4. Probleme mit alias
A.5.5. Zeilen aus verwandten Tabellen löschen
A.5.6. Probleme bei keinen übereinstimmenden Zeilen lösen
A.6. Tabellendefinitionsbezogene Themen
A.6.1. Probleme mit ALTER TABLE.
A.6.2. Wie man die Reihenfolge der Spalten in einer Tabelle ändert
A.6.3. TEMPORARY TABLE-Probleme

Dieses Kapitel listet einige gebräuchliche Probleme und Fehlermeldungen auf, denen Benutzer in die Arme laufen. Sie lernen herauszufinden, was das Problem ist und wie Sie es lösen. Hier finden sich auch korrekte Lösungen einiger häufiger Probleme.

A.1. Wie man feststellt, was Probleme verursacht

Wenn Sie Probleme bekommen, sollten Sie als erstes herausfinden, welches Programm oder Hardware-Teil die Probleme verursacht:

  • Wenn Sie eins der folgenden Symptome beobachten, gibt es wahrscheinlich ein Hardware- (Speicher, Hauptplatine, Prozessor oder Festplatte) oder Kernel-Problem:

    • Die Tastatur funktioniert nicht. Normalerweise können Sie das durch Drücken der Feststelltaste (Caps Lock) überprüfen. Wenn sich die Anzeigeleuchte beim Drücken nicht an- und ausschaltet, müssen Sie Ihre Tastatur ersetzen. (Bevor Sie das tun, sollten Sie Ihren Computer neu starten und alle Kabelverbindungen zur Tastatur überprüfen.)

    • Der Mauszeiger bewegt sich nicht.

    • Die Maschine antwortet auf entfernte Ping-Versuche nicht.

    • Andere Programme, die mit MySQL nichts zu tun haben, funktionieren nicht korrekt.

    • Wenn Ihr System unerwartet neu startet (ein fehlerhaftes Programm auf Benutzerebene sollte NIE in der Lage sein, Ihr System zum Absturz zu bringen).

    In solchen Fällen sollten Sie zunächst alle Kabel überprüfen und Diagnoseprogramme laufen lassen, um Ihre Hardware zu untersuchen! Sie sollten auch prüfen, ob Patches, Aktualisierungen oder Service-Packs für Ihre Betriebssystem verfügbar sind, die Ihre Probleme möglicherweise lösen. Prüfen Sie auch, ob Ihre Bibliotheken (wie glibc) aktuell sind.

    Es ist immer eine gute Idee, eine Maschine mit ECC-Speicher zu benutzen, um Speicherprobleme frühzeitig zu erkennen!

  • Wenn Ihre Tastatur gesperrt ist, können Sie das eventuell beheben, indem Sie sich von einer anderen Maschine aus verbinden und kbd_mode -a ausführen.

  • Untersuchen Sie Ihre System-Log-Datei (/var/log/messages oder ähnliches) nach Gründen für Ihre Probleme. Wenn Sie glauben, dass das Problem an MySQL liegt, sollten Sie auch die Log-Dateien von MySQL überprüfen. See Abschnitt 5.9.3, „Die Update-Log-Datei“.

  • Wenn Sie nicht glauben, ein Hardware-Problem zu haben, sollten Sie herausfinden, welches Programm die Probleme verursacht.

    Probieren Sie top, ps, taskmanager oder ein ähnliches Programm, um zu prüfen, welches Programm die gesamte Prozessorzeit konsumiert oder die Maschine blockiert.

  • Prüfen Sie mit top, df oder einem ähnlichen Programm, wenn Sie keinen freien Arbeitsspeicher, Festplattenspeicher, verfügbare Datei-Handler oder eine andere kritische Ressource mehr haben.

  • Wenn das Problem an einem aus dem Ruder gelaufenen Prozess liegt, können Sie versuchen, diesen zu killen. Wenn er nicht sterben will, gibt es wahrscheinlich einen Bug im Betriebssystem.

Wenn Sie alle anderen Möglichkeiten untersucht und ausgeschlossen haben und zur Schlussfolgerung gekommen sind, dass die Probleme durch den MySQL-Server oder ein MySQL-Client-Programm verursacht werden, ist es an der Zeit, einen Bug-Bericht für die Mailing-Liste oder unser Support-Team zu schreiben. Machen Sie im Bug-Bericht eine sehr detaillierte Beschreibung, wie sich Ihr System verhält und was Sie vermuten, was passiert. Sie sollten auch angeben, warum Sie denken, dass MySQL die Probleme verursacht. Ziehen Sie alle Situationen in diesem Kapitel in Betracht. Geben Sie genau an, welche Probleme wie auftauchen, wenn Sie Ihr System untersuchen. Benutzen Sie Kopieren und Einfügen, wenn Sie Ausgaben und / oder Fehlermeldungen von Programmen oder aus Log-Dateien beifügen!

Versuchen Sie detailliert zu beschreiben, welches Programm nicht funktioniert, und alle Symptome, die Sie sehen! In der Vergangenheit haben wir viele Bug-Berichte erhalten, in denen schlicht steht, dass "das System nicht funktioniert". Daraus können wir natürlich keinerlei Informationen ziehen, wie das Problem gelöst werden könnte.

Wenn ein Programm fehlschlägt, ist es immer nützlich, folgendes zu wissen:

  • Hat das fragliche Programm einen Segmentation-Fehler verursacht (Core Dump)?

  • Nimmt das Programm sich die gesamte Prozessorleistung? Überprüfen Sie das mit top. Lassen Sie das Programm eine Weile laufen, denn vielleicht evaluiert es gerade nur etwas Schwieriges.

  • Wenn der mysqld-Server Probleme verursacht, können Sie dann mysqladmin -u root ping oder mysqladmin -u root processlist ausführen?

  • Was sagt ein Client-Programm (zum Beispiel mysql), wenn Sie versuchen, sich mit dem MySQL-Server zu verbinden? Bricht der Client zusammen? Erhalten Sie von diesem Programm irgend welche Ausgaben?

Wenn Sie einen Bug-Bericht senden, sollten Sie immer den Angaben folgen, die in diesem Handbuch beschrieben sind. See Abschnitt 2.6.2.2, „Wie man Fragen stellt oder Bugs berichtet“.

A.2. Einige gebräuchliche Fehler bei der Benutzung von MySQL

Dieser Abschnitt listet einige Fehler auf, die Benutzer häufig erhalten. Hier finden Sie Beschreibungen dieser Fehler und wie man die Probleme löst.

A.2.2. MySQL server has gone away-Fehler

Dieser Abschnitt behandelt auch den verwandten Lost connection to server during query-Fehler.

Der häufigste Grund für den MySQL server has gone away-Fehler ist eine Zeitüberschreitung, nach der der Server die Verbindung schloss. Vorgabemäßig schließt der Server die Verbindung nach 8 Stunden, wenn nichts passiert ist. Sie können diesen Wert mit der wait_timeout-Variablen ändern, die beim Start von mysqld gesetzt wird.

Ein weiterer häufiger Grund für den MySQL server has gone away-Fehler ist das Absetzen eines ``close'' auf Ihre MySQL-Verbindung mit dem anschließenden Versuch, auf der geschlossenen Verbindung eine Anfrage abzusetzen.

Sie können überprüfen, ob der MySQL-Server gestorben ist, indem Sie mysqladmin version ausführen und die Uptime untersuchen.

Wenn Sie ein Skript haben, müssen Sie die Anfrage lediglich noch einmal für den Client absetzen, um eine automatische Neuverbindung zu machen.

Normalerweise können Sie folgende Fehler-Codes für diesen Fall abfragen (die Betriebssystem-abhängig sind):

CR_SERVER_GONE_ERRORDer Client konnte keine Anfrage an den Server schicken.
CR_SERVER_LOSTDer Client erhielt beim Schreiben zum Server keinen Fehler, bekam aber keine vollständige (oder überhaupt keine) Antwort.

Sie erhalten diese Fehler auch, wenn Sie eine Anfrage zum Server schicken, die falsch oder zu Groß ist. Wenn mysqld ein Paket erhält, das zu Groß oder nicht in Ordnung ist, nimmt er hat, dass etwas mit dem Client schief ging und schließt die Verbindung. Wenn Sie große Anfragen brauchen (beispielsweise wenn Sie mit BLOB-Spalten arbeiten), können Sie die Anfragebeschränkung erhöhen, indem Sie mysqld mit der -O max_allowed_packet=#-Option starten (Vorgabe 1 MB). Der zusätzliche Speicher wird bei Bedarf zugewiesen, daher benutzt mysqld nur dann mehr Speicher, wenn Sie eine große Anfrage ausführen oder wenn mysqld ein großes Ergebnis zurückgeben muss!

A.2.3. Can't connect to [local] MySQL server-Fehler

Ein MySQL-Client unter Unix kann sich auf zwei unterschiedliche Arten mit dem mysqld-Server verbinden: Unix-Sockets, die sich durch eine Datei im Dateisystem verbinden (Vorgabe /tmp/mysqld.sock) oder über TCP/IP, was sich über eine Portnummer verbindet. Unix-Sockets sind schneller als TCP/IP, können aber nur benutzt werden, wenn man sich zu einem Server auf demselben Computer verbindet. Unix-Sockets werden benutzt, wenn Sie keinen Hostnamen oder den speziellen Hostnamen localhost angeben.

Unter Windows können Sie sich nur mit TCP/IP verbinden, wenn der mysqld-Server unter Windows 95 / 98 läuft. Wenn er unter Windows NT läuft, können Sie sich auch mit Named Pipes verbinden. Der Name der Named Pipe ist MySQL. Wenn Sie bei der Verbindung zu mysqld keinen Hostnamen angeben, versucht ein MySQL-Client zuerst, sich über die Named Pipe zu verbinden. Erst wenn das fehlschlägt, versucht er, sich über den TCP/IP-Port zu verbinden. Sie können die Benutzung von Named Pipes unter Windows erzwingen, indem Sie . als Hostnamen benutzen.

Der Fehler (2002) Can't connect to ... bedeutet normalerweise, dass auf dem System kein MySQL-Server läuft oder dass Sie eine falsche Socket-Datei oder einen falschen TCP/IP-Port bei der Verbindung mit dem mysqld-Server benutzen.

Prüfen Sie zuerst mit ps oder dem Task-Manager unter Windows, ob es einen laufenden Prozess namens mysqld auf Ihrem Server gibt! Wenn es keinen mysqld-Prozess gibt, sollten Sie einen starten. See Abschnitt 3.4.2, „Probleme mit dem Start des MySQL-Servers“.

Wenn ein mysqld-Prozess läuft, können Sie den Server mit diesen unterschiedlichen Verbindungen überprüfen (die Portnummer und Socket-Pfadnamen können auf Ihrem System natürlich anders sein):

shell> mysqladmin version
shell> mysqladmin variables
shell> mysqladmin -h `hostname` version variables
shell> mysqladmin -h `hostname` --port=3306 version
shell> mysqladmin -h 'ip_ihres_hosts' version
shell> mysqladmin --socket=/tmp/mysql.sock version

Beachten Sie die Benutzung umgedrehter Anführungszeichen statt normaler Anführungszeichen beim hostname-Befehl. Diese verursachen, dass die Ausgabe durch hostname (das heißt des aktuellen Hostnamens) im mysqladmin-Befehl ersetzt wird.

Hier sind einige Gründe für das Auftreten des Can't connect to local MySQL server-Fehlers:

  • mysqld läuft nicht.

  • Sie fahren auf einem System, das MIT-pThread verwendet. Wenn Sie auf einem System fahren, das keine nativen Threads hat, benutzt mysqld das MIT-pThread-Paket. See Abschnitt 3.2.2, „Betriebssysteme, die von MySQL unterstützt werden“. Nicht alle MIT-pThread-Versionen unterstützen jedoch Unix-Sockets. Auf einem System ohne Socket-Unterstützung müssen Sie den Hostnamen immer explizit angeben, wenn Sie sich mit dem Server verbinden. Benutzen Sie diesen Befehl, um die Verbindung zum Server zu überprüfen:

    shell> mysqladmin -h `hostname` version
    

  • Jemand hat den Unix-Socket entfernt, den mysqld benutzt (Vorgabe /tmp/mysqld.sock). Vielleicht gibt es einen cron-Job, der den MySQL-Socket entfernt (beispielsweise ein Job, der alte Dateien aus dem /tmp-Verzeichnis entfernt). Sie können mysqladmin version laufen lassen und überprüfen, dass der Socket, den mysqladmin versucht zu benutzen, tatsächlich existiert. Die Problemlösung besteht in diesem Fall darin, den cron-Job so zu ändern, dass er nicht mysqld.sock entfernt oder den Socket an andere Stelle zu platzieren. See Abschnitt A.4.5, „Wie Sie die MySQL-Socket-Datei /tmp/mysql.sock schützen oder ändern“.

  • Sie haben den mysqld-Server mit der --socket=/pfad/zu/socket-Option gestartet. Wenn Sie den Socket-Pfadnamen zum Server ändern, müssen Sie auch die MySQL-Clients darüber unterrichten. Das können Sie tun, indem Sie den Socket-Pfad als Argument an den Client übergeben. See Abschnitt A.4.5, „Wie Sie die MySQL-Socket-Datei /tmp/mysql.sock schützen oder ändern“.

  • Sie benutzen Linux und ein Thread ist gestorben (Core Dump). In diesem Fall müssen Sie den anderen mysqld-Thread killen (beispielsweise mit dem mysql_zap-Skript), bevor Sie einen neuen MySQL-Server starten können. See Abschnitt A.4.1, „Was zu tun ist, wenn MySQL andauernd abstürzt“.

  • Eventuell haben Sie keine Lese- und Schreibberechtigungen entweder für das Verzeichnis, in dem die Socket-Datei liegt, oder keine Berechtigung für die Socket-Datei selbst. In diesem Fall können Sie entweder die Berechtigung für die Datei und / oder das Verzeichnis ändern oder mysqld neu starten, so dass er ein Verzeichnis benutzt, auf das Sie Zugriff haben.

Wenn Sie die Fehlermeldung Can't connect to MySQL server on ein_hostname erhalten, können Sie folgendes probieren, um den Grund des Problems herauszufinden:

  • Überprüfen Sie, ob der Server hochgefahren ist, indem Sie telnet ihr_hostname tcp-ip-port-nummer ausführen und einige Male die Eingabetaste (RETURN) drücken. Wenn es auf diesem Port einen laufenden MySQL-Server gibt, sollten Sie eine Antwort erhalten, die die Versionsnummer des Server enthält. Wenn Sie einen Fehler wie telnet: Unable to connect to remote host: Connection refused erhalten, gibt es auf diesem Port keinen laufenden Server.

  • Versuchen Sie, sich mit dem mysqld-Daemon auf der lokalen Maschine zu verbinden und prüfen Sie den TCP/IP-Port, den mysqld laut Konfiguration benutzen soll (Variable port), mit mysqladmin variables.

  • Prüfen Sie, ob Ihr mysqld-Server nicht gestartet wurde, indem Sie die --skip-networking-Option verwenden.

A.2.4. Host '...' is blocked-Fehler

Wenn Sie einen Fehler wie folgt erhalten:

Host 'hostname' is blocked because of too many connection errors.
Unblock with 'mysqladmin flush-hosts'

Bedeutet das, dass mysqld zu viele (max_connect_errors) Verbindungsanforderungen vom Host 'hostname' erhalten hat, die mittendrin unterbrochen wurden. Nach max_connect_errors fehlgeschlagenen Anfragen nimmt mysqld an, dass etwas nicht stimmt (wie ein Angriff eines Crackers) und blockiert weitere Verbindungsanforderungen von der Site, bis jemand mysqladmin flush-hosts ausführt.

Vorgabemäßig blockiert mysqld einen Host nach 10 Verbindungsfehlern. Das können Sie leicht durch Starten des Servers wie folgt ändern:

shell> safe_mysqld -O max_connect_errors=10000 &

Beachten Sie, dass Sie bei dieser Fehlermeldung für einen gegebenen Host zunächst prüfen sollten, ob etwas mit den TCP/IP-Verbindungen von diesem Host aus nicht stimmt. Wenn Ihre TCP/IP-Verbindungen nicht funktionieren, nützt es Ihnen nichts, den Wert der max_connect_errors-Variablen heraufzusetzen!

A.2.5. Too many connections-Fehler

Wenn Sie beim Verbindungsversuch den Fehler Too many connections erhalten, heißt das, dass es bereits max_connections Clients gibt, die mit dem mysqld-Server verbunden sind.

Wenn Sie mehr Verbindungen als die Vorgabe (100) benötigen, können Sie mysqld mit einem größeren Wert für die max_connections-Variable neu starten.

Beachten Sie, dass mysqld tatsächlich (max_connections+1) Clients für Verbindungen zuläßt. Die letzte Verbindung wird für einen Benutzer mit der process-Berechtigung reserviert. Wenn Sie keinem normalen Benutzer diese Berechtigung geben (diese sollte sie nie benötigen), kann sich ein Administrator mit dieser Berechtigung einloggen und SHOW PROCESSLIST benutzen, um herauszufinden, was schief geht. See Abschnitt 5.5.5, „SHOW-Syntax“.

Die maximale Anzahl von Verbindungen ist davon abhängig, wie gut die Thread-Bibliothek auf der Plattform ist. Linux oder Solaris sollten in der Lage sein, 500 bis 1000 gleichzeitige Verbindungen zu unterstützen, abhängig davon, wie viel Arbeitsspeicher Sie haben und was Ihre Clients ausführen.

A.2.6. Some non-transactional changed tables couldn't be rolled back-Fehler

Wenn Sie den Fehler Warning: Some non-transactional changed tables couldn't be rolled back erhalten, wenn Sie ein ROLLBACK versuchen, bedeutet das, dass einige der bei der Transaktion benutzten Tabellen keine Transaktionen unterstützen. Diese nicht transkationalen Tabellen werden vom ROLLBACK-Statement nicht betroffen.

Der typischste Fall, bei dem dieser Fehler auftritt, ist, wenn Sie versucht haben, eine Tabelle von einem Typ zu erzeugen, der von Ihrer mysqld-Binärdatei nicht unterstützt wird. Wenn mysqld einen Tabellentyp nicht unterstützt (oder wenn der Tabellentyp durch die Startoption ausgeschaltet ist), wird statt dessen ein Tabellentyp erzeugt, der dem angeforderten am nächsten entspricht (wahrscheinlich MyISAM.

Sie können den Tabellentyp für eine Tabelle wie folgt überprüfen:

SHOW TABLE STATUS LIKE 'tabelle'. See Abschnitt 5.5.5.2, „SHOW TABLE STATUS.

Sie können die Erweiterungen, die Ihre mysqld-Binärdatei unterstützt, wie folgt überprüfen:

show variables like 'have_%'. See Abschnitt 5.5.5.4, „SHOW VARIABLES.

A.2.7. No free memory-Fehler

Wenn Sie eine Anfrage ausführen und etwas wie folgenden Fehler erhalten:

mysql: No free memory at line 42, 'malloc.c'
mysql: needed 8136 byte (8k), memory in use: 12481367 Bytes (12189k)
ERROR 2008: MySQL client ran No free memory

Beachten Sie, dass sich dieser Fehler auf den MySQL-Client mysql bezieht. Der Grund für diesen Fehler ist einfach, dass der Client nicht genug freien Speicher hat, um das gesamte Ergebnis zu speichern.

Um das Problem zu beheben, prüfen Sie zunächst, ob Ihre Anfrage korrekt ist. Sollte sie vernünftigerweise so viele Zeilen zurückgeben? Wenn das der Fall ist, können Sie mysql --quick benutzen, was mysql_use_result() benutzt, um die Ergebnismenge abzurufen. Hierdurch wird Last vom Client auf den Server verlagert.

A.2.8. Packet too large-Fehler

Wenn ein MySQL-Client oder der mysqld-Server ein Paket erhält, das größer als max_allowed_packet Bytes ist, gibt er einen Packet too large-Fehler aus und schließt die Verbindung.

Wenn Sie den mysql-Client benutzen, müssen Sie einen größeren Puffer angeben, indem Sie den Client mit mysql --set-variable=max_allowed_packet=8M starten.

Wenn Sie andere Clients benutzen, die die Angabe der maximalen Paketgröße nicht zulassen (wie DBI), müssen Sie die Paketgröße beim Start des Servers setzen. Sie können eine Kommandozeilenoption für mysqld benutzen, um max_allowed_packet auf eine höhere Größe zu setzen. Wenn Sie zum Beispiel beabsichtigen, die volle Länge eines BLOB in eine Tabelle zu speichern, müssen Sie den Server mit der --set-variable=max_allowed_packet=16M-Option starten.

Sie können merkwürdige Probleme mit großen Paketen erhalten, wenn Sie große Blobs benutzen, aber mysqld keinen Zugriff auf genug Speicher gegeben haben, um die Anfrage zu handhaben. Wenn Sie vermuten, dass das der Fall ist, versuchen Sie, am Anfang des safe_mysqld-Skripts ulimit -d 256000 hinzuzufügen, und starten Sie mysqld neu.

A.2.9. Kommunikationsfehler / Abgebrochene Verbindung

Ab MySQL 3.23.40 erhalten Sie den Aborted connection-Fehler nur dann, wenn Sie mysqld mit --warnings starten.

Wenn Sie Fehler wie den folgenden in Ihrer Fehler-Log-Datei entdecken:

010301 14:38:23  Aborted connection 854 to db: 'Benutzer' user: 'josh'

See Abschnitt 5.9.1, „Die Fehler-Log-Datei“.

Bedeutet das, dass eins der folgenden Dinge passiert ist:

  • Das Client-Programm rief vor dem Beenden nicht mysql_close() auf.

  • Der Client schlief länger als wait_timeout oder interactive_timeout, ohne Anfragen auszuführen.

    See Abschnitt 5.5.5.4, „SHOW VARIABLES.

  • Das Client-Programm wurde abrupt während einer Übertragung beendet.

Wenn das oben Genannte passiert, wird die Servervariable Aborted_clients heraufgezählt.

Die Servervariable Aborted_connects wird in folgenden Fällen heraufgezählt:

  • Wenn ein Verbindungspaket nicht die richtigen Informationen enthält.

  • Wenn der Benutzer keine Berechtigung hat, sich mit einer Datenbank zu verbinden.

  • Wenn ein Benutzer ein falsches Passwort angegeben hat.

  • Wenn es länger als connect_timeout Sekunden dauert, um ein Verbindungspaket zu erhalten.

Beachten Sie, dass obiges auch anzeigen könnte, dass jemand versucht, in Ihre Datenbank einzubrechen!

See Abschnitt 5.5.5.4, „SHOW VARIABLES.

Andere Gründe für Probleme mit abgebrochenen Clients / abgebrochenen Verbindungen:

  • Benutzung des Duplex-Ethernet-Protokolls, sowohl Halb- als auch Voll-Duplex, unter Linux. Viele Linux-Ethernet-Treiber haben diesen Bug. Sie können auf diesen Bug überprüfen, indem Sie eine sehr große Datei via FTP zwischen diesen beiden Maschinen übertragen. Wenn ein Transfer nach dem Schema schnelle Übertragung - Pause - schnelle Übertragung - Pause läuft, haben Sie ein Linux-Duplex-Syndrom. Die einzige Lösung besteht darin, Halb- und Vollduplex auf Hubs und Switches auszuschalten.

  • Probleme mit der Thread-Bibliothek, was Unterbrechungen bei Lesevorgängen verursacht.

  • Schlecht konfiguriertes TCP/IP.

  • Fehlerhafte Ethernets, Hubs, Switches, Kabel usw. Das kann nur durch Austausch von Hardware sauber diagnostiziert werden.

  • max_allowed_packet ist zu klein oder Anfragen erfordern mehr Speicher, als Sie für mysqld zugewiesen haben.

    See Abschnitt A.2.8, „Packet too large-Fehler“.

A.2.10. The table is full-Fehler

Der Fehler tritt in älteren MySQL-Versionen auf, wenn eine Hauptspeicher-basierende temporäre Tabelle größer als tmp_table_size Bytes wird. Um dieses Problem zu vermeiden, können Sie die -O tmp_table_size=#-Option für mysqld benutzen, um die Größe der temporären Tabelle zu erhöhen, oder die SQL-Option SQL_BIG_TABLES verwenden, bevor Sie die problematische Anfrage abschicken. See Abschnitt 6.5.6, „SET-Syntax“.

Sie können auch mysqld mit der --big-tables-Option starten. Das ist genau dasselbe, wie SQL_BIG_TABLES für alle Anfragen zu benutzen.

In MySQL-Version 3.23 werden Hauptspeicher-basierende temporäre Tabellen automatisch in Festplatten-basierende MyISAM-Tabellen umgewandelt, wenn die Tabelle größer als tmp_table_size wird.

A.2.11. Can't create/write to file-Fehler

Wenn Sie für einige Anfragen Fehler folgenden Typs erhalten:

Can't create/write to file '\\sqla3fe_0.ism'.

Bedeutet das, dass MySQL keine temporäre Datei für die Ergebnismenge im angegebenen temporären Verzeichnis erzeugen kann. (Der obige Fehler ist eine typische Fehlermeldung unter Windows; die Unix-Fehlermeldung ist ähnlich.) Das Problem läßt sich beheben, indem Sie mysqld mit --tmpdir=pfad starten oder folgendes in Ihrer Optionsdatei ergänzen:

[mysqld]
tmpdir=C:/temp

Unter der Annahme, dass das c:\\temp-Verzeichnis existiert. See Abschnitt 5.1.2, „my.cnf-Optionsdateien“.

Überprüfen Sie auch den Fehler-Code, den Sie bei perror erhalten. Ein Grund kann ein Fehler wegen fehlenden Festplattenspeichers sein:

shell> perror 28
Error code  28:  No space left on device

A.2.12. Command out of sync-Fehler in Client

Wenn Sie den Fehler command out of sync; You can't run this command now in Ihrem Client-Code erhalten, rufen Sie Client-Funktionen in der falschen Reihenfolge auf!

Das kann zum Beispiel passieren, wenn Sie mysql_use_result() benutzen und versuchen, eine neue Anfrage auszuführen, bevor Sie mysql_free_result() aufgerufen haben. Der Fehler passiert ebenfalls, wenn Sie versuchen, zwei Anfragen auszuführen, die Daten zurückgeben, ohne zwischendrin mysql_use_result() oder mysql_store_result() aufzurufen.

A.2.13. User ignored-Fehler

Wenn Sie folgenden Fehler erhalten:

Found wrong password for user: 'benutzer@ein_host'; User ignored

Bedeutet das, dass mysqld beim Start oder nach dem Neuladen der Berechtigungstabellen einen Eintrag in der user-Tabelle mit einem ungültigen Passwort gefunden hat. Als Ergebnis wird der Eintrag vom Berechtigungssystem einfach ignoriert.

Mögliche Gründe und Problembehebung:

  • Sie lassen eine neue Version von mysqld mit einer alten user-Tabelle laufen. Das können Sie prüfen, indem Sie mysqlshow mysql user eingeben, um zu sehen, ob das Passwortfeld kürzer als 16 Zeichen ist. Wenn das der Fall ist, können Sie diesen Zustand beheben, indem Sie das scripts/add_long_password-Skript laufen lassen.

  • Der Benutzer hat ein altes Passwort (8 Zeichen lang) und Sie haben mysqld nicht mit der --old-protocol-Option gestartet.

  • Sie haben in der user-Tabelle ein Passwort eingegeben, ohne die PASSWORD()-Funktion zu benutzen. Benutzen Sie mysql, um den Benutzer in der user-Tabelle mit einem neuen Passwort zu aktualisieren. Stellen Sie sicher, dass Sie die PASSWORD()-Funktion benutzen:

    mysql> update user set password=PASSWORD('ihr_passwort')
               where user='XXX';
    

A.2.14. Table 'xxx' doesn't exist-Fehler

Wenn Sie den Fehler Table 'xxx' doesn't exist oder Can't find file: 'xxx' (errno: 2) erhalten, bedeutet das, dass in der aktuellen Datenbank keine Tabelle mit dem Namen xxx existiert.

Beachten Sie, dass Datenbank- und Tabellennamen abhängig von der verwendeten Groß-/Kleinschreibung sind, weil MySQL Verzeichnisse und Dateien benutzt, um Datenbanken und Tabellen zu speichern! (Unter Windows sind Datenbank- und Tabellennamen unabhängig von der Schreibweise, aber alle Verweise auf eine gegebene Tabelle innerhalb einer Anfrage müssen dieselbe Schreibweise benutzen!)

Sie finden heraus, welche Tabellen sich in der aktuellen Datenbank befinden, indem Sie SHOW TABLES eingeben. See Abschnitt 5.5.5, „SHOW-Syntax“.

A.2.15. Can't initialize charset xxx-Fehler.

Wenn Sie folgenden Fehler erhalten:

MySQL Connection Failed: Can't initialize charset xxx

Bedeutet das eins der folgenden Dinge:

  • Der Zeichensatz ist ein Multi-Byte-Zeichensatz und Ihr Client unterstützt diesen Zeichensatz nicht.

    In diesem Fall müssen Sie Ihren Client neu kompilieren und die --with-charset=xxx- oder die --with-extra-charsets=xxx-Option angeben. See Abschnitt 3.3.3, „Typische configure-Optionen“.

    Alle Standard-MySQL-Binärdistributionen werden mit --with-extra-character-sets=complex kompiliert, was die Unterstützung für alle Multi-Byte-Zeichensätze aktiviert. See Abschnitt 5.6.1, „Der für Daten und Sortieren benutzte Zeichensatz“.

  • Der Zeichensatz ist ein einfacher Zeichensatz, der nicht in mysqld kompiliert wurde, und die Zeichensatz-Definitionsdateien sind nicht an der Stelle, an der der Client sie erwartet.

    In diesem Fall müssen Sie:

    • Den Client mit Unterstützung für den Zeichensatz neu kompilieren. See Abschnitt 3.3.3, „Typische configure-Optionen“.

    • Dem Client angeben, wo die Zeichensatz-Definitionsdateien sind. Bei vielen Clients können Sie das mit der --character-sets-dir=pfad-to-charset-dir-Option machen.

    • Die Zeichensatz-Definitionsdatei in den Pfad kopieren, wo der Client sie zu finden erwartet.

A.2.16. File Not Found

Wenn Sie den Fehler ERROR '...' not found (errno: 23), Can't open file: ... (errno: 24) oder irgend einen anderen Fehler mit errno 23 oder errno 24 erhalten, bedeutet das, dass Sie MySQL nicht genug Datei-Deskriptoren zugewiesen haben. Sie können das perror-Dienstprogramm benutzen, um eine Beschreibung dessen zu erhalten, was die Fehlernummer bedeutet:

shell> perror 23
File table overflow
shell> perror 24
Too many open files
shell> perror 11
Resource temporarily unavailable

Das Problem hierbei ist, dass mysqld versucht, zu viele Dateien gleichzeitig offen zu halten. Sie können entweder mysqld veranlassen, nicht so viele Dateien auf einmal zu öffnen, oder die Anzahl von Datei-Deskriptoren heraufsetzen, über die mysqld verfügen kann.

Um mysqld anzuweisen, weniger Dateien zugleich offen zu halten, können Sie den Tabellen-Cache kleiner machen, indem Sie die -O table_cache=32-Option für safe_mysqld benutzen (der Vorgabewert ist 64). Wenn Sie den Wert von max_connections verringern, reduziert auch das die Anzahl offener Dateien (der Vorgabewert ist 90).

Um die Anzahl von Datei-Deskriptoren, die mysqld zur Verfügung stehen, zu ändern, können Sie die --open-files-limit=#-Option für safe_mysqld oder die -O open-files-limit=#-Option für mysqld benutzen. See Abschnitt 5.5.5.4, „SHOW VARIABLES. Die einfachste Art, das zu tun, besteht darin, eine Option zu Ihrer Optionsdatei hinzuzufügen. See Abschnitt 5.1.2, „my.cnf-Optionsdateien“. Wenn Sie eine alte mysqld-Version haben, die das nicht unterstützt, können Sie das safe_mysqld-Skript editieren. Es gibt dort eine auskommentierte Zeile ulimit -n 256. Entfernen Sie das '#'-Zeichen, um diese Zeile zu aktivieren, und ändern Sie die Anzahl 256, um die Anzahl verfügbarer Datei-Deskriptoren zu beeinflussen.

Mit ulimit (und open-files-limit) kann man die Anzahl von Datei-Deskriptoren heraufsetzen, aber nur bis zu der Grenze, die das Betriebssystem vorgibt. Darüber hinaus gibt es eine 'harte' Grenze, die nur überschrieben werden kann, wenn Sie safe_mysqld oder mysqld als Root starten (denken Sie daran, dass Sie in diesem Fall auch die --user=..-Option benutzen müssen). Wenn Sie die Betriebssystem-Grenze hinsichtlich der Anzahl von Datei-Deskriptoren, die für jeden Prozess verfügbar sind, heraufsetzen müssen, schauen Sie in der Dokumentation Ihres Betriebssystems nach.

Beachten Sie, dass ulimit nicht funktioniert, wenn Sie die tcsh-Shell laufen lassen! tcsh berichtet auch nicht korrekte Werte, wenn Sie die aktuellen Grenzen abfragen! In diesem Fall sollten Sie safe_mysqld mit sh starten!

A.3. Installationsbezogene Themen

A.3.1. Probleme beim Linken mit der MySQL-Client-Bibliothek

Wenn Sie Ihr Programm linken und Fehler für unreferenzierte Symbole erhalten, die mit mysql_ beginnen, wie folgende:

/tmp/ccFKsdPa.o: In function `main':
/tmp/ccFKsdPa.o(.text+0xb): undefined reference to `mysql_init'
/tmp/ccFKsdPa.o(.text+0x31): undefined reference to `mysql_real_connect'
/tmp/ccFKsdPa.o(.text+0x57): undefined reference to `mysql_real_connect'
/tmp/ccFKsdPa.o(.text+0x69): undefined reference to `mysql_error'
/tmp/ccFKsdPa.o(.text+0x9a): undefined reference to `mysql_close'

Sollten Sie das durch Hinzufügen von -Lpath-to-the-mysql-library-lmysqlclient als LETZTES in Ihrer Link-Zeile beheben können.

Wenn Sie undefined reference-Fehler bei der uncompress- oder compress-Funktion erhalten, fügen Sie -lz als LETZTES zu Ihrer Link-Zeile hinzu und versuchen Sie es noch einmal!

Wenn Sie undefined reference-Fehler bei Funktionen erhalten, die es auf Ihrem System geben sollte, wie connect, sehen Sie in der Handbuch-Seite (ManPage) für die fragliche Funktion nach, welche Bibliotheken Sie zur Link-Zeile hinzufügen sollten!

Wenn Sie undefined reference-Fehler bei Funktionen erhalten, die es auf Ihrem System nicht gibt, wie folgenden:

mf_format.o(.text+0x201): undefined reference to `__lxstat'

Heißt das üblicherweise, dass Ihre Bibliothek auf einem System kompiliert wurde, das nicht 100% kompatibel zu Ihrem System ist. In diesem Fall sollten Sie die letzte MySQL-Quelldistribution herunter laden und sie selbst kompilieren. See Abschnitt 3.3, „Installation der Quelldistribution“.

Wenn Sie versuchen, ein Programm laufen zu lassen und Fehler für unreferenzierte Symbole erhalten, die mit mysql_ anfangen, oder den Fehler, dass die mysqlclient-Bibliothek nicht gefunden werden kann, heißt das, dass Ihr System die gemeinsam genutzte libmysqlclient.so-Bibliothek nicht findet.

Das Problem beheben Sie, indem Sie Ihr System anweisen, dort nach gemeinsam genutzten Bibliotheken zu suchen, wo sich die Bibliothek befindet, mit einer der folgenden Methoden:

  • Fügen Sie den Pfad zum Verzeichnis, in dem Sie libmysqlclient.so haben, der LD_LIBRARY_PATH-Umgebungsvariablen hinzu.

  • Fügen Sie den Pfad zum Verzeichnis, in dem Sie libmysqlclient.so haben, der LD_LIBRARY-Umgebungsvariablen hinzu.

  • Kopieren Sie libmysqlclient.so an eine Stelle, die von Ihrem System durchsucht wird, wie /lib, und aktualisieren Sie die Informationen über gemeinsam genutzte Bibliotheken, indem Sie ldconfig ausführen.

Eine weitere Möglichkeit, dieses Problem zu lösen, besteht darin, Ihr Programm statisch mit -static zu linken oder die dynamischen MySQL-Bibliotheken zu entfernen, bevor Sie Ihren Code linken. Im letzteren Fall sollten Sie sicherstellen, dass keine anderen Programme die dynamischen Bibliotheken benutzen!

A.3.2. Wie man MySQL als normaler Benutzer laufen läßt

Der MySQL-Server mysqld kann von jedem beliebigen Benutzer gestartet werden und unter diesem laufen. Damit mysqld als Unix-Benutzer benutzername läuft, müssen Sie folgendes tun:

  1. Halten Sie den Server an, falls er läuft (benutzen Sie mysqladmin shutdown).

  2. Ändern Sie die Datenbankverzeichnisse und Dateien so, dass benutzername die Berechtigungen zum Lesen und Schreiben von Dateien darin hat (das müssen Sie eventuell als Unix-root-Benutzer machen):

    shell> chown -R benutzername /pfad/zu/mysql/datadir
    

    Wenn Verzeichnisse oder Dateien im MySQL-Daten-Verzeichnis symbolische Links sind, müssen Sie auch diesen Verknüpfungen folgen und die Verzeichnisse und Dateien, auf die sie zeigen, ändern. chown -R kann SymLinks für Sie folgen.

  3. Starten Sie den Server als Benutzer benutzername oder, wenn Sie MySQL-Version 3.22 oder später benutzen, starten Sie mysqld als Unix-root-Benutzer und benutzen Sie die --user=benutzername-Option. mysqld schaltet um und läuft dann unter Unix-Benutzer benutzername, bevor er irgend welche Verbindungen annimmt.

  4. Um den Server automatisch beim Hochfahren des Systems unter dem angegebenen Benutzernamen zu starten, fügen Sie zur [mysqld]-Gruppe der /etc/my.cnf-Optionendatei oder der my.cnf-Optionendatei im Datenverzeichnis des Servers eine user-Zeile hinzu, die den Benutzernamen angibt. Beispiel:

    [mysqld]
    user=benutzername
    

Nunmehr sollte Ihr mysqld-Prozess korrekt unter dem Unix-Benutzer benutzername laufen. Dennoch hat sich eins nicht geändert: Die Inhalte der Berechtigungstabellen. Vorgabemäßig (direkt nach dem Laufenlassen des Skripts mysql_install_db, das die Berechtigungstabellen installiert), ist der MySQL-Benutzer root der einzige Benutzer mit Zugriffsrechten auf die mysql-Datenbank. Er ist auch der einzige, der Datenbanken erzeugen und löschen kann. Wenn Sie diese Berechtigungen nicht geändert haben, sind sie noch gültig. Das sollte Sie nicht davon abhalten, auf MySQL als der MySQL-root-Benutzer zuzugreifen, wenn Sie als ein anderer Unix-Benutzer als root eingeloggt sind. Geben Sie einfach für Client-Programme die -u root-Option an.

Beachten Sie, dass der Zugriff auf MySQL als root (indem Sie -u root auf der Kommandozeile eingeben) nichts damit zu tun hat, dass Sie MySQL als Unix-root-Benutzer laufen lassen oder als irgend ein anderer Unix-Benutzer. Die Zugriffsberechtigungen und Benutzernamen von MySQL sind komplett unterschiedlich von den Unix-Benutzernamen. Die einzige Verbindung mit Unix-Benutzernamen besteht darin, dass ein Client versuchen wird, sich mit Ihrem Unix-Login-Namen als MySQL-Benutzernamen zu verbinden, wenn Sie beim Aufruf eines Client-Programms keine -u-Option angeben.

Wenn Ihre Unix-Box selbst nicht abgesichert ist, sollten Sie zumindest ein Passwort für den MySQL-root-Benutzer in den Berechtigungstabellen angeben. Ansonsten kann jeder beliebige Benutzer mit einem Konto auf der Maschine mysql -u root datenbank eingeben und tun, was er will.

A.3.3. Probleme mit Dateirechten

Wenn Sie Probleme mit Dateirechten haben, wenn mysql zum Beispiel folgende Fehlermeldung beim Erzeugen einer Tabelle ausgibt:

Error: Can't find file: 'pfad/mit/dateiname.frm' (Errcode: 13)

Kann es sein, dass die Umgebungsvariable UMASK falsch gesetzt ist, wenn mysqld startet. Der vorgabemäßige umask-Wert ist 0660. Sie können dieses Verhalten ändern, indem Sie safe_mysqld wie folgt starten:

shell> UMASK=384  # = 600 in oktal
shell> export UMASK
shell> /pfad/zu/safe_mysqld &

Vorgabemäßig erzeugt MySQL Datenbank- und RAID-Verzeichnisse mit dem Berechtigungstyp 0700. Dieses Verhalten können Sie durch Setzen der UMASK_DIR-Variablen ändern. Wenn Sie diese setzen, werden neue Verzeichnisse mit kombiniertem UMASK und UMASK_DIR erzeugt. Wenn Sie zum Beispiel Gruppenzugriff auf alle neuen Verzeichnisse geben wollen, können Sie folgendes tun:

shell> UMASK_DIR=504  # = 770 in oktal
shell> export UMASK_DIR
shell> /pfad/zu/safe_mysqld &

Ab MySQL-Version 3.23.25 nimmt MySQL an, dass die Werte für UMASK und UMASK_DIR in oktal angegeben sind, wenn sie mit einer 0 anfangen.

See Anhang E, Umgebungsvariablen.

A.4. Administrationsbezogene Themen

A.4.1. Was zu tun ist, wenn MySQL andauernd abstürzt

Alle MySQL-Versionen werden auf vielen Plattformen getestet, bevor sie herausgegeben werden. Das heißt nicht, dass es keinerlei Bugs in MySQL gibt, aber es heißt, dass, wenn es Bugs gibt, diese sehr wenige und schwer zu finden sind. Wenn Sie ein Problem haben, ist es immer hilfreich herauszufinden, was Ihr System zum Absturz bringt, weil Sie dann viel bessere Chancen haben, es schnell zu beheben.

Zunächst sollten Sie versuchen herauszufinden, ob das Problem darin besteht, dass Ihr mysqld-Daemon stirbt, oder ob Sie ein Problem mit Ihrem Client haben. Sie können herausfinden, seit wann Ihr mysqld-Server hochgefahren ist, indem Sie mysqladmin version ausführen. Wenn mysqld gestorben ist, finden Sie den Grund hierfür womöglich in der Datei mysql-daten-verzeichnis/`hostname`.err. See Abschnitt 5.9.1, „Die Fehler-Log-Datei“.

Viele Abstürze von MySQL werden durch beschädigte Index- oder Daten-Dateien verursacht. MySQL aktualisiert die Daten auf Platte mit dem write() Systemaufruf, nach jedem SQL-Statement und bevor der Client über das Ergebnis unterrichtet wird. (Das gilt nicht, wenn Sie mit delayed_key_writes fahren, denn in diesem Fall werden nur die Daten geschrieben.) Das bedeutet, dass die Daten sicher sind, selbst wenn mysqld abstürzt, weil das Betriebssystem sicherstellt, dass die nicht von MySQL zurückgeschriebenen Daten (flush) auf Platte zurückgeschrieben werden. Sie können MySQL zwingen, alles nach jedem SQL-Befehl auf Platte zurückzusynchronisieren, indem Sie mysqld mit --flush starten.

Das Gesagte bedeutet, dass Sie normalerweise keine beschädigten Tabellen erhalten sollten, ausser in folgenden Fällen:

  • Jemand oder etwas killte mysqld oder die Maschine mitten während einer Aktualisierung.

  • Sie haben einen Bug in mysqld gefunden, der dazu führte, dass er mitten während einer Aktualisierung starb.

  • Jemand manipuliert die Daten- / Index-Dateien ausserhalb von mysqld, ohne die Tabelle korrekt zu sperren.

  • Wenn Sie viele mysqld-Server auf denselben Daten auf einem System laufen lassen, das Dateisystem-Sperren nicht gut unterstützt (das wird normalerweise vom lockd-Daemon gehandhabt) oder wenn Sie mehrere Server mit --skip-locking fahren.

  • Wenn Sie eine beschädigte Index- / Daten-Datei haben, die sehr falsche Daten enthält, die mysqld durcheinander brachten.

  • Sie haben einen Bug im Datenspeicher-Code gefunden. Das ist nicht sehr wahrscheinlich, aber zumindest möglich. In diesem Fall können Sie versuchen, den Dateityp auf einen anderen Datenbank-Handler umzustellen, indem Sie ALTER TABLE auf eine reparierte Kopie der Tabelle anwenden!

Weil es sehr schwierig ist herauszufinden, warum etwas abstürzt, versuchen Sie zuerst herauszufinden, ob Dinge, die bei anderen funktionieren, bei Ihnen abstürzen, oder ob das nicht der Fall ist. Versuchen Sie bitte folgendes:

  • Fahren Sie den mysqld-Daemon mit mysqladmin shutdown herunter und führen Sie myisamchk --silent --force */*.MYI auf alle Tabellen aus. Starten Sie den mysqld-Daemon erneut. Das stellt sicher, dass Sie von einem sauberen Ausgangszustand aus fahren. See Kapitel 5, MySQL-Datenbankadministration.

  • Benutzen Sie mysqld --log und versuchen Sie den Informationen im Log zu entnehmen, ob eine bestimmte Anfrage den Server killt oder nicht. Etwa 95% aller Bugs beziehen sich auf eine bestimmte Anfrage! Normalerweise ist das eine der letzten Anfragen in der Log-Datei, direkt bevor MySQL neu startete. See Abschnitt 5.9.2, „Die allgemeine Anfragen-Log-Datei“. Wenn Sie MySQL wiederholt mit einer der Anfragen killen, selbst wenn Sie alle Tabellen direkt vor der Ausführung der Anfrage überprüft haben, haben Sie den Bug eingegrenzt und sollten dafür einen Bug-Bericht schreiben! See Abschnitt 2.6.2.3, „Wie man Bugs oder Probleme berichtet“.

  • Versuchen Sie, einen Testfall herzustellen, den wir zur Reproduzierung des Problems verwenden können. See Abschnitt D.1.6, „Einen Testfall herstellen, wenn Sie Tabellenbeschädigung feststellen“.

  • Versuchen Sie, die beigefügten mysql-test test und MySQL-Benchmarks laufen zu lassen. See Abschnitt 10.3.2, „MySQL-Test-Suite“. Sie können MySQL recht gut prüfen. Sie können den Benchmarks auch selbst Code hinzufügen, der Ihre Applikation simuliert! Die Benchmarks finden sich im bench-Verzeichnis in der Quelldistribution oder bei einer Binärdistribution im sql-bench-Verzeichnis unter Ihrem MySQL-Installationsverzeichnis.

  • Probieren Sie fork_test.pl und fork2_test.pl.

  • Wenn Sie MySQL zum Debuggen konfigurieren, ist es wesentlich einfacher, Informationen über mögliche Fehler zu erhalten, wenn etwas schief geht. Konfigurieren Sie MySQL mit der --with-debug-Option oder mit der --with-debug=full-Option für configure neu und kompilieren Sie neu. See Abschnitt D.1, „Einen MySQL-Server debuggen“.

  • Wenn MySQL zum Debuggen konfiguriert wird, wird ein sicherer Speicher-Zuweiser (Memory Allocator) hinzugefügt, der einige Fehler finden kann. Ausserdem erfolgen etliche Ausgaben über das, was gerade geschieht.

  • Haben Sie die neuesten Patches für Ihr Betriebssystem installiert?

  • Benutzen Sie die --skip-locking-Option für mysqld. Auf manchen Systemen arbeitet der lockd-Sperrmanager nicht korrekt. Die --skip-locking-Option weist mysqld an, keine externen Sperren zu benutzen. (Das heißt, dass Sie nicht zwei mysqld-Server auf denselben Daten laufen lassen können und dass Sie vorsichtig sein müssen, wenn Sie myisamchk benutzen, aber es kann aufschlussreich sein, die Option testweise zu benutzen.)

  • Haben Sie mysqladmin -u root processlist ausprobiert, wenn mysqld zu laufen scheint, aber nicht antwortet? Manchmal ist mysqld nicht komatös, obwohl es so aussieht. Das Problem kann darin bestehen, dass alle Verbindungen in Benutzung sind, oder es kann ein internes Sperrproblem vorliegen. mysqladmin processlist ist üblicherweise in der Lage, in solchen Fällen eine Verbindung aufzubauen und kann nützliche Informationen über die momentane Anzahl von Verbindungen und ihren Status liefern.

  • Lassen Sie den Befehl mysqladmin -i 5 status oder mysqladmin -i 5 -r status in einem separaten Fenster laufen, um statistische Informationen auszugeben, während Sie Ihre anderen Anfragen laufen lassen.

  • Versuchen Sie folgendes:

    1. Starten Sie mysqld von gdb aus (oder in einem anderen Debugger). See Abschnitt D.1.3, „mysqld unter gdb debuggen“.

    2. Lassen Sie Ihre Test-Skripts laufen.

    3. Geben Sie die Ablaufverfolgung (Backtrace) und die lokalen Variablen der untersten 3 Ebenen aus. In gdb können Sie das mit folgenden Befehle tun, wenn mysqld innerhalb von gdb abgestürzt ist:

      backtrace
      info local
      up
      info local
      up
      info local
      

      Mit gdb können Sie auch untersuchen, welchen Thread es gibt (mit info thread und zu einem speziellen Thread umschalten (mit thread #, wobei # die Thread-Kennung ist).

  • Versuchen Sie, Ihre Applikation mit einem Perl-Skript zu simulieren, um MySQL zu zwingen, abzustürzen oder fehlerhaftes Verhalten an den Tag zu legen.

  • Senden Sie einen normalen Bug-Bericht. See Abschnitt 2.6.2.3, „Wie man Bugs oder Probleme berichtet“. Geben Sie mehr Details an als üblich. Weil MySQL bei vielen Leuten funktioniert, kann es sein, dass der Absturz das Ergebnis von etwas ist, das nur auf Ihrem Computer existiert (beispielsweise ein Fehler, der aus Ihren besonderen Systembibliotheken resultiert).

  • Wenn Sie ein Problem mit Tabellen haben, die Zeilen dynamischer Länge enthalten, und Sie nicht BLOB/TEXT-Spalten benutzen (sondern nur VARCHAR-Spalten), können Sie versuchen, alle VARCHAR- in CHAR-Spalten umzuwandeln, indem Sie ALTER TABLE verwenden. Das erzwingt, dass MySQL Zeilen fester Länge verwendet. Zeilen fester Länge benötigen etwas mehr Platz, sind aber fehlertoleranter gegenüber Beschädigungen!

    Der aktuelle Code mit dynamischen Zeilen ist bei MySQL AB seit mindestens drei Jahren ohne jedes Problem in Benutzung, aber naturgemäß sind Zeilen dynamischer Länge fehleranfälliger. Daher kann es eine gute Idee sein, das oben Gesagte auszuprobieren.

A.4.2. Wie ein vergessenes Passwort zurückgesetzt wird

Wenn Sie das root-Benutzerpasswort für MySQL vergessen haben, können Sie es mit folgender Prozedur wiederherstellen:

  1. Fahren Sie den mysqld-Server durch Senden von kill (nicht kill -9) an den mysqld-Server herunter. Die Prozess-Kennung (PID) wird in einer .pid-Datei gespeichert, die sich normalerweise im MySQL-Datenbank-Verzeichnis befindet:

    kill `cat /mysql-daten-verzeichnis/hostname.pid`
    

    Hierfür müssen Sie entweder der Unix-root-Benutzer sein oder derselbe Benutzer, unter dem der Server läuft.

  2. Starten Sie mysqld mit der --skip-grant-tables-Option neu.

  3. Verbinden Sie sich mit dem mysqld-Server mit mysql -h hostname mysql und ändern Sie das Passwort mit einem GRANT-Befehl. See Abschnitt 5.3.1, „GRANT- und REVOKE-Syntax“. Sie können dasselbe auch mit mysqladmin -h hostname -u benutzer password 'neues_passwort' machen.

  4. Laden Sie die Berechtigungstabellen neu mit mysqladmin -h hostname flush-privileges oder mit dem SQL-Befehl FLUSH PRIVILEGES.

Beachten Sie, dass nach dem Start von mysqld mit --skip-grant-tables jede Benutzung von GRANT-Befehlen zu einem Unknown command-Fehler führt, bis Sie FLUSH PRIVILEGES ausgeführt haben.

A.4.3. Wie MySQL mit vollen Festplatten umgeht

Wenn etwas hinsichtlich der Festplatte passiert, tut MySQL folgendes:

  • Er prüft einmal pro Minute, um festzustellen, ob es genug Platz gibt, um die aktuelle Zeile zu schreiben oder nicht. Wenn genug Platz vorhanden ist, wird fortgefahren, als sei nichts geschehen.

  • Alle 6 Minuten schreibt er einen Eintrag in die Log-Datei mit einer Warnung wegen voller Festplatte.

Um das Problem abzumildern, können Sie folgende Aktionen unternehmen:

  • Um einfach weiterzumachen, müssen Sie lediglich genug Festplattenplatz freigeben, damit alle Datensätze eingefügt werden können.

  • Um den Thread abzubrechen, müssen Sie mysqladmin kill an den Thread senden. Der Thread wird beim nächsten Mal, wenn er die Festplatte prüft (in 1 Minute) abgebrochen.

  • Beachten Sie, dass eventuell ein anderer Thread auf die Tabelle wartet, die den Zustand ``Platte voll'' verursachte. Wenn Sie mehrere ``gesperrte'' Threads haben, kann es sein, dass Sie einen Thread killen, der wegen ``Platte voll'' wartet, dass dafür aber ein anderer Thread weitermacht.

Ausnahmen zum obigen Verhalten treten bei der Benutzung von REPAIR oder OPTIMIZE auf, oder wenn die Indexe nach einem LOAD DATA INFILE- oder einem ALTER TABLE-Statement im Stapel erzeugt werden.

Alle obigen Befehle benutzen eventuell große temporäre Dateien, die - sich selbst überlassen - für den Rest des Systems große Probleme verursachen können. Wenn MySQL ein ``Platte voll'' erhält, während irgend eine der obigen Operationen ausgeführt wird, entfernt er die großen temporären Dateien und markiert die Tabelle als beschädigt (ausser bei ALTER TABLE, wobei die alte Tabelle unverändert gelassen wird).

A.4.4. Wohin MySQL temporäre Dateien speichert

MySQL benutzt den Wert der TMPDIR-Umgebungsvariablen als Pfadnamen des Verzeichnisses, in dem temporäre Dateien gespeichert werden. Wenn Sie TMPDIR nicht gesetzt haben, benutzt MySQL die System-Vorgabe, die normalerweise /tmp oder /usr/tmp ist. Wenn das Dateisystem, das Ihr Verzeichnis für temporäre Dateien enthält, zu klein ist, sollten Sie safe_mysqld editieren, um TMPDIR so zu setzen, dass sie auf ein Verzeichnis in einem Dateisystem zeigt, wo Sie genug Platz haben! Sie können das temporäre Verzeichnis auch mit der --tmpdir-Option für mysqld setzen.

MySQL erzeugt alle temporären Dateien als versteckte Dateien. Das stellt sicher, dass die temporären Dateien entfernt werden, wenn mysqld beendet wird. Der Nachteil versteckter Dateien ist, dass Sie eine große temporäre Datei nicht sehen, die das Dateisystem auffüllt, in dem sich das Verzeichnis für temporäre Dateien befindet.

Zum Sortieren (ORDER BY oder GROUP BY) benutzt MySQL normalerweise ein oder zwei temporäre Dateien. Der maximal benötigte Speicherplatz ist:

(laenge_dessen_was_sortiert_wird + groesse_von(datenbank_zeiger)) *
anzahl_uebereinstimmender_zeilen * 2

groesse_von(datenbank_zeiger) ist üblicherweise 4, kann in Zukunft aber für wirklich große Tabellen anwachsen.

Bei einigen SELECT-Anfragen erzeugt MySQL zusätzliche temporäre SQL-Tabellen. Diese sind nicht versteckt und haben Namen der Form SQL_*.

ALTER TABLE erzeugt eine temporäre Tabelle im selben Verzeichnis, in dem sich die Original-Tabelle befindet.

A.4.5. Wie Sie die MySQL-Socket-Datei /tmp/mysql.sock schützen oder ändern

Wenn Sie Probleme damit haben, dass jeder beliebige den MySQL-Kommunikations-Socket /tmp/mysql.sock löschen kann, können Sie unter den meisten Versionen von Unix Ihr /tmp-Dateisystem schützen, indem Sie darauf das sticky Bit setzen. Loggen Sie sich als root ein und tun Sie folgendes:

shell> chmod +t /tmp

Das schützt Ihr /tmp-Dateisystem, so dass Dateien nur von ihren Besitzern oder dem Superuser (root) gelöscht werden können.

Sie können überprüfen, ob das sticky Bit gesetzt ist, indem Sie ls -ld /tmp ausführen. Wenn das letzte Berechtigungsbit t ist, ist das Bit gesetzt.

Sie können den Speicherort ändern, den MySQL benutzt, um die Socket-Datei Socket-Datei abzulegen, indem Sie eine der folgenden Prozeduren ausführen:

  • Geben Sie den Pfad in einer globalen oder lokalen Optionsdatei an. Beispielsweise können Sie in /etc/my.cnf eintragen:

    [client]
    socket=pfad-fuer-socket-datei
    
    [mysqld]
    socket=pfad-fuer-socket-datei
    

    See Abschnitt 5.1.2, „my.cnf-Optionsdateien“.

  • Geben Sie den Pfad auf der Kommandozeile für safe_mysqld und die meisten Clients mit der --socket=pfad-fuer-socket-datei-Option an.

  • Geben Sie den Pfad zum Socket in der MYSQL_UNIX_PORT-Umgebungsvariablen an. variable.

  • Definieren Sie den Pfad mit der configure-Option --with-unix-socket-path=pfad-fuer-socket-datei. See Abschnitt 3.3.3, „Typische configure-Optionen“.

Mit folgendem Befehl können Sie testen, ob der Socket funktioniert:

shell> mysqladmin --socket=/pfad/zu/socket version

A.4.6. Zeitzonen-Probleme

Wenn es Probleme damit gibt, dass SELECT NOW() Werte in GMT (Greenwich Mean Time) zurückgibt und nicht in Ihrer lokalen Zeit, müssen Sie die TZ-Umgebungsvariable auf Ihre aktuelle Zeitzone setzen. Das sollte für die Umgebung gemacht werden, in der der Server läuft, zum Beispiel in safe_mysqld oder mysql.server. See Anhang E, Umgebungsvariablen.

A.5. Anfragenbezogene Themen

A.5.1. Groß-/Kleinschreibung beim Suchen

Vorgabemäßig sind MySQL-Suchen unabhängig von der verwendeten Groß-/Kleinschreibung (obwohl es einige Zeichensätze gibt, die nie unabhängig von der verwendeten Groß-/Kleinschreibung sind, wie tschechisch). Wenn Sie daher mit spalten_name LIKE 'a%' suchen, erhalten Sie alle Spaltenwerte, die mit A oder a anfangen. Wenn Sie die Suche abhängig von der verwendeten Groß-/Kleinschreibung machen wollen, verwenden Sie etwas wie INSTR(spalten_name, "A")=1, um ein Präfix zu überprüfen, oder benutzen Sie STRCMP(spalten_name, "A") = 0, wenn der Spaltenwert exakt "A" sein muss.

Einfache Vergleichsoperationen (>=, >, = , < , <=, Sortieren und Gruppieren) basieren auf dem ``Sortierwert'' jedes Zeichens. Buchstaben mit demselben Sortierwert (wie E, e und é) werden als dasselbe Zeichen behandelt!

In älteren MySQL-Versionen wurden LIKE-Vergleiche mit dem Großschreibungswert jedes Zeichens durchgeführt (E == e, aber E <> é). In neueren MySQL-Versionen funktioniert LIKE genau wie die anderen Vergleichsoperatoren.

Wenn Sie wollen, dass eine Spalte immer abhängig von der verwendeten Groß-/Kleinschreibung behandelt wird, deklarieren Sie sie als BINARY. See Abschnitt 7.5.3, „CREATE TABLE-Syntax“.

Wenn Sie chinesische Daten in der so genannten Big5-Kodierung verwenden, sollten Sie alle Zeichenspalten BINARY machen. Das funktioniert, weil die Sortierreihenfolge von Big5-Zeichen auf der Reihenfolge von ASCII-Codes basiert.

A.5.2. Probleme bei der Benutzung von DATE-Spalten

Das Format eines DATE-Werts ist 'YYYY-MM-DD'. Gemäß ANSI-SQL ist kein anderes Format zulässig. Sie sollten dieses Format in UPDATE-Ausdrücken und in der WHERE-Klausel von SELECT-Statements benutzen. Beispiel:

mysql> SELECT * FROM tabelle WHERE date >= '1997-05-05';

Aus Gründen der Annehmlichkeit konvertiert MySQL automatisch ein Datum in eine Zahl, wenn das Datum in einem numerischen Zusammenhang benutzt wird (und umgekehrt). MySQL unterstützt ausserdem ein ``entspanntes'' Zeichenkettenformat beim Aktualisieren und in einer WHERE-Klausel, die ein Datum mit einer TIMESTAMP-, DATE- oder einer DATETIME-Spalte vergleicht. (Entspannt heißt hierbei, dass jedes beliebige Satzzeichen als Trennzeichen zwischen Bestandteilen benutzt werden darf. Beispielsweise sind '1998-08-15' und '1998#08#15' äquivalent.) MySQL kann auch eine Zeichenkette umwandeln, die keine Trennzeichen enthält (wie '19980815'), vorausgesetzt, dass diese als Datum einen Sinn ergibt.

Das spezielle Datum '0000-00-00' kann als '0000-00-00' gespeichert und abgerufen werden. Wenn man ein '0000-00-00'-Datum über MyODBC benutzt, wird es automatisch in NULL umgewandelt (MyODBC-Version 2.50.12 und höher), weil ODBC diese Art von Datum nicht handhaben kann.

Weil MySQL die oben genannten Umwandlungen durchführt, funktionieren folgende Statements:

mysql> INSERT INTO tabelle (idate) VALUES (19970505);
mysql> INSERT INTO tabelle (idate) VALUES ('19970505');
mysql> INSERT INTO tabelle (idate) VALUES ('97-05-05');
mysql> INSERT INTO tabelle (idate) VALUES ('1997.05.05');
mysql> INSERT INTO tabelle (idate) VALUES ('1997 05 05');
mysql> INSERT INTO tabelle (idate) VALUES ('0000-00-00');

mysql> SELECT idate FROM tabelle WHERE idate >= '1997-05-05';
mysql> SELECT idate FROM tabelle WHERE idate >= 19970505;
mysql> SELECT mod(idate,100) FROM tabelle WHERE idate >= 19970505;
mysql> SELECT idate FROM tabelle WHERE idate >= '19970505';

Folgendes jedoch funktioniert nicht:

mysql> SELECT idate FROM tabelle WHERE STRCMP(idate,'19970505')=0;

STRCMP() ist eine Zeichenkettenfunktion, daher wird idate in eine Zeichenkette umgewandelt und ein Zeichenkettenvergleich durchgeführt. MySQL wandelt '19970505' nicht in ein Datum um und führt einen Datumsvergleich durch.

Beachten Sie, dass MySQL nicht prüft, ob ein Datum korrekt ist oder nicht. Wenn Sie ein falsches Datum wie '1998-2-31' speichern, wird das falsche Datum gespeichert. Wenn das Datum in keinen vernünftigen Wert umgewandelt werden kann, wird 0 im DATE-Feld gespeichert. Das ist hauptsächlich eine Sache der Geschwindigkeit, und wir sind der Meinung, dass es Sache der Applikation und nicht des Servers ist, Datumsangaben zu überprüfen.

A.5.3. Probleme mit NULL-Werten

Das Konzept des NULL-Wert ist eine häufige Quelle der Verwirrung für SQL-Anfänger. Diese denken häufig, NULL sei dasselbe wie eine leere Zeichenkette ''. Das ist nicht der Fall! So sind zum Beispiel folgende Statements grundverschieden:

mysql> INSERT INTO meine_tabelle (Telefon) VALUES (NULL);
mysql> INSERT INTO meine_tabelle (Telefon) VALUES ("");

Beide Statements fügen einen Wert in die Telefon-Spalte ein, aber das erste fügt einen NULL-Wert und das zweite eine leere Zeichenkette ein. Die Bedeutung des ersten ist etwa ``Telefonnummer unbekannt'' und des zweiten ``Keine Telefonnummer''.

In SQL ist der NULL-Wert im Vergleich mit jedem anderen Wert immer UNWAHR (false), selbst im Vergleich mit NULL. Ein Ausdruck, der NULL enthält, erzeugt immer einen NULL-Wert, ausser wenn es in der Dokumentation der Operatoren und Funktionen, die im Ausdruck beteiligt sind, anders angegeben ist. Alle Spalten im folgenden Beispiel geben NULL zurück:

mysql> SELECT NULL,1+NULL,CONCAT('unsichtbar',NULL);

Wenn Sie nach Spaltenwerten suchen, die NULL sind, können Sie nicht =NULL benutzen. Folgendes Statement gibt keine Zeilen zurück, weil ausdruck = NULL für jeden beliebigen Ausdruck UNWAHR (false) ist:

mysql> SELECT * FROM meine_tabelle WHERE Telefon = NULL;

Um nach NULL-Werten zu suchen, müssen Sie IS NULL benutzen. Folgende Beispiele zeigen, wie Sie die NULL-Telefonnummer und die leere Telefonnummer finden:

mysql> SELECT * FROM meine_tabelle WHERE Telefon IS NULL;
mysql> SELECT * FROM meine_tabelle WHERE Telefon = "";

In MySQL können Sie - wie bei vielen anderen SQL-Servern - keine Spalten indexieren, die NULL-Werte enthalten dürfen. Sie müssen solche Spalten aus NOT NULL deklarieren. Sie dürfen in eine indexierte Spalte keine NULL-Werte einfügen.

Wenn Sie Daten mit LOAD DATA INFILE einlesen, werden leere Spalten mit '' aktualisiert. Wenn Sie einen NULL-Wert in einer Spalte haben wollen, müssen Sie in der Textdatei \N benutzen. Unter manchen Umständen kann auch das Literalwort 'NULL' benutzt werden. See Abschnitt 7.4.9, „LOAD DATA INFILE-Syntax“.

Wenn Sie ORDER BY benutzen, werden NULL-Werte zuerst angezeigt. Wenn Sie mit DESC in absteigender Reihenfolge sortieren, werden NULL-Werte zuletzt angezeigt. Wenn Sie GROUP BY benutzen, werden alle NULL-Werte als gleich betrachtet.

Um die Handhabung von NULL zu erleichtern, können Sie die IS NULL- und IS NOT NULL-Operatoren und die IFNULL()-Funktion benutzen.

Bei manchen Spaltentypen werden NULL-Werte besonders behandelt. Wenn Sie NULL in die erste TIMESTAMP-Spalte einer Tabelle einfügen, werden das aktuelle Datum und die aktuelle Zeit eingefügt. Wenn Sie NULL in eine AUTO_INCREMENT-Spalte einfügen, wird die nächste Zahl in der Zahlenfolge eingefügt.

A.5.4. Probleme mit alias

Sie können ein Alias verwenden, um auf eine Spalte im GROUP BY-, ORDER BY- oder HAVING-Teil zu verweisen. Aliase können auch verwendet werden, um Spalten bessere Namen zu geben:

SELECT SQRT(a*b) as wurzel FROM tabelle GROUP BY wurzel HAVING wurzel > 0;
SELECT id,COUNT(*) AS zaehl FROM tabelle GROUP BY id HAVING zaehl > 0;
SELECT id AS "kunden-kennung" FROM tabelle;

Beachten Sie, dass ANSI-SQL verbietet, in einer WHERE-Klausel auf ein Alias zu verweisen. Das liegt daran, dass der Spaltenwert möglicherweise noch nicht feststeht, wenn der WHERE-Code ausgeführt wird. Folgende Anfrage zum Beispiel ist unzulässig:

SELECT id,COUNT(*) AS zaehl FROM tabelle WHERE zaehl > 0 GROUP BY id;

Das WHERE-Statement wird ausgeführt, um festzulegen, welche Zeilen im GROUP BY-Teil enthalten sein sollen, während HAVING benutzt wird, um zu entscheiden, welche Zeilen der Ergebnismenge benutzt werden sollten.

A.5.5. Zeilen aus verwandten Tabellen löschen

Weil MySQL keine Sub-Selects oder die Benutzung von mehr als einer Tabelle im DELETE-Statement unterstützt, müssen Sie folgenden Ansatz wählen, um Zeilen aus zwei verwandten Tabellen zu löschen:

  1. Wählen (SELECT) Sie die Zeilen auf der Grundlage einer WHERE-Bedingung in der Haupt-Tabelle aus.

  2. Löschen (DELETE) Sie die Zeilen in der Haupt-Tabelle auf der Grundlage derselben Bedingung.

  3. Löschen Sie die Zeilen aus der verwandten Tabelle, bei denen die verwandte Spalte in den ausgewählten Zeilen vorkommt (DELETE FROM verwandte_tabelle WHERE verwandte_spalte IN (ausgewaehlte_zeilen).

Wenn die Gesamtzahl von Zeichen in der Anfrage mit verwandte_spalte mehr als 1.048.576 beträgt (der Vorgabewert von max_allowed_packet, sollten Sie sie in kleinere Teile aufspalten und mehrfache DELETE-Statements ausführen. Wahrscheinlich geht das Löschen (DELETE) am Schnellsten, wenn Sie nur 100 bis 1000 verwandte_spalte-Kennungen pro Anfrage löschen, wenn verwandte_spalte ein Index ist. Wenn verwandte_spalte kein Index ist, ist die Geschwindigkeit unabhängig von der Anzahl von Argumenten in der IN-Klausel.

A.5.6. Probleme bei keinen übereinstimmenden Zeilen lösen

Wenn Sie eine komplizierte Anfrage haben, die viele Tabellen hat und keine Zeilen zurückgibt, sollten Sie folgende Prozedur benutzen, um herauszufinden, was bei Ihrer Anfrage falsch ist:

  1. Testen Sie die Anfrage mit EXPLAIN und prüfen Sie, ob Sie etwas finden können, das offensichtlich falsch ist. See Abschnitt 6.2.1, „EXPLAIN-Syntax (Informationen über ein SELECT erhalten)“.

  2. Wählen Sie in der WHERE-Klausel nur die Felder aus, die benutzt werden.

  3. Entfernen Sie nacheinander Tabelle für Tabelle aus der Anfrage, bis sie Zeilen zurückgibt. Wenn die Tabellen Groß sind, ist es eine gute Idee, LIMIT 10 bei der Anfrage zu benutzen.

  4. Machen Sie ein SELECT für die Spalte, die mit einer Zeile hätte übereinstimmen sollen, gegen die Tabelle, die als letzte aus der Anfrage entfernt wurde.

  5. Wenn Sie FLOAT- oder DOUBLE-Spalten mit Zahlen vergleichen, die Dezimalstellen haben, können Sie nicht = benutzen! Das Problem tritt in den meisten Computersprachen auf, weil Fließkommawerte keine exakten Werte sind:

    mysql> SELECT * FROM tabelle WHERE float_spalte=3.5;
    mysql> SELECT * FROM tabelle WHERE float_spalte between 3.45 und 3.55;
    

    In den meisten Fällen kann dies durch Umwandlung von FLOAT in DOUBLE behoben werden!

  6. Wenn Sie immer noch nicht herausfinden können, was schief geht, erzeugen Sie einen minimalen Test, der mit mysql test < anfrage.sql laufen gelassen werden kann, um Ihre Probleme aufzuzeigen. Sie können eine Testdatei mit mysqldump --quick datenbanktabellen > anfrage.sql erzeugen. Öffnen Sie die Datei in einem Editor, entfernen Sie ein paar Einfügezeilen (wenn es davon zu viele gibt) und fügen Sie Ihr SELECT--Statement am Ende der Datei an.

    Testen Sie, ob es hiermit immer noch das Problem gibt:

    shell> mysqladmin create test2
    shell> mysql test2 < anfrage.sql
    

    Schicken Sie die Testdatei mittels mysqlbug an .

A.6. Tabellendefinitionsbezogene Themen

A.6.1. Probleme mit ALTER TABLE.

ALTER TABLE ändert eine Tabelle zum aktuellen Zeichensatz. Wenn Sie während ALTER TABLE einen Fehler wegen doppelter Schlüsseleinträge bekommen, liegt das entweder daran, dass die neuen Zeichensätze auf bei Schlüsseln auf dieselben Werte gemappt sind, oder dass die Tabelle beschädigt ist, wobei Sie REPAIR TABLE auf die Tabelle laufen lassen sollten.

Wenn ALTER TABLE mit einem Fehler wie folgt stirbt:

Error on rename of './datenbank/name.frm' to './datenbank/B-a.frm' (Errcode: 17)

Kann das Problem darin bestehen, dass MySQL bei einem vorhergehenden ALTER TABLE abgestürzt ist und es eine alte Tabelle namens A-etwas oder B-etwas gibt, die herum liegt. Gehen Sie in diesem Fall ins MySQL-Daten-Verzeichnis und löschen Sie alle Dateien, die Namen wie A- oder B- haben. (Statt löschen können Sie sie auch an eine andere Stelle verschieben.)

ALTER TABLE funktioniert auf folgenden Weise:

  • Erzeugt eine neue Tabellen namens A-xxx mit den angeforderten Änderungen.

  • Alle Zeilen der alten Tabelle werden nach A-xxx kopiert.

  • Die alte Tabelle wird in B-xxx umbenannt.

  • A-xxx wird in Ihren alten Tabellennamen umbenannt.

  • B-xxx wird gelöscht.

Wenn etwas bei dieser Umbennungsoperation fehlschlägt, versucht MySQL, die Änderungen rückgängig zu machen. Wenn etwas Schwerwiegendes schief geht (was natürlich passieren kann), läßt MySQL eventuell die alte Tabelle als B-xxx, aber ein einfaches Umbenennen auf Systemebene sollte Ihre Daten zurückbringen.

A.6.2. Wie man die Reihenfolge der Spalten in einer Tabelle ändert

Im großen und Ganzen geht es bei SQL darum, die Applikation vom Daten-Speicherformat zu abstrahieren. Sie sollten immer die Reihenfolge angeben, in der Sie Ihre Daten abrufen wollen. Beispiel:

SELECT spalten_name1, spalten_name2, spalten_name3 FROM tabelle;

Das gibt die Spalten in der Reihenfolge spalten_name1, spalten_name2, spalten_name3 zurück, wohingegen:

SELECT spalten_name1, spalten_name3, spalten_name2 FROM tabelle;

die Spalten in der Reihenfolge spalten_name1, spalten_name3, spalten_name2 zurückgibt.

Sie sollten in einer Applikation NIE SELECT * benutzen und die Spalten basierend auf ihrer Position abrufen, weil die Reihenfolge, in der Spalten zurückgegeben werden, im Zeitablauf NICHT garantiert werden kann. Eine einfache Änderung in Ihrer Datenbank kann dazu führen, dass Ihre Applikation dramatisch scheitert.

Wenn Sie dennoch die Spalten-Reihenfolge ändern wollen, können Sie das wie folgt tun:

  1. Erzeugen Sie eine neue Tabelle mit den Spalten in der richtigen Reihenfolge.

  2. Führen Sie INSERT INTO neue_tabelle SELECT felder-in-der-reihenfolge-von-neue_tabelle FROM alte_tabelle aus.

  3. Löschen Sie alte_tabelle oder benennen Sie sie um.

  4. Führen Sie ALTER TABLE neue_tabelle RENAME alte_tabelle aus.

A.6.3. TEMPORARY TABLE-Probleme

Im Folgenden eine Auflistung der Beschränkungen bei TEMPORARY TABLES.

  • Eine temporäre Tabelle kann nur vom Typ HEAP, ISAM oder MyISAM sein.

  • Sie können temporäre Tabellen nicht mehr als einmal in derselben Anfrage benutzen. Folgendes zum Beispiel funktioniert nicht:

    select * from temporary_table, temporary_table as t2;
    

    Das soll in Version 4.0 behoben werden.

  • Sie können kein RENAME auf eine TEMPORARY-Tabelle benutzen. Beachten Sie, dass ALTER TABLE alter_name RENAME neuer_name dagegen funktioniert! Das soll in Version 4.0 behoben werden.


This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.