manual.de_Porting.html
MySQL-Referenzhandbuch für Version 4.1.1-alpha - E Anmerkungen zur Portierung auf andere Systeme
Go to the first, previous, next, last section, table of contents.
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 section E.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 section 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 section 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 section 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 section E.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 section 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 section 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 section 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 section E.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 section 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 section 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 section 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 section 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 section 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 section 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 section 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 section 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 section 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 section E.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 section 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 section 8.6 BDB- oder Berkeley_db-Tabellen.
Der Optimierungsabschnitt dieses Handbuchs behandelt viele verschiedene
Aspekte dessen, wie man seine Applikationen optimieren kann. See section 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''.
Go to the first, previous, next, last section, table of contents.
|