Inhaltsverzeichnis
Für den Server wird eine funktionierende Posix-Thread-Bibliothek
benötigt. Auf Solaris 2.5 benutzen wir Sun PThread (die native
Thread-Unterstützung in Version 2.4 und früher ist nicht gut
genug). Auf Linux benutzen wir LinuxThread von Xavier Leroy,
<Xavier.Leroy@inria.fr>
.
Der schwierige Teil der Portierung auf eine neue Unix-Variante ohne
gute native Thread-Unterstützung ist wahrscheinlich, MIT-pThread zu
portieren. Siehe with-pThread/README
und
POSIX-Thread
programmieren.
Die MySQL-Distribution enthält eine gepatchte Version von Provenzanos PThread von MIT (siehe MIT-PThread-Website). Diese kann für einige Betriebssysteme benutzt werden, die kein POSIX-Thread haben.
Es ist ebenfalls möglich, ein anderes Thread-Paket auf Benutzerebene namens FSU-PThread zu benutzen (siehe FSU-PThread-Homepage). Diese Implementation wird für die SCO-Portierung benutzt.
In den thr_lock.c
- und
thr_alarm.c
-Programmen im
mysys
-Verzeichnis finden Sie einige Tests /
Beispiele dieser Probleme.
Sowohl Server als auch Client benötigen einen funktionierenden
C++-Kompiler (wir benutzen gcc
und haben
SparcWorks ausprobiert). Ein anderer bekanntermaßen
funktionierender Compiler ist Irix cc
.
Um nur den Client zu kompilieren, benutzen Sie ./configure
--without-server
.
Es gibt momentan keine Unterstützung, um nur den Server zu kompilieren, noch ist es wahrscheinlich, dass eine solche hinzugefügt wird, falls nicht jemand einen guten Grund dafür findet.
Wenn Sie irgend welche Makefile
oder das
configure-Skript ändern wollen / müssen, müssen Sie sich Automake
und Autoconf holen. Wir haben die automake-1.2
-
und autoconf-2.12
-Distributionen benutzt.
Alle Schritte, die notwendig sind, um alles aus den grundlegendsten Dateien neu zu machen (make):
/bin/rm */.deps/*.P /bin/rm -f config.cache aclocal autoheader aclocal automake autoconf ./configure --with-debug=full --prefix='ihr_installationsverzeichnis' # Die oben erzeugten makefiles benötigen GNU-make 3.75 oder neuer. # (unten gmake genannt) gmake clean all install init-db
Wenn Sie bei einer neuen Portierung Probleme bekommen, kann es sein, dass Sie MySQL etwas debuggen müssen! See Abschnitt D.1, „Einen MySQL-Server debuggen“.
HINWEIS: Bevor Sie mit dem Debuggen
von mysqld
anfangen, bringen Sie sich zuerst die
Testprogramme mysys/thr_alarm
und
mysys/thr_lock
zum Laufen. Das stellt sicher,
dass Ihre Thread-Installation zumindest überhaupt eine Chance hat,
zu funktionieren!
Wenn Sie Funktionalität benutzen, die in MySQL sehr neu ist,
können Sie versuchen, mysqld
mit der
--skip-new
-Option laufen zu lassen (die alle sehr
neue, potenziell unsichere Funktionalität abschaltet) oder mit
--safe-mode
, was viel an Optimierung abschaltet,
die möglicherweise Probleme verursacht. See
Abschnitt A.4.1, „Was zu tun ist, wenn MySQL andauernd abstürzt“.
Wenn mysqld
nicht starten will, sollten Sie
prüfen, ob Sie irgend welche my.cnf
-Dateien
haben, die mit Ihrer Konfiguration in Konflikt kommen! Sie können
Ihre my.cnf
-Argumente mit mysqld
--print-defaults
prüfen und sie vermeiden, indem Sie
mit mysqld --no-defaults ...
starten.
Wenn mysqld
anfängt, Prozessorleistung oder
Speicher zu fressen, oder wenn er ``hängt'', können Sie
mysqladmin processlist status
benutzen, um
herauszufinden, ob irgend etwas eine Anfrage ausführt, die sehr
lange dauert. Es ist eine gute Idee, mysqladmin -i10
processlist status
in irgend einem Fenster laufen zu
haben, wenn Sie Performance-Probleme oder Probleme damit haben,
dass sich neue Clients nicht verbinden können.
Der Befehl mysqladmin debug
dumpt Informationen
über Sperren, die in Gebrauch sind, den benutzten Speicher und
den Anfragengebrauch in die mysql-Log-Datei aus. Das kann helfen,
einige Probleme zu lösen. Dieser Befehl stellt auch nützliche
Informationen zur Verfügung, selbst wenn Sie MySQL nicht zum
Debuggen kompiliert haben!
Wenn das Problem darin besteht, dass einige Tabellen langsamer und
langsamer werden, sollten Sie versuchen, die Tabelle mit
OPTIMIZE TABLE
der myisamchk
zu optimieren. See
Kapitel 5, MySQL-Datenbankadministration. Sie sollten
langsame Anfragen darüber hinaus mit EXPLAIN
überprüfen.
Ebenfalls sollten Sie den Abschnitt über betriebssystemspezifische Dinge in diesem Handbuch lesen, weil Sie Probleme haben könnten, die einzigartig für Ihre Umgebung sind. See Abschnitt 3.6, „Betriebssystem-spezifische Anmerkungen“.
Wenn Sie sehr spezielle Probleme haben, können Sie immer
versuchen, MySQL zu debuggen. Dafür müssen Sie MySQL mit der
--with-debug
- oder der
--with-debug=full
-Option kompilieren. Sie
können prüfen, ob MySQL mit Debuggen kompiliert wurde oder
nicht, wenn Sie mysqld --help
ausführen.
Wenn das --debug
-Flag in den Optionen
aufgeführt ist, haben Sie Debuggen eingeschaltet.
mysqladmin ver
gibt die
mysqld
-Version in diesem Fall ebenfalls als
mysql ... --debug
aus.
Wenn Sie gcc oder egcs benutzen, ist die empfohlene configure-Zeile:
CC=gcc CFLAGS="-O2" CXX=gcc CXXFLAGS="-O2 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-debug --with-extra-charsets=complex
Das vermeidet Probleme mit der
libstdc++
-Bibliothek und mit C++-Ausnahmen
(viele Compiler haben Probleme mit C++-Ausnahmen in threaded
Code) und kompiliert eine MySQL-Version mit Unterstützung für
alle Zeichensätze.
Wenn Sie einen Speicherüberlauffehler vermuten, können Sie
MySQL mit --with-debug=full
kompilieren, was
zusätzlich einen (SAFEMALLOC
)-Prüfer für
die Speicherzuweisung installiert. Das Laufenlassen mit
SAFEMALLOC
ist jedoch recht langsam. Wenn Sie
daher Performance-Probleme bekommen, sollten Sie
mysqld
mit der
--skip-safemalloc
-Option starten. Das schaltet
die Speicherüberlaufprüfung für jeden Aufruf von
malloc
und free
ab.
Wenn mysqld
nicht mehr abstürzt, wenn Sie
ihn mit --with-debug
kompilieren, haben Sie
wahrscheinlich einen Compiler-Bug oder einen Timing-Bug
innerhalb von MySQL gefunden. In diesem Fall können Sie
versuchen, -g
für die
CFLAGS
- und
CXXFLAGS
-Variablen oben hinzuzufügen und
nicht mehr --with-debug
zu benutzen. Wenn
mysqld
jetzt stirbt, können Sie wenigstens
mit gdb
mit ihm verbinden oder
gdb
auf die Core-Datei benutzen, um
herauszufinden, was passiert ist.
Wenn Sie MySQL zum Debuggen konfigurieren, können Sie viele
zusätzliche Sicherheitprüffunktionen hinzufügen, die die
Gesundheit von mysqld
beobachten. Wenn Sie
etwas ``Unerwartetes'' finden, wird ein Eintrag nach
stderr
geschrieben, den
safe_mysqld
in die Fehler-Log-Datei leitet!
Das heißt auch, dass Sie bei unerwarteten Problemen mit MySQL
und der Benutzung einer Quelldistribution als erstes MySQL zum
Debuggen konfigurieren sollten! (Die zweite Sache wäre
natürlich, eine E-Mail an <mysql@lists.mysql.com>
zu schicken und um Hilfe zu bitten. Bitte benutzen Sie das
mysqlbug
-Skript für alle Bug-Berichte oder
Fragen hinsichtlich der MySQL-Version, die Sie benutzen!
In der Windows-MySQL-Distribution wird
mysqld.exe
vorgabemäßig mit Unterstützung
für Trace-Dateien kompiliert.
Wenn der mysqld
-Server nicht startet oder
wenn Sie den mysqld
-Server schnell zum
Absturz bringen können, können Sie versuchen, eine Trace-Datei
zu erzeugen, um das Problem zu finden.
Hierfür brauchen Sie einen mysqld
, der zum
Debuggen kompiliert ist. Sie können das mit mysqld
-V
prüfen. Wenn die Versionsnummer mit
-debug
endet, ist Unterstützung für
Trace-Dateien einkompiliert.
Starten Sie den mysqld
-Server mit einem
Trace-Log in /tmp/mysqld.trace
(oder
C:\mysqld.trace
unter Windows):
mysqld --debug
Unter Windows sollten Sie auch den
--standalone
-Flag benutzen, um
mysqld
nicht als Systemdienst zu starten.
Machen Sie folgendes in einem DOS-Fenster:
mysqld --debug --standalone
Danach können Sie das
mysql.exe
-Kommandozeilenwerkzeug in einem
zweiten DOS-Fenster benutzen, um das Problem zu reproduzieren.
Sie können den obigen mysqld
-Server mit
mysqladmin shutdown
herunter fahren.
Beachten Sie, dass die Trace-Datei sehr Groß wird! Wenn Sie eine kleinere Trace-Datei haben wollen, können Sie etwa folgendes tun:
mysqld
--debug=d,info,error,query,general,where:O,/tmp/mysqld.trace
Das gibt nur Informationen für die interessantesten Dinge in
/tmp/mysqld.trace
aus.
Wenn Sie hierüber einen Bug-Bericht erstellen, schicken Sie bitte nur die Zeilen aus der Trace-Datei an die entsprechende Mailing-Liste, in denen etwas schief zu gehen scheint! Wenn Sie diese Stelle nicht finden können, können Sie die Trace-Datei per FTP einschicken, zusammen mit einem kompletten Bug-Bericht, an ftp://Support.mysql.com/pub/mysql/secret, so dass ein MySQL-Entwickler sich das ansehen kann.
Die Trace-Datei wird mit dem DBUG-Paket von Fred Fish hergestellt. See Abschnitt D.3, „Das DBUG-Paket“.
Auf den meisten Systemen können Sie mysqld
von gdb
starten, um mehr Informationen zu
erhalten, wenn mysqld
abstürzt.
Bei einigen älteren gdb
-Versionen unter
Linux müssen Sie run --one-thread
benutzen,
um den mysqld
-Thread debuggen zu können. In
diesem Fall können Sie zur gleichen Zeit nur einen Thread aktiv
haben.
Wenn Sie mysqld
unter gdb laufen lassen,
sollten Sie den Stack-Trace mit
--skip-stack-trace
abschalten, um
Segmentation-Fehler innerhalb gdb abfangen zu können.
Es ist sehr schwierig, MySQL unter gdb
zu
debuggen, wenn Sie permanent viele neue Verbindungen aufbauen,
weil gdb
den Speicher für den alten Thread
nicht freigibt. Sie können dieses Problem vermeiden, indem Sie
mysqld
mit -O thread_cache_size=
'maximale_verbindungen +1'
starten. In den meisten
Fällen hilft bereits schon die Benutzung von -O
thread_cache_size=5'
recht viel!
Wenn Sie einen Coredump unter Linux erhalten wollen, wenn
mysqld
mit einem SIGSEGV-Signal stirbt,
können Sie mysqld
mit der
--core-file
-Option starten. Diese Core-Datei
kann benutzt werden, um eine Zurückverfolgung (Backtrace) zu
machen, die Ihnen helfen kann herauszufinden, warum
mysqld
starb:
shell> gdb mysqld core
gdb> backtrace full
gdb> exit
See Abschnitt A.4.1, „Was zu tun ist, wenn MySQL andauernd abstürzt“.
Wenn Sie gdb 4.17.x oder höher unter Linux benutzen, sollten
Sie eine .gdb
-Datei mit folgenden
Informationen in Ihrem aktuellen Verzeichnis installieren:
set print sevenbit off handle SIGUSR1 nostop noprint handle SIGUSR2 nostop noprint handle SIGWAITING nostop noprint handle SIGLWP nostop noprint handle SIGPIPE nostop handle SIGALRM nostop handle SIGHUP nostop handle SIGTERM nostop noprint
Wenn Sie Probleme haben, den Thread mit gdb zu debuggen, sollten Sie gdb 5.x herunter laden und diesen statt dessen benutzen. Die neue gdb-Version hat eine stark verbesserte Thread-Handhabung!
Hier ist ein Beispiel, wie man mysqld debuggt:
shell> gdb /usr/local/libexec/mysqld
gdb> run
...
backtrace full # Tun Sie das, wenn mysqld abstürzt
Schließen Sie die obige Ausgabe in eine Mail ein, die mit
mysqlbug
erzeugt wurde und schicken Sie sie
an mysql@lists.mysql.com
.
Wenn mysqld
hängen bleibt, können Sie
versuchen, einige Systemwerkzeuge wie strace
oder /usr/proc/bin/pstack
zu benutzen, um
herauszufinden, was mysqld
zum Hängen
brachte.
strace /tmp/log libexec/mysqld
Wenn Sie die Perl-DBI
-Schnittstelle benutzen,
können Sie Debug-Informationen anschalten, indem Sie die
trace
-Methode benutzen oder die
DBI_TRACE
-Umgebungsvariable setzen. See
Abschnitt 9.2.2, „Die DBI
-Schnittstelle“.
Auf manchen Betriebssystemen enthält die Fehler-Log-Datei einen
Stack-Trace, wenn mysqld
unerwartet stirbt.
Diese können Sie benutzen, um herauszufinden, wo (und
vielleicht warum) mysqld
starb. See
Abschnitt 5.9.1, „Die Fehler-Log-Datei“. Um einen Stack-Trace zu erhalten,
sollten Sie mysqld
NICHT mit der
-fomit-frame-pointer
-Option für gcc
kompilieren. See Abschnitt D.1.1, „MySQL zum Debuggen kompilieren“.
Wenn die Fehlerdatei etwas wie folgendes enthält:
mysqld got signal 11; The manual section 'debugging a MySQL server' tells you how to use a stack trace and/or the core file to produce a readable backtrace that may help in finding out why mysqld died Attemping backtrace. You can use the following information to find out where mysqld died. Wenn you see no messages after this, something went terribly wrong stack range sanity check, ok, backtrace follows 0x40077552 0x81281a0 0x8128f47 0x8127be0 0x8127995 0x8104947 0x80ff28f 0x810131b 0x80ee4bc 0x80c3c91 0x80c6b43 0x80c1fd9 0x80c1686
Können Sie herausfinden, wo mysqld
starb,
indem Sie folgendes tun:
Kopieren Sie die obigen Zahlen in eine Datei, zum Beispiel
mysqld.stack
.
Machen Sie eine symbolische Datei für den
mysqld
-Server:
nm -n libexec/mysqld > /tmp/mysqld.sym
Beachten Sie, dass viele MySQL-Binärdistributionen die
obige Datei namens mysqld.sym.gz
enthalten. In diesem Fall müssen Sie sie wie folgt
entpacken:
gunzip < bin/mysqld.sym.gz > /tmp/mysqld.sym
Führen Sie resolve_stack_dump -s /tmp/mysqld.sym
-n mysqld.stack
aus.
Das gibt aus, wo mysqld
starb. Wenn Ihnen
das nicht hilft, herauszufinden, warum
mysqld
starb, sollten Sie einen
Bug-Bericht machen und die Ausgabe des obigen Befehls in
diesen Bericht einschließen.
Beachten Sie aber, dass es uns in den meisten Fällen nicht
weiterhilft, nur einen Stack-Trace zu haben, um die Ursache
des Problems herauszufinden. Um den Bug feststellen oder
einen Workaround zur Verfügung stellen zu können, müssen
wir in den meisten Fällen die Anfrage kennen, die
mysqld
tötete, und am besten einen
Testfall, so dass wir das Problem wiederholen können! See
Abschnitt 2.6.2.3, „Wie man Bugs oder Probleme berichtet“.
Beachten Sie, dass Sie vor dem Start von
mysqld
mit --log
alle Ihre
Tabellen mit myisamchk
prüfen sollten. See
Kapitel 5, MySQL-Datenbankadministration.
Wenn mysqld
stirbt oder hängenbleibt,
sollten Sie ihn mit --log
starten. Wenn
mysqld
wieder stirbt, können Sie das Ende
der Log-Datei nach der Anfrage durchsuchen, die
mysqld
tötete.
Wenn Sie --log
ohne einen Dateinamen verwenden,
wird das Log im Datenbank-Verzeichnis als 'hostname'.log
gespeichert. In den meisten Fällen ist es die letzte Anfrage in
der Log-Datei, die mysqld
tötete, aber das
sollten Sie falls möglich sicherstellen, indem Sie
mysqld
neu starten und dieselbe Anfrage mit
dem mysql
-Kommandozeilenwerkzeug wiederholen.
Wenn das funktioniert, sollten Sie ebenfalls alle komplizierten
Anfragen testen, die nicht beendet wurden.
Sie können auch den Befehl EXPLAIN
auf alle
SELECT
-Statements ausprobieren, die lange
Zeit benötigen, um sicherzustellen, dass
mysqld
Indexe korrekt benutzt. See
Abschnitt 6.2.1, „EXPLAIN
-Syntax (Informationen über ein SELECT
erhalten)“.
Sie finden Anfragen, die zur Ausführung lange Zeit benötigen,
indem Sie mysqld
mit
--log-slow-queries
starten. See
Abschnitt 5.9.5, „Die Anfragen-Log-Datei für langsame Anfragen“.
Wenn Sie den Text mysqld restarted
in der
Fehler-Log-Datei-Datei (normalerweise namens
hostname.err
) finden, haben Sie
wahrscheinlich eine Anfrage gefunden, die
mysqld
zum Absturz brachte. Wenn das
passiert, sollten Sie alle Ihre Tabellen mit
myisamchk
prüfen (see
Kapitel 5, MySQL-Datenbankadministration) und die
Anfragen in den MySQL-Log-Dateien untersuchen, um
herauszufinden, ob eine nicht funktioniert. Wenn Sie eine solche
Anfrage finden, versuchen Sie zunächst, auf die neueste
MySQL-Version zu aktualisieren. Wenn das nicht hilft und Sie
nichts im mysql
-Mailarchiv finden können,
sollten Sie den Bug an <mysql@lists.mysql.com>
berichten. Links zu Mailarchiven finden Sie online auf der
MySQL-Dokumentationsseite.
Wenn Sie mysqld
mit
--with-myisam-recover
gestartet haben, prüft
MySQL automatisch MyISAM
-Tabellen und
versucht sie zu reparieren, wenn sie als 'nicht korrekt
geschlossen' oder 'beschädigt' gekennzeichnet sind. Wenn das
passiert, schreibt MySQL einen Eintrag in die
hostname.err
-Datei 'Warning:
Checking table ...'
, der von Warning:
Repairing table
gefolgt wird, wenn die Tabelle
repariert werden muss. Wenn Sie viele solcher Fehler erhalten,
ohne dass mysqld
direkt davor unerwartet
gestorben ist, stimmt etwas nicht und muss weiter untersucht
werden. See Abschnitt 5.1.1, „mysqld-Kommandozeilenoptionen“.
Natürlich ist es kein gutes Zeichen, wenn
mysqld
unerwartet stirbt, doch in diesem Fall
sollte man nicht die Checking
table...
-Meldungen untersuchen, sondern statt dessen
versuchen herauszufinden, warum mysqld
starb.
Wenn Sie beschädigte Tabellen erhalten oder wenn
mysqld
immer nach irgend einem
Aktualisierungsbefehl fehlschlägt, können Sie mit folgendem
überprüfen, ob der Bug reproduzierbar ist:
Fahren Sie den MySQL-Daemon herunter (mit
mysqladmin shutdown
).
Machen Sie eine Datensicherung der Tabellen (um dem sehr unwahrscheinlichen Fall vorzubeugen, dass die Reparatur etwas Schlechtes macht).
Prüfen Sie alle Tabellen mit myisamchk -s
Datenbank/*.MYI
. Reparieren Sie jegliche
beschädigten Tabellen mit myisamchk -r
datenbank/tabelle.MYI
.
Machen Sie eine Datensicherung der Tabellen.
Entfernen (oder verschieben) Sie jegliche alten Log-Dateien aus dem MySQL-Daten-Verzeichnis, wenn Sie mehr Platz brauchen.
Starten Sie mysqld
mit
--log-binary
. See
Abschnitt 5.9.4, „Die binäre Update-Log-Datei“. Wenn Sie eine Anfrage finden
wollen, die mysqld
zum Absturz brachte,
sollten Sie --log --log-binary
benutzen.
Wenn Sie eine beschädigte Tabelle erhalten, halten Sie
mysqld
an.
Stellen Sie die Datensicherung wieder her.
Starten Sie den mysqld
-Server neu,
ohne
--log-binary
.
Führen Sie die Befehle mit mysqlbinlog
update-log-file | mysql
erneut aus. Die
Update-Log-Datei wird im MySQL-Datenbank-Verzeichnis unter
dem Namen hostname-bin.#
gespeichert.
Wenn die Tabellen wieder beschädigt werden oder Sie
mysqld
wieder dazu bringen können zu
sterben, haben Sie einen reproduzierbaren Bug gefunden, der
sich leicht beheben lassen sollte! Schicken Sie die Tabellen
und die Binär-Log-Datei an
ftp://support.mysql.com/pub/mysql/secret
und schicken Sie eine E-Mail an
<bugs@lists.mysql.com>
oder (wenn Sie ein
Support-Kunde sind) an <Support@mysql.com>
, und
das MySQL-Team wird den Bug so schnell wie möglich beheben.
Sie können auch das Skript mysql_find_rows
benutzen, um einfach einige der Aktualisierungs-Statements
auszuführen, wenn Sie das Problem eingrenzen wollen.
Um einen MySQL-Client mit dem integrierten Debug-Paket debuggen zu
können, sollten Sie MySQL mit --with-debug
oder
--with-debug=full
kompilieren. See
Abschnitt 3.3.3, „Typische configure
-Optionen“.
Bevor Sie einen Client laufen lassen, sollten Sie die
MYSQL_DEBUG
-Umgebungsvariable setzen:
shell>MYSQL_DEBUG=d:t:O,/tmp/client.trace
shell>export MYSQL_DEBUG
Das bringt Clients dazu, eine Trace-Datei in
/tmp/client.trace
zu erzeugen.
Wenn Sie Probleme mit Ihrem eigenen Client-Code haben, sollten Sie
versuchen, sich mit dem Server zu verbinden und Ihre Anfragen mit
einem Client laufen zu lassen, der bekanntermaßen funktioniert.
Lassen Sie dabei mysql
im Debug-Modus laufen
(unter der Annahme, dass Sie MySQL mit angeschaltetem Debuggen
kompiliert haben):
shell> mysql --debug=d:t:O,/tmp/client.trace
Das stellt nützliche Informationen für den Fall bereit, dass Sie einen Bug-Bericht schicken. See Abschnitt 2.6.2.3, „Wie man Bugs oder Probleme berichtet“.
Wenn Ihr Client bei irgend einem 'zulässigen' Sperr-Code
abstürzt, sollten Sie sicherstellen, dass Ihre
mysql.h
-Include-Datei mit Ihrer
MySQL-Bibliotheksdatei zusammenpasst. Es ist ein häufiger Fehler,
eine alte mysql.h
-Datei aus einer alten
MySQL-Installation mit einer neuen MySQL-Bibliothek zu benutzen.
Der MySQL-Server und die meisten MySQL-Clients werden mit dem DBUG-Paket kompiliert, das ursprünglich von Fred Fish stammt. Wenn man MySQL zum Debuggen kompiliert hat, ermöglicht es dieses Paket, eine Trace-Datei davon zu erhalten, was das Programm debuggt. See Abschnitt D.1.2, „Trace-Dateien erzeugen“.
Man benutzt das Debug-Paket durch Aufruf des Programms mit der
--debug="..."
- oder der
-#...
-Option.
Die meisten MySQL-Programme haben eine vorgabemäßige
Debug-Zeichenkette, die benutzt wird, wenn Sie keine Option für
--debug
angeben. Die vorgabemäßige Trace-Datei
ist üblicherweise /tmp/programm_name.trace
unter Unix und \programm_name.trace
unter
Windows.
Die Debug-Steuerungs-Zeichenkette ist eine Folge durch Doppelpunkte getrennter Felder, wie folgt:
<feld_1>:<feld_2>:...:<feld_N>
Jedes Feld besteht aus einem zwingend erforderlichen Flag-Zeichen, gefolgt durch ein optionales Komma (",") und eine durch Kommas getrennte Auflistung von Modifikatoren:
flag[,modifikator,modifikator,...,modifikator]
Aktuell werden folgende Flag-Zeichen erkannt:
d | Ausgabe von DBUG_<N>-Makros des aktuellen Status ermöglichen. Gegebenenfalls gefolgt von einer Auflistung von Schlüsselwörtern, die Ausgaben nur für die DBUG-Makros mit diesem Schlüsselwort auswählt. Eine leere Auflistung von Schlüsselwörtern bedeutet Ausgabe für alle Makros. |
D | Nach jeder Debugger-Ausgabezeile verzögern. Das Argument ist die Anzahl
von Zehntelsekunden der Verzögerung, abhängig von den
Fähigkeiten der Maschine. -#D,20
bedeutet als eine Verzögerung von 2 Sekunden. |
f | Debuggen und / oder Tracen und Profilen auf die in der Auflistung genannten Funktionen beschränken. Beachten Sie, dass eine leere Liste alle Funktionen abschaltet. Die entsprechenden "d"- oder "t"-Flags müssen immer noch angegeben werden; dieser Flag beschränkt nur ihre Aktionen, wenn Sie angeschaltet sind. |
F | Den Quell-Dateinamen für jede Zeile der Debug- oder Trace-Ausgabe festlegen. |
i | Den Prozess mit der PID- oder Thread-Kennung für jede Ziele der Debug- oder Trace-Ausgabe festlegen. |
g | Profiling anschalten. Es wird eine Datei namens 'dbugmon.out' erzeugt, die Informationen enthält, die benutzt werden können, um das Programm zu profilen. Wir gegebenenfalls von einer Auflistung von Schlüsselwörter gefolgt, die Profiling nur für die Funktionen in dieser Liste auswählen. Eine leere Liste bedeutet, dass alle Funktionen in Betracht gezogen werden. |
L | Die Quell-Datei-Zeilennummer für jede Zeile der Debug- oder Trace-Ausgabe festlegen. |
n | Die aktuelle Funktionsverschachtelungstiefe für jede Zeile der Debug- oder Trace-Ausgabe ausgeben. |
N | Jede Zeile der dbug-Ausgabe nummerieren. |
o | Die Debugger-Ausgabe in die angegebene Datei umlenken. Die vorgabemäßige Ausgabe ist stderr. |
O | Wie O , aber die Datei wird nach jedem Schreiben auf
die Platte zurückgeschrieben (flush). Wenn nötig, wird
die Datei geschlossen und wieder geöffnet. |
p | Debugger-Aktionen auf die angegebenen Prozesse beschränken. Ein Prozess muss mit dem DBUG_PROCESS-Makro gekennzeichnet sein und mit einer der Aktionen in der Liste übereinstimmen, damit Debugger-Aktionen durchgeführt werden. |
P | Den aktuellen Prozessnamen für jede Zeile der Debug- oder Trace-Ausgabe ausgeben. |
r | Wenn ein neuer Zustand gepusht wird, nicht die Funktionsverschachtelungsebene des alten Zustands übernehmen (erben). Nützlich, wenn die Ausgabe am linken Rand anfangen soll. |
S | Funktion _sanity(_datei_,_zeile_) bei jeder debuggten Funktion ausführen, bis _sanity() etwas anderes als 0 zurückgibt. (Wird meist zusammen mit safemalloc benutzt, um Speicherlecks zu finden.) |
t | Trace-Zeile für Funktionsaufrufen / Funktionsende anschalten. Wird gegebenenfalls gefolgt von einer Liste (die nur einen Modifikator enthält), in der numerisch eine maximale Trace-Ebene angegeben wird, nach der keine Ausgaben mehr erfolgen, weder für Debuggen noch für das Tracen von Makros. Die Vorgabe ist eine Kompilierzeit-Option. |
Einige Beispiele von Debug-Steuerungs-Zeichenketten, die auf einer Shell-Kommandozeile erscheinen können (das "-#" wird typischerweise benutzt, um eine Steuerungs-Zeichenkette für ein Applikationsprogramm einzuführen):
-#d:t -#d:f,main,subr1:F:L:t,20 -#d,input,output,files:n -#d:t:i:O,\\mysqld.trace
In MySQL werden gebräuchlicherweise (mit der
d
-Option) folgende Tags ausgegeben:
enter
, exit
,
error
, warning
,
info
und loop
.
Momentan unterstützt MySQL Tabellensperren nur für
ISAM
- / MyISAM
- und
HEAP
-Tabellen und Sperren auf Seitenebene nur
für BDB
-Tabellen. See
Abschnitt 6.3.1, „Wie MySQL Tabellen sperrt“. Bei
MyISAM
-Tabellen können Sie
INSERT
und SELECT
ohne
Sperren frei vermischen. (Versionierung
).
Ab Version 3.23.33 können Sie die Tabellensperr-Konkurrenz auf
Ihrem System durch Prüfen der
Table_locks_waited
- und
Table_locks_immediate
-Umgebungsvariablen
analysieren.
Einige Datenbankbenutzer behaupten, dass MySQL keine große Anzahl gleichzeitiger Benutzer unterstützen kann, weil es kein Sperren auf Zeilenebene hat. Das mag bei einigen speziellen Applikationen zutreffen, aber nicht allgemein. Wie immer hängt das völlig davon ab, was Ihre Applikation macht, und davon, wie das Zugriffs-/Aktualisierungs-Muster der Daten aussieht.
Vorteile für Zeilensperren:
Weniger Sperrkonflikte beim Zugriff auf unterschiedliche Zeilen in vielen Threads.
Weniger Änderungen bei Rollbacks.
Macht es möglich, eine einzelne Zeile lange zu sperren.
Nachteile:
Benötigt mehr Speicher als Sperren auf Seiten- oder Tabellenebene.
Ist langsamer als Sperren auf Seiten- oder Tabellenebene, wenn es einen großen Teil der Tabelle betrifft, weil man viel mehr Sperren durchführen muss.
Ist definitiv viel schlechter als andere Sperren, wenn Sie oft
GROUP BY
auf einen großen Teil der Daten
ausführen oder wenn man die gesamte Tabelle oft scannen muss.
Bei Sperren auf höherer Ebene kann man einfacher Sperren unterschiedlichen Typs unterstützen, um die Applikation zu optimieren, weil der Sperr-Overhead sich weniger als bei Sperren auf Zeilenebene bemerkbar macht.
Tabellensperren sind Seiten- oder Zeilensperren in folgenden Fällen überlegen:
Wenn man meist liest.
Wenn Lese- und Aktualisierungsoperationen auf strengen Schlüsseln erfolgen. Das ist dann der Fall, wenn man eine Zeile aktualisiert oder löscht, die mit einem Schlüssel-Lesen geholt werden kann:
UPDATE tabelle SET spalte=wert WHERE eindeutige_schluessel_nummer DELETE FROM tabelle WHERE eindeutiger_schluessel=#
SELECT
in Kombination mit
INSERT
(und sehr wenigen
UPDATE
's und DELETE
's).
Viele Scans / GROUP BY
auf die gesamte
Tabelle ohne irgend welche Schreibvorgänge.
Andere Optionen als Sperren auf Zeilen- / Seiten-Ebene:
Versionierung (wie die, die wir bei MySQL für gleichzeitige Einfügevorgänge nutzen), bei der man gleichzeitig einen Schreibvorgang haben kann, während viele Lesevorgänge stattfinden. Das heißt, dass die Datenbank / Tabelle verschiedene Sichten der Daten unterstützt, abhängig davon, wann man anfing, darauf zuzugreifen. Andere Namen hierfür sind Zeitreisen, Kopieren beim Schreiben (Copy on Write) oder Kopieren bei Bedarf (Copy on Demand).
Kopieren bei Bedarf ist in vielen Fällen viel besser als Sperren auf Seiten- oder Zeilenebene. Im schlimmsten Fall wird jedoch viel mehr Speicher verbraucht als bei der Benutzung normaler Sperren.
Anstelle von Zeilen-Sperren kann man Sperren auf Applikationsebene benutzen (wie get_lock/release_lock in MySQL). Das funktioniert natürlich nur bei 'wohl erzogenen' Applikationen.
In vielen Fällen kann man auf fortgeschrittene Art raten, welcher Sperrtyp der beste für die Applikation ist, aber allgemein ist es sehr schwer zu sagen, dass ein bestimmter Sperrtyp besser ist als ein anderer. Alles hängt von der Applikation ab, und verschiedene Teile der Applikation können nach unterschiedlichen Sperrtypen verlangen.
Hier sind einige Tipps zu Sperren in MySQL:
Bei Web-Applikation führen die meisten Applikationen viele SELECTs aus, sehr wenige DELETEs, UPDATEs hauptsächlich auf Schlüssel und INSERTs in einigen bestimmten Tabellen. Die grundlegende Einrichtung von MySQL ist hierfür BESTENS optimiert.
Gleichzeitige Benutzer sind kein Problem, solange man UPDATEs und SELECTs nicht vermischt, die beide gleichzeitig viele Zeilen in derselben Tabelle untersuchen müssen.
Wenn man INSERTs und DELETEs auf dieselbe Tabelle mischt, kann
INSERT DELAYED
eine große Hilfe sein.
Man kann auch LOCK TABLES
benutzen, um Dinge zu
beschleunigen (viele UPDATEs innerhalb einer einzelnen Sperre sind
viel schneller als UPDATEs ohne Sperren). Daten in
unterschiedliche Tabellen aufteilen hilft hierbei auch.
Wenn Sie Geschwindigkeitsprobleme mit den Tabellensperren in MySQL
bekommen, können Sie diese eventuell dadurch lösen, dass Sie
Ihre Tabellen in BDB
-Tabellen umwandeln. See
Abschnitt 8.6, „BDB- oder Berkeley_db-Tabellen“.
Der Optimierungsabschnitt dieses Handbuchs behandelt viele verschiedene Aspekte dessen, wie man seine Applikationen optimieren kann. See Abschnitt 6.2.11, „Weitere Optimierungstipps“.
Ich habe versucht, die RTS-Thread-Pakete bei MySQL zu benutzen, bin aber über folgende Probleme gestolpert:
Sie benutzen die alte Version vieler POSIX-Aufrufe und es ist sehr mühsam, Wrapper für alle Funktionen zu schreiben. Ich neige dazu zu denken, dass es leichter ist, die Thread-Bibliotheken auf die neueste POSIX-Spezifikation zu ändern.
Einige Wrapper sind bereits geschrieben. Siehe
mysys/my_pThread.c
wegen weiterer
Informationen.
Zumindest folgendes sollte geändert werden:
pthread_get_specific
sollte ein Argument
benutzen. sigwait
sollte zwei Argumente
entgegennehmen. Viele Funktionen (zumindest
pthread_cond_wait
und
pthread_cond_timedwait
) sollten bei einem
Fehler den Fehler-Code zurückgeben. Momentan geben sie -1 zurück
und setzen errno
.
Ein weiteres Problem ist, dass Threads auf Benutzerebene das
ALRM
-Signal benutzen und dass dieses viele
Funktionen abbricht (read
,
write
, open
, ...). MySQL
sollte versuchen, nach der Unterbrechung all dieser Funktionen
weiterzumachen, aber das ist nicht einfach zu verifizieren.
Das größte ungelöste Problem ist folgendes:
Um Alarme auf Thread-Ebene zu erhalten, änderte ich
mysys/thr_alarm.c
in der Art, dass es
zwischen Alarmen wartet, mit
pthread_cond_timedwait()
, aber das bricht mit
Fehler EINTR
ab. Ich versuchte, die
Thread-Bibliothek zu debuggen, um den Grund herauszufinden, konnte
aber keine einfache Lösung finden.
Wenn jemand MySQL mit RTS-Thread ausprobieren möchte, schlage ich folgendes vor:
Funktionen, die MySQL benutzt, von der Thread-Bibliothek zu POSIX ändern. Das sollte nicht lange dauern.
Alle Bibliotheken mit -DHAVE_rts_thread
kompilieren.
thr_alarm
kompilieren.
Wenn es kleine Unterschiede in der Implementation gibt,
können diese behoben werden, indem man
my_pThread.h
und
my_pThread.c
ändert.
thr_alarm
laufen lassen. Wenn es ohne
irgend welche ``warning''-, ``error''- oder
``aborted''-Meldungen läuft, sind Sie auf dem richtigen Weg.
Hier ist ein erfolgreiches Laufenlassen unter Solaris:
Main Thread: 1 Thread 0 (5) started Thread: 5 Waiting process_alarm Thread 1 (6) started Thread: 6 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 1 (1) sec Thread: 6 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 2 (2) sec Thread: 6 Simulation of no alarm needed Thread: 6 Slept for 0 (3) sec Thread: 6 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 4 (4) sec Thread: 6 Waiting process_alarm thread_alarm Thread: 5 Slept for 10 (10) sec Thread: 5 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 5 (5) sec Thread: 6 Waiting process_alarm process_alarm ... thread_alarm Thread: 5 Slept for 0 (1) sec end
MySQL ist sehr abhängig vom verwendeten Thread-Paket. Wenn Sie daher eine gute Plattform für MySQL auswählen, ist das Thread-Paket sehr wichtig.
Es gibt mindestens drei Typen von Thread-Paketen:
Benutzer-Thread in einem einzelnen Prozess. Das Thread-Umschalten wird mit Alarmen gemacht und die Thread-Bibliothek verwaltet alle nicht Thread-sicheren Funktionen mit Sperren. Lese-, Schreib- und Auswahl-Operationen werden üblicherweise mit einer Thread-spezifischen Auswahl verwaltet, die auf einen anderen Thread umschaltet, wenn der laufende Thread auf Daten warten muss. Wenn die Benutzer-Thread-Pakete in die Standard-Bibliotheken integriert sind (FreeBSD- und BSDI-Thread), erfordert das Thread-Paket weniger Overhead als Thread-Pakete, die alle unsicheren Aufrufen mappen müssen (MIT-pThread, FSU-PThread und RTS-Thread). In einigen Umgebungen (beispielsweise SCO) sind alle Systemaufrufe Thread-sicher, weshalb das Mapping sehr leicht durchgeführt werden kann (FSU-PThread unter SCO). Nachteil: Alle gemappten Aufrufe benötigen etwas Zeit und es ist sehr verzwickt, alle Situationen handhaben zu können. Üblicherweise gibt es auch einige Systemaufrufe, die vom Thread-Paket nicht gehandhabt werden (wie MIT-pThread und Sockets). Thread-Scheduling ist nicht immer optimal.
Benutzer-Thread in separaten Prozessen. Das Thread-Umschalten wird vom Kernel durchgeführt und alle Daten werden zwischen den Threads geteilt. Das Thread-Paket verwaltet die Standard-Thread-Aufrufe, so dass diese Daten zwischen Threads teilen können. LinuxThread benutzt diese Methode. Nachteil: viele Prozesse. Die Erzeugung von Threads ist langsam. Wenn ein Thread stirbt, bleiben die übrigen üblicherweise hängen, und Sie müssen alle töten, bevor Sie neu starten können. Man kann sagen, dass die Thread-Umschaltung ziemlich viel kostet.
Kernel-Thread. Das Thread-Umschalten wird von der
Thread-Bibliothek oder dem Kernel durchgeführt und ist sehr
schnell. Alles wird in einem Prozess gemacht, aber auch
manchen Systemen zeigt ps
die verschiedenen
Threads. Wenn ein Thread abbricht, bricht der gesamte Prozess
ab. Die meisten Systemaufrufe sind Thread-sicher und sollten
sehr wenig Overhead beanspruchen. Solaris, HP-UX, AIX und OSF1
haben Kernel-Thread.
Auf manchen Systemen wird Kernel-Thread gehandhabt, indem Benutzerebenen-Thread in die Systembibliotheken integriert wird. In solchen Fällen kann das Umschalten nur von der Thread-Bibliothek durchgeführt werden und der Kernel ist sich nicht wirklich ``der Threads bewusst''.
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.