Die folgenden Probleme sind bekannt und werden vorrangig gelöst:
Wenn Sie einen NULL
-Wert mit einer
Unterabfrage kombinieren, die eine
ALL/ANY/SOME
-Klausel hat, und die
Unterabfrage ein leeres Ergebnis zurückliefert, kann der
Vergleich das nicht standardmäßige Resultat
NULL
ergeben anstatt
TRUE
oder FALSE
. Dies
wird in MySQL 5.1 behoben.
Die Optimierung von Unterabfragen ist bei
IN
weniger effizient als bei
=
.
Selbst wenn Sie lower_case_table_names=2
verwenden (damit sich MySQL an die Groß-/Kleinschreibung
von Datenbank- und Tabellennamen erinnert) kann MySQL sich
diese nicht für Datenbanknamen im Zusammenhang mit der
Funktion DATABASE()
oder den diversen
Logs merken (dies gilt für Systeme, die nicht zwischen
Groß- und Kleinschreibung unterscheiden).
Das Löschen eines FOREIGN
KEY
-Constraints funktioniert nicht in einer
Replikation, da der Constraint auf dem Slave unter
Umständen einen anderen Namen hat.
REPLACE
(und LOAD DATA
mit der REPLACE
-Option) löst kein
ON DELETE CASCADE
aus.
DISTINCT
mit ORDER BY
funktioniert nicht in GROUP_CONCAT()
,
wenn Sie nicht nur die Spalten verwenden, die in der
DISTINCT
-Liste aufgeführt sind.
Wenn ein Benutzer eine langwierige Transaktion laufen lässt
und ein anderer Benutzer eine Tabelle löscht, die von der
Transaktion geändert wird, besteht ein gewisses Risiko,
dass der DROP TABLE
im Binärlog
festgehalten wird, bevor die Tabelle in der Transaktion
benutzt wird. Dies wollen wir beheben, indem wir den
DROP TABLE
-Befehl so lange aussetzen
lassen, bis die Tabelle in keiner Transaktion mehr benutzt
wird.
Wenn Sie einen großen Integer-Wert (zwischen 263 und 264–1) in eine Decimal- oder String-Spalte einfügen, wird er als negativer Wert geschrieben, da die Zahl als vorzeichenbehafteter Integer ausgewertet wird.
FLUSH TABLES WITH READ LOCK
kann
COMMIT
nicht blockieren, wenn der Server
ohne Binärlogging läuft. Das kann zu Konsistenzproblemen
mit Tabellen führen, wenn Sie eine vollständige
Datensicherung ausführen.
ANALYZE TABLE
kann
BDB
-Tabellen unter Umständen bis zum
nächsten Neustart von mysqld unbenutzbar
machen. Wenn dies geschieht, suchen Sie in der Fehlerdatei
von MySQL nach Fehlern der folgenden Art:
001207 22:07:56 bdb: log_flush: LSN past current end-of-log
Führen Sie kein ALTER TABLE
auf einer
BDB
-Tabelle aus, auf der Transaktionen
mit mehreren Anweisungen laufen. Dies können Sie erst nach
Abschluss aller dieser Transaktionen tun, da die Transaktion
ansonsten eventuell ignoriert wird.
ANALYZE TABLE
, OPTIMIZE
TABLE
und REPAIR TABLE
können
Probleme mit Tabellen verursachen, die mit INSERT
DELAYED
laufen.
Auch mit LOCK TABLE ...
und
FLUSH TABLES ...
ist nicht
gewährleistet, dass nicht noch eine halbfertige Transaktion
auf der Tabelle abläuft.
BDB
-Tabellen öffnen sich relativ
langsam. Wenn Sie viele BDB
-Tabellen in
einer Datenbank haben, braucht der
mysql-Client viel Zeit, es sei denn, Sie
verwenden die Option -A
oder
rehash
. Das macht sich besonders bei
großen Tabellen-Caches bemerkbar.
Replikation verwendet Logging auf Anweisungsebene: Der Master schreibt die ausgeführten Anweisungen in das Binärlog. Dies ist eine sehr schnelle, kompakte und wirkungsvolle Loggingmethode, die in den meisten Fällen auch perfekt funktioniert.
Es ist jedoch möglich, dass Unterschiede zwischen den Daten von Master und Slave auftreten, wenn eine Anfrage so entworfen wurde, dass sie Daten in nichtdeterministischer Weise ändert (was allerdings generell, auch außerhalb einer Replikation, nicht zu empfehlen ist).
Beispielsweise:
CREATE ... SELECT
- oder
INSERT ... SELECT
-Anweisungen, die
null oder NULL
-Werte in eine
AUTO_INCREMENT
-Spalte einfügen.
DELETE
, wenn Sie Zeilen aus einer
Tabelle löschen, die Fremdschlüssel mit ON
DELETE CASCADE
-Eigenschaften hat.
REPLACE ... SELECT
, INSERT
IGNORE ... SELECT
, wenn Sie in den
eingefügten Daten Schlüsselduplikate haben.
Genau dann, wenn die vorangegangenen
Anfragen keine ORDER BY
-Klausel haben,
die eine deterministische Sortierreihenfolge
garantiert.
So kann beispielsweise ein SELECT
für
INSERT ... SELECT
ohne ORDER
BY
-Klausel Zeilen in einer anderen Reihenfolge
zurückliefern (was dazu führt, dass eine Zeile einen
unterschiedlichen Rang und somit auch unterschiedliche
Nummern in der AUTO_INCREMENT
-Spalte
haben kann), je nachdem, wie sich die Optimierer von Master
und Slave entscheiden.
Eine Anfrage wird auf Master und Slave nur in folgenden Fällen unterschiedlich optimiert:
Wenn die Tabelle auf dem Master mit einer anderen
Speicher-Engine als auf dem Slave gespeichert wird. (Es
ist nämlich möglich, auf Master und Slave verschiedene
Speicher-Engines zu verwenden. So können Sie
beispielsweise InnoDB
auf dem Master
und MyISAM
auf dem Slave einsetzen,
wenn der Slave weniger Festplattenspeicher zur
Verfügung hat.)
Wenn die Größen der MySQL-Puffer
(key_buffer_size
und so weiter) auf
Master und Slave unterschiedlich sind.
Wenn Master und Slave mit unterschiedlichen MySQL-Versionen laufen und der Optimierungscode einen Unterschied zwischen diesen beiden Versionen macht.
Dieses Problem kann auch die Datenbankwiederherstellung mit mysqlbinlog|mysql beeinträchtigen.
Am einfachsten lässt sich dieses Problem verhindern, wenn
Sie den oben erwähnten nichtdeterministischen Anfragen eine
ORDER BY
-Klausel hinzufügen, um zu
gewährleisten, dass die Zeilen immer in derselben
Reihenfolge gespeichert oder modifiziert werden.
In künftigen MySQL-Versionen werden wir automatisch eine
ORDER BY
-Klausel hinzufügen, wo sie
nötig ist.
Die folgenden Probleme sind bekannt und werden bald behoben:
Die Logdateinamen basieren auf dem Namen des Serverhosts
(sofern Sie nicht mit der Startoption einen Dateinamen
vorgeben). Wenn Sie Ihren Hostnamen ändern möchten,
müssen Sie Optionen wie beispielsweise
--log-bin=
verwenden. Oder Sie benennen die alten Dateien mit dem neuen
Hostnamen um (wenn es Binärlogs sind, müssen Sie dazu auch
die Indexdatei des Binärlogs bearbeiten und die Binlognamen
ebenfalls ändern). Siehe Abschnitt 5.2.1, „Befehlsoptionen für mysqld“.
old_host_name
-bin
mysqlbinlog löscht keine temporären
Dateien, die nach einem LOAD DATA
INFILE
-Befehl übrig bleiben. Siehe
Abschnitt 8.8, „mysqlbinlog — Hilfsprogramm für die Verarbeitung binärer Logdateien“.
RENAME
funktioniert nicht mit
TEMPORARY
-Tabellen oder Tabellen, die in
einer MERGE
-Tabelle benutzt werden.
Aufgrund der Art und Weise, wie Tabellenformatdateien
(.frm
-Dateien) gespeichert werden,
können Sie Zeichen 255 (CHAR(255)
) nicht
in Tabellennamen, Spaltennamen und Enumerationen verwenden.
Dies soll in Version 5.1 behoben werden, wenn wir neue
Formatdateien für die Tabellendefinitionen implementieren.
Wenn Sie SET CHARACTER SET
benutzen,
können Sie keine übersetzten Zeichen in den Namen von
Datenbanken, Tabellen und Spalten verwenden.
Sie dürfen kein ‘_
’ oder
‘%
’ mit
ESCAPE
in LIKE ...
ESCAPE
verwenden.
Wenn Sie in einer DECIMAL
-Spalte dieselbe
Zahl in verschiedenen Formaten gespeichert haben
(beispielsweise +01.00
,
1.00
, 01.00
), kann es
passieren, dass GROUP BY
diese Werte als
unterschiedlich betrachtet.
Sie können den Server nicht in einem anderen Verzeichnis bauen, wenn Sie MIT-pthreads verwenden. Da sich dies nur durch eine Änderung von MIT-pthreads beheben ließe, werden wir es wahrscheinlich nicht reparieren können. Siehe auch Abschnitt 2.8.5, „Anmerkungen zu MIT-pthreads“.
BLOB
- und TEXT
-Werte
können in GROUP BY
, ORDER
BY
oder DISTINCT
nicht
zuverlässig benutzt werden, da in diesen Fällen zum
Vergleich von BLOB
-Werten nur die ersten
max_sort_length
Bytes herangezogen
werden. Der Standardwert von
max_sort_length
beträgt 1.024 und kann
beim Serverstart oder zur Laufzeit geändert werden.
Numerische Berechnungen werden mit BIGINT
oder DOUBLE
ausgeführt (beide sind
normalerweise 64 Bits lang). Welche Genauigkeit sie haben,
hängt von der Funktion ab. Im Allgemeinen werden
Bitfunktionen mit einer
BIGINT
-Genauigkeit, IF
und ELT()
mit einer
BIGINT
- oder
DOUBLE
-Genauigkeit und alles Übrige mit
einer DOUBLE
-Genauigkeit ausgeführt. Sie
sollten möglichst (außer für Bitfelder) keine sehr langen
Werte verwenden, wenn diese länger als 63 Bits
(9223372036854775807) werden können.
In einer Tabelle dürfen bis zu 255 ENUM
-
und SET
-Spalten vorhanden sein.
In MIN()
, MAX()
und
anderen Aggregatfunktionen vergleicht MySQL
ENUM
- und SET
-Spalten
gegenwärtig nach ihrem Stringwert anstatt nach der
relativen Position des Strings in der Menge.
mysqld_safe leitet alle Meldungen von
mysqld in das
mysqld-Log. Wenn Sie das Log mit
mysqladmin refresh schließen und neu
öffnen, besteht jedoch das Problem, dass
stdout
und stderr
weiterhin in das alte Log umgeleitet werden. Wenn Sie viel
mit --log
arbeiten, sollten Sie
mysqld_safe so bearbeiten, dass es
Logeinträge in
statt in
host_name
.err
schreibt, damit Sie den Speicherplatz des alten Logs
leichter zurückholen können, indem Sie es einfach löschen
und mysqladmin refresh ausführen.
host_name
.log
In einer UPDATE
-Anweisung werden die
Spalten von links nach rechts aktualisiert. Wenn Sie eine
aktualisierte Spalte benutzen, bekommen Sie den
aktualisierten statt des ursprünglichen Werts. Die folgende
Anweisung inkrementiert beispielsweise
KEY
um 2
und
nicht um
1
:
mysql> UPDATE tbl_name
SET KEY=KEY+1,KEY=KEY+1;
Sie können zwar in derselben Anfrage mehrere temporäre Tabellen benutzen, aber nicht dieselbe zweimal. Das Folgende funktioniert beispielsweise nicht:
mysql> SELECT * FROM temp_table, temp_table AS t2;
ERROR 1137: Can't reopen table: 'temp_table'
Der Optimierer behandelt DISTINCT
unterschiedlich, je nachdem, ob Sie in einem Join
„verborgene“ Spalten benutzen oder nicht.
Verborgene Spalten werden in einem Join als Teil des
Ergebnisses betrachtet (obwohl sie nicht angezeigt werden),
während sie in normalen Anfragen nicht an einem
DISTINCT
-Vergleich teilnehmen. Dies
werden wir wahrscheinlich in Zukunft dahingehend ändern,
dass die verborgenen Spalten bei DISTINCT
nicht mehr am Vergleich beteiligt werden.
Ein Beispiel dafür ist:
SELECT DISTINCT mp3id FROM band_downloads WHERE userid = 9 ORDER BY id DESC;
und
SELECT DISTINCT band_downloads.mp3id FROM band_downloads,band_mp3 WHERE band_downloads.userid = 9 AND band_mp3.id = band_downloads.mp3id ORDER BY band_downloads.id DESC;
Im zweiten Fall bekommen Sie mit MySQL Server 3.23.x
vielleicht zwei identische Zeilen in der Ergebnismenge (da
die Werte in der verborgenen id
-Spalte
unterschiedlich sein können).
Beachten Sie, dass dies nur in Anfragen ohne ORDER
BY
-Spalten im Ergebnis passieren kann.
Wenn Sie eine PROCEDURE
auf einer Anfrage
ausführen, die eine leere Menge zurückgibt, wird die
PROCEDURE
in manchen Fällen die Spalten
nicht transformieren.
Beim Anlegen einer Tabelle vom Typ MERGE
wird nicht geprüft, ob die Typen der zugrunde liegenden
Tabellen kompatibel sind.
Wenn Sie einer Tabelle, die in einer
MERGE
-Tabelle benutzt wird, mit
ALTER TABLE
einen
UNIQUE
-Index hinzufügen und dann einen
normalen Index auf die MERGE
-Tabelle
legen, ist die Reihenfolge der Schlüssel bei Tabellen
anders, wenn zuvor ein
Nicht-UNIQUE
-Schlüssel in der Tabelle
bestand. Der Grund: ALTER TABLE
setzt
UNIQUE
-Indizes vor normale Indizes, um so
früh wie möglich Schlüsselduplikate erkennen zu können.
Dies ist eine Übersetzung des MySQL-Referenzhandbuchs, das sich auf dev.mysql.com befindet. Das ursprüngliche Referenzhandbuch ist auf Englisch, und diese Übersetzung ist nicht notwendigerweise so aktuell wie die englische Ausgabe. Das vorliegende deutschsprachige Handbuch behandelt MySQL bis zur Version 5.1.