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.
Wenn Sie Probleme bekommen, sollten Sie als erstes herausfinden, welches Programm oder Hardware-Teil die Probleme verursacht:
kbd_mode -a
ausführen.
top
, ps
, taskmanager
oder ein ähnliches
Programm, um zu prüfen, welches Programm die gesamte Prozessorzeit
konsumiert oder die Maschine blockiert.
top
, df
oder einem ähnlichen Programm, wenn
Sie keinen freien Arbeitsspeicher, Festplattenspeicher, verfügbare
Datei-Handler oder eine andere kritische Ressource mehr haben.
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:
top
. Lassen Sie das Programm eine Weile laufen, denn vielleicht
evaluiert es gerade nur etwas Schwieriges.
mysqld
-Server Probleme verursacht, können Sie dann
mysqladmin -u root ping
oder mysqladmin -u root processlist
ausführen?
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 section 2.6.2.2 Wie man Fragen stellt oder Bugs berichtet.
Dieser Abschnitt listet einige Fehler auf, die Benutzer häufig erhalten. Hier finden Sie Beschreibungen dieser Fehler und wie man die Probleme löst.
Access denied
-Fehler
See section 5.2.5 Wie das Berechtigungssystem funktioniert, insbesondere See section 5.2.10 Gründe für Access denied
-Fehler.
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_ERROR | Der Client konnte keine Anfrage an den Server schicken. |
CR_SERVER_LOST | Der 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!
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 section 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.
mysqld
das
MIT-pThread-Paket. See section 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
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 section A.4.5 Wie Sie die MySQL-Socket-Datei `/tmp/mysql.sock' schützen oder ändern.
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 section A.4.5 Wie Sie die MySQL-Socket-Datei `/tmp/mysql.sock' schützen oder ändern.
mysqld
-Thread killen (beispielsweise mit dem
mysql_zap
-Skript), bevor Sie einen neuen MySQL-Server starten
können. See section A.4.1 Was zu tun ist, wenn MySQL andauernd abstürzt.
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:
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.
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
.
mysqld
-Server nicht gestartet wurde, indem Sie
die --skip-networking
-Option verwenden.
Host '...' is blocked
-FehlerWenn 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!
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 section 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.
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 section 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 section 5.5.5.4 SHOW VARIABLES
.
No free memory
-FehlerWenn 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.
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.
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 section 5.9.1 Die Fehler-Log-Datei.
Bedeutet das, dass eins der folgenden Dinge passiert ist:
mysql_close()
auf.
wait_timeout
oder
interactive_timeout
, ohne Anfragen auszuführen.
See section 5.5.5.4 SHOW VARIABLES
.
Wenn das oben Genannte passiert, wird die Servervariable
Aborted_clients
heraufgezählt.
Die Servervariable Aborted_connects
wird in folgenden Fällen
heraufgezählt:
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 section 5.5.5.4 SHOW VARIABLES
.
Andere Gründe für Probleme mit abgebrochenen Clients / abgebrochenen Verbindungen:
max_allowed_packet
ist zu klein oder Anfragen erfordern mehr
Speicher, als Sie für mysqld
zugewiesen haben.
See section A.2.8 Packet too large
-Fehler.
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 section 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.
Can't create/write to file
-FehlerWenn 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 section 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
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.
User ignored
-FehlerWenn 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:
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.
mysqld
nicht mit der --old-protocol
-Option gestartet.
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';
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 section 5.5.5 SHOW
-Syntax.
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:
--with-charset=xxx
- oder die --with-extra-charsets=xxx
-Option
angeben. See section 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 section 5.6.1 Der für Daten und Sortieren benutzte Zeichensatz.
mysqld
kompiliert wurde, und die Zeichensatz-Definitionsdateien sind nicht an der
Stelle, an der der Client sie erwartet.
In diesem Fall müssen Sie:
configure
-Optionen.
--character-sets-dir=pfad-to-charset-dir
-Option machen.
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 section 5.5.5.4 SHOW VARIABLES
. Die einfachste Art, das zu
tun, besteht darin, eine Option zu Ihrer Optionsdatei hinzuzufügen.
See section 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!
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 section 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:
libmysqlclient.so
haben, der LD_LIBRARY_PATH
-Umgebungsvariablen hinzu.
libmysqlclient.so
haben, der LD_LIBRARY
-Umgebungsvariablen hinzu.
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!
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:
mysqladmin
shutdown
).
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/datadirWenn 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.
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.
[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.
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 section E Umgebungsvariablen.
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 section 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:
mysqld
oder die Maschine mitten während
einer Aktualisierung.
mysqld
gefunden, der dazu führte, dass er
mitten während einer Aktualisierung starb.
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.
mysqld
durcheinander brachten.
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:
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 section 5 MySQL-Datenbankadministration.
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 section 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 section 2.6.2.3 Wie man Bugs oder Probleme berichtet.
fork_test.pl
und fork2_test.pl
.
--with-debug
-Option oder mit der
--with-debug=full
-Option für configure
neu und kompilieren
Sie neu. See section D.1 Einen MySQL-Server debuggen.
--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.)
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.
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.
mysqld
von gdb
aus (oder in einem anderen
Debugger).
See section D.1.3 mysqld unter gdb debuggen.
mysqld
innerhalb von gdb abgestürzt ist:
backtrace info local up info local up info localMit 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).
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.
Wenn Sie das root
-Benutzerpasswort für MySQL vergessen haben, können
Sie es mit folgender Prozedur wiederherstellen:
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.
mysqld
mit der --skip-grant-tables
-Option neu.
mysqld
-Server mit mysql -h hostname
mysql
und ändern Sie das Passwort mit einem GRANT
-Befehl.
See section 5.3.1 GRANT
- und REVOKE
-Syntax. Sie können dasselbe auch mit mysqladmin
-h hostname -u benutzer password 'neues_passwort'
machen.
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.
Wenn etwas hinsichtlich der Festplatte passiert, tut MySQL folgendes:
Um das Problem abzumildern, können Sie folgende Aktionen unternehmen:
mysqladmin kill
an den Thread
senden. Der Thread wird beim nächsten Mal, wenn er die Festplatte prüft (in
1 Minute) abgebrochen.
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).
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.
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:
/etc/my.cnf
eintragen:
[client] socket=pfad-fuer-socket-datei [mysqld] socket=pfad-fuer-socket-dateiSee section 5.1.2 my.cnf-Optionsdateien.
safe_mysqld
und die
meisten Clients mit der --socket=pfad-fuer-socket-datei
-Option an.
MYSQL_UNIX_PORT
-Umgebungsvariablen an.
variable.
configure
-Option
--with-unix-socket-path=pfad-fuer-socket-datei
.
See section 3.3.3 Typische configure
-Optionen.
Mit folgendem Befehl können Sie testen, ob der Socket funktioniert:
shell> mysqladmin --socket=/pfad/zu/socket version
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 section E Umgebungsvariablen.
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 section 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.
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.
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 section 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.
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.
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:
SELECT
) Sie die Zeilen auf der Grundlage einer
WHERE
-Bedingung in der Haupt-Tabelle aus.
DELETE
) Sie die Zeilen in der Haupt-Tabelle auf der
Grundlage derselben Bedingung.
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.
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:
EXPLAIN
und prüfen Sie, ob Sie etwas
finden können, das offensichtlich falsch ist. See section 6.2.1 EXPLAIN
-Syntax (Informationen über ein SELECT
erhalten).
WHERE
-Klausel nur die Felder aus, die benutzt
werden.
LIMIT 10
bei der Anfrage zu benutzen.
SELECT
für die Spalte, die mit einer Zeile hätte
übereinstimmen sollen, gegen die Tabelle, die als letzte aus der Anfrage
entfernt wurde.
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!
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.sqlSchicken Sie die Testdatei mittels
mysqlbug
an
mysql@lists.mysql.com.
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:
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.
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:
INSERT INTO neue_tabelle SELECT
felder-in-der-reihenfolge-von-neue_tabelle FROM alte_tabelle
aus.
alte_tabelle
oder benennen Sie sie um.
ALTER TABLE neue_tabelle RENAME alte_tabelle
aus.
Im Folgenden eine Auflistung der Beschränkungen bei TEMPORARY TABLES
.
HEAP
, ISAM
oder
MyISAM
sein.
select * from temporary_table, temporary_table as t2;Das soll in Version 4.0 behoben werden.
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.
Go to the first, previous, next, last section, table of contents.