Kapitel 5. Datenbankverwaltung
Zurück |  | Weiter

## Kapitel 5. Datenbankverwaltung

Dieses Kapitel behandelt Themen im Zusammenhang mit der Administration einer MySQL-Installation:

- Server konfigurieren

- Benutzerkonten verwalten

- Sicherungen durchführen

- Serverlogdateien

- Abfrage-Cache

## 5.1. Überblick über serverseitige Programme und Dienstprogramme

Der MySQL-Server mysqld ist das Hauptprogramm, welches in einer MySQL-Installation die meiste Arbeit leistet. Der Server wird von mehreren zugehörigen Skripten begleitet, die bei der Einrichtung von MySQL Konfigurationsarbeiten durchführen oder Ihnen beim Starten und Beenden des Servers behilflich sind. Dieser Abschnitt vermittelt einen Überblick über den Server und zugehörige Programme. Die nachfolgenden Abschnitte beschreiben dann alle diese Programme im Detail.

Jedes MySQL-Programm akzeptiert viele verschiedene Optionen. Die meisten Programme enthalten eine Option `--help`, über die Sie eine Beschreibung der verschiedenen Programmoptionen erhalten können. Probieren Sie z. B. mysqld --help aus.

Sie können die Standardoptionswerte bei MySQL-Programmen außer Kraft setzen, indem Sie Optionen auf der Befehlszeile oder in einer Optionsdatei angeben. Abschnitt 4.3, „Angabe von Programmoptionen“.

Die folgende Liste stellt eine kurze Beschreibung des MySQL-Servers und der serverbezogenen Programme dar:

- mysqld

  Dies ist der SQL-Daemon (d. h. der eigentliche MySQL-Server). Damit Sie Clientprogramme verwenden können, muss mysqld ausgeführt werden, denn die Clients greifen über eine Verbindung zum Server auf die Datenbanken zu. Siehe auch Abschnitt 5.2, „mysqld — Der MySQL-Server“.

- mysqld-max

  Dies ist eine Serverversion, die zusätzliche Funktionen enthält. Siehe auch Abschnitt 5.3, „mysqld-max, ein erweiterter mysqld-Server“.

- mysqld_safe

  Dies ist ein Serverstartskript. mysqld_safe versucht mysqld-max zu starten, sofern es vorhanden ist; andernfalls wird mysqld gestartet. Siehe auch Abschnitt 5.4.1, „mysqld_safe — Startskript für den MySQL-Server“.

- mysql.server

  Dies ist ein Serverstartskript. Es wird auf Systemen eingesetzt, die Ausführungsverzeichnisse im System V-Stil verwenden. Diese Verzeichnisse enthalten Skripten, die Systemstartdienste für bestimmte Ausführungsebenen enthalten. Das Skript ruft mysqld_safe auf, um den MySQL-Server zu starten. Siehe auch Abschnitt 5.4.2, „mysql.server — Startskript für den MySQL-Server“.

- mysqld_multi

  Ein Serverstartskript, welches mehrere auf dem System installierte Server starten oder beenden kann. Siehe auch Abschnitt 5.4.3, „mysqld_multi — Verwalten mehrerer MySQL-Server“. Eine Alternative zu mysqld_multi ist `mysqlmanager`, der MySQL Instance Manager. Siehe auch Abschnitt 5.5, „mysqlmanager — Der MySQL Instance Manager“.

- mysql_install_db

  Dieses Skript erstellt die MySQL-Datenbank und initialisiert die Grant-Tabellen mit Standardberechtigungen. Es wird normalerweise nur einmal ausgeführt, nämlich dann, wenn Sie MySQL zum ersten Mal auf einem System installieren. Siehe auch Abschnitt 2.9.2, „Schritte nach der Installation unter Unix“.

- mysql_fix_privilege_tables

  Dieses Skript wird nach Durchführung eines MySQL-Upgrades verwendet. Es aktualisiert die Grant-Tabellen mit allen Änderungen, die in der neueren MySQL-Version vorgenommen wurden. Siehe auch Abschnitt 5.6, „mysql_fix_privilege_tables — Upgrade von MySQL-Systemtabellen“.

- mysqlmanager

  Der MySQL Instance Manager, ein Programm zur Überwachung und Verwaltung von MySQL-Servern. Siehe auch Abschnitt 5.5, „mysqlmanager — Der MySQL Instance Manager“.

Es gibt noch einige andere Programme, die auf dem Serverhost ausgeführt werden.

- make_binary_distribution

  Dieses Programm erstellt einen Binär-Release aus einer kompilierten MySQL-Distribution. Dieses für andere MySQL-Benutzer praktische Format kann dann via FTP nach `/pub/mysql/upload/` auf `ftp.mysql.com` übertragen werden.

## 5.2. mysqld — Der MySQL-Server

mysqld ist der MySQL-Server. Nachfolgend werden wir folgende Themen in Zusammenhang mit der Konfiguration dieses MySQL-Servers behandeln:

- Startoptionen, die vom Server unterstützt werden

- Serversystemvariablen

- Serverstatusvariablen

- Einstellen des SQL-Modus des Servers

- Herunterfahren des Servers

### 5.2.1. Befehlsoptionen für mysqld

Wenn Sie den Server mysqld starten, können Sie Programmoptionen mithilfe aller in Abschnitt 4.3, „Angabe von Programmoptionen“, beschriebenen Methoden festlegen. Die meistverwendeten Methoden sind die Angabe von Optionen in einer Optionsdatei oder über die Befehlszeile. In den meisten Fällen ist es wünschenswert, dass der Server stets die gleichen Optionen verwendet. Dies lässt sich am einfachsten gewährleisten, indem man die Optionen in einer Optionsdatei auflistet. Siehe auch Abschnitt 4.3.2, „my.cnf-Optionsdateien“.

mysqld liest Optionen aus den Abschnitten `[mysqld]` und `[server]` aus. mysqld_safe liest Optionen aus den Abschnitten `[mysqld]`, `[server]`, `[mysqld_safe]` und `[safe_mysqld]` aus. mysql.server schließlich liest Optionen aus den Abschnitten `[mysqld]` und `[mysql.server]` aus.

Ein eingebetteter MySQL-Server entnimmt seine Optionen den Abschnitten `[server]`, `[embedded]` und `[`xxxxx`_SERVER]`, wobei `xxxxx` der Name der Anwendung ist, in die der Server eingebettet ist.

mysqld akzeptiert viele Befehlsoptionen. Eine kurze Liste erhalten Sie, wenn Sie mysqld --help ausführen. Die vollständige Liste rufen Sie über mysqld --verbose --help auf.

Die folgende Liste zeigt einige der häufigsten Serveroptionen (weitere Optionen sind an anderer Stelle beschrieben):

- Sicherheitsspezifische Optionen: Siehe auch Abschnitt 5.7.3, „Startoptionen für `mysqld` in Bezug auf Sicherheit“.

- SSL-spezifische Optionen: Siehe auch Abschnitt 5.9.7.5, „SSL-Befehlsoptionen“.

- Optionen zur Steuerung von Binärlogs: Siehe auch Abschnitt 5.12.3, „Die binäre Update-Logdatei“.

- Optionen zur Replikation: Siehe auch Abschnitt 6.9, „Replikationsoptionen in my.cnf“.

- Optionen für bestimmte Speicher-Engines: Siehe auch Abschnitt 14.1.1, „`MyISAM`-Startoptionen“, Abschnitt 14.5.3, „BDB-Startoptionen“, Abschnitt 14.2.4, „`InnoDB`: Startoptionen und Systemvariablen“, und Abschnitt 16.5.5.1, „MySQL Cluster-spezifische Befehlsoptionen für mysqld“.

Sie können die Werte der Serversystemvariablen auch mithilfe von Variablennamen als Optionen zuweisen. Dies wird im weiteren Verlauf dieses Abschnitts beschrieben.

- `--help`, `-?`

  Zeigt eine kurze Hilfemeldung an und wird dann beendet. Verwenden Sie die Optionen `--verbose` und `--help`, um die vollständige Meldung zu sehen.

- `--allow-suspicious-udfs`

  Diese Option bestimmt, ob UDFs (User-Defined Functions, benutzerdefinierte Funktionen), die nur ein `xxx`-Symbol für die Hauptfunktion aufweisen, geladen werden dürfen. Standardmäßig ist die Option deaktiviert, und es dürfen nur UDFs geladen werden, die mindestens ein Hilfssymbol aufweisen. Hierdurch soll das Laden von Funktionen aus solchen freigegebenen Objektdateien verhindert werden, die keine zulässigen UDFs enthalten. Siehe auch Abschnitt 26.3.4.6, „Vorsichtsmaßnahmen bei benutzerdefinierten Funktionen (UDF)“.

- `--ansi`

  Verwendet die ANSI-konforme SQL-Standardsyntax (statt der MySQL-Syntax). Für eine genauere Steuerung des SQL-Modus des Servers verwenden Sie stattdessen die Option `--sql-mode`. Siehe auch Abschnitt 1.9.3, „MySQL im ANSI-Modus laufen lassen“, und Abschnitt 5.2.5, „Der SQL-Modus des Servers“.

- `--basedir=`path`, -b `path``

  Der Pfad zum MySQL-Installationsverzeichnis. Normalerweise werden alle Pfad relativ zu diesem Verzeichnis aufgelöst.

- `--bind-address=`IP``

  Die IP-Adresse, zu der eine Bindung hergestellt wird.

- `--binlog-format={row|statement}`

  Gibt an, ob die datensatz- oder die anweisungsbasierte Replikation verwendet werden soll (die anweisungsbasierte Replikation ist die Vorgabe). Siehe auch Abschnitt 6.3, „Zeilenbasierte Replikation“. Diese Option wurde in MySQL 5.1.5 hinzugefügt.

- `--binlog-row-event-max-size=`N``

  Gibt die maximale Größe eines datensatzbasierten Binärlogereignisses in Byte an. Datensätze werden zu Ereignissen zusammengefasst, die – sofern möglich – kleiner sind als die hier angegebene Größe. Der Wert sollte ein Vielfaches von 256 sein, Standard ist 1.024. Siehe auch Abschnitt 6.3, „Zeilenbasierte Replikation“. Diese Option wurde in MySQL 5.1.5 hinzugefügt.

- `--both-log-formats`

  Aktiviert alte und neue Logformate (Logdateien und Logtabellen). Diese Option wurde in MySQL 5.1.6 hinzugefügt.

- `--bootstrap`

  Diese Option wird vom Skript mysql_install_db verwendet, um die MySQL-Berechtigungstabellen zu erstellen, ohne einen vollständigen MySQL-Server starten zu müssen.

- `--character-sets-dir=`path``

  Das Verzeichnis, in dem Zeichensätze installiert sind. Siehe auch Abschnitt 5.11.1, „Der für Daten und zum Sortieren benutzte Zeichensatz“.

- `--character-set-client-handshake`

  Zeichensatzinformationen, die vom Client übermittelt wurden, sollten nicht ignoriert werden. Um die Clientangaben zu ignorieren und den Standardzeichensatz des Servers zu benutzen, verwenden Sie `--skip-character-set-client-handshake`. In diesem Fall verhält sich MySQL wie MySQL 4.0.

- `--character-set-filesystem=`charset_name``

  Der Zeichensatz des Dateisystems. Diese Option wurde in MySQL 5.1.6 hinzugefügt.

- `--character-set-server=`charset_name``, `-C `charset_name``

  Verwendet `charset_name` als Standardzeichensatz am Server. Siehe auch Abschnitt 5.11.1, „Der für Daten und zum Sortieren benutzte Zeichensatz“.

- `--chroot=`path``

  Versetzt den Server mysqld während des Starts mithilfe des Systemaufrufs `chroot()` in eine geschlossene Umgebung. Dies ist eine empfohlene Sicherheitsmaßnahme. Beachten Sie, dass durch Verwendung dieser Option `LOAD DATA INFILE` und `SELECT ... INTO OUTFILE` in geringem Maße eingeschränkt werden.

- `--collation-server=`collation_name``

  Verwendet `collation_name` als Standardsortierung auf dem Server. Siehe auch Abschnitt 5.11.1, „Der für Daten und zum Sortieren benutzte Zeichensatz“.

- `--console`

  (Nur für Windows.) Schreibt Fehlerlogmeldungen auch dann in `stderr` und `stdout`, wenn `--log-error` angegeben ist. Wenn diese Option verwendet wird, schließt mysqld das Konsolenfenster nicht.

- `--core-file`

  Schreibt eine Speicherauszugsdatei, wenn mysqld sich aufhängt. Bei einigen Systemen müssen Sie zusätzlich die Option `--core-file-size` für mysqld_safe angeben. Siehe auch Abschnitt 5.4.1, „mysqld_safe — Startskript für den MySQL-Server“. Beachten Sie, dass auf manchen Systemen (z. B. Solaris) keine Speicherauszugsdateien geschrieben werden, wenn gleichzeitig die Option `--user` verwendet wird.

- `--datadir=`path`, -h `path``

  Der Pfad zum Datenverzeichnis.

- `--debug[=`debug_options`]`, `-# [`debug_options`]`

  Wird MySQL mit der Option `--with-debug` konfiguriert, dann können Sie mithilfe dieser Option eine Trace-Datei mit Angaben dazu erstellen, was mysqld tut. Der String `debug_options` heißt häufig `'d:t:o,`file_name`'`. Standardwert ist `'d:t:i:o,mysqld.trace'`. Siehe auch Abschnitt E.1.2, „Trace-Dateien erzeugen“.

- `--default-character-set=`charset_name`` (AUSLAUFEND)

  Verwendet `charset_name` als Standardzeichensatz. Diese Option läuft zugunsten von `--character-set-server` aus. Siehe auch Abschnitt 5.11.1, „Der für Daten und zum Sortieren benutzte Zeichensatz“.

- `--default-collation=`collation_name``

  Verwendet `collation_name` als Standardsortierung. Diese Option läuft zugunsten von `--collation-server` aus. Siehe auch Abschnitt 5.11.1, „Der für Daten und zum Sortieren benutzte Zeichensatz“.

- `--default-storage-engine=`type``

  Stellt die standardmäßige Speicher-Engine für Tabellen ein. Siehe auch Kapitel 14, Speicher-Engines und Tabellentypen.

- `--default-table-type=`type``

  Diese Option ist synonym zu `--default-storage-engine`.

- `--default-time-zone=`timezone``

  Stellt die Standardzeitzone des Servers ein. Diese Option stellt die globale Systemvariable `time_zone` ein. Wird die Option nicht angegeben, dann ist die Standardzeitzone mit der Systemzeitzone identisch (diese wird durch den Wert der Systemvariablen `system_time_zone` bestimmt).

- `--delay-key-write[= OFF | ON | ALL]`

  Legt fest, wie verzögerte Schlüsselschreiboperationen gehandhabt werden. Das verzögerte Schreiben von Schlüsseln sorgt dafür, dass Schlüsselpuffer zwischen einzelnen Schreibvorgängen für `MyISAM`-Tabellen neu geladen werden. `OFF` deaktiviert das verzögerte Schreiben von Schlüsseln, während `ON` es für jene Tabellen aktiviert, die mit der Option `DELAY_KEY_WRITE` erstellt worden sind. `ALL` schließlich verzögert das Schreiben der Schlüssel für alle `MyISAM`-Tabellen. Siehe auch Abschnitt 7.5.2, „Serverparameter feineinstellen“, und Abschnitt 14.1.1, „`MyISAM`-Startoptionen“.

  Hinweis: Wenn Sie diese Variable auf `ALL` setzen, sollten Sie `MyISAM`-Tabellen nicht aus einem anderen Programm (z. B. einem anderen MySQL-Server oder myisamchk) heraus verwenden, wenn diese Tabellen bereits in Benutzung sind. Andernfalls können Indizes beschädigt werden.

- `--des-key-file=`file_name``

  Liest den DES-Standardschlüssel aus der angegebenen Datei aus. Diese Schlüssel werden von den Funktionen `DES_ENCRYPT()` und `DES_DECRYPT()` verwendet.

- `--enable-named-pipe`

  Aktiviert die Unterstützung für Named Pipes. Diese Option betrifft nur Systeme unter Windows NT/2000/XP/2003 und kann nur für die Server mysqld-nt und mysqld-max-nt benutzt werden, die Named-Pipe-Verbindungen benutzen.

- `--event-scheduler`

  Aktiviert den Ereignisplaner. Diese Option wurde in MySQL 5.1.6 hinzugefügt.

- `--exit-info[=`flags`]`, `-T [`flags`]`

  Dies ist eine Bitmaske mit verschiedenen Flags, die Sie zum Debugging des Servers mysqld verwenden können. Verwenden Sie diese Option nur, wenn Sie genau wissen, was sie tut!

- `--external-locking`

  Aktiviert die externe Sperrung (Systemsperrung). Diese ist seit MySQL 4.0 standardmäßig deaktiviert. Beachten Sie, dass, wenn Sie diese Option auf einem System verwenden, auf dem `lockd` nicht vollständig funktioniert (z. B. unter Linux), mysqld vollständig gesperrt werden kann. Diese Option hieß früher `--enable-locking`.

  Hinweis: Wenn Sie diese Option verwenden, um das Aktualisieren von `MyISAM`-Tabellen durch mehrere MySQL-Prozesse zu ermöglichen, dann müssen Sie sicherstellen, dass die folgenden Bedingungen erfüllt sind:

  - Sie sollten den Abfrage-Cache nicht für Abfragen benutzen, die Tabellen verwenden, welche durch einen anderen Prozess aktualisiert werden.

  - Sie sollten `--delay-key-write=ALL` oder `DELAY_KEY_WRITE=1` nicht bei gemeinsam genutzten Tabellen einsetzen.

  Die einfachste Möglichkeit, dies zu gewährleisten, besteht darin, `--external-locking` immer zusammen mit `--delay-key-write=OFF` und `--query-cache-size=0` zu benutzen. (Dies wird standardmäßig nicht gemacht, weil es in vielen Konfigurationen nützlich ist, eine Mischung der vorangegangenen Optionen einzusetzen.)

- `--flush`

  Schreibt nach jeder SQL-Anweisung alle Änderungen neu auf die Festplatte (Synchronisierung). Normalerweise schreibt MySQL alle Änderungen erst nach der jeweiligen SQL-Anweisung auf die Festplatte und überlässt dem Betriebssystem die Festplattensynchronisierung. Siehe auch Abschnitt A.4.2, „Was zu tun ist, wenn MySQL andauernd abstürzt“.

- `--init-file=`file``

  Liest beim Start SQL-Anweisungen aus der angegebenen Datei aus. Jede Anweisung muss in einer eigenen Zeile stehen und darf keine Kommentare enthalten.

- `--innodb-`xxx``

  Die `InnoDB`-Optionen sind in Abschnitt 14.2.4, „`InnoDB`: Startoptionen und Systemvariablen“, beschrieben.

- `--language=`lang_name`, -L `lang_name``

  Gibt Clientfehlermeldungen in der angegebenen Sprache zurück. `lang_name` kann als Sprachname oder als vollständiger Pfadname zu dem Verzeichnis angegeben werden, in dem die Sprachdateien installiert sind. Siehe auch Abschnitt 5.11.2, „Nicht englische Fehlermeldungen“.

- `--large-pages`

  Einige Hardware- und Betriebssystemarchitekturen unterstützen Speicherseiten, die größer als der Standardwert (normalerweise 4 Kbyte) sind. Die eigentliche Implementierung dieser Unterstützung hängt von der zugrundeliegenden Hardware und dem Betriebssystem ab. Anwendungen, die häufig auf den Speicher zugreifen, können leistungsseitig von der Verwendung großer Seiten profitieren, da die Anzahl von TLB-Fehlschlägen (Translation Lookaside Buffer, Übersetzungspuffer) verringert wird.

  Zurzeit unterstützt MySQL nur die Linux-Implementierung der Unterstützung für große Seiten (diese heißt in Linux HugeTLB). Wir beabsichtigen, diese Unterstützung auf FreeBSD, Solaris und möglicherweise auch andere Plattformen auszudehnen.

  Bevor unter Linux große Seiten verwendet werden können, ist es notwendig, den HugeTLB-Speicherpool zu konfigurieren. Hinweise hierzu entnehmen Sie der Datei `hugetlbpage.txt` im Linux-Kernel-Quellcode.

  Die Option ist standardmäßig deaktiviert.

- `--log[=`file_name`]`, `-l [`file_name`]`

  Verbindungen und SQL-Anweisungen, die von Clients empfangen werden, werden in dieser Datei protokolliert. Siehe auch Abschnitt 5.12.2, „Die allgemeine Anfragen-Logdatei“. Wenn Sie den Dateinamen weglassen, verwendet MySQL ``host_name`.log` als Dateinamen.

- `--log-bin=[`base_name`]`

  Aktiviert das binäre Loggen. Der Server loggt alle datenändernden Anweisungen in das Binärlog, welches für Sicherungs- und Replikationszwecke verwendet wird. Siehe auch Abschnitt 5.12.3, „Die binäre Update-Logdatei“.

  Sofern angegeben, ist der Optionswert der Basisname der Logabfolge. Der Server erstellt Binärlogs in einer Abfolge und fügt dabei an den Basisnamen jeweils ein numerisches Suffix an. Die Angabe eines Basisnamens wird empfohlen (siehe Abschnitt A.8.1, „Offene Probleme in MySQL“ zu den Gründen). Andernfalls verwendet MySQL ``host_name`-bin` als Basisnamen.

- `--log-bin-index[=`file_name`]`

  Dies ist die Indexdatei für Dateinamen von Binärlogs. Siehe auch Abschnitt 5.12.3, „Die binäre Update-Logdatei“. Wenn Sie den Dateinamen weglassen und auch mit `--log-bin` keinen Namen festgelegt haben, verwendet MySQL ``host_name`-bin.index` als Dateinamen.

- `--log-bin-trust-function-creators[={0|1}]`

  Ohne Argument oder mit dem Argument 1 setzt diese Option die Systemvariable `log_bin_trust_function_creators` auf 1. Wird als Argument 0 übergeben, dann wird die Systemvariable auf 0 gesetzt. `log_bin_trust_function_creators` beeinflusst, wie MySQL Beschränkungen für die Erstellung gespeicherter Funktionen durchsetzt. Siehe auch Abschnitt 19.4, „Binärloggen gespeicherter Routinen und Trigger“.

- `--log-error[=`file_name`]`

  Fehler- und Startmeldungen werden in der genannten Datei protokolliert. Siehe auch Abschnitt 5.12.1, „Die Fehler-Logdatei“. Wenn Sie den Dateinamen weglassen, verwendet MySQL ``host_name`.err`. Hat der Dateiname keine Erweiterung, dann fügt der Server die Erweiterung `.err` hinzu.

- `--log-isam[=`file_name`]`

  Protokolliert alle `MyISAM`-Änderungen an dieser Datei (wird nur zum `MyISAM`-Debugging verwendet).

- `--log-long-format` (AUSLAUFEND)

  Schreibt Zusatzinformationen in das Update-Log, das Binärlog und das Log für langsame Abfragen, sofern diese aktiviert sind. So werden etwa der Benutzername und ein Zeitstempel für alle Abfragen protokolliert. Diese Option läuft aus, da sie mittlerweile das Standardverhalten beim Loggen darstellt. (Siehe Beschreibung zu `--log-short-format`.) Die Option `--log-queries-not-using-indexes` dient dem Loggen von Abfragen, die keine Indizes verwenden, in das Log für langsame Abfragen.

- `--log-queries-not-using-indexes`

  Wenn Sie diese Option in Verbindung mit `--log-slow-queries` verwenden, werden Abfragen, die keine Indizes verwenden, in das Log für langsame Abfragen geschrieben. Siehe auch Abschnitt 5.12.4, „Die Logdatei für langsame Anfragen“.

- `--log-short-format`

  Protokolliert weniger Informationen in das Update-Log, das Binärlog und das Log für langsame Abfragen, sofern diese aktiviert sind. So werden etwa weder Benutzername noch ein Zeitstempel für Abfragen protokolliert.

- `--log-slow-admin-statements`

  Protokolliert administrative Anweisungen wie `OPTIMIZE TABLE`, `ANALYZE TABLE` und `ALTER TABLE` in das Log für langsame Abfragen.

- `--log-slow-queries[=`file_name`]`

  Protokolliert alle Abfragen, deren Ausführung mehr als `long_query_time` Sekunden gedauert hat, in die angegebene Datei. Siehe auch Abschnitt 5.12.4, „Die Logdatei für langsame Anfragen“. Details finden Sie in den Beschreibungen zu den Optionen `--log-long-format` und `--log-short-format`.

- `--log-warnings`, `-W`

  Schreibt Warnungen wie `Aborted connection...` in das Fehlerlog. Die Aktivierung dieser Option wird beispielsweise empfohlen, wenn Sie die Replikation verwenden. (Sie erhalten dann mehr Informationen zu den ablaufenden Vorgängen, z. B. Netzwerkausfälle und Neuverbindungen.) Die Option ist standardmäßig aktiviert. Sie können sie mithilfe von `--skip-log-warnings` deaktivieren. Unterbrochene Verbindungen werden nicht in das Fehlerlog protokolliert, sofern der Wert größer als 1 ist. Siehe auch Abschnitt A.2.10, „Kommunikationsfehler/abgebrochene Verbindung“.

- `--low-priority-updates`

  Gibt tabellenändernden Operationen (`INSERT`, `REPLACE`, `DELETE`, `UPDATE`) eine niedrigere Priorität als Auswahloperationen. Dies kann auch via `{INSERT | REPLACE | DELETE | UPDATE} LOW_PRIORITY ...` erfolgen, um die Priorität nur einer Abfrage zu verringern. Die Priorität eines Threads können Sie mit `SET LOW_PRIORITY_UPDATES=1` verringern. Siehe auch Abschnitt 7.3.2, „Themen, die Tabellensperren betreffen“.

- `--memlock`

  Sperrt den mysqld-Prozess im Speicher. Dies funktioniert auf Systemen wie Solaris, die den Systemaufruf `mlockall()` unterstützen. Die Option kann hilfreich sein, wenn ein Problem auftritt, bei dem das Betriebssystem eine Auslagerung von mysqld auf die Festplatte verursacht. Beachten Sie, dass die Verwendung dieser Option eine Ausführung des Servers als `root` erfordert, wovon in der Regel aus Sicherheitsgründen abzuraten ist. Siehe auch Abschnitt 5.7.5, „Wie man MySQL als normaler Benutzer laufen läßt“.

- `--myisam-recover [=`option`[,`option`]...]]`

  Stellt den Wiederherstellungsmodus der `MyISAM`-Speicher-Engine ein. Der Optionswert ist eine beliebige Kombination der Werte `DEFAULT`, `BACKUP`, `FORCE` oder `QUICK`. Wenn Sie mehrere Werte angeben, trennen Sie sie durch Kommata. Sie können auch den Wert `""` angeben, um die Option zu deaktivieren. Wird die Option verwendet, dann prüft mysqld bei jedem Öffnen einer `MyISAM`-Tabelle, ob diese als abgestürzt gekennzeichnet ist oder beim letzten Mal nicht korrekt geschlossen wurde. (Die zweite Option funktioniert nur, wenn die Ausführung mit deaktivierter externer Sperrung erfolgt.) In diesem Fall führt mysqld eine Überprüfung der Tabelle durch. Ist die Tabelle tatsächlich beschädigt, dann versucht mysqld sie zu reparieren.

  Die folgenden Optionen beeinflussen die Ausführung der Reparatur:

  Option | Beschreibung
  `DEFAULT` | Ist identisch mit der Nichtangabe von Optionen für `--myisam-recover`.
  `BACKUP` | Speichert, wenn die Datendatei während der Wiederherstellung geändert wurde, eine Sicherungskopie der Datei ``tbl_name`.MYD` als ``tbl_name-datetime`.BAK`.
  `FORCE` | Führt die Wiederherstellung auch dann durch, wenn dadurch mehr als nur ein Datensatz in der `.MYD`-Datei verloren geht.
  `QUICK` | Überprüft die Datensätze in der Tabelle nicht, wenn keine Löschblöcke vorhanden sind.

  Bevor der Server eine Tabelle automatisch repariert, schreibt er einen Hinweis zur Reparatur in das Fehlerlog. Wollen Sie die meisten Probleme durch eine Wiederherstellung ohne Benutzereingriff beseitigen, dann sollten Sie die Optionen `BACKUP,FORCE` angeben. Hierdurch wird die Reparatur der Tabelle auch dann erzwungen, wenn mehrere Datensätze gelöscht würden; gleichzeitig wird aber die alte Datendatei als Sicherungskopie vorgehalten, sodass Sie später untersuchen können, was passiert ist.

  Siehe auch Abschnitt 14.1.1, „`MyISAM`-Startoptionen“.

- `--ndb-connectstring=`connect_string``

  Wenn Sie die `NDB`-Speicher-Engine verwenden, können Sie den Managementserver angeben, der die Clusterkonfiguration verteilt. Dies tun Sie durch Einstellung der Option `--ndb-connectstring`. Informationen zur Syntax finden Sie in Abschnitt 16.4.4.2, „MySQL Cluster: `connectstring`“.

- `--ndbcluster`

  Wenn die Binärdatei eine Unterstützung der `NDB Cluster`-Speicher-Engine enthält, aktiviert diese Option die Engine (diese ist standardmäßig deaktiviert). Siehe auch Kapitel 16, MySQL Cluster.

- `--old-log-format`

  Aktiviert nur das alte Logformat. Hierdurch werden Logtabellen und die `SELECT`-Funktionalität für Loginhalte deaktiviert. Diese Option wurde in MySQL 5.1.6 hinzugefügt.

- `--old-passwords`

  Erzwingt die Erzeugung kurzer Passwort-Hashes (wie vor Version 4.1) auch für neue Passwörter. Dies kann zu Kompatibilitätszwecken erforderlich sein, wenn der Server ältere Clientprogramme unterstützen muss. Siehe auch Abschnitt 5.8.9, „Kennwort-Hashing ab MySQL 4.1“.

- `--one-thread`

  Verwendet nur einen Thread (zum Debuggen unter Linux). Diese Option ist nur verfügbar, wenn der Server mit aktiviertem Debugging erstellt wurde. Siehe auch Abschnitt E.1, „Einen MySQL-Server debuggen“.

- `--open-files-limit=`count``

  Ändert die Anzahl der für mysqld verfügbaren Dateideskriptoren. Wenn diese Option nicht oder auf 0 gesetzt ist, verwendet mysqld den Wert, um Dateideskriptoren mit `setrlimit()` zu reservieren. Ist der Wert hingegen 0, dann reserviert mysqld `max_connections×5` oder `max_connections + table_open_cache×2` Dateien (je nachdem, welcher Wert höher ist). Versuchen Sie, diesen Wert zu erhöhen, wenn mysqld die Fehlermeldung `Too many open files` ausgibt.

- `--pid-file=`path``

  Der Pfadname der Prozesskennungsdatei. Diese Datei wird von anderen Programmen wie mysqld_safe verwendet, um die Prozesskennung des Servers zu bestimmen.

- `--port=`port_num`, -P `port_num``

  Die Portnummer, die beim Horchen auf TCP/IP-Verbindungen verwendet wird. Die Portnummer muss 1024 oder höher sein, sofern der Server nicht vom Systembenutzer `root` gestartet wird.

- `--port-open-timeout=`num``

  Bei manchen Systemen wird, wenn der Server beendet wird, der TCP/IP-Port unter Umständen nicht mehr verfügbar gemacht. Wenn der Server kurz darauf neu gestartet wird, kann der Versuch fehlschlagen, den Port neu zu öffnen. Diese Option gibt an, wie viele Sekunden der Server warten soll, bis der TCP/IP-Port wieder frei wird, sofern er nicht geöffnet werden kann. Standardmäßig gibt es keine Wartezeit. Diese Option wurde in MySQL 5.1.5 hinzugefügt.

- `--safe-mode`

  Überspringt einige Optimierungsstufen.

- `--safe-show-database` (AUSLAUFEND)

  Siehe auch Abschnitt 5.8.3, „Von MySQL zur Verfügung gestellte Berechtigungen“.

- `--safe-user-create`

  Wenn diese Option aktiviert ist, kann ein Benutzer mit der `GRANT`-Anweisung keine neuen MySQL-Benutzer erstellen, wenn er für die Tabelle `mysql.user` oder eine der Spalten in dieser Tabelle nicht die Berechtigung `INSERT` hat.

- `--secure-auth`

  Unterbindet die Authentifizierung von Clients, die Konten mit alten Passwörtern (vor Version 4.1) zu verwenden versuchen.

- `--shared-memory`

  Aktiviert Verbindungen mit gemeinsamem Speicher durch lokale Clients. Diese Option ist nur unter Windows verfügbar.

- `--shared-memory-base-name=`name``

  Der Name des gemeinsamen Speichers, der für Verbindungen mit gemeinsamem Speicher verwendet werden soll. Diese Option ist nur unter Windows verfügbar. Der Standardname ist `MYSQL`. Beim Namen wird die Groß-/Kleinschreibung unterschieden.

- `--skip-bdb`

  Deaktiviert die `BDB`-Speicher-Engine. Hierdurch wird Speicher gespart, ferner werden einige Operationen beschleunigt. Verwenden Sie die Option nicht, wenn Sie `BDB`-Tabellen benötigen.

- `--skip-concurrent-insert`

  Schaltet die Möglichkeit ab, bei `MyISAM`-Tabellen gleichzeitig auszuwählen und einzufügen. (Diese Option sollte nur verwendet werden, wenn Sie das Gefühl haben, einen Bug in dieser Funktion gefunden zu haben.)

- `--skip-external-locking`

  Eine externe Sperrung (Systemsperrung) wird nicht verwendet. Bei deaktivierter externer Sperrung müssen Sie den Server herunterfahren, um myisamchk verwenden zu können. (Siehe auch Abschnitt 1.4.3, „Wie stabil ist MySQL?“.) Um diese Anforderung zu umgehen, verwenden Sie die Anweisungen `CHECK TABLE` und `REPAIR TABLE` zur Überprüfung und Reparatur von `MyISAM`-Tabellen.

  Die externe Sperrung wird seit MySQL 4.0 standardmäßig deaktiviert.

- `--skip-grant-tables`

  Diese Option sorgt dafür, dass der Server das Berechtigungssystem überhaupt nicht verwendet. Hierdurch erhalten alle Benutzer, die auf den Server zugreifen können, uneingeschränkten Zugang zu allen Datenbanken. Sie können einen laufenden Server dazu bringen, die Grant-Tabellen wieder zu verwenden, indem Sie mysqladmin flush-privileges oder mysqladmin reload über die System-Shell ausführen oder die MySQL-Anweisung `FLUSH PRIVILEGES` nach Herstellen einer Verbindung zum Server absetzen. Diese Option unterbindet auch das Laden von Plug-Ins und benutzerdefinierten Funktionen (UDFs).

- `--skip-host-cache`

  Der interne Hostnamencache wird nicht zur schnelleren Namensauflösung verwendet. Stattdessen wird bei jeder Verbindungsherstellung durch einen Client der DNS-Server abgefragt. Siehe auch Abschnitt 7.5.6, „Wie MySQL DNS benutzt“.

- `--skip-innodb`

  Deaktiviert die `InnoDB`-Speicher-Engine. Hierdurch wird Speicher und Festplattenkapazität gespart, ferner werden einige Operationen beschleunigt. Verwenden Sie die Option nicht, wenn Sie `InnoDB`-Tabellen benötigen.

- `--skip-name-resolve`

  Bei der Überprüfung von Clientverbindungen werden Hostnamen nicht aufgelöst. Es werden ausschließlich IP-Nummern verwendet. Wenn Sie diese Option verwenden, müssen alle Werte in der Spalte `Host` der Grant-Tabellen IP-Nummern oder `localhost` sein. Siehe auch Abschnitt 7.5.6, „Wie MySQL DNS benutzt“.

- `--skip-ndbcluster`

  Deaktiviert die `NDB Cluster`-Speicher-Engine. Dies ist die Standardeinstellung bei Binärdistributionen, die mit Unterstützung für die `NDB Cluster`-Speicher-Engine erstellt wurden. Der Server reserviert dieser Speicher-Engine nur dann Speicher und andere Ressourcen, wenn die Option `--ndbcluster` explizit angegeben wird. Ein Anwendungsbeispiel finden Sie in Abschnitt 16.4.3, „Schnelle Testeinrichtung von MySQL Cluster“.

- `--skip-networking`

  Unterbindet das Horchen auf TCP/IP-Verbindungen ganz. Die gesamte Interaktion mit mysqld muss über Named Pipes oder gemeinsamen Speicher (unter Windows) bzw. Unix-Socketdateien (unter Unix) erfolgen. Diese Option ist für Systeme, bei denen nur lokale Clients zulässig sind, sehr empfehlenswert. Siehe auch Abschnitt 7.5.6, „Wie MySQL DNS benutzt“.

- `--standalone`

  Nur unter Windows NT-basierten Systemen vorhanden. Die Option weist den MySQL-Server an, nicht als Dienst ausgeführt zu werden.

- `--symbolic-links`, `--skip-symbolic-links`

  Aktiviert bzw. deaktiviert die Unterstützung für symbolische Verknüpfungen. Die Option hat unter Windows und Unix unterschiedliche Auswirkungen:

  - Unter Windows erlaubt Ihnen die Aktivierung symbolischer Verknüpfungen die Einrichtung einer solchen Verknüpfung zu einem Datenbankverzeichnis durch Erstellen einer Datei ``db_name`.sym`, die den Pfad zum echten Verzeichnis enthält. Siehe auch Abschnitt 7.6.1.3, „Daten unter Windows auf verschiedene Platten aufteilen“.

  - Unter Unix hat die Aktivierung symbolischer Verknüpfungen zur Folge, dass Sie eine `MyISAM`-Index- oder -Datendatei mit einem anderen Verzeichnis verknüpfen können. Diese Verknüpfung erfolgt mit den Optionen `INDEX DIRECTORY` oder `DATA DIRECTORY` der `CREATE TABLE`-Anweisung. Wenn Sie die Tabelle löschen oder umbenennen, werden die Dateien, auf die die symbolischen Verknüpfungen verweisen, ebenfalls gelöscht bzw. umbenannt. Siehe auch Abschnitt 7.6.1.2, „Benutzung symbolischer Links für Tabellen“.

- `--skip-safemalloc`

  Wenn MySQL mit der Option `--with-debug=full` konfiguriert wird, prüfen alle MySQL-Programme bei jedem Speicherzuweisungs- und -freigabevorgang auf Speicherüberläufe. Diese Überprüfung erfolgt recht langsam, weswegen Sie sie für den Server mithilfe der Option `--skip-safemalloc` umgehen sollten, wenn Sie sie nicht brauchen.

- `--skip-show-database`

  Bei dieser Option darf die `SHOW DATABASES`-Anweisung nur von Benutzern verwendet werden, die die Berechtigung `SHOW DATABASES` haben. Die Anweisung zeigt dann alle Datenbanknamen an. Ohne diese Option dürfen alle Benutzer `SHOW DATABASES` verwenden, aber die Datenbanknamen werden nur angezeigt, wenn der Benutzer die Berechtigung `SHOW DATABASES` oder spezifische Berechtigungen für eine Datenbank hat. Beachten Sie, dass jede globale Berechtigung als Berechtigung für die Datenbank betrachtet wird.

- `--skip-stack-trace`

  Stapel-Trace-Dateien werden nicht geschrieben. Diese Option ist praktisch, wenn Sie mysqld unter einem Debugger ausführen. Bei manchen Systemen müssen Sie die Option auch verwenden, um eine Speicherauszugsdatei zu erhalten. Siehe auch Abschnitt E.1, „Einen MySQL-Server debuggen“.

- `--skip-thread-priority`

  Deaktiviert die Verwendung von Thread-Prioritäten für eine schnellere Antwortzeit.

- `--socket=`path``

  Unter Unix gibt diese Option die Unix-Socketdatei an, die beim Horchen nach lokalen Verbindungen verwendet werden soll. Der Vorgabewert ist `/tmp/mysql.sock`. Unter Windows legt die Option den Pipe-Namen fest, der beim Horchen nach lokalen Verbindungen verwendet werden soll, die eine Named Pipe nutzen. Der Vorgabewert ist `MySQL` (keine Unterscheidung der Groß-/Kleinschreibung).

- `--sql-mode=`value`[,`value`[,`value`...]]`

  Stellt den SQL-Modus ein. Siehe auch Abschnitt 5.2.5, „Der SQL-Modus des Servers“.

- `--temp-pool`

  Diese Option sorgt dafür, dass die meisten vom Server erstellten Temporärdateien eine kleine Menge von Namen nutzt (statt dass ein eindeutiger Name für jede neue Datei erstellt wird). Hierdurch wird ein Problem umgangen, dass der Linux-Kernel mit der Erstellung vieler neuer Dateien mit unterschiedlichen Namen hat. Beim ursprünglichen Verhalten scheint Linux ein „Speicherleck“ aufzuweisen, da der Speicher nicht dem Festplattencache, sondern dem Verzeichniseintragscache zugewiesen wird.

- `--transaction-isolation=`level``

  Stellt die Standardstufe für die Transaktionsisolierung ein. Der Wert `level` kann `READ-UNCOMMITTED`, `READ-COMMITTED`, `REPEATABLE-READ` oder `SERIALIZABLE` sein. Siehe auch Abschnitt 13.4.6, „`SET TRANSACTION`“.

- `--tmpdir=`path`, -t `path``

  Der Pfad des Verzeichnisses, in dem Temporärdateien erstellt werden. Die Option kann nützlich sein, wenn Ihr `/tmp`-Standardverzeichnis auf einer Partition liegt, die zu klein für die Aufnahme temporärer Tabellen ist. Die Option akzeptiert mehrere Pfade, die zyklisch abwechselnd verwendet werden. Pfade sollten unter Unix durch Doppelpunkte (‘`:`’) und unter Windows, NetWare und OS/2 durch Semikola (‘`;`’) getrennt werden. Wenn der MySQL-Server als Replikations-Slave agiert, sollten Sie die Option `--tmpdir` nicht auf ein Verzeichnis auf einem speicherbasierten Dateisystem oder aber ein Verzeichnis verweisen lassen, welches gelöscht wird, wenn der Serverhost neu gestartet wird. Weitere Informationen zur Speicherposition temporärer Dateien finden Sie in Abschnitt A.4.4, „Wohin MySQL temporäre Dateien speichert“. Ein Replikations-Slave benötigt einen Teil seiner Temporärdateien, um einen Systemneustart so zu überstehen, dass er Temporärtabellen oder `LOAD DATA INFILE`-Operationen replizieren kann. Wenn Dateien in im Verzeichnis für Temporärdateien beim Serverneustart verloren gehen, schlägt die Replikation fehl.

- `--user={`user_name` | `user_id`}, -u {`user_name` | `user_id`}`

  Führt den Server mysqld als Benutzer mit dem spezifizierten Benutzernamen (`user_name`) oder der numerischen Benutzerkennung (`user_id`) aus. („Benutzer“ bezeichnet in diesem Kontext ein Systemanmeldekonto und keinen in den Grant-Tabellen aufgeführten MySQL-Benutzer.)

  Diese Option zwingend erforderlich, wenn Sie mysqld als `root` starten. Der Server wechselt seine Benutzerkennung während der Startsequenz und wird dann als der angegebene Benutzer statt als `root` ausgeführt. Siehe auch Abschnitt 5.7.1, „Allgemeine Sicherheitsrichtlinien“.

  Um eine potenzielle Sicherheitslücke zu vermeiden, wenn ein Benutzer die Option `--user=root` in einer Datei `my.cnf` hinzufügt (und auf diese Weise eine Ausführung des Servers als `root` veranlasst), verwendet mysqld nur die erste angegebene Option `--user` und erzeugt eine Warnung, wenn mehrere `--user`-Optionen vorhanden sind. Optionen in `/etc/my.cnf` und `$MYSQL_HOME/my.cnf` werden vor eventuellen Befehlszeilenoptionen verarbeitet, weswegen empfohlen wird, eine Option `--user` in `/etc/my.cnf` einzufügen und dort einen anderen Wert als `root` anzugeben. Die Option in `/etc/my.cnf` wird vor allen anderen `--user`-Optionen gefunden; hierdurch ist sichergestellt, dass der Server als ein anderer Benutzer als `root` ausgeführt und eine Warnung erzeugt wird, wenn eine andere `--user`- Option gefunden wird.

- `--version`, `-V`

  Zeigt die Versionsinformation an und wird dann beendet.

Sie können einer Serversystemvariablen einen Wert zuweisen, indem Sie eine Option der Form `--`var_name`=`value`` verwenden. So setzt beispielsweise `--key_buffer_size=32M` die Variable `key_buffer_size` auf einen Wert von 32 Mbyte.

Beachten Sie, dass, wenn Sie einer Variablen einen Wert zuweisen, MySQL diesen ggf. automatisch so korrigiert, dass er innerhalb eines gegebenen Bereichs bleibt, oder den Wert auf den nächstgelegenen zulässigen Wert setzt, sofern nur bestimmte Werte gestattet sind.

Wenn Sie den Höchstwert, auf den eine Variable zur Laufzeit mit `SET` gesetzt werden kann, beschränken wollen, definieren Sie dies unter Verwendung der Befehlszeileoption `--maximum-`var_name``.

Es ist ferner möglich, Variablen über die Syntax `--set-variable=`var_name`=`value`` oder `-O `var_name`=`value`` einzustellen. Diese Syntax läuft jedoch aus.

Sie können die Werte der meisten Systemvariablen für einen laufenden Server mit der Anweisung `SET` ändern. Siehe auch Abschnitt 13.5.3, „`SET`“.

Abschnitt 5.2.2, „Server-Systemvariablen“, bietet eine vollständige Beschreibung aller Variablen sowie weitere Informationen zu deren Einstellung beim Serverstart und zur Laufzeit. Abschnitt 7.5.2, „Serverparameter feineinstellen“, enthält Informationen zur Optimierung des Servers durch gezielte Einstellung der Systemvariablen.

### 5.2.2. Server-Systemvariablen

Der Server mysql verwaltet eine ganze Reihe von Systemvariablen, die angeben, wie er konfiguriert ist. Für alle diese Variablen gibt es Vorgabewerte. Diese können beim Serverstart über Optionen auf der Befehlszeile oder in Optionsdateien eingestellt werden. Die meisten Variablen lassen sich zur Laufzeit des Servers dynamisch mithilfe der `SET`-Anweisung ändern; auf diese Weise können Sie den Betrieb des Servers beeinflussen, ohne ihn beenden und neu starten zu müssen. Ferner können Sie die Werte auch in Ausdrücken verwenden.

Durch Absetzen der `SHOW VARIABLES`-Anweisung können Sie die Namen und Werte der Systemvariablen auflisten lassen.

Die meisten Systemvariablen werden an dieser Stelle beschrieben. Variablen, bei denen keine Version angegeben ist, sind in allen Releases von MySQL 5.1 vorhanden. Historische Informationen zu ihrer Implementierung finden Sie im MySQL 5.0 Reference Manual und im MySQL-Referenzhandbuch für die Versionen 3.23, 4.0 und 4.1.

Hinweise zur Syntax bei der Einstellung und Anzeige von Werten von Systemvariablen finden Sie in Abschnitt 5.2.3, „Verwendung von Server-Systemvariablen“. Abschnitt 5.2.3.2, „Dynamische Systemvariablen“, listet die Variablen auf, die zur Laufzeit eingestellt werden können. Abschnitt 14.2.4, „`InnoDB`: Startoptionen und Systemvariablen“, listet `InnoDB`-Systemvariablen auf. Informationen zur Optimierung der Systemvariablen sind in Abschnitt 7.5.2, „Serverparameter feineinstellen“, enthalten.

Hinweis: Verschiedene Systemvariablen lassen sich mit der Anweisung `SET` aktivieren, indem sie auf `ON` bzw. `1` gesetzt werden. Ähnlich können Sie sie mit `SET` deaktivieren, indem Sie sie auf `OFF` bzw. `0` setzen. Um solche Variablen über die Befehlszeile oder in Optionsdateien einstellen zu können, müssen Sie sie auf `1` oder `0` setzen (d. h. die Einstellungen `ON` und `OFF` funktionieren nicht). So führt beispielsweise auf der Befehlszeile die Option `--delay_key_write=1` zum gewünschten Ergebnis – anders als `--delay_key_write=ON`.

Werte für Puffergrößen, Längen und Stapelgrößen sind in Byte angegeben, sofern nichts anderes festgelegt ist.

- `auto_increment_increment`

  `auto_increment_increment` und `auto_increment_offset` sind zur Verwendung bei der Master-to-Master-Replikation vorgesehen und können zur Steuerung des Betriebs von `AUTO_INCREMENT`-Spalten eingesetzt werden. Beide Variablen können global oder lokal eingestellt werden und jeweils einen Integer-Wert zwischen 1 und 65.535 einnehmen. Wenn eine dieser Variablen auf 0 gesetzt wird, wird der Wert automatisch auf 1 umgestellt. Der Versuch, ihnen einen ganzzahligen Wert größer 65.535 oder kleiner 0 zuzuweisen, führt hingegen zur automatischen Zuweisung des Wertes 65.535. Sollten Sie versuchen, `auto_increment_increment` oder `auto_increment_offset` auf einen nicht ganzzahligen Wert zu stellen, dann wird eine Fehlermeldung ausgegeben, und der Wert der Variable bleibt unverändert.

  Diese beiden Variablen beeinflussen das Verhalten von `AUTO_INCREMENT`-Spalten wie folgt:

  - `auto_increment_increment` steuert das Intervall zwischen aufeinanderfolgenden Spaltenwerten. Zum Beispiel:

        mysql> SHOW VARIABLES LIKE 'auto_inc%';
        +--------------------------+-------+
        | Variable_name            | Value |
        +--------------------------+-------+
        | auto_increment_increment | 1     |
        | auto_increment_offset    | 1     |
        +--------------------------+-------+
        2 rows in set (0.00 sec)

        mysql> CREATE TABLE autoinc1
            -> (col INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
          Query OK, 0 rows affected (0.04 sec)

        mysql> SET @@auto_increment_increment=10;
        Query OK, 0 rows affected (0.00 sec)

        mysql> SHOW VARIABLES LIKE 'auto_inc%';
        +--------------------------+-------+
        | Variable_name            | Value |
        +--------------------------+-------+
        | auto_increment_increment | 10    |
        | auto_increment_offset    | 1     |
        +--------------------------+-------+
        2 rows in set (0.01 sec)

        mysql> INSERT INTO autoinc1 VALUES (NULL), (NULL), (NULL), (NULL);
        Query OK, 4 rows affected (0.00 sec)
        Records: 4  Duplicates: 0  Warnings: 0

        mysql> SELECT col FROM autoinc1;
        +-----+
        | col |
        +-----+
        |   1 |
        |  11 |
        |  21 |
        |  31 |
        +-----+
        4 rows in set (0.00 sec)

    (Beachten Sie, wie hier mithilfe von `SHOW VARIABLES` die aktuellen Werte dieser Variablen ermittelt werden.)

  - `auto_increment_offset` bestimmt den Startwert der Spalte `AUTO_INCREMENT`. Betrachten Sie folgendes Beispiel (hier wird davon ausgegangen, dass diese Anweisungen während derselben Sitzung ausgeführt werden, bei der auch obiges Beispiel für `auto_increment_increment` erstellt wurde):

        mysql> SET @@auto_increment_offset=5;
        Query OK, 0 rows affected (0.00 sec)

        mysql> SHOW VARIABLES LIKE 'auto_inc%';
        +--------------------------+-------+
        | Variable_name            | Value |
        +--------------------------+-------+
        | auto_increment_increment | 10    |
        | auto_increment_offset    | 5     |
        +--------------------------+-------+
        2 rows in set (0.00 sec)

        mysql> CREATE TABLE autoinc2
            -> (col INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
        Query OK, 0 rows affected (0.06 sec)

        mysql> INSERT INTO autoinc2 VALUES (NULL), (NULL), (NULL), (NULL);
        Query OK, 4 rows affected (0.00 sec)
        Records: 4  Duplicates: 0  Warnings: 0

        mysql> SELECT col FROM autoinc2;
        +-----+
        | col |
        +-----+
        |   5 |
        |  15 |
        |  25 |
        |  35 |
        +-----+
        4 rows in set (0.02 sec)

    Wenn der Wert von `auto_increment_offset` größer ist als der von `auto_increment_increment`, dann wird der Wert von `auto_increment_offset` ignoriert.

  Sollte eine dieser Variablen (oder beide) geändert werden und dann neue Datensätze in eine Tabelle mit einer `AUTO_INCREMENT`-Spalte eingefügt werden, dann könnten die Ergebnisse unlogisch erscheinen, da die Berechnung der `AUTO_INCREMENT`-Wertereihe ohne Berücksichtigung ggf. bereits in der Spalte vorhandener Werte erfolgt und der nächste eingefügte Wert der kleinste Wert in der Reihe ist, der größer ist als der größte vorhandene Wert in der `AUTO_INCREMENT`-Spalte. Mit anderen Worten wird die Reihe so berechnet:

  `auto_increment_offset + `N` × auto_increment_increment`

  Hierbei ist `N` ist ein positiver Integer-Wert in der Reihe [1, 2, 3, ...]. Zum Beispiel:

      mysql> SHOW VARIABLES LIKE 'auto_inc%';
      +--------------------------+-------+
      | Variable_name            | Value |
      +--------------------------+-------+
      | auto_increment_increment | 10    |
      | auto_increment_offset    | 5     |
      +--------------------------+-------+
      2 rows in set (0.00 sec)

      mysql> SELECT col FROM autoinc1;
      +-----+
      | col |
      +-----+
      |   1 |
      |  11 |
      |  21 |
      |  31 |
      +-----+
      4 rows in set (0.00 sec)

      mysql> INSERT INTO autoinc1 VALUES (NULL), (NULL), (NULL), (NULL);
      Query OK, 4 rows affected (0.00 sec)
      Records: 4  Duplicates: 0  Warnings: 0

      mysql> SELECT col FROM autoinc1;
      +-----+
      | col |
      +-----+
      |   1 |
      |  11 |
      |  21 |
      |  31 |
      |  35 |
      |  45 |
      |  55 |
      |  65 |
      +-----+
      8 rows in set (0.00 sec)

  Die für `auto_increment_increment` und `auto_increment_offset` angezeigten Werte erzeugen die Reihe 5 + `N` × 10, also [5, 15, 25, 35, 45, ...]. Der größte Wert, der vor der `INSERT`-Anweisung in der `col`-Spalte vorhanden ist, ist 31. Der nächste verfügbare Wert in der `AUTO_INCREMENT`-Reihe ist 35, d. h. die eingefügten Werte für `col` beginnen bei diesem Punkt; die Ergebnisse der `SELECT`-Abfrage sehen also so aus wie angezeigt.

  Es ist wichtig, sich zu vergegenwärtigen, dass es nicht möglich ist, die Wirkungen dieser zwei Variablen auf eine einzige Tabelle zu beschränken, weswegen sie nicht die Funktion von Folgen wahrnehmen, die einige andere Datenbanksysteme anbieten; die Variablen steuern vielmehr das Verhalten aller `AUTO_INCREMENT`-Spalten in allen Tabellen auf dem MySQL-Server. Wird eine dieser Variablen global eingestellt, dann wird die Wirkung aufrechterhalten, bis der globale Wert geändert oder durch eine lokale Einstellung außer Kraft gesetzt oder mysqld neu gestartet wird. Bei einer lokalen Einstellung wirkt sich der neue Wert auf die `AUTO_INCREMENT` in allen Tabellen aus, in die vom aktuellen Benutzer während der laufenden Sitzung neue Datensätze eingefügt werden, sofern die Werte nicht während dieser Sitzung geändert werden.

  Der Standardwert von `auto_increment_increment` ist 1. Siehe auch Abschnitt 6.15, „Auto-Increment in der Multi-Master-Replikation“.

- `auto_increment_offset`

  Diese Variable hat den Vorgabewert 1. Besonderheiten entnehmen Sie der Beschreibung von `auto_increment_increment`.

- `back_log`

  Dies ist die Anzahl der ausstehenden Verbindungsanforderungen, die bei MySQL zulässig sind. Die Option wird wichtig, wenn der MySQL-Haupt-Thread sehr viele Verbindungsanforderungen innerhalb kürzester Zeit erhält. Es dauert dann eine (wenn auch sehr kurze) Zeit, bis der Haupt-Thread die Verbindung geprüft und einen neuen Thread gestartet hat. Der Wert `back_log` gibt an, wie viele Anforderungen während dieser kurzen Zeit gestapelt werden können, bevor MySQL neue Anforderungen vorübergehend nicht mehr beantwortet. Sie müssen diesen Wert nur dann erhöhen, wenn Sie eine hohe Anzahl von Verbindungen innerhalb kurzer Zeit erwarten.

  Anders gesagt bestimmt der Wert die Größe der Horchwarteschlange für eingehende TCP/IP-Verbindungen. Ihr Betriebssystem hat eine eigene Begrenzung dieser Warteschlangengröße. Weitere Informationen hierzu sollten Sie auf der Manpage zum Unix-Systemaufruf `listen()` finden. Überprüfen Sie Ihre Betriebssystemdokumentation zu Angaben für den Maximalwert dieser Variablen. `back_log` darf nicht höher gesetzt sein als für das jeweilige Betriebssystem zulässig.

- `basedir`

  Gibt das Basisverzeichnis der MySQL-Installation an. Die Variable kann mit der Option `--basedir` eingestellt werden.

- `bdb_cache_parts`

  Die Anzahl der Teile, die für den `BDB`-Cache verwendet werden sollen. Wurde in MySQL 5.1.2 hinzugefügt.

- `bdb_cache_size`

  Die Größe des Puffers, der für das Caching von Indizes und Datensätzen für `BDB`-Tabellen reserviert wird. Einige Systeme erlauben eine Einstellung dieser Variablen auf einen Wert von mehr als 4 Gbyte. Wenn Sie keine `BDB`-Tabellen verwenden, sollten Sie mysqld mit `--skip-bdb` starten, damit für diesen Cache kein Speicher reserviert wird.

- `bdb_home`

  Dies ist das Basisverzeichnis für `BDB`-Tabellen. Hier sollte der gleiche Wert stehen wie bei der Variablen `datadir`.

- `bdb_log_buffer_size`

  Gibt die Größe des Puffers an, der für das Caching von Indizes und Datensätzen für `BDB`-Tabellen reserviert wird. Wenn Sie keine `BDB`-Tabellen verwenden, sollten Sie hier 0 zuweisen oder mysqld mit `--skip-bdb`, damit für diesen Cache kein Speicher reserviert wird.

- `bdb_logdir`

  Gibt das Verzeichnis an, in das die `BDB`-Speicher-Engine ihre Logdateien schreibt. Die Variable kann mit der Option `--bdb-logdir` eingestellt werden.

- `bdb_max_lock`

  Die maximale Anzahl von Sperren, die für eine `BDB`-Tabelle aktiv sein können (standardmäßig 10.000). Sie sollten diesen Wert erhöhen, wenn bei der Durchführung langer Transaktionen oder dann, wenn mysqld viele Datensätze zur Berechnung einer Abfrage untersuchen muss, die folgende Fehlermeldung auftritt:

      bdb: Lock table is out of available locks
      Got error 12 from ...

- `bdb_region_size`

  Die Größe des zugrundeliegenden Logbereichs der `BDB`-Umgebung. Dies ist die Größe des Speicherpools, der zur Aufzeichnung der in einer Transaktion verwendeten Dateinamen verwendet wird. Wurde in MySQL 5.1.2 hinzugefügt.

- `bdb_shared_data`

  Ist `ON`, wenn Sie Berkeley DB mithilfe von `--bdb-shared-data` im Multiprozessmodus starten. (Verwenden Sie `DB_PRIVATE` nicht bei der Initialisierung von Berkeley DB.)

- `bdb_tmpdir`

  Gibt das Verzeichnis für `BDB`-Temporärdateien an.

- `binlog_cache_size`

  Gibt die Größe des Caches an, der die SQL-Anweisungen für das Binärlog während einer Transaktion aufnimmt. Ein Binärlog-Cache wird jedem Client zugewiesen, wenn der Server transaktionssichere Speicher-Engines unterstützt und an ihm das Binärlog aktiviert ist (Option `--log-bin`). Wenn Sie häufig umfangreiche, aus mehreren Anweisungen bestehende Transaktionen verwenden, können Sie diese Cachegröße erhöhen, um mehr Leistung zu erzielen. Die Statusvariablen `Binlog_cache_use` und `Binlog_cache_disk_use` können für die Optimierung dieser Variable nützlich sein. Siehe auch Abschnitt 5.12.3, „Die binäre Update-Logdatei“.

- `binlog_format`

  Das Binärlogformat (entweder `STATEMENT` oder `ROW`). Diese Variable wird von der Option `--binlog-format` eingestellt. Siehe auch Abschnitt 6.3, „Zeilenbasierte Replikation“.

- `bulk_insert_buffer_size`

  `MyISAM` verwendet einen speziellen Cache mit Baumstruktur, um Masseneinfügeoperation für `INSERT ... SELECT`, `INSERT ... VALUES (...), (...), ...` und `LOAD DATA INFILE` beim Hinzufügen von Daten in nicht leere Tabellen zu beschleunigen. Diese Variable beschränkt die Größe der Cachebaumstruktur und ist in Byte pro Thread angegeben. Die Einstellung 0 deaktiviert diese Optimierung. Der Vorgabewert ist 8 Mbyte.

- `character_set_client`

  Der Zeichensatz für Anweisungen, die vom Client kommend eintreffen.

- `character_set_connection`

  Der Zeichensatz für Literale, die keine Zeichensatzeinführung aufweisen, und für die Umwandlung von Zahlen in Strings.

- `character_set_database`

  Der von der Standarddatenbank verwendete Zeichensatz. Der Server stellt diese Variable immer dann ein, wenn die Standarddatenbank sich ändert. Ist keine Standarddatenbank vorhanden, dann hat die Variable denselben Wert wie `character_set_server`.

- `character_set_filesystem`

  Der Zeichensatz des Dateisystems. Der Vorgabewert ist `binary`. Diese Variable wurde in MySQL 5.1.6 hinzugefügt.

- `character_set_results`

  Der zur Rückgabe von Abfrageergebnissen an den Client verwendete Zeichensatz.

- `character_set_server`

  Der Standardzeichensatz des Servers.

- `character_set_system`

  Der vom Server zur Speicherung von Bezeichnern verwendete Zeichensatz. Der Wert ist immer `utf8`.

- `character_sets_dir`

  Das Verzeichnis, in dem Zeichensätze installiert sind.

- `collation_connection`

  Die Sortierung des Verbindungszeichensatzes.

- `collation_database`

  Die von der Standarddatenbank verwendete Sortierung. Der Server stellt diese Variable immer dann ein, wenn die Standarddatenbank sich ändert. Ist keine Standarddatenbank vorhanden, dann hat die Variable denselben Wert wie `collation_server`.

- `collation_server`

  Die Standardsortierung des Servers.

- `completion_type`

  Der Transaktionsabschlusstyp:

  - Wenn der Wert 0 ist (Standardeinstellung), werden `COMMIT` und `ROLLBACK` nicht beeinflusst.

  - Ist der Wert 1, dann sind `COMMIT` und `ROLLBACK` äquivalent zu `COMMIT AND CHAIN` bzw. `ROLLBACK AND CHAIN`. (Eine neue Transaktion wird mit derselben Isolierungsstufe gestartet wie die unmittelbar zuvor beendete Transaktion.)

  - Ist der Wert 2, dann sind `COMMIT` und `ROLLBACK` äquivalent zu `COMMIT RELEASE` bzw. `ROLLBACK RELEASE`. (Der Server trennt die Verbindung nach Abschluss der Transaktion.)

- `concurrent_insert`

  Wenn die Variable den Wert `ON` hat (Standardeinstellung), gestattet MySQL die nebenläufige Ausführung von `INSERT`- und `SELECT`-Anweisungen für `MyISAM`-Tabellen, die in der Mitte keine freien Blöcke aufweisen. Sie können diese Option deaktivieren, indem Sie mysqld mit `--safe` oder `--skip-new` starten.

  Diese Variable kann drei ganzzahlige Werte annehmen:

  Wert | Beschreibung
  0 | Die Funktion ist deaktiviert.
  1 | Dies ist die Standardeinstellung. Sie aktiviert nebenläufige Einfügeoperationen für `MyISAM`-Tabellen, die keine Lücken aufweisen.
  2 | Dieser Wert aktiviert nebenläufige Einfügeoperationen für alle `MyISAM`-Tabellen. Wenn eine Tabelle eine Lücke aufweist und gerade von einem anderen Thread verwendet wird, wird der neue Datensatz am Tabellenende eingefügt. Wird die Tabelle gerade nicht verwendet, dann setzt MySQL eine normale Lesesperre und fügt den neuen Datensatz in die Lücke ein.

  Siehe auch Abschnitt 7.3.3, „Gleichzeitige Einfügevorgänge“.

- `connect_timeout`

  Zeit in Sekunden, während der der mysqld-Server auf ein Verbindungspaket wartet, bevor er mit der Meldung `Bad handshake` antwortet.

- `datadir`

  Das MySQL-Datenverzeichnis. Die Variable kann mit der Option `--datadir` eingestellt werden.

- `date_format`

  Diese Variable ist nicht implementiert.

- `datetime_format`

  Diese Variable ist nicht implementiert.

- `default_week_format`

  Standardmoduswert für die Funktion `WEEK()`. Siehe auch Abschnitt 12.5, „Datums- und Zeitfunktionen“.

- `delay_key_write`

  Diese Option gilt nur für `MyISAM`-Tabellen. Sie kann einen der folgenden Werte annehmen und beeinflusst hierdurch die Wirkung der Tabellenoption `DELAY_KEY_WRITE`, die in `CREATE TABLE`-Anweisungen verwendet werden kann.

  Option | Beschreibung
  `OFF` | `DELAY_KEY_WRITE` wird ignoriert.
  `ON` | MySQL beachtet alle `DELAY_KEY_WRITE`-Optionen, die in `CREATE TABLE`-Anweisungen angegeben sind. Dies ist der Standardwert.
  `ALL` | Alle neu geöffneten Tabellen werden so behandelt, als ob sie mit aktivierter Option `DELAY_KEY_WRITE` erstellt worden wären.

  Wenn `DELAY_KEY_WRITE` für eine Tabelle aktiviert ist, wird der Schlüsselpuffer der Tabelle nicht bei jeder Indexaktualisierung, sondern nur dann neu geschrieben, wenn die Tabelle geschlossen wird. Hierdurch werden Schreiboperationen für Schlüssel erheblich beschleunigt. Wenn Sie diese Funktion nutzen, sollten Sie jedoch eine automatische Überprüfung aller `MyISAM`-Tabellen ergänzen, indem Sie den Server mit der Option `--myisam-recover` starten (beispielsweise `--myisam-recover=BACKUP,FORCE`). Siehe auch Abschnitt 5.2.1, „Befehlsoptionen für mysqld“, und Abschnitt 14.1.1, „`MyISAM`-Startoptionen“.

  Beachten Sie, dass die Aktivierung der externen Sperrung mit `--external-locking` keinen Schutz gegen die Beschädigung von Indizes gewährleistet, deren Tabellen das verzögerte Schreiben von Schlüsseln verwenden.

- `delayed_insert_limit`

  Nach dem Einfügen von mit `delayed_insert_limit` verzögerten Datensätzen überprüft der Handler `INSERT DELAYED`, ob noch `SELECT`-Anweisungen ausstehen. Ist dies der Fall, dann gestattet er deren Ausführung, bevor er mit dem Einfügen verzögerter Datensätze fortfährt.

- `delayed_insert_timeout`

  Gibt an, wie viele Sekunden ein `INSERT DELAYED`-Handler auf `INSERT`-Anweisungen warten soll, bevor er beendet wird.

- `delayed_queue_size`

  Dies ist eine tabellenspezifische Beschränkung der Anzahl von Datensätze, die bei der Verarbeitung von `INSERT DELAYED`-Anweisungen in der Warteschlange stehen dürfen. Wenn die Warteschlange voll wird, wartet jeder Client mit dem Absetzen einer `INSERT DELAYED`-Anweisung, bis wieder Platz in der Warteschlange ist.

- `div_precision_increment`

  Diese Variable gibt die Anzahl der Präzisionsstellen an, um die das Ergebnis von Divisionsoperationen mit dem Operator `/` erweitert werden soll. Der Standardwert ist 4, der Mindestwert 0 und der Höchstwert 30. Das folgende Beispiel veranschaulicht die Wirkung einer Erhöhung des Standardwertes.

      mysql> SELECT 1/7;
      +--------+
      | 1/7    |
      +--------+
      | 0.1429 |
      +--------+
      mysql> SET div_precision_increment = 12;
      mysql> SELECT 1/7;
      +----------------+
      | 1/7            |
      +----------------+
      | 0.142857142857 |
      +----------------+

- `event_scheduler`

  Gibt an, ob der Ereignisplaner aktiviert oder deaktiviert ist. Standardmäßig ist der Planer deaktiviert. Diese Variable wurde in MySQL 5.1.6 hinzugefügt.

- `engine_condition_pushdown`

  Diese Variable betrifft NDB. Der Standardwert ist 0 (deaktiviert): Wenn Sie eine Abfrage wie `SELECT * FROM t WHERE mycol = 42` ausführen, wobei `mycol` eine nicht indizierte Spalte ist, dann wird die Abfrage als vollständiger Tabellenscan an jedem NDB-Knoten durchgeführt. Jeder Knoten sendet jeden Datensatz an den MySQL-Server, auf dem dann die `WHERE`-Bedingung angewendet wird. Ist `engine_condition_pushdown` auf 1 gesetzt (aktiviert), dann wird die Bedingung an die Speicher-Engine „zurückverwiesen“ und an die NDB-Knoten gesendet. Jeder Knoten führt dann den Scan unter Anwendung der Bedingung durch und sendet nur diejenigen Datensätze an den MySQL-Server zurück, bei denen eine Übereinstimmung vorliegt.

- `expire_logs_days`

  Die Anzahl der Tage, nach denen Binärlogs automatisch entfernt werden. Der Standardwert ist 0, d. h. es erfolgt keine automatische Entfernung. Sofern Logs entfernt werden, erfolgt dies beim Start sowie bei der Binärlogrotation.

- `flush`

  Wenn aktiviert, schreibt der Server nach jeder SQL-Anweisung alle Änderungen neu auf die Festplatte (Synchronisierung). Normalerweise schreibt MySQL alle Änderungen erst nach der jeweiligen SQL-Anweisung auf die Festplatte und überlässt dem Betriebssystem die Festplattensynchronisierung. Siehe auch Abschnitt A.4.2, „Was zu tun ist, wenn MySQL andauernd abstürzt“. Diese Variable ist aktiviert, wenn Sie mysqld mit der Option `--flush` starten.

- `flush_time`

  Hat diese Variable einen Wert ungleich Null, dann werden alle Tabellen nach Verstreichen des durch `flush_time` (in Sekunden) angegebenen Zeitraums geschlossen, um Ressourcen freizugeben und nicht geschriebene Daten auf die Festplatte zu synchronisieren. Wir empfehlen die Verwendung dieser Option lediglich unter Windows 9x/Me und auf Systemen mit nur minimalen Ressourcen.

- `ft_boolean_syntax`

  Die Liste der Operatoren, die bei mit der Option `IN BOOLEAN MODE` durchgeführter Volltextsuche unterstützt werden. Siehe auch Abschnitt 12.7.1, „Boolesche Volltextsuche“.

  Vorgabe ist `'+ -><()~*:""&|'`. Es gelten folgende Regeln zur Änderung des Wertes:

  - Die Operatorfunktion wird durch die Position innerhalb des Strings bestimmt.

  - Der Ersetzungswert muss 14 Zeichen umfassen.

  - Jedes Zeichen muss ein ASCII-konformes, nicht alphanumerisches Zeichen sein.

  - Das erste oder zweite Zeichen muss ein Leerzeichen sein.

  - Mit Ausnahme der Anführungszeichen für Phrasen an den Positionen 11 und 12 sind Duplikate unzulässig. Die beiden Anführungszeichen müssen nicht identisch sein, dürfen es jedoch als einzige.

  - Die Positionen 10, 13 und 14 (Standardeinstellungen: ‘`:`’, ‘`&`’ und ‘`|`’) sind für zukünftige Erweiterungen vorgesehen.

- `ft_max_word_len`

  Die maximale Länge des Wortes, das in einem `FULLTEXT`-Index enthalten sein darf.

  Hinweis: Wenn Sie diese Variable ändern, müssen Sie `FULLTEXT`-Indizes neu erstellen. Verwenden Sie `REPAIR TABLE `tbl_name` QUICK`.

- `ft_min_word_len`

  Die minimale Länge des Wortes, das in einem `FULLTEXT`-Index enthalten sein darf.

  Hinweis: Wenn Sie diese Variable ändern, müssen Sie `FULLTEXT`-Indizes neu erstellen. Verwenden Sie `REPAIR TABLE `tbl_name` QUICK`.

- `ft_query_expansion_limit`

  Die Anzahl der obersten zu verwendenden Übereinstimmungen, die bei einer mit `WITH QUERY EXPANSION` ausgeführten Volltextsuche verwendet werden.

- `ft_stopword_file`

  Datei, aus der die Liste der Stoppwörter für die Volltextsuche ausgelesen wird. Es werden alle Wörter aus der Datei verwendet; Kommentare hingegen werden nicht berücksichtigt. Standardmäßig wird eine eingebaute Liste mit Stoppwörtern (wie in der Datei `myisam/ft_static.c` definiert) verwendet. Wenn Sie die Variable auf den Leer-String setzen (`''`), wird die Ausfilterung von Stoppwörtern deaktiviert.

  Hinweis: Wenn Sie diese Variable ändern oder den Inhalt der Stoppwortdatei ändern, müssen die `FULLTEXT`-Indizes neu erstellt werden. Verwenden Sie `REPAIR TABLE `tbl_name` QUICK`.

- `group_concat_max_len`

  Die maximal zulässige Ergebnislänge der Funktion `GROUP_CONCAT()`. Der Standardwert ist 1.024.

- `have_archive`

  `YES`, wenn mysqld `ARCHIVE`-Tabellen unterstützt, andernfalls `NO`.

- `have_bdb`

  `YES`, wenn mysqld `BDB`-Tabellen unterstützt. `DISABLED`, wenn `--skip-bdb` verwendet wird.

- `have_blackhole_engine`

  `YES`, wenn mysqld `BLACKHOLE`-Tabellen unterstützt, andernfalls `NO`.

- `have_compress`

  `YES`, wenn die Komprimierungsbibliothek `zlib` auf dem Server verfügbar ist, andernfalls `NO`. In diesem Fall können die Funktionen `COMPRESS()` und `UNCOMPRESS()` nicht verwendet werden.

- `have_crypt`

  `YES`, wenn der Systemaufruf `crypt()` auf dem Server verfügbar ist, andernfalls `NO`. In diesem Fall kann die Funktion `ENCRYPT()` nicht verwendet werden.

- `have_csv`

  `YES`, wenn mysqld `ARCHIVE`-Tabellen unterstützt, andernfalls `NO`.

- `have_example_engine`

  `YES`, wenn mysqld `EXAMPLE`-Tabellen unterstützt, andernfalls `NO`.

  `have_federated_engine`

  `YES`, wenn mysqld `FEDERATED`-Tabellen unterstützt, andernfalls `NO`.

- `have_geometry`

  `YES`, wenn der Server raumbezogene Datentypen unterstützt, andernfalls `NO`.

- `have_innodb`

  `YES`, wenn mysqld `InnoDB`-Tabellen unterstützt. `DISABLED`, wenn `--skip-innodb` verwendet wird.

- `have_isam`

  In MySQL 5.1 ist diese Variable nur aus Gründen der Abwärtskompatibilität vorhanden. Sie hat immer den Wert `NO`, da `ISAM` nicht mehr unterstützt werden.

- `have_ndbcluster`

  `YES`, wenn mysqld `NDB Cluster`-Tabellen unterstützt. `DISABLED`, wenn `--skip-ndbcluster` verwendet wird.

- `have_partitioning`

  `YES`, wenn mysqld die Partitionierung unterstützt. Wurde in MySQL 5.1.1 als `have_partition_engine` hinzugefügt und in 5.1.6 in `have_partioning` umbenannt.

- `have_openssl`

  `YES`, wenn mysqld eine SSL-Verschlüsselung des Client/Server-Protokolls unterstützt, andernfalls `NO`.

- `have_query_cache`

  `YES`, wenn mysqld den Abfrage-Cache unterstützt, andernfalls `NO`.

- `have_raid`

  `YES`, wenn mysqld die Option `RAID` unterstützt, andernfalls `NO`.

- `have_row_based_replication`

  `YES`, wenn der Server die Replikation unter Verwendung datensatzbasierten Binärloggens durchführen kann. Wenn der Wert `NO` ist, kann der Server nur anweisungsbasiertes Loggen durchführen. Siehe auch Abschnitt 6.3, „Zeilenbasierte Replikation“. Diese Variable wurde in MySQL 5.1.5 hinzugefügt.

- `have_rtree_keys`

  `YES`, wenn `RTREE`-Indizes verfügbar sind, andernfalls `NO`. (Diese werden für raumbezogene Indizes in `MyISAM`-Tabellen verwendet.)

- `have_symlink`

  `YES`, wenn die Unterstützung für symbolische Verknüpfungen aktiviert ist, andernfalls `NO`. Diese ist unter Unix für die Unterstützung der Tabellenoptionen `DATA DIRECTORY` und `INDEX DIRECTORY` und unter Windows für die Unterstützung von symbolischen Verknüpfungen mit Datenverzeichnissen erforderlich.

- `init_connect`

  Ein String, der vom Server immer dann ausgeführt wird, wenn ein Client eine Verbindung herstellt. Der String besteht aus einer oder mehreren SQL-Anweisungen. Wenn Sie mehrere Anweisungen angeben wollen, trennen Sie sie durch Semikola. So beginnt beispielsweise jeder Client bei einer Verbindung mit aktiviertem Autocommit-Modus. Es gibt keine globale Systemvariable, mit der festgelegt werden kann, dass Autocommit standardmäßig deaktiviert werden soll; mithilfe von `init_connect` aber können Sie genau dies realisieren:

      SET GLOBAL init_connect='SET AUTOCOMMIT=0';

  Diese Variable können Sie sowohl über die Befehlszeile als auch in einer Optionsdatei einstellen. Wenn Sie die Variable wie gezeigt in einer Optionsdatei einstellen wollen, ergänzen Sie die folgenden Zeilen:

      [mysqld]
      init_connect='SET AUTOCOMMIT=0'

  Beachten Sie, dass der Inhalt von `init_connect` nicht für Benutzer ausgeführt wird, die die Berechtigung `SUPER` haben. Zweck dieser Maßnahme ist es zu verhindern, dass ein fehlerhafter Wert für `init_connect` eine Verbindung zum System für alle Benutzer unmöglich macht. Wenn der Wert etwa eine Anweisung mit einem Syntaxfehler enthält, dann könnte dieser dazu führen, dass sich die Clients nicht mehr anmelden können. Da `init_connect` für Benutzer mit der Berechtigung `SUPER` nicht ausgeführt wird, können diese eine Verbindung herstellen und den Wert von `init_connect` korrigieren.

- `init_file`

  Der Name der beim Serverstart mit der Option `--init-file` angegebenen Datei. Es sollte sich hierbei um eine Datei mit SQL-Anweisungen handeln, die der Server beim Start ausführen soll. Jede Anweisung muss in einer eigenen Zeile stehen und darf keine Kommentare enthalten.

- `init_slave`

  Diese Variable ähnelt `init_connect`, es handelt sich hierbei aber um einen String, der von einem Slave-Server jedes Mal dann ausgeführt wird, wenn der SQL-Thread startet. Das Format des Strings ist identisch mit dem der Variable `init_connect`.

- `innodb_`xxx``

  `InnoDB`-Systemvariablen werden in Abschnitt 14.2.4, „`InnoDB`: Startoptionen und Systemvariablen“ beschrieben.

- `interactive_timeout`

  Zeit in Sekunden, während der der Server bei einer interaktiven Verbindung auf Aktivitäten wartet, bevor er sie schließt. Ein interaktiver Client ist als Client definiert, der die Option `CLIENT_INTERACTIVE` für `mysql_real_connect()` verwendet. Siehe auch `wait_timeout`.

- `join_buffer_size`

  Die Größe des Puffers, der für Joins benutzt wird, die keine Indizes verwenden und deswegen vollständige Tabellenscans durchführen. Normalerweise besteht die beste Möglichkeit der Realisierung schneller Joins darin, Indizes hinzuzufügen. Erhöhen Sie den Wert von `join_buffer_size`, um einen schnelleren vollständigen Join zu implementieren, wenn das Hinzufügen von Indizes nicht möglich ist. Für jeden vollständigen Join zwischen zwei Tabellen wird ein Join-Puffer hinzugefügt. Für einen komplexen Join zwischen mehreren Tabellen, für den Indizes nicht verwendet werden, sind unter Umständen mehrere Join-Puffer erforderlich.

- `key_buffer_size`

  Indexblöcke für `MyISAM`-Tabellen werden gepuffert und von allen Threads gemeinsam verwendet. `key_buffer_size` ist die Größe des für die Indexblöcke verwendeten Puffers. Der Schlüsselpuffer heißt auch Schlüssel-Cache.

  Die maximal zulässige Größe für `key_buffer_size` beträgt 4 Gbyte. Das effektive Limit kann abhängig davon, wie viel physisches RAM vorhanden ist und welche RAM-spezifischen Grenzwerte je Prozess unter Ihrem Betriebssystem bzw. auf Ihrer Hardwareplattform gelten, niedriger liegen.

  Wenn Sie die Indexverwaltung (für Lese- und mehrfachen Schreiboperationen) optimieren wollen, erhöhen Sie diesen Wert so weit wie möglich. Ein Wert von 25 Prozent des gesamten Speichers auf einem System, auf dem hauptsächlich MySQL läuft, ist durchaus normal. Wenn Sie den Wert jedoch zu hoch (beispielsweise auf mehr als 50 Prozent Ihres gesamten Speichers) setzen, wird Ihr System Daten auslagern und so extrem langsam werden. Zur Durchführung des Dateisystem-Cachings für Datenleseoperationen ist MySQL auf das Betriebssystem angewiesen, d. h. Sie müssen ein wenig Platz für den Dateisystem-Cache lassen. Außerdem müssen Sie die Speicheranforderungen anderer Speicher-Engines berücksichtigen.

  Um eine noch höhere Geschwindigkeit beim Schreiben vieler Datensätze zur gleichen Zeit zu erzielen, verwenden Sie `LOCK TABLES`. Siehe auch Abschnitt 7.2.16, „Geschwindigkeit von `INSERT`-Anweisungen“.

  Sie können die Leistung des Schlüsselpuffers durch Absetzen einer `SHOW STATUS`-Anweisung und Überprüfung der Statusvariablen `Key_read_requests`, `Key_reads`, `Key_write_requests` und `Key_writes` verifizieren. (Siehe auch Abschnitt 13.5.4, „`SHOW`“.) Das Verhältnis von `Key_reads` zu `Key_read_requests` sollte möglichst kleiner als 0,01 sein. Das `Key_writes/Key_write_requests`-Verhältnis hat normalerweise einen Wert von knapp 1, wenn Sie in erster Linie Aktualisierungs- und Löschvorgänge durchführen, kann aber wesentlich kleiner sein, wenn Sie entweder häufig Updates ausführen, die zahlreiche Datensätze gleichzeitig betreffen, oder die Tabellenoption `DELAY_KEY_WRITE` verwenden.

  Der Anteil des verwendeten Schlüsselpuffers kann mithilfe von `key_buffer_size` in Verbindung mit der Statusvariablen `Key_blocks_unused` und der Pufferblockgröße bestimmt werden, die über die Systemvariable `key_cache_block_size` verfügbar ist:

      1 - ((Key_blocks_unused × key_cache_block_size) / key_buffer_size)

  Dies ist lediglich ein Näherungswert, weil ein Teil des Schlüsselpuffers möglicherweise intern für Verwaltungsstrukturen reserviert ist.

  Sie können mehrere `MyISAM`-Schlüssel-Caches erstellen. Die Größenbeschränkung von 4 Gbyte gilt für jeden einzelnen Cache, nicht für die Summe aller Caches. Siehe auch Abschnitt 7.4.6, „Der `MyISAM`-Schlüssel-Cache“.

- `key_cache_age_threshold`

  Dieser Wert steuert die Herabstufung von Puffern aus der heißen Unterkette eines Schlüssel-Caches in eine warme Unterkette. Niedrige Werte führen dazu, dass diese Herabstufung schneller erfolgt. Der minimale Wert ist 100, der Vorgabewert 300. Siehe auch Abschnitt 7.4.6, „Der `MyISAM`-Schlüssel-Cache“.

- `key_cache_block_size`

  Größe der Blocks im Schlüssel-Cache in Byte. Der Standardwert ist 1.024. Siehe auch Abschnitt 7.4.6, „Der `MyISAM`-Schlüssel-Cache“.

- `key_cache_division_limit`

  Der Trennpunkt zwischen heißen und warmen Unterketten der Schlüssel-Cache-Pufferkette. Der Wert gibt den Anteil der Pufferkette, die für die warme Unterkette benutzt wird, prozentual an. Der zulässige Wertebereich liegt zwischen 1 und 100, Vorgabewert ist 100. Siehe auch Abschnitt 7.4.6, „Der `MyISAM`-Schlüssel-Cache“.

- `language`

  Sprache, in der Fehlermeldungen ausgegeben werden.

- `large_file_support`

  Gibt an, ob mysqld mit Optionen zur Unterstützung großer Dateien kompiliert wurde.

- `large_pages`

  Gibt an, ob die Unterstützung großer Seiten aktiviert wurde.

- `license`

  Der Lizenztyp des Servers.

- `local_infile`

  Gibt an, ob `LOCAL` für `LOAD DATA INFILE`-Anweisungen unterstützt wird. Siehe auch Abschnitt 5.7.4, „Sicherheitsprobleme mit `LOAD DATA LOCAL`“.

- `locked_in_memory`

  Gibt an, ob mysqld mit der Option `--memlock` im Speicher gesperrt wurde.

- `log`

  Gibt an, ob das Loggen aller Anweisungen im allgemeinen Abfragelog aktiviert wurde Siehe auch Abschnitt 5.12.2, „Die allgemeine Anfragen-Logdatei“.

- `log_bin`

  Gibt an, ob das Binärlog aktiviert wurde. Siehe auch Abschnitt 5.12.3, „Die binäre Update-Logdatei“.

- `log_bin_trust_function_creators`

  Diese Variable wird angewendet, wenn das binäre Loggen aktiviert ist. Sie steuert, ob die Ersteller gespeicherter Funktionen vertrauenswürdig sind, keine gespeicherten Funktionen zu erstellen, die das Schreiben unsicherer Ereignisse in das Binärlog bewirken könnten. Wenn die Variable den Wert 0 hat (Standardeinstellung), dann dürfen Benutzer gespeicherte Routinen nur dann erstellen oder ändern, wenn sie zusätzlich zu den Berechtigungen `CREATE ROUTINE` oder `ALTER ROUTINE` die Berechtigung `SUPER` haben. Die Einstellung 0 implementiert auch eine Beschränkung, dass eine Funktion mit der Eigenschaft `DETERMINISTIC`, der Eigenschaft `READS SQL DATA` oder der Eigenschaft `NO SQL` deklariert werden muss. Hat die Variable den Wert 1, dann setzt MySQL diese Beschränkungen bei der Erstellung gespeicherter Funktionen nicht durch. Siehe auch Abschnitt 19.4, „Binärloggen gespeicherter Routinen und Trigger“.

- `log_error`

  Die Position des Fehlerlogs.

- `log_slave_updates`

  Gibt an, ob Updates, die ein Slave-Server von einem Master-Server empfängt, im eigenen Binärlog des Slave-Servers aufgezeichnet werden sollen. Damit diese Variable Wirkung zeigt, muss das binäre Loggen am Slave aktiviert sein. Siehe auch Abschnitt 6.9, „Replikationsoptionen in my.cnf“.

- `log_slow_queries`

  Gibt an, ob langsame Abfragen protokolliert werden sollen. „Langsam“ wird hierbei durch den Wert der Variable `long_query_time` bestimmt. Siehe auch Abschnitt 5.12.4, „Die Logdatei für langsame Anfragen“.

- `log_warnings`

  Gibt an, ob zusätzliche Warnmeldungen erzeugt werden sollen. Die Funktion ist standardmäßig aktiviert. Unterbrochene Verbindungen werden nicht in das Fehlerlog protokolliert, sofern der Wert größer als 1 ist.

- `long_query_time`

  Wenn eine Abfrage länger dauert als durch diese Variable (in Sekunden) angegeben, erhöht der Server die Statusvariable `Slow_queries` entsprechend. Wenn Sie die Option `--log-slow-queries` verwenden, wird die Abfrage in der Logdatei für langsame Abfragen protokolliert. Dieser Wert wird als Echtzeit (nicht als Prozessorzeit) gemessen, d. h. eine Abfrage, die bei einem System mit geringer Belastung den Schwellwert unterschreitet, kann bei einem stark belasteten System bereits darüber liegen. Der Mindestwert ist 1. Siehe auch Abschnitt 5.12.4, „Die Logdatei für langsame Anfragen“.

- `low_priority_updates`

  Wenn diese Variable den Wert `1` hat, warten alle `INSERT`-, `UPDATE`-, `DELETE`- und `LOCK TABLE WRITE`-Anweisungen, bis keine `SELECT`- oder `LOCK TABLE READ`-Anweisungen für die betreffende Tabelle mehr anhängig sind. Diese Variable hieß früher `sql_low_priority_updates`.

- `lower_case_file_system`

  Diese Variable beschreibt die Auswirkungen der Groß-/Kleinschreibung auf dem Dateisystem, auf dem sich das Datenverzeichnis befindet. `OFF` bedeutet, dass die Groß-/Kleinschreibung bei Dateinamen unterschieden wird, bei `ON` ist dies nicht der Fall.

- `lower_case_table_names`

  Hat die Variable den Wert 1, dann werden Tabellennamen in Kleinschreibung auf der Festplatte gespeichert. Vergleiche von Tabellennamen werden dann nicht durch unterschiedliche Groß-/Kleinschreibung beeinträchtigt. Der Wert 2 führt zu einer Speicherung der Tabellennamen in der eingegebenen Form, Vergleiche erfolgen aber stets in Kleinschreibung. Diese Option gilt auch für Datenbanknamen und Tabellenaliase. Siehe auch Abschnitt 9.2.2, „Groß-/Kleinschreibung in Namen“.

  Wenn Sie `InnoDB`-Tabellen verwenden, sollten Sie diese Variable auf allen Plattformen auf 1 setzen. Hiermit wird die Konvertierung von Namen in die Kleinschreibung erzwungen.

  Sie sollten diese Variable keinesfalls auf 0 setzen, wenn Sie MySQL auf einem System ausführen, bei dem die Groß-/Kleinschreibung von Dateinamen nicht unterschieden wird (dies betrifft etwa Windows oder Mac OS X). Wird diese Variable beim Start nicht eingestellt und unterscheidet das Dateisystem, auf dem sich das Datenverzeichnis befindet, keine Groß-/Kleinschreibung bei Dateinamen, dann stellt MySQL `lower_case_table_names` automatisch auf 2.

- `max_allowed_packet`

  Die maximale Größe eines Pakets oder eines erzeugten oder temporären Strings.

  Der Paketmeldungspuffer wird mit `net_buffer_length` Bytes initialisiert, kann aber bei Bedarf auf bis zu `max_allowed_packet` Bytes anwachsen. Dieser Wert ist standardmäßig niedrig, damit große (und möglicherweise falsche) Pakete abgefangen werden.

  Wenn Sie große `BLOB`-Spalten oder lange Strings verwenden, müssen Sie ihn erhöhen. Es sollte so groß sein wie das größte `BLOB`, das Sie verwenden wollen. Das Protokolllimit für `max_allowed_packet` beträgt 1Gbyte.

- `max_binlog_cache_size`

  Wenn eine Transaktion mit mehreren Anweisungen mehr Speicher benötigt als hier angegeben, dann erzeugt der Server die Fehlermeldung `Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage`.

- `max_binlog_size`

  Wenn eine Schreiboperation in das Binärlog bewirkt, dass die aktuelle Größe der Logdatei den Wert dieser Variable überschreitet, dann führt der Server eine Rotation der Binärlogs durch (d. h. er schließt die aktuelle Datei und öffnet die nächste). Sie können diese Variable nur auf einen Wert im Bereich zwischen 4096 Bytes und 1 Gbyte setzen. Der Vorgabewert ist 1 Gbyte.

  Eine Transaktion wird am Stück in das Binärlog geschrieben, kann also niemals auf mehrere Binärlogs verteilt werden. Deswegen kann es vorkommen, dass, wenn Transaktionen sehr groß sind, Binärlogs am Ende größer sind als mit `max_binlog_size` angegeben.

  Wenn `max_relay_log_size` 0 ist, gilt der Wert von `max_binlog_size` auch für Relay-Logdateien.

- `max_connect_errors`

  Wenn die Anzahl unterbrochener Verbindungen zu einem Host höher liegt als durch diese Variable angegeben, dann werden weitere Verbindungen für diesen Host gesperrt. Diese Sperrung von Hosts können Sie mit `FLUSH HOSTS` aufheben.

- `max_connections`

  Die zulässige Anzahl nebenläufiger Clientverbindungen. Wenn Sie diesen Wert erhöhen, erhöht sich auch die Anzahl der Dateideskriptoren, die mysqld benötigt. Anmerkungen zu Grenzwerten für Dateideskriptoren finden Sie in Abschnitt 7.4.8, „Nachteile der Erzeugung großer Mengen von Tabellen in derselben Datenbank“. Siehe auch Abschnitt A.2.6, „`Too many connections`-Fehler“.

- `max_delayed_threads`

  Maximale Anzahl von Threads, die zur Verarbeitung von `INSERT DELAYED`-Anweisungen gestartet werden dürfen. Wenn Sie versuchen, Daten in eine neue Tabelle einzufügen, während alle `INSERT DELAYED`-Threads gerade verwendet werden, dann wird der Datensatz so eingefügt, als ob das Attribut `DELAYED` nicht angegeben worden wäre. Wenn Sie hier den Wert 0 angeben, erstellt MySQL in keinem Fall einen Thread zur Verarbeitung von `DELAYED`-Datensätzen; im Endeffekt bedeutet dies eine vollständige Deaktivierung von `DELAYED`.

- `max_error_count`

  Die maximale Anzahl von Fehlermeldungen, Warnungen und Hinweisen, die mit `SHOW ERRORS`- und `SHOW WARNINGS`-Anweisungen zur Anzeige gespeichert werden.

- `max_heap_table_size`

  Diese Variable bestimmt die maximale Größe, auf die `MEMORY`-Tabellen anwachsen dürfen. Der Wert der Variable wird zur Berechnung von `MAX_ROWS`-Werte für `MEMORY`-Tabellen verwendet. Die Einstellung der Variable hat keine Auswirkungen auf bereits vorhandene `MEMORY`-Tabellen, sofern diese nicht mit einer Anweisung wie `CREATE TABLE` neu erstellt oder mit `ALTER TABLE` oder `TRUNCATE TABLE` modifiziert werden.

- `max_insert_delayed_threads`

  Diese Variable ist synonym zu `max_delayed_threads`.

- `max_join_size`

  Ermöglicht das Unterbinden von `SELECT`-Anweisungen, die unter Umständen eine größere Anzahl von Datensätzen (bei Anweisungen für eine Tabelle) oder Datensatzkombinationen (bei Anweisungen für mehrere Tabellen) untersuchen müssen als durch `max_join_size` angegeben. Ebenfalls unterbunden werden `SELECT`-Anweisungen, bei denen mehr Festplattenzugriffe erfolgen würden als durch `max_join_size` angegeben. Durch Einstellen dieses Wertes können Sie `SELECT`-Anweisungen abfangen, bei denen Schlüssel nicht korrekt verwendet wurden und deren Verarbeitung wahrscheinlich sehr lange dauern würde. Nehmen Sie diese Einstellung vor, wenn Ihre Benutzer dazu neigen, Joins durchzuführen, bei denen entweder eine `WHERE`-Klausel fehlt oder die sehr lange dauern oder mehrere Millionen Datensätze zurückgeben könnten.

  Wenn Sie die Variable auf einen anderen Wert als `DEFAULT` setzen, wird der Wert von `SQL_BIG_SELECTS` auf `0` zurückgesetzt. Stellen Sie den Wert von `SQL_BIG_SELECTS` erneut ein, dann wird die Variable `max_join_size` ignoriert.

  Befindet sich ein Abfrageergebnis im Abfrage-Cache, dann wird keine Überprüfung der Ergebnisgröße durchgeführt, weil das Ergebnis zuvor bereits berechnet wurde und der Server durch den Versand des Ergebnisses nicht belastet würde.

  Diese Variable hieß früher `sql_max_join_size`.

- `max_length_for_sort_data`

  Die Teilungsgröße bei Indexwerten. Sie bestimmt, welcher `filesort`-Algorithmus verwendet werden soll. Siehe auch Abschnitt 7.2.12, „`ORDER BY`-Optimierung“.

- `max_relay_log_size`

  Wenn eine Schreiboperation durch einen Replikations-Slave in seine Relay-Logdatei bewirkt, dass die aktuelle Größe der Logdatei den Wert dieser Variable überschreitet, dann führt der Slave eine Rotation der Relay-Logs durch (d. h. er schließt die aktuelle Datei und öffnet die nächste). Wenn `max_relay_log_size` 0 ist, verwendet der Server `max_binlog_size` sowohl für das Binär- als auch für das Relay-Log. Ist `max_relay_log_size` größer als 0, dann wird hierdurch die Größe des Relay-Logs beschränkt. Dies ermöglicht Ihnen die Konfiguration unterschiedlicher Größen für die beiden Logdateien. Sie müssen `max_relay_log_size` auf einen Wert zwischen 4.096 Bytes und 1 Gbyte (jeweils einschließlich) oder auf 0 setzen. Der Standardwert ist 0. Siehe auch Abschnitt 6.4, „Replikation: Implementationsdetails“.

- `max_seeks_for_key`

  Beschränkt die voraussichtliche Anzahl von Festplattenzugriffen beim schlüsselbasierten Suchen nach Datensätzen. Der MySQL-Optimierer geht davon aus, dass nicht mehr als die hier angegebene Anzahl von Schlüsselsuchvorgängen bei der Suche nach passenden Datensätzen in einer Tabelle durch einen Indexscan erforderlich ist (und zwar unabhängig von der tatsächlichen Kardinalität des Index; siehe auch Abschnitt 13.5.4.12, „`SHOW INDEX`“). Durch Einstellen eines niedrigen Wertes (z. B. 100) können Sie MySQL dazu zwingen, Indizes statt Tabellenscans zu bevorzugen.

- `max_sort_length`

  Die bei der Sortierung von `BLOB`- oder `TEXT`-Werten zu verwendende Anzahl von Bytes. Nur die ersten `max_sort_length` Bytes jedes Wertes werden berücksichtigt; der Rest wird ignoriert.

- `max_tmp_tables`

  Die maximale Anzahl temporärer Tabellen, die ein Client zur selben Zeit offen halten darf. (Diese Option hat derzeit noch keine Auswirkungen.)

- `max_user_connections`

  Die maximale Anzahl gleichzeitiger Verbindungen zu einem gegebenen MySQL-Konto. Der Wert 0 hat die Bedeutung „unbeschränkt“.

  Diese Variable hat sowohl einen globalen als auch einen (schreibgeschützten) sitzungsbezogenen Geltungsbereich. Die Sitzungsvariable hat denselben Wert wie die globale Variable, sofern das aktuelle Konto nicht eine `MAX_USER_CONNECTIONS`-Ressourcenbeschränkung ungleich Null hat. In diesem Fall beschreibt der Sitzungswert die kontenbezogene Beschränkung.

- `max_write_lock_count`

  Nach Verstreichen der hier angegebenen Anzahl von Schreibsperren muss zunächst einmal eine Anzahl anhängiger Anforderungen für Lesesperren verarbeitet werden.

- `myisam_data_pointer_size`

  Die Standardgröße (in Byte) des Zeigers, der von `CREATE TABLE` für `MyISAM`-Tabellen verwendet wird, wenn die Option `MAX_ROWS` nicht angegeben ist. Der Variablenwert muss zwischen 2 und 7 liegen, der Standardwert ist 6. Siehe auch Abschnitt A.2.11, „`The table is full`-Fehler“.

- `myisam_max_extra_sort_file_size` (AUSLAUFEND)

  Hinweis: Diese Variable wird in MySQL 5.1 nicht unterstützt. Weitere Informationen finden Sie im MySQL 5.0 Reference Manual.

- `myisam_max_sort_file_size`

  Die maximale Größe der Temporärdatei, die MySQL bei der Neuerstellung eines `MyISAM`-Indexes (bei `REPAIR TABLE`, `ALTER TABLE` oder `LOAD DATA INFILE`) verwenden darf. Ist die Datei größer als durch diesen Wert angegeben, dann wird der Index stattdessen unter Verwendung des Schlüssel-Caches erstellt (was allerdings langsamer ist). Der Wert wird in Byte angegeben.

- `myisam_recover_options`

  Der Wert der Option `--myisam-recover`. Siehe auch Abschnitt 5.2.1, „Befehlsoptionen für mysqld“.

- `myisam_repair_threads`

  Wenn dieser Wert größer als 1 ist, werden Indizes von `MyISAM`-Tabellen parallel (d. h. jeder Index mit einem eigenen Thread) während des Prozesses `Repair by sorting` erstellt. Der Standardwert ist 1. Hinweis: Der Code für die Multithread-Reparatur befindet sich noch im Betastadium.

- `myisam_sort_buffer_size`

  Die Größe des Puffers, der bei der Sortierung von `MyISAM`-Indizes bei Ausführung von `REPAIR TABLE` oder bei der Erstellung von Indizes mit `CREATE INDEX` oder `ALTER TABLE` zugewiesen wird.

- `myisam_stats_method`

  Bestimmt, wie der Server `NULL`-Werte bei der Ermittlung von Statistiken zur Verteilung von Indexwerten bei `MyISAM`-Tabellen behandelt. Für die Variable gibt es zwei mögliche Werte: `nulls_equal` und `nulls_unequal`. Bei `nulls_equal` werden alle `NULL`-Indexwerte als gleichwertig betrachtet und bilden eine einzelne Wertegruppe, deren Größe der Anzahl der `NULL`-Werte entspricht. Bei `nulls_unequal` hingegen werden `NULL`-Werte nicht als gleichwertig betrachtet, und jeder `NULL`-Wert bildet eine eigene Wertegruppe der Größe 1.

  Die Methode, mit der Tabellenstatistiken erzeugt werden, wirkt sich darauf aus, wie der Optimierer Indizes zur Abfrageausführung auswählt. Eine Beschreibung finden Sie in Abschnitt 7.4.7, „Sammlung von `MyISAM`-Indexstatistiken“.

- `myisam_use_mmap`

  Sorgt für die Verwendung der Speicherzuordnung zum Lesen und Schreiben von `MyISAM`-Tabellen. Diese Variable wurde in MySQL 5.1.4 hinzugefügt.

- `multi_read_range`

  Gibt die maximale Anzahl von Bereichen an, die bei der Bereichsauswahl an eine Speicher-Engine gesendet werden. Der Standardwert beträgt 256. Das Senden mehrerer Bereiche an eine Engine ist eine Funktion, die die Leistung bestimmter Auswahloperationen drastisch optimieren kann. Dies gilt insbesondere für `NDBCLUSTER`: Diese Engine muss Bereichsanforderungen an alle Knoten senden, und das gleichzeitige Senden vieler derartiger Anforderungen verringert die Kommunikationskosten erheblich.

- `named_pipe`

  (Nur für Windows.) Gibt an, ob der Server Verbindungen über Named Pipes unterstützt.

- `ndb_extra_logging`

  Diese Variable kann auf einen Wert ungleich Null gesetzt werden, um das zusätzliche NDB-Loggen zu aktivieren. Diese Variable wurde in MySQL 5.1.6 hinzugefügt.

- `net_buffer_length`

  Der Kommunikationspuffer wird zwischen SQL-Anweisungen auf diese Größe zurücksetzt. Der Wert dieser Variable sollte normalerweise nicht geändert werden. Wenn Sie aber sehr wenig Speicher haben, können Sie ihn auf die voraussichtliche Länge der von Clients gesendeten Anweisungen setzen. Überschreiten Anweisungen diese Länge, dann wird der Puffer automatisch auf bis zu `max_allowed_packet` Bytes vergrößert.

- `net_read_timeout`

  Gibt an (in Sekunden), wie lange auf weitere Daten über eine Verbindung gewartet wird, bevor die Leseoperation abgebrochen wird. Dieser Grenzwert gilt nur für TCP/IP-Verbindungen, nicht jedoch für Verbindungen, die über Unix-Socketdateien, Named Pipes oder gemeinsamen Speicher erfolgen. Wenn der Server vom Client liest, gibt `net_read_timeout` den Zeitwert an, mit dem der Zeitpunkt des Abbruchs gesteuert wird. Wenn der Server hingegen auf den Client schreibt, gibt `net_write_timeout` den Zeitwert an, mit dem der Zeitpunkt des Abbruchs gesteuert wird. Siehe auch `slave_net_timeout`.

- `net_retry_count`

  Wenn eine Leseoperation an einem Kommunikationsport unterbrochen wird, erfolgt die hier angegebene Anzahl von Wiederverbindungsversuchen, bevor der Vorgang endgültig abgebrochen wird. Bei FreeBSD sollte dieser Wert ziemlich hoch sein, weil interne Interrupts an alle Threads gesendet werden.

- `net_write_timeout`

  Gibt an (in Sekunden), wie lange auf das Schreiben eines Blocks über eine Verbindung gewartet wird, bis die Schreiboperation abgebrochen wird. Dieser Grenzwert gilt nur für TCP/IP-Verbindungen, nicht jedoch für Verbindungen, die über Unix-Socketdateien, Named Pipes oder gemeinsamen Speicher erfolgen. Siehe auch `net_read_timeout`.

- `new`

  Diese Variable wurde in MySQL 4.0 verwendet, um bestimmte Verhaltensweisen von Version 4.1 zu aktivieren. Sie ist aus Gründen der Abwärtskompatibilität noch vorhanden. In MySQL 5.1 ist der Wert immer `OFF`.

- `old_passwords`

  Gibt an, ob der Server Passwörter im vor Version 4.1 verwendeten Stil benutzen soll. Siehe auch Abschnitt A.2.3, „`Client does not support authentication protocol`“.

- `one_shot`

  Dies ist keine Variable, kann aber zur Einstellung einiger Variablen verwendet werden. Eine Beschreibung finden Sie in Abschnitt 13.5.3, „`SET`“.

- `open_files_limit`

  Die Anzahl der Dateien, die mysqld nach Maßgabe des Betriebssystems öffnen darf. Dies ist der wirkliche, vom System gestattete Wert; er kann sich von dem Wert unterscheiden, den Sie mithilfe der Option `--open-files-limit` an mysqld bzw. mysqld_safe übergeben haben. Auf Systemen, bei denen MySQL die Anzahl offener Dateien nicht ändern kann, ist der Wert 0.

- `optimizer_prune_level`

  Steuert die bei der Abfrageoptimierung angewendete Heuristik, um den Suchraum des Optimierers von wenig vielversprechenden Teilplänen zu säubern. Der Wert 0 deaktiviert die Heuristik, d. h. der Optimierer führt eine erschöpfende Suche durch. Der Wert 1 hingegen sorgt dafür, dass der Optimierer Pläne basierend auf der Anzahl der von temporären Plänen abgerufenen Datensätze entfernt.

- `optimizer_search_depth`

  Die maximale Tiefe der vom Abfrageoptimierer durchgeführten Suche. Werte, die größer sind als die Anzahl der Beziehungen in einer Abfrage, führen zu besseren Abfrageplänen, benötigen aber mehr Zeit zur Erzeugung eines Ausführungsplans für eine Abfrage. Bei Werten hingegen, die kleiner sind als die Anzahl der Beziehungen in einer Abfrage, wird der Ausführungsplan schneller zurückgegeben; allerdings ist der zurückgegebene Plan unter Umständen weit davon entfernt, optimal zu sein. Wenn der Wert 0 gewählt wird, wählt das System automatisch einen sinnvollen Wert aus. Wird ein Wert zugewiesen, der der maximalen Anzahl der in einer Abfrage verwendeten Tabelle plus 2 entspricht, dann verwendet der Optimierer zur Durchführung von Suchvorgängen den in MySQL 5.0.0 (und vorher) verwendeten Algorithmus.

- `pid_file`

  Der Pfadname der Prozesskennungsdatei. Die Variable kann mit der Option `--pid-file` eingestellt werden.

- `plugin_dir`

  Der Pfadname des Plug-In-Verzeichnisses. Diese Variable wurde in MySQL 5.1.2 hinzugefügt.

- `port`

  Die Nummer des Ports, auf dem der Server nach TCP/IP-Verbindungen horcht. Die Variable kann mit der Option `--port` eingestellt werden.

- `preload_buffer_size`

  Die Größe des Puffers, der beim Vorabladen von Indizes reserviert wird.

- `protocol_version`

  Die Version des vom MySQL-Server verwendeten Client/Server-Protokolls.

- `query_alloc_block_size`

  Die Zuweisungsgröße von Speicherblöcken, die für Objekte reserviert sind, welche während der Verarbeitung und Ausführung von Anweisungen erstellt werden. Wenn Sie Probleme mit der Speicherfragmentierung haben, kann es hilfreich sein, diesen Wert ein wenig zu erhöhen.

- `query_cache_limit`

  Es werden nur Ergebnisse zwischengespeichert, die nicht größer sind als die hier angegebene Anzahl von Bytes. Der Vorgabewert ist 1 Mbyte.

- `query_cache_min_res_unit`

  Die Mindestgröße (in Byte) für Blöcke, die vom Abfrage-Cache reserviert wurden. Der Vorgabewert ist 4.096 (4 Kbyte). Informationen zur Optimierung dieser Variable finden Sie in Abschnitt 5.14.3, „Konfiguration des Anfragen-Cache“.

- `query_cache_size`

  Die Menge des Speichers, der zur Zwischenspeicherung von Abfrageergebnissen reserviert wird. Der Standardwert ist 0, d. h. der Abfrage-Cache ist deaktiviert. Beachten Sie, dass die hier angegebene Speichermenge auch dann reserviert wird, wenn `query_cache_type` den Wert 0 hat. Weitere Informationen finden Sie in Abschnitt 5.14.3, „Konfiguration des Anfragen-Cache“.

- `query_cache_type`

  Bestimmt den Typ des Abfrage-Caches. Die Einstellung des `GLOBAL`-Wertes legt den Typ für alle Clients fest, die sich nachfolgend anmelden. Einzelne Clients können den `SESSION`-Wert einstellen, um die eigene Verwendung des Abfrage-Caches zu beeinflussen. Die zulässigen Werte entnehmen Sie folgender Tabelle:

  Option | Beschreibung
  `0` oder `OFF` | Ergebnisse werden nicht zwischengespeichert oder abgerufen. Beachten Sie, dass die Reservierung des Puffers für den Abfrage-Cache hierdurch nicht aufgehoben wird. Zu diesem Zweck müssen Sie `query_cache_size` auf 0 setzen.
  `1` oder `ON` | Legt alle Abfrageergebnisse mit Ausnahme derjenigen, die mit `SELECT SQL_NO_CACHE` beginnen, im Cache ab.
  `2` oder `DEMAND` | Zwischengespeichert werden nur die Ergebnisse der Abfragen, die mit `SELECT SQL_CACHE` beginnen.

  Diese Variable hat den Standardwert `ON`.

- `query_cache_wlock_invalidate`

  Wenn ein Client eine Schreibsperre auf eine `MyISAM`-Tabelle erwirkt, dann wird das Absetzen von Anweisungen anderer Clients, die aus dieser Tabelle lesen, normalerweise nicht unterbunden, wenn die Abfrageergebnisse im Abfrage-Cache vorhanden sind. Wenn Sie diese Variable auf 1 setzen, werden bei vorhandener Schreibsperre für eine Tabelle alle Abfragen im Abfrage-Cache, die auf diese Tabelle verweisen, ungültig. Hierdurch sind andere Clients, die auf diese Tabelle zugreifen wollen, zum Warten gezwungen, bis die Sperre aufgehoben wird.

- `query_prealloc_size`

  Die Größe des Permanentpuffers, der zur Abarbeitung und Ausführung von Anweisungen verwendet wird. Dieser Puffer wird zwischen den Anweisungen nicht geleert. Wenn Sie komplexe Abfragen ausführen, kann ein höherer Wert für `query_prealloc_size` die Leistung optimieren, weil er dafür sorgt, dass der Server während der Abfrageausführung weniger Speicherreservierungen vornehmen muss.

- `range_alloc_block_size`

  Die Größe der Blöcke, die bei der Bereichsoptimierung reserviert werden.

- `read_buffer_size`

  Jeder Thread, der einen sequenziellen Scan durchführt, reserviert einen Puffer dieser Größe (in Byte) pro gescannter Tabelle. Wenn Sie mehrere sequenzielle Scans durchführen, sollten Sie den Wert erhöhen. Standardmäßig steht er bei 131.072.

- `read_only`

  Wenn die Variable für einen Replikations-Slave-Server auf `ON` gesetzt ist, gestattet der Slave Updates lediglich von Slave-Threads oder von Benutzern, die die Berechtigung `SUPER` haben. Dies kann sinnvoll sein, um sicherzustellen, dass ein Slave-Server Updates nur von seinem Master-Server und nicht von Clients akzeptiert. Diese Variable gilt nicht für `TEMPORARY`-Tabellen.

- `relay_log_purge`

  Aktiviert oder deaktiviert das automatische Säubern von Relay-Logdateien, sobald diese nicht mehr benötigt werden. Der Vorgabewert ist 1 (`ON`).

- `read_rnd_buffer_size`

  Beim Lesen von Datensätzen in sortierter Reihenfolge (auf einen Schlüsselsortiervorgang folgend) werden die Datensätze über diesen Puffer gelesen, um Festplattenzugriffe zu vermeiden. Das Setzen dieser Variable auf einen hohen Wert kann die Leistung von `ORDER BY` erheblich verbessern. Allerdings ist dies ein Puffer, der je Client zugewiesen wird. Deswegen sollten Sie die globale Variable nicht auf einen hohen Wert setzen. Ändern Sie stattdessen die Sitzungsvariablen nur bei den Clients, die große Abfragen ausführen müssen.

- `secure_auth`

  Wenn der MySQL-Server mit der Option `--secure-auth` gestartet wurde, sperrt er Verbindungen aller Konten, deren Passwörter im alten (d. h. vor Version 4.1 gültigen) Format gespeichert sind. In diesem Fall ist der Wert dieser Variable `ON`, andernfalls `OFF`.

  Sie sollten diese Option aktivieren, wenn Sie die Verwendung von Passwörtern im alten Format (und damit eine unsichere Kommunikation über das Netzwerk) generell unterbinden wollen.

  Der Serverstart schlägt mit einer Fehlermeldung fehl, wenn diese Option aktiviert ist, die Berechtigungstabellen jedoch das alte Format verwenden. Siehe auch Abschnitt A.2.3, „`Client does not support authentication protocol`“.

- `server_id`

  Die Serverkennung. Der Wert wird mit der Option `--server-id` eingestellt. Er erlaubt im Rahmen der Replikation die eindeutige Identifizierung von Master- und Slave-Servern.

- `shared_memory`

  (Nur für Windows.) Gibt an, ob der Server Verbindungen mit gemeinsamem Speicher gestattet.

- `shared_memory_base_name`

  (Nur für Windows.) Der Name des gemeinsamen Speichers, der für Verbindungen mit gemeinsamem Speicher verwendet werden soll. Dies ist praktisch, wenn Sie mehrere MySQL-Instanzen auf einem einzelnen physischen Computer ausführen. Der Standardname ist `MYSQL`. Beim Namen wird die Groß-/Kleinschreibung unterschieden.

- `skip_external_locking`

  Hat den Wert `OFF`, wenn mysqld die externe Sperrung verwendet, bzw. `ON`, wenn die externe Sperrung deaktiviert ist.

- `skip_networking`

  Diese Variable hat den Wert `ON`, wenn der Server nur lokale Verbindungen (Nicht-TCP/IP-Verbindungen) zulässt. Unter Unix verwenden lokale Verbindungen eine Unix-Socketdatei. Unter Windows nutzen lokale Verbindungen eine Named Pipe oder gemeinsamen Speicher. Unter NetWare werden nur TCP/IP-Verbindungen unterstützt; hier dürfen Sie diese Variable nicht auf `ON` setzen. Die Variable kann mit der Option `--skip-networking` auf `ON` gesetzt werden.

- `skip_show_database`

  Diese Variable verhindert, dass Benutzer die Anweisung `SHOW DATABASES` verwenden, wenn sie die Berechtigung `SHOW DATABASES` nicht haben. Dies kann die Sicherheit erhöhen, wenn Sie es für unerwünscht halten, dass Benutzer Datenbanken sehen können, die anderen Benutzern gehören. Die Wirkung der Variable hängt von der Berechtigung `SHOW DATABASES` ab: Wenn der Variablenwert `ON` ist, darf die `SHOW DATABASES`-Anweisung nur von Benutzern verwendet werden, die die Berechtigung `SHOW DATABASES` haben. Die Anweisung zeigt dann alle Datenbanknamen an. Ist der Wert hingegen `OFF`, dann dürfen alle Benutzer `SHOW DATABASES` absetzen; angezeigt werden in diesem Fall aber nur diejenigen Datenbanken, für die der jeweilige Benutzer die Berechtigung `SHOW DATABASES` oder eine ähnliche Berechtigung hat.

- `slave_compressed_protocol`

  Gibt an, ob eine Komprimierung des Slave/Master-Protokolls verwendet werden soll, wenn sowohl Slave als auch Master diese unterstützen.

- `slave_load_tmpdir`

  Der Name des Verzeichnisses, in dem der Slave Temporärdateien zur Replikation von `LOAD DATA INFILE`-Anweisungen erstellt.

- `slave_net_timeout`

  Gibt an (in Sekunden), wie lange auf weitere Daten über eine Master/Slave-Verbindung gewartet wird, bevor die Leseoperation abgebrochen wird. Dieser Grenzwert gilt nur für TCP/IP-Verbindungen, nicht jedoch für Verbindungen, die über Unix-Socketdateien, Named Pipes oder gemeinsamen Speicher erfolgen.

- `slave_skip_errors`

  Anzahl der Replikationsfehler, die der Slave übergehen (d. h. ignorieren) soll.

- `slave_transaction_retries`

  Wenn ein SQL-Thread auf einem Replikations-Slave eine Transaktion nicht ausführen kann, weil eine `InnoDB`-Blockade aufgetreten ist oder die Werte `innodb_lock_wait_timeout` von `InnoDB` bzw. `TransactionDeadlockDetectionTimeout` oder `TransactionInactiveTimeout` von NDBCluster überschritten wurden, erfolgt die durch `slave_transaction_retries` angegebene Anzahl von Neuversuchen, bevor der Vorgang mit einer Fehlermeldung beendet wird. Der Vorgabewert ist 10.

- `slow_launch_time`

  Wenn die Erstellung eines Threads länger dauert als durch diese Variable (in Sekunden) angegeben, dann erhöht der Server den Wert der Statusvariablen `Slow_launch_threads` entsprechend.

- `socket`

  Auf Unix-Plattformen bezeichnet diese Variable den Namen der Socketdatei, die für lokale Clientverbindungen verwendet wird. Der Vorgabewert ist `/tmp/mysql.sock`. (Bei einigen Distributionsformaten kann das Verzeichnis anders aussehen, z. B. `/var/lib/mysql` bei RPMs.)

  Unter Windows bezeichnet diese Variable den Namen der Named Pipe, die für lokale Clientverbindungen verwendet wird. Der Vorgabewert ist `MySQL` (keine Unterscheidung der Groß-/Kleinschreibung).

- `sort_buffer_size`

  Jeder Thread, der eine Sortierung durchführen muss, reserviert einen Puffer dieser Größe. Erhöhen Sie den Wert, um `ORDER BY`- oder `GROUP BY`-Operationen zu beschleunigen. Siehe auch Abschnitt A.4.4, „Wohin MySQL temporäre Dateien speichert“.

- `sql_mode`

  Der aktuelle SQL-Modus des Servers. Dieser kann dynamisch eingestellt werden. Siehe auch Abschnitt 5.2.5, „Der SQL-Modus des Servers“.

- `sql_slave_skip_counter`

  Die Anzahl der vom Master kommenden Ereignisse, die ein Slave-Server übergehen soll. Siehe auch Abschnitt 13.6.2.6, „`SET GLOBAL SQL_SLAVE_SKIP_COUNTER`“.

- `storage_engine`

  Die vorgabeseitige Speicher-Engine (Tabellentyp). Um die Speicher-Engine beim Serverstart einzustellen, verwenden Sie die Option `--default-storage-engine`. Siehe auch Abschnitt 5.2.1, „Befehlsoptionen für mysqld“.

- `sync_binlog`

  Ist der Wert dieser Variable positiv, dann synchronisiert der MySQL-Server sein Binärlog jedes Mal auf die Festplatte (unter Verwendung von `fdatasync()`), wenn `sync_binlog` in das Binärlog geschrieben wird. Beachten Sie, dass, wenn der Autocommit-Modus aktiviert ist, eine Schreiboperation pro Anweisung im Binärlog gespeichert wird; andernfalls handelt es sich um eine Schreiboperation je Transaktion. Der Standardwert ist 0, d. h. es wird keine Synchronisierung auf Festplatte durchgeführt. Der Wert 1 ist die sicherste Variante, denn im Falle eines Absturzes verlieren Sie maximal eine Anweisung bzw. eine Transaktion aus dem Binärlog. Allerdings ist diese Methode auch die langsamste (sofern die Festplatte nicht über einen batteriegestützten Cache verfügt, der die Synchronisierung extrem beschleunigt).

  Ist der Wert von `sync_binlog` 0 (Standardeinstellung), dann erfolgt kein zusätzliches Schreiben auf die Festplatte. Der Server ist wie bei jeder anderen Datei auch auf das Betriebssystem angewiesen, um den Dateiinhalt regelmäßig auf die Festplatte schreiben zu können.

- `sync_frm`

  Wenn diese Variable auf 1 gesetzt ist, wird, wenn eine nichttemporäre Tabelle erstellt wird, deren `.frm`-Datei auf Festplatte synchronisiert (dies geschieht mithilfe von `fdatasync()`). Dies ist zwar langsamer, im Falle eines Absturzes aber sicherer. Der Standardwert ist 1.

- `system_time_zone`

  Die Systemzeitzone des Servers. Wenn die Serverausführung startet, erbt sie eine Zeitzoneneinstellung von den Standardwerten des Computers, welche unter Umständen von der Umgebung des Kontos modifiziert wird, welches zur Ausführung des Servers oder Startskripts verwendet wird. Der Wert wird verwendet, um `system_time_zone` einzustellen. Normalerweise wird die Zeitzone durch die Umgebungsvariable `TZ` festgelegt. Eine Definition kann aber auch mithilfe der Option `--timezone` des Skripts mysqld_safe erfolgen.

  Die Variable `system_time_zone` unterscheidet sich von `time_zone`. Zwar können diese beiden Variablen denselben Wert haben, letztere wird aber zur Initialisierung der Zeitzone für die Clients verwendet, die eine Verbindung herstellen. Siehe auch Abschnitt 5.11.8, „Zeitzonen-Unterstützung des MySQL-Servers“.

- `table_cache`

  Dies ist der alte Name von `table_open_cache`, der vor MySQL 5.1.3 verwendet wurde. Verwenden Sie ab MySQL 5.1.3 stattdessen `table_open_cache`.

- `table_definition_cache`

  Die Anzahl der Tabellendefinitionen, die im Definitions-Cache gespeichert werden können. Wenn Sie eine hohe Anzahl von Tabellen verwenden, können Sie einen großen Tabellendefinitions-Cache erstellen, um das Öffnen von Tabellen zu beschleunigen. Der Tabellendefinitions-Cache benötigt weniger Platz als der normale Tabellen-Cache und verwendet anders als jener keine Dateideskriptoren. Diese Variable wurde in MySQL 5.1.3 hinzugefügt.

- `table_open_cache`

  Die Anzahl offener Tabellen für alle Threads. Wenn Sie diesen Wert erhöhen, erhöht sich auch die Anzahl der Dateideskriptoren, die mysqld benötigt. Wenn Sie überprüfen wollen, ob Sie den Tabellen-Cache vergrößern müssen, kontrollieren Sie die Statusvariable `Opened_tables`. Siehe auch Abschnitt 5.2.4, „Server-Statusvariablen“. Wenn der Wert von `Opened_tables` sehr groß ist und Sie `FLUSH TABLES` nicht sehr häufig verwenden (was nichts anderes tut, als alle Tabellen zu schließen und neu zu öffnen), dann sollten Sie den Wert von `table_open_cache` erhöhen. Weitere Informationen zum Tabellen-Cache finden Sie unter Abschnitt 7.4.8, „Nachteile der Erzeugung großer Mengen von Tabellen in derselben Datenbank“. Vor MySQL 5.1.3 hieß diese Variable `table_cache`.

- `table_type`

  Diese Variable ist synonym zu `storage_engine`. Bei MySQL 5.1 ist `storage_engine` der bevorzugte Name.

- `thread_cache_size`

  Gibt an, wie viele Threads der Server zur Neuverwendung zwischenspeichern soll. Wenn ein Client seine Verbindung trennt, dann werden die Threads dieses Clients im Cache abgelegt, sofern die Anzahl der dort vorhandenen Threads geringer als `thread_cache_size` ist. Thread-Anforderungen werden erfüllt, indem, sofern möglich, Threads aus dem Cache neu verwendet werden; neue Threads werden nur erstellt, wenn der Cache leer ist. Der Wert dieser Variablen kann erhöht werden, um die Leistung zu optimieren, wenn viele neue Verbindungen auftreten. (Bei einer guten Thread-Implementierung werden Sie normalerweise jedoch keine spürbare Leistungsverbesserung bemerken.) Durch Überprüfung der Differenz zwischen den Statusvariablen `Connections` und `Threads_created` können Sie die Wirksamkeit des Thread-Caches kontrollieren. Detaillierte Informationen finden Sie in Abschnitt 5.2.4, „Server-Statusvariablen“.

- `thread_concurrency`

  Unter Solaris ruft mysqld `thr_setconcurrency()` mit diesem Wert auf. Diese Funktionen erlaubt es Anwendungen, dem Thread-System Hinweise zur gewünschten Anzahl der gleichzeitig ausgeführten Threads zukommen zu lassen.

- `thread_stack`

  Die Stapelgröße für jeden Thread. Viele der vom `crash-me`-Test erkannten Einschränkungen hängen von diesem Wert ab. Der Standardwert ist für den normalen Betrieb ausreichend groß. Siehe auch Abschnitt 7.1.4, „Die MySQL-Benchmark-Reihe“. Standardwert ist 192 Kbyte.

- `time_format`

  Diese Variable ist nicht implementiert.

- `time_zone`

  Die aktuelle Zeitzone. Diese Variable wird zur Initialisierung der Zeitzone für die Clients verwendet, die eine Verbindung herstellen. Standardmäßig ist der Ausgangswert `'SYSTEM'` (mit der Bedeutung „Den Wert von `system_time_zone` verwenden“). Der Wert kann beim Serverstart mit der Option `--default-time-zone` explizit angegeben werden. Siehe auch Abschnitt 5.11.8, „Zeitzonen-Unterstützung des MySQL-Servers“.

- `tmp_table_size`

  Wenn eine temporäre Tabelle im Arbeitsspeicher diese Größe überschreitet, wandelt MySQL sie automatisch in eine `MyISAM`-Tabelle auf der Festplatte um. Erhöhen Sie den Wert von `tmp_table_size`, wenn Sie viele erweiterte `GROUP BY`-Abfragen ausführen und viel Speicher haben.

- `tmpdir`

  Das für Temporärdateien und Temporärtabellen verwendete Verzeichnis. Dieser Variable kann eine Liste mit mehreren verschiedenen Pfaden zugewiesen werden, die zyklisch abwechselnd verwendet werden. Die Pfade sollten unter Unix mit Doppelpunkten (‘`:`’) und unter Windows, NetWare und OS/2 mit Semikola (‘`;`’) voneinander getrennt werden.

  Diese Multiverzeichnisfunktion kann verwendet werden, um die Last auf mehrere physische Festplatten zu verteilen. Wenn der MySQL-Server als Replikations-Slave agiert, sollten Sie `tmpdir` nicht auf ein Verzeichnis auf einem speicherbasierten Dateisystem oder ein Verzeichnis verweisen lassen, das gelöscht wird, wenn der Server neu startet. Ein Replikations-Slave benötigt einen Teil seiner Temporärdateien, um einen Systemneustart so zu überstehen, dass er Temporärtabellen oder `LOAD DATA INFILE`-Operationen replizieren kann. Wenn Dateien im Verzeichnis für Temporärdateien beim Serverneustart verloren gehen, schlägt die Replikation fehl. Wenn Sie allerdings MySQL 4.0.0 oder höher verwenden, können Sie das Temporärverzeichnis des Slaves mithilfe der Variable `slave_load_tmpdir` einstellen. In diesem Fall wird der Slave den globalen Wert von `tmpdir` nicht verwenden, und Sie können `tmpdir` auch auf eine nichtpermanente Position verweisen lassen.

- `transaction_alloc_block_size`

  Die Menge an Bytes, um die ein Speicherpool für eine Transaktion erhöht wird, für die Speicher benötigt wird. Siehe auch die Beschreibung zu `transaction_prealloc_size`.

- `transaction_prealloc_size`

  Es gibt für jede Transaktion einen Speicherpool, aus dem verschiedene transaktionsbezogene Reservierungen Speicher entnehmen. Die Ausgangsgröße dieses Pools entspricht der Anzahl von Bytes, die durch `transaction_prealloc_size` angegeben ist. Für jede Reservierung, die aus dem Pool nicht erfüllt werden kann, da zu wenig Speicher verfügbar ist, wird der Pool um die Anzahl von Bytes erhöht, die durch `transaction_alloc_block_size` angegeben ist. Sobald die Transaktion endet, wird der Pool wieder um die durch `transaction_prealloc_size` angegebene Anzahl von Bytes verringert.

  Wenn Sie dafür Sorge tragen, dass `transaction_prealloc_size` groß genug ist, um alle Anweisungen einer einzelnen Transaktion aufzunehmen, können Sie viele `malloc()`-Aufrufe vermeiden.

- `tx_isolation`

  Die Standardstufe für die Transaktionsisolierung. Der Vorgabewert ist `REPEATABLE-READ`.

  Diese Variable wird durch die `SET TRANSACTION ISOLATION LEVEL`-Anweisung eingestellt. Siehe auch Abschnitt 13.4.6, „`SET TRANSACTION`“. Wenn Sie `tx_isolation` direkt auf einen Isolierungsstufennamen setzen, der ein Leerzeichen enthält, dann sollte der Name in Anführungszeichen gesetzt und das Leerzeichen durch einen Bindestrich ersetzt werden. Zum Beispiel:

      SET tx_isolation = 'READ-COMMITTED';

- `updatable_views_with_limit`

  Diese Variable steuert, ob Updates unter Verwendung einer View vorgenommen werden können, die keinen Primärschlüssel in der zugrundeliegenden Tabelle enthält, wenn das Update eine `LIMIT`-Klausel enthält. (Derartige Updates werden häufig von GUI-Tools erzeugt.) Ein Update ist eine `UPDATE`- oder `DELETE`-Anweisung. Unter dem Primärschlüssel versteht man hier einen `PRIMARY KEY`- oder einen `UNIQUE`-Index, bei dem keine Spalte `NULL` enthalten kann.

  Die Variable kann zwei Werte haben:

  - `1` oder `YES`: Es wird nur eine Warnung (d. h. keine Fehlermeldung) ausgegeben. Dies ist der Standardwert.

  - `0` oder `NO`: Das Update wird untersagt.

- `version`

  Die Versionsnummer des Servers.

- `version_bdb`

  Die Version der `BDB`-Speicher-Engine.

- `version_comment`

  Das Skript configure umfasst eine Option `--with-comment`, die die Angabe eines Kommentars bei der Erstellung von MySQL erlaubt. Diese Variable enthält den Wert dieses Kommentars.

- `version_compile_machine`

  Der Typ des Computers oder der Architektur, auf der MySQL erstellt wurde.

- `version_compile_os`

  Der Typ des Betriebssystem, auf der MySQL erstellt wurde.

- `wait_timeout`

  Zeit (in Sekunden), während der der Server bei einer nichtinteraktiven Verbindung auf Aktivitäten wartet, bevor er sie schließt. Dieser Grenzwert gilt nur für TCP/IP-Verbindungen, nicht jedoch für Verbindungen, die über Unix-Socketdateien, Named Pipes oder gemeinsamen Speicher erfolgen.

  Beim Thread-Start wird der Sitzungswert `wait_timeout` auf der Basis des globalen Wertes `wait_timeout` oder des globalen Wertes `interactive_timeout` initialisiert. Welcher Wert verwendet wird, hängt vom Clienttyp (entsprechend der Definition durch die Verbindungsoption `CLIENT_INTERACTIVE` von `mysql_real_connect()`) ab. Siehe auch `interactive_timeout`.

### 5.2.3. Verwendung von Server-Systemvariablen

Der Server mysqld arbeitet mit einer ganzen Reihe von Systemvariablen, die angeben, wie er konfiguriert ist. Für alle diese Variablen gibt es Vorgabewerte. Diese können beim Serverstart über Optionen auf der Befehlszeile oder in Optionsdateien eingestellt werden. Die meisten Variablen lassen sich zur Laufzeit des Servers dynamisch mithilfe der `SET`-Anweisung ändern; auf diese Weise können Sie den Betrieb des Servers beeinflussen, ohne ihn beenden und neu starten zu müssen. Ferner können Sie die Werte auch in Ausdrücken verwenden.

Hinweis: Verschiedene Systemvariablen lassen sich mit der Anweisung `SET` aktivieren, indem sie auf `ON` bzw. `1` gesetzt werden. Ähnlich können Sie sie mit `SET` deaktivieren, indem Sie sie auf `OFF` bzw. `0` setzen. Um solche Variablen über die Befehlszeile oder in Optionsdateien einstellen zu können, müssen Sie sie auf `1` oder `0` setzen (d. h. die Einstellungen `ON` und `OFF` funktionieren nicht). So führt beispielsweise auf der Befehlszeile die Option `--delay_key_write=1` zum gewünschten Ergebnis – anders als `--delay_key_write=ON`.

Der Server verwendet zwei Arten von Systemvariablen. Globale Variablen beeinflussen den Gesamtbetrieb des Servers. Sitzungsvariablen hingegen wirken sich auf seinen Betrieb bezogen auf jeweils individuelle Clientverbindungen aus. Eine gegebene Systemvariable kann sowohl einen globalen als auch einen sitzungsbezogenen Wert haben.

Wenn der Server startet, setzt er alle globalen Variablen auf ihr jeweiligen Standardwerte. Diese Vorgaben können mithilfe von Optionen geändert werden, die in Optionsdateien oder über die Befehlszeile angegeben werden.

Wenn Sie eine Variable, die einen numerischen Wert annimmt, über eine Startoption konfigurieren, dann kann dieser Wert mit den Suffixen `K`, `M` oder `G` (in Groß- oder Kleinschreibung) angegeben werden, um einen Multiplikator von 1.024, 1.0242 oder 1.0243 anzuzeigen. Bei der Einstellung von `key_buffer_size` etwa würden hiermit die Werte als Kbyte, Mbyte oder Gbyte angegeben. Der folgende Befehl startet den Server also mit einem Abfrage-Cache, der eine Größe von 16 Mbyte hat.

    mysqld --query_cache_size=16M

Die Groß-/Kleinschreibung der Suffixbuchstaben ist irrelevant: `16M` und `16m` sind gleichwertig.

Wenn Sie den Maximalwert, auf den eine Systemvariable zur Laufzeit mit der `SET`-Anweisung gesetzt werden kann, beschränken wollen, können Sie das gewünschte Maximum mithilfe einer Option des Typs `--maximum-`var_name`` beim Serverstart festlegen. Um beispielsweise eine Erhöhung des Wertes von `query_cache_size` auf mehr als 32 Mbyte zu verhindern, benutzen Sie die Option `--maximum-query_cache_size=32M`.

Wenn der Server gestartet wurde, können diejenigen Variablen, die dynamisch sind, geändert werden, indem Sie eine Verbindung mit dem Server herstellen und eine `SET GLOBAL `var_name` = `value``-Anweisung absetzen. Um eine globale Variable ändern zu können, benötigen Sie die Berechtigung `SUPER`.

Der Server verwendet zudem einen Satz von Sitzungsvariablen für jeden Client, der eine Verbindung herstellt. Die Sitzungsvariablen des Clients werden zum Zeitpunkt der Verbindungsherstellung unter Verwendung der aktuellen Werte der entsprechenden globalen Variablen initialisiert. So wird z. B. der SQL-Modus des Clients von der Sitzungsvariable `sql_mode` gesteuert, die, wenn der Client die Verbindung herstellt, mit dem Wert der globalen Variable `sql_mode` initialisiert wird.

Sitzungsvariablen, die dynamisch sind, kann der Client durch Absetzen einer `SET SESSION `var_name` = `value``-Anweisung ändern. Das Einstellen einer Sitzungsvariable erfordert keine speziellen Berechtigungen, aber ein Client kann nur seine eigenen Sitzungsvariablen einstellen, nicht jedoch die anderer Clients.

Eine Änderung einer globalen Variable ist für alle Clients sichtbar, die auf diese globale Variable zugreifen. Allerdings wirkt sich diese Änderung nur auf die entsprechenden Sitzungsvariablen derjenigen Clients aus, die nach ihrer Durchführung eine Verbindung herstellen. Änderungen an globalen Variablen haben hingegen keinen Einfluss auf die betreffende Sitzungsvariable derjenigen Clients, die bereits eine Verbindung hergestellt haben (dies gilt sogar für Clients, die die `SET GLOBAL`-Anweisung absetzen).

Es gibt unterschiedliche Möglichkeiten, globale und Sitzungsvariablen zur Laufzeit einzustellen. Die folgenden Beispiele verwenden `sort_buffer_size` als Beispiel für einen Variablennamen.

Um den Wert einer `GLOBAL`-Variable einzustellen, verwenden Sie eine der folgenden Syntaxen:

    SET GLOBAL sort_buffer_size = value;
    SET @@global.sort_buffer_size = value;

Um den Wert einer `SESSION`-Variable einzustellen, verwenden Sie eine der folgenden Syntaxen:

    SET SESSION sort_buffer_size = value;
    SET @@session.sort_buffer_size = value;
    SET sort_buffer_size = value;

`LOCAL` ist ein Synonym für `SESSION`, und `@@local.` ist ein Synonym für `@@session.`.

Wenn Sie beim Einstellen einer Variable keinen `GLOBAL`- oder `SESSION`-Modifikator angeben, stellt die Anweisung den Sitzungswert ein.

Um eine falsche Verwendung zu verhindern, erzeugt MySQL einen Fehler, wenn Sie `SET GLOBAL` für eine Variable verwenden, für die nur `SET SESSION` zulässig ist, oder `GLOBAL` (bzw. `@@global.`) beim Einstellen einer globalen Variable nicht angeben.

Wenn Sie einer Systemvariablen mit `SET` einen Wert zuweisen, dann können Sie in diesem Wert keine Suffixbuchstaben verwenden. Allerdings kann der Wert die Form eines Ausdrucks annehmen:

    SET sort_buffer_size = 10 * 1024 * 1024;

Um explizit anzugeben, ob Sie die globale oder die Sitzungsvariable einstellen wollen, verwenden Sie die Modifikatoren `GLOBAL` oder `SESSION`:

    SET GLOBAL sort_buffer_size = 10 * 1024 * 1024;
    SET SESSION sort_buffer_size = 10 * 1024 * 1024;

Systemvariablen und ihre Werte zeigen Sie mit der `SHOW VARIABLES`-Anweisung an.

    mysql> SHOW VARIABLES;
    +---------------------------------+--------------------------------------+
    | Variable_name                   | Value                                |
    +---------------------------------+--------------------------------------+
    | auto_increment_increment        | 1                                    |
    | auto_increment_offset           | 1                                    |
    | automatic_sp_privileges         | ON                                   |
    | back_log                        | 50                                   |
    | basedir                         | /home/jon/bin/mysql/                 |
    | binlog_cache_size               | 32768                                |
    | bulk_insert_buffer_size         | 8388608                              |
    | character_set_client            | latin1                               |
    | character_set_connection        | latin1                               |
    | character_set_database          | latin1                               |
    | character_set_results           | latin1                               |
    | character_set_server            | latin1                               |
    | character_set_system            | utf8                                 |
    | character_sets_dir              | /usr/bin/mysql/share/mysql/charsets/ |
    | collation_connection            | latin1_swedish_ci                    |
    | collation_database              | latin1_swedish_ci                    |
    | collation_server                | latin1_swedish_ci                    |
    ...
    | innodb_additional_mem_pool_size | 1048576                              |
    | innodb_autoextend_increment     | 8                                    |
    | innodb_buffer_pool_awe_mem_mb   | 0                                    |
    | innodb_buffer_pool_size         | 8388608                              |
    | innodb_checksums                | ON                                   |
    | innodb_commit_concurrency       | 0                                    |
    | innodb_concurrency_tickets      | 500                                  |
    | innodb_data_file_path           | ibdata1:10M:autoextend               |
    | innodb_data_home_dir            |                                      |
    ...
    | version                         | 5.1.6-alpha-log                      |
    | version_comment                 | Source distribution                  |
    | version_compile_machine         | i686                                 |
    | version_compile_os              | suse-linux                           |
    | wait_timeout                    | 28800                                |
    +---------------------------------+--------------------------------------+

Um den Wert einer bestimmten `GLOBAL`-Variable abzurufen, geben Sie eine der folgenden Anweisungen ein:

    SELECT @@global.sort_buffer_size;
    SHOW GLOBAL VARIABLES like 'sort_buffer_size';

Um den Wert einer `SESSION`-Variable abzurufen, geben Sie eine der folgenden Anweisungen ein:

    SELECT @@sort_buffer_size;
    SELECT @@session.sort_buffer_size;
    SHOW SESSION VARIABLES like 'sort_buffer_size';

Wenn Sie eine Variable mit `SELECT @@`var_name`` abrufen (d. h. `global.` oder `session.` nicht angeben), gibt MySQL den `SESSION`-Wert zurück, sofern dieser vorhanden ist, ansonsten den `GLOBAL`-Wert.

Wenn Sie bei `SHOW VARIABLES` weder `GLOBAL` noch `SESSION` angeben, gibt MySQL die `SESSION`-Werte zurück.

Der Grund dafür, warum das Schlüsselwort `GLOBAL` bei der Einstellung von Variablen angegeben werden muss, die ohnehin nur global verfügbar sind, nicht jedoch bei deren Abrufen, besteht darin, zukünftige Probleme von vornherein auszuschließen. Wenn wir in Zukunft eine `SESSION`-Variable entfernen müssten, die denselben Namen wie eine `GLOBAL`-Variable hat, würde ein Client mit der Berechtigung `SUPER` möglicherweise ungewollt die `GLOBAL`-Variable ändern – und nicht die `SESSION`-Variable für die eigene Verbindung. Würden wir ein `SESSION`-Variable mit demselben Namen hinzufügen, den auch eine `GLOBAL`-Variable hat, dann könnte ein Client, der eigentlich die `GLOBAL`-Variable ändern sollte, am Ende seine eigene `SESSION`-Variable modifizieren.

#### 5.2.3.1. Strukturierte Systemvariablen

Eine Strukturvariable unterscheidet sich in zweierlei Hinsicht von einer regulären Systemvariablen:

- Ihr Wert ist eine Struktur mit Komponenten, die Serverparameter angeben, welche als zusammengehörig zu betrachten sind.

- Es kann mehrere Instanzen eines gegebenen Strukturvariablentyps geben. Jede Instanz hat einen anderen Namen und verweist auf eine andere Ressource, die vom Server verwaltet wird.

MySQL 5.1 unterstützt genau einen Typ von Strukturvariablen. Dieser gibt Parameter an, die den Betrieb von Schlüssel-Caches regeln. Eine Strukturvariable für Schlüssel-Caches hat die folgenden Komponenten:

- `key_buffer_size`

- `key_cache_block_size`

- `key_cache_division_limit`

- `key_cache_age_threshold`

In diesem Abschnitt beschreiben wir die Syntax, mit der Strukturvariablen referenziert werden. Schlüssel-Cache-Variablen werden zwar für Syntaxbeispiele verwendet; die einzelnen Details dazu, wie Schlüssel-Caches funktionieren, finden Sie jedoch an anderer Stelle in Abschnitt 7.4.6, „Der `MyISAM`-Schlüssel-Cache“.

Um eine Komponente einer Strukturvariableninstanz zu referenzieren, können Sie einen zusammengesetzten Namen des Formats `instance_name.component_name` verwenden. Ein paar Beispiele:

    hot_cache.key_buffer_size
    hot_cache.key_cache_block_size
    cold_cache.key_cache_block_size

Für jede strukturierte Systemvariable ist immer eine Instanz mit dem Namen `default` vordefiniert. Wenn Sie eine Komponente einer Strukturvariable ohne einen Instanznamen referenzieren, wird die Instanz `default` verwendet. Auf diese Weise referenzieren `default.key_buffer_size` und `key_buffer_size` dieselbe Systemvariable.

Strukturvariableninstanzen und Komponenten gehorchen den folgenden Benennungsregeln:

- Für einen gegebenen Strukturvariablentyp muss jede Instanz einen Namen haben, der innerhalb der Variablen dieses Typs eindeutig ist. Typenübergreifend hingegen müssen die Instanznamen nicht eindeutig sein. So gibt es für jede Strukturvariable eine Instanz namens `default` – der Name `default` ist also keineswegs typübergreifend eindeutig.

- Die Namen der Komponenten jedes Strukturvariablentyps muss über alle Systemvariablennamen hinweg eindeutig sein. Wäre dies nicht der Fall (d. h. könnten zwei verschiedene Strukturvariablentypen die gleichen Mitgliedsnamen für Komponenten aufweisen), dann wäre nicht eindeutig, welche Standardstrukturvariable zur Referenzierung von Mitgliedsnamen verwendet werden sollte, die nicht durch einen Instanznamen qualifiziert wären.

- Wenn der Namen einer Strukturvariableninstanz als Bezeichner ohne Anführungszeichen nicht zulässig ist, setzen Sie sie ihn in Backticks. So ist etwa `hot-cache` unzulässig – anders als ``hot-cache``.

- `global`, `session` und `local` sind unzulässige Instanznamen. Hierdurch wird ein Konflikt umgangen, der bei der Referenzierung nichtstrukturierter Systemvariablen auftreten kann, bei denen die Schreibung `@@global.`var_name`` zulässig ist.

Zurzeit besteht die Möglichkeit des Verstoßes gegen die ersten beiden Regeln nicht, weil der einzige Strukturvariablentyp der für die Schlüssel-Caches ist. Die Bedeutung dieser Regeln wird jedoch zunehmen, wenn zukünftig andere Typen strukturierter Variablen eingeführt werden.

Mit einer Ausnahme können Sie Komponenten von Strukturvariablen über zusammengesetzte Namen in jedem Kontext referenzieren, in dem einfache Variablennamen auftauchen können. So können Sie einer Strukturvariablen beispielsweise über eine Befehlszeilenoption einen Wert zuweisen:

    shell> mysqld --hot_cache.key_buffer_size=64K

In einer Optionsdatei verwenden Sie folgende Syntax:

    [mysqld]
    hot_cache.key_buffer_size=64K

Wenn Sie den Server mit dieser Option starten, erstellt er einen Schlüssel-Cache namens `hot_cache` mit einer Größe von 64 Kbyte zusätzlich zum vorgabeseitigen Schlüssel-Cache mit der Standardgröße von 8 Mbyte.

Nehmen wir an, Sie starten den Server wie folgt:

    shell> mysqld --key_buffer_size=256K \
             --extra_cache.key_buffer_size=128K \
             --extra_cache.key_cache_block_size=2048

In diesem Fall setzt der Server die Größe des vorgabeseitigen Caches auf 256 Kbyte. (Sie hätten auch `--default.key_buffer_size=256K` schreiben können.) Ferner erstellt der Server einen zweiten Schlüssel-Cache namens `extra_cache` mit einer Größe von 128 Kbyte. Bei diesem ist die Größe der Blockpuffer für die Zwischenspeicherung von Tabellenindexblöcken auf 2.048 Bytes gesetzt.

Das folgende Beispiel startet den Server mit drei verschiedenen Schlüssel-Caches, deren Größen das Verhältnis 3:1:1 aufweisen:

    shell> mysqld --key_buffer_size=6M \
             --hot_cache.key_buffer_size=2M \
             --cold_cache.key_buffer_size=2M

Strukturvariablen können auch zur Laufzeit eingestellt und abgefragt werden. Um beispielsweise einen Schlüssel-Cache namens `hot_cache` auf eine Größe von 10 Mbyte zu setzen, verwenden Sie eine der folgenden Anweisungen:

    mysql> SET GLOBAL hot_cache.key_buffer_size = 10*1024*1024;
    mysql> SET @@global.hot_cache.key_buffer_size = 10*1024*1024;

Um die Cache-Größe abzufragen, tun Sie Folgendes:

    mysql> SELECT @@global.hot_cache.key_buffer_size;

Die folgende Anweisung wird hingegen nicht funktionieren. Die Variable wird nicht als zusammengesetzter Name, sondern als einfacher String für einen `LIKE`-Mustervergleich aufgefasst:

    mysql> SHOW GLOBAL VARIABLES LIKE 'hot_cache.key_buffer_size';

Dies ist die oben erwähnte Ausnahme bei der Verwendung von Strukturvariablennamen in allen Kontexten, in denen einfache Variablennamen auftreten können.

#### 5.2.3.2. Dynamische Systemvariablen

Viele Serversystemvariablen sind dynamisch und lassen sich mit `SET GLOBAL` oder `SET SESSION` zur Laufzeit einstellen. Sie können ihre Werte auch mit `SELECT` abrufen. Siehe auch Abschnitt 5.2.3, „Verwendung von Server-Systemvariablen“.

Die folgende Tabelle zeigt eine vollständige Liste aller Systemvariablen. Dabei gibt die letzte Spalte für jede Variable an, ob `GLOBAL` oder `SESSION` (oder beide) gültig sind. Die Tabelle listet auch Sitzungsoptionen auf, die sich mit der `SET`-Anweisung einstellen lassen. Abschnitt 13.5.3, „`SET`“, beschreibt diese Optionen.

Variablen, die vom Typ „String“ sind, nehmen einen String-Wert entgegen. Variablen, die vom Typ „numerisch“ sind, nehmen einen Zahlenwert entgegen. Variablen vom Typ „boolesch“ können die Werte 0, 1, `ON` und `OFF` annehmen. (Wenn Sie sie über die Befehlszeile oder in einer Optionsdatei einstellen, verwenden Sie die numerischen Werte.) Variablen, die als „Aufzählung“ gekennzeichnet sind, sollten normalerweise einen der für die Variable verfügbaren Werte enthalten; solche Variablen können aber auch auf die Zahl gesetzt werden, die der Stelle des gewünschten Wertes in der Aufzählung entspricht. Bei Aufzählungssystemvariablen ist der erste Aufzählungswert 0. Hier liegt ein Unterschied zu `ENUM`-Spalten vor, bei denen der erste Aufzählungswert der 1 entspricht.

Variablenname | Werttyp | Typ
`autocommit` | boolesch | `SESSION`
`big_tables` | boolesch | `SESSION`
`binlog_cache_size` | numerisch | `GLOBAL`
`bulk_insert_buffer_size` | numerisch | `GLOBAL` | `SESSION`
`character_set_client` | String | `GLOBAL` | `SESSION`
`character_set_connection` | String | `GLOBAL` | `SESSION`
`character_set_results` | String | `GLOBAL` | `SESSION`
`character_set_server` | String | `GLOBAL` | `SESSION`
`collation_connection` | String | `GLOBAL` | `SESSION`
`collation_server` | String | `GLOBAL` | `SESSION`
`completion_type` | numerisch | `GLOBAL` | `SESSION`
`concurrent_insert` | boolesch | `GLOBAL`
`connect_timeout` | numerisch | `GLOBAL`
`convert_character_set` | String | `GLOBAL` | `SESSION`
`default_week_format` | numerisch | `GLOBAL` | `SESSION`
`delay_key_write` | `OFF` | `ON` | `ALL` | `GLOBAL`
`delayed_insert_limit` | numerisch | `GLOBAL`
`delayed_insert_timeout` | numerisch | `GLOBAL`
`delayed_queue_size` | numerisch | `GLOBAL`
`div_precision_increment` | numerisch | `GLOBAL` | `SESSION`
`engine_condition_pushdown` | boolesch | `GLOBAL` | `SESSION`
`error_count` | numerisch | `SESSION`
`event_scheduler` | boolesch | `GLOBAL`
`expire_logs_days` | numerisch | `GLOBAL`
`flush` | boolesch | `GLOBAL`
`flush_time` | numerisch | `GLOBAL`
`foreign_key_checks` | boolesch | `SESSION`
`ft_boolean_syntax` | numerisch | `GLOBAL`
`group_concat_max_len` | numerisch | `GLOBAL` | `SESSION`
`identity` | numerisch | `SESSION`
`innodb_autoextend_increment` | numerisch | `GLOBAL`
`innodb_commit_concurrency` | numerisch | `GLOBAL`
`innodb_concurrency_tickets` | numerisch | `GLOBAL`
`innodb_max_dirty_pages_pct` | numerisch | `GLOBAL`
`innodb_max_purge_lag` | numerisch | `GLOBAL`
`innodb_support_xa` | boolesch | `GLOBAL` | `SESSION`
`innodb_sync_spin_loops` | numerisch | `GLOBAL`
`innodb_table_locks` | boolesch | `GLOBAL` | `SESSION`
`innodb_thread_concurrency` | numerisch | `GLOBAL`
`innodb_thread_sleep_delay` | numerisch | `GLOBAL`
`insert_id` | boolesch | `SESSION`
`interactive_timeout` | numerisch | `GLOBAL` | `SESSION`
`join_buffer_size` | numerisch | `GLOBAL` | `SESSION`
`key_buffer_size` | numerisch | `GLOBAL`
`last_insert_id` | numerisch | `SESSION`
`local_infile` | boolesch | `GLOBAL`
`log_warnings` | numerisch | `GLOBAL`
`long_query_time` | numerisch | `GLOBAL` | `SESSION`
`low_priority_updates` | boolesch | `GLOBAL` | `SESSION`
`max_allowed_packet` | numerisch | `GLOBAL` | `SESSION`
`max_binlog_cache_size` | numerisch | `GLOBAL`
`max_binlog_size` | numerisch | `GLOBAL`
`max_connect_errors` | numerisch | `GLOBAL`
`max_connections` | numerisch | `GLOBAL`
`max_delayed_threads` | numerisch | `GLOBAL`
`max_error_count` | numerisch | `GLOBAL` | `SESSION`
`max_heap_table_size` | numerisch | `GLOBAL` | `SESSION`
`max_insert_delayed_threads` | numerisch | `GLOBAL`
`max_join_size` | numerisch | `GLOBAL` | `SESSION`
`max_relay_log_size` | numerisch | `GLOBAL`
`max_seeks_for_key` | numerisch | `GLOBAL` | `SESSION`
`max_sort_length` | numerisch | `GLOBAL` | `SESSION`
`max_tmp_tables` | numerisch | `GLOBAL` | `SESSION`
`max_user_connections` | numerisch | `GLOBAL`
`max_write_lock_count` | numerisch | `GLOBAL`
`myisam_stats_method` | Aufzählung | `GLOBAL` | `SESSION`
`multi_read_range` | numerisch | `GLOBAL` | `SESSION`
`myisam_data_pointer_size` | numerisch | `GLOBAL`
`log_bin_trust_function_creators` | boolesch | `GLOBAL`
`myisam_max_sort_file_size` | numerisch | `GLOBAL` | `SESSION`
`myisam_repair_threads` | numerisch | `GLOBAL` | `SESSION`
`myisam_sort_buffer_size` | numerisch | `GLOBAL` | `SESSION`
`myisam_use_mmap` | boolesch | `GLOBAL`
`ndb_extra_logging` | numerisch | `GLOBAL`
`net_buffer_length` | numerisch | `GLOBAL` | `SESSION`
`net_read_timeout` | numerisch | `GLOBAL` | `SESSION`
`net_retry_count` | numerisch | `GLOBAL` | `SESSION`
`net_write_timeout` | numerisch | `GLOBAL` | `SESSION`
`old_passwords` | numerisch | `GLOBAL` | `SESSION`
`optimizer_prune_level` | numerisch | `GLOBAL` | `SESSION`
`optimizer_search_depth` | numerisch | `GLOBAL` | `SESSION`
`preload_buffer_size` | numerisch | `GLOBAL` | `SESSION`
`query_alloc_block_size` | numerisch | `GLOBAL` | `SESSION`
`query_cache_limit` | numerisch | `GLOBAL`
`query_cache_size` | numerisch | `GLOBAL`
`query_cache_type` | Aufzählung | `GLOBAL` | `SESSION`
`query_cache_wlock_invalidate` | boolesch | `GLOBAL` | `SESSION`
`query_prealloc_size` | numerisch | `GLOBAL` | `SESSION`
`range_alloc_block_size` | numerisch | `GLOBAL` | `SESSION`
`read_buffer_size` | numerisch | `GLOBAL` | `SESSION`
`read_only` | numerisch | `GLOBAL`
`read_rnd_buffer_size` | numerisch | `GLOBAL` | `SESSION`
`rpl_recovery_rank` | numerisch | `GLOBAL`
`safe_show_database` | boolesch | `GLOBAL`
`secure_auth` | boolesch | `GLOBAL`
`server_id` | numerisch | `GLOBAL`
`slave_compressed_protocol` | boolesch | `GLOBAL`
`slave_net_timeout` | numerisch | `GLOBAL`
`slave_transaction_retries` | numerisch | `GLOBAL`
`slow_launch_time` | numerisch | `GLOBAL`
`sort_buffer_size` | numerisch | `GLOBAL` | `SESSION`
`sql_auto_is_null` | boolesch | `SESSION`
`sql_big_selects` | boolesch | `SESSION`
`sql_big_tables` | boolesch | `SESSION`
`sql_buffer_result` | boolesch | `SESSION`
`sql_log_bin` | boolesch | `SESSION`
`sql_log_off` | boolesch | `SESSION`
`sql_log_update` | boolesch | `SESSION`
`sql_low_priority_updates` | boolesch | `GLOBAL` | `SESSION`
`sql_max_join_size` | numerisch | `GLOBAL` | `SESSION`
`sql_mode` | Aufzählung | `GLOBAL` | `SESSION`
`sql_notes` | boolesch | `SESSION`
`sql_quote_show_create` | boolesch | `SESSION`
`sql_safe_updates` | boolesch | `SESSION`
`sql_select_limit` | numerisch | `SESSION`
`sql_slave_skip_counter` | numerisch | `GLOBAL`
`updatable_views_with_limit` | Aufzählung | `GLOBAL` | `SESSION`
`sql_warnings` | boolesch | `SESSION`
`sync_binlog` | numerisch | `GLOBAL`
`sync_frm` | boolesch | `GLOBAL`
`storage_engine` | Aufzählung | `GLOBAL` | `SESSION`
`table_definition_cache` | numerisch | `GLOBAL`
`table_open_cache` | numerisch | `GLOBAL`
`table_type` | Aufzählung | `GLOBAL` | `SESSION`
`thread_cache_size` | numerisch | `GLOBAL`
`time_zone` | String | `GLOBAL` | `SESSION`
`timestamp` | boolesch | `SESSION`
`tmp_table_size` | Aufzählung | `GLOBAL` | `SESSION`
`transaction_alloc_block_size` | numerisch | `GLOBAL` | `SESSION`
`transaction_prealloc_size` | numerisch | `GLOBAL` | `SESSION`
`tx_isolation` | Aufzählung | `GLOBAL` | `SESSION`
`unique_checks` | boolesch | `SESSION`
`wait_timeout` | numerisch | `GLOBAL` | `SESSION`
`warning_count` | numerisch | `SESSION`

### 5.2.4. Server-Statusvariablen

Der Server verwaltet eine Vielzahl von Statusvariablen, die Daten zu seinem Betrieb enthalten. Sie können sich diese Variablen und die zugehörigen Werte mit der Anweisung `SHOW STATUS` anzeigen lassen:

    mysql> SHOW STATUS;
    +-----------------------------------+------------+
    | Variable_name                     | Value      |
    +-----------------------------------+------------+
    | Aborted_clients                   | 0          |
    | Aborted_connects                  | 0          |
    | Bytes_received                    | 155372598  |
    | Bytes_sent                        | 1176560426 |
    ...
    | Connections                       | 30023      |
    | Created_tmp_disk_tables           | 0          |
    | Created_tmp_files                 | 3          |
    | Created_tmp_tables                | 2          |
    ...
    | Threads_created                   | 217        |
    | Threads_running                   | 88         |
    | Uptime                            | 1389872    |
    +-----------------------------------+------------+

Viele Statusvariablen werden durch die Anweisung `FLUSH STATUS` auf 0 zurückgesetzt.

Die Statusvariablen haben die nachfolgend beschriebenen Bedeutungen. Variablen ohne Versionsangabe waren bereits vor MySQL 5.1 vorhanden. Informationen zur Implementierungshistorie finden Sie im MySQL 5.0 Reference Manual.

- `Aborted_clients`

  Anzahl der Verbindungen, die abgebrochen wurden, weil der Client beendet wurde, ohne die Verbindung ordnungsgemäß zu schließen. Siehe auch Abschnitt A.2.10, „Kommunikationsfehler/abgebrochene Verbindung“.

- `Aborted_connects`

  Anzahl der fehlgeschlagenen Versuche, eine Verbindung mit dem MySQL-Server herzustellen. Siehe auch Abschnitt A.2.10, „Kommunikationsfehler/abgebrochene Verbindung“.

- `Binlog_cache_disk_use`

  Anzahl der Transaktionen, die den temporären Binärlog-Cache verwendeten, aber den Wert von `binlog_cache_size` überstiegen, weswegen eine Temporärdatei zur Speicherung von Anweisungen aus der Transaktion benutzt wurde.

- `Binlog_cache_use`

  Anzahl der Transaktionen, die den Binärlog-Cache verwendet haben.

- `Bytes_received`

  Anzahl der Bytes, die von allen Clients empfangen wurden.

- `Bytes_sent`

  Anzahl der Bytes, die an alle Clients gesendet wurden.

- `Com_`xxx``

  Die `Com_`xxx``-Variablen zum Zählen von Anweisungen geben die Häufigkeit an, mit der die Anweisung `xxx` ausgeführt wurde. Für jeden Anweisungstyp gibt es eine Statusvariable. So zählen etwa `Com_delete` und `Com_insert` die `DELETE`- bzw. `INSERT`-Anweisungen.

  Die folgenden `Com_stmt_`xxx``-Statusvariablen sind vorhanden:

  - `Com_stmt_prepare`

  - `Com_stmt_execute`

  - `Com_stmt_fetch`

  - `Com_stmt_send_long_data`

  - `Com_stmt_reset`

  - `Com_stmt_close`

  Diese Variablen stehen für vorbereitete Anweisungsbefehle. Ihre Namen beziehen sich auf den `COM_`xxx``-Befehlssatz, der in der Vermittlungsschicht zum Einsatz kommt. Mit anderen Worten erhöhen sich ihre Werte immer dann, wenn vorbereitete Anweisungs-API-Aufrufe wie mysql_stmt_prepare(), mysql_stmt_execute() usw. ausgeführt werden. Allerdings erhöhen sich `Com_stmt_prepare`, `Com_stmt_execute` und `Com_stmt_close` auch bei `PREPARE`, `EXECUTE` bzw. `DEALLOCATE PREPARE`. Ferner erhöhen sich die Werte der älteren (d. h. seit MySQL 4.1.3 vorhandenen) Anweisungszählvariablen `Com_prepare_sql`, `Com_execute_sql` und `Com_dealloc_sql` bei den Anweisungen `PREPARE`, `EXECUTE` und `DEALLOCATE PREPARE`. `Com_stmt_fetch` steht für die Gesamtanzahl der beim Holen von Cursorn abgesetzten Netzwerkrundreisen.

  Alle `Com_stmt_`xxx``-Variablen werden auch dann erhöht, wenn ein Argument einer vorbereiteten Anweisung unbekannt ist oder während der Ausführung ein Fehler aufgetreten ist. Mit anderen Worten entsprechen ihre Werte der Anzahl der abgesetzten (und nicht der erfolgreich verarbeiteten) Anfragen.

- `Compression`

  Gibt an, ob die Clientverbindung eine Komprimierung im Client/Server-Protokoll verwendet. Wurde in MySQL 5.1.2 hinzugefügt.

- `Connections`

  Anzahl der Versuche, eine Verbindung mit dem MySQL-Server herzustellen (unabhängig davon, ob diese erfolgreich waren oder nicht).

- `Created_tmp_disk_tables`

  Anzahl der vom Server bei der Ausführung von Anweisungen automatisch auf der Festplatte erstellten Temporärtabellen.

- `Created_tmp_files`

  Gibt an, wie viele Temporärdateien mysqld erstellt hat.

- `Created_tmp_tables`

  Anzahl der vom Server bei der Ausführung von Anweisungen automatisch im Speicher erstellten Temporärtabellen. Wenn `Created_tmp_disk_tables` einen hohen Wert hat, sollten Sie den Wert von `tmp_table_size` erhöhen, damit Temporärtabellen im Speicher statt auf Festplatte erstellt werden.

- `Delayed_errors`

  Anzahl der mit `INSERT DELAYED` geschriebenen Datensätze, bei denen ein Fehler aufgetreten ist (wahrscheinlich `duplicate key`).

- `Delayed_insert_threads`

  Anzahl der verzögerten `INSERT DELAYED`-Threads, die in Verwendung sind.

- `Delayed_writes`

  Anzahl der geschriebenen `INSERT DELAYED`-Datensätze.

- `Flush_commands`

  Anzahl der ausgeführten `FLUSH`-Anweisungen.

- `Handler_commit`

  Anzahl der internen `COMMIT`-Anweisungen.

- `Handler_discover`

  Der MySQL-Server kann bei der `NDB Cluster`-Speicher-Engine fragen, ob sie eine Tabelle mit einem gegebenen Namen kennt. Dies bezeichnet man als Entdeckung. `Handler_discover` gibt die Häufigkeit ein, mit der Tabellen mithilfe dieser Methode entdeckt wurden.

- `Handler_delete`

  Häufigkeit, mit der Datensätze aus Tabellen gelöscht wurden.

- `Handler_read_first`

  Häufigkeit, mit der der erste Eintrag aus einem Index gelesen wurde. Wenn dieser Wert hoch ist, kann man davon ausgehen, dass der Server eine große Zahl vollständiger Indexscans ausführt (z. B. für die Spalte `SELECT col1 FROM foo`, vorausgesetzt, `col1` ist indiziert).

- `Handler_read_key`

  Anzahl der Anforderungen zum Auslesen eines Datensatzes basierend auf einem Schlüssel. Wenn der Wert hoch ist, können Sie davon ausgehen, dass Ihre Tabellen passend für Ihre Abfragen indiziert sind.

- `Handler_read_next`

  Anzahl der Anforderungen zum Auslesen des nächsten Datensatzes in der Schlüsselreihenfolge. Dieser Wert wird hochgezählt, wenn Sie eine Indexspalte mit einer Bereichsbeschränkung abfragen oder einen Indexscan ausführen.

- `Handler_read_prev`

  Anzahl der Anforderungen zum Auslesen des vorherigen Datensatzes in der Schlüsselreihenfolge. Diese Lesemethode wird in erster Linie zur Optimierung von `ORDER BY ... DESC` verwendet.

- `Handler_read_rnd`

  Anzahl der Anforderungen zum Auslesen eines Datensatzes basierend auf einer festen Position. Dieser Wert ist hoch, wenn Sie viele Abfragen ausführen, die eine Sortierung des Ergebnisses erfordern. Sie setzen dann wahrscheinlich viele Abfragen ab, die für MySQL das Scannen ganzer Tabellen erforderlich machen, oder verwenden Joins, die die Schlüssel nicht optimal nutzen.

- `Handler_read_rnd_next`

  Anzahl der Anforderungen zum Auslesen des nächsten Datensatzes in der Datendatei. Dieser Wert ist hoch, wenn Sie viele Tabellenscans ausführen. Im Allgemeinen lässt dies darauf schließen, dass Ihre Tabellen nicht korrekt indiziert sind oder Ihre Abfragen nicht so geschrieben sind, dass sie die vorhandenen Indizes nutzen können.

- `Handler_rollback`

  Anzahl der internen `ROLLBACK`-Anweisungen.

- `Handler_update`

  Anzahl der Anforderungen zur Aktualisierung eines Datensatzes in einer Tabelle.

- `Handler_write`

  Anzahl der Anforderungen zum Einfügen eines Datensatzes in eine Tabelle.

- `Innodb_buffer_pool_pages_data`

  Anzahl der Seiten, die (schmutzige wie auch saubere) Daten enthalten.

- `Innodb_buffer_pool_pages_dirty`

  Anzahl der derzeit schmutzigen Seiten.

- `Innodb_buffer_pool_pages_flushed`

  Anzahl der Anforderungen nach einem Neuladen der Pufferpoolseiten.

- `Innodb_buffer_pool_pages_free`

  Anzahl der freien Seiten.

- `Innodb_buffer_pool_pages_latched`

  Anzahl der verriegelten Seiten im `InnoDB`-Pufferpool. Dies sind die Seiten, die derzeit gelesen oder geschrieben oder aus einem anderen Grund nicht auf Festplatte synchronisiert werden können.

- `Innodb_buffer_pool_pages_misc`

  Anzahl der Seiten, die in Verwendung sind, weil sie aufgrund administrativer Mehrbelastung (z. B. Datensatzsperren oder eines adaptiven Hash-Index) zugewiesen wurden. Dieser Wert kann auch als `Innodb_buffer_pool_pages_total` – `Innodb_buffer_pool_pages_free` – `Innodb_buffer_pool_pages_data` berechnet werden.

- `Innodb_buffer_pool_pages_total`

  Gesamtgröße des Pufferpools in Seiten.

- `Innodb_buffer_pool_read_ahead_rnd`

  Anzahl der vorab durchgeführten „zufälligen“ Leseoperationen, die durch `InnoDB` eingeleitet wurden. Dies geschieht, wenn eine Abfrage einen Großteil einer Tabelle in zufälliger Reihenfolge scannt.

- `Innodb_buffer_pool_read_ahead_seq`

  Anzahl der vorab durchgeführten sequenziellen Leseoperationen, die durch `InnoDB` eingeleitet wurden. Dies geschieht, wenn `InnoDB` einen vollständigen sequenziellen Tabellenscan durchführt.

- `Innodb_buffer_pool_read_requests`

  Anzahl der Anforderungen logischer Leseoperationen durch `InnoDB`.

- `Innodb_buffer_pool_reads`

  Anzahl der Anforderungen logischer Leseoperationen, die `InnoDB` nicht aus dem Pufferpool erfüllen konnte, weswegen eine Leseoperationen für eine einzelne Seite ausgeführt werden musste.

- `Innodb_buffer_pool_wait_free`

  Normalerweise erfolgen Schreiboperationen in den `InnoDB`-Pufferpool im Hintergrund. Wenn es allerdings notwendig ist, eine Seite zu lesen oder zu erstellen, und keine sauberen Seiten verfügbar sind, ist es auch erforderlich zu warten, bis die Seiten neu geschrieben wurden. Dieser Zähler enthält die Anzahl der Instanzen dieser Wartevorgänge. Wenn die Größe des Pufferpools korrekt eingestellt wurde, sollte dieser Wert niedrig sein.

- `Innodb_buffer_pool_write_requests`

  Anzahl der Schreiboperationen in den `InnoDB`-Pufferpool.

- `Innodb_data_fsyncs`

  Anzahl der bislang aufgetretenen `fsync()`-Operationen.

- `Innodb_data_pending_fsyncs`

  Aktuelle Anzahl anhängiger `fsync()`-Operationen.

- `Innodb_data_pending_reads`

  Aktuelle Anzahl anhängiger Leseoperationen.

- `Innodb_data_pending_writes`

  Aktuelle Anzahl anhängiger Schreiboperationen.

- `Innodb_data_read`

  Menge der bislang gelesenen Daten (in Byte).

- `Innodb_data_reads`

  Gesamtanzahl der Datenleseoperationen.

- `Innodb_data_writes`

  Gesamtanzahl der Datenschreiboperationen.

- `Innodb_data_written`

  Menge der bislang geschriebenen Daten (in Byte).

- `Innodb_dblwr_writes`, `Innodb_dblwr_pages_written`

  Anzahl der durchgeführten doppelten Schreiboperationen und Anzahl der Seiten, die zu diesem Zweck geschrieben wurden. Siehe auch Abschnitt 14.2.14.1, „Festplattenein- und -ausgaben“.

- `Innodb_log_waits`

  Häufigkeit, mit der der Logpuffer zu klein und ein Wartevorgang erforderlich war, bis der Vorgang nach dem Neuschreiben fortgesetzt werden konnte.

- `Innodb_log_write_requests`

  Anzahl der Logschreibeanforderungen.

- `Innodb_log_writes`

  Anzahl der physischen Schreiboperationen in die Logdatei.

- `Innodb_os_log_fsyncs`

  Anzahl der abgeschlossenen `fsync()`-Schreiboperationen in die Logdatei.

- `Innodb_os_log_pending_fsyncs`

  Anzahl der anhängigen `fsync()`-Operationen für die Logdatei.

- `Innodb_os_log_pending_writes`

  Anzahl der anhängigen Schreiboperationen für die Logdatei.

- `Innodb_os_log_written`

  Anzahl der in die Logdatei geschriebenen Bytes.

- `Innodb_page_size`

  Die einkompilierte `InnoDB`-Seitengröße (standardmäßig 16 Kbyte). Viele Werte werden in Seiten gezählt. Die Angabe der Seitengröße erlaubt eine einfache Konvertierung in Bytes.

- `Innodb_pages_created`

  Anzahl der erstellten Seiten.

- `Innodb_pages_read`

  Anzahl der gelesenen Seiten.

- `Innodb_pages_written`

  Anzahl der geschriebenen Seiten.

- `Innodb_row_lock_current_waits`

  Anzahl der Datensatzsperren, auf die derzeit gewartet wird.

- `Innodb_row_lock_time`

  Die mit dem Erwirken von Datensatzsperren verbrachte Zeit (in Millisekunden).

- `Innodb_row_lock_time_avg`

  Die durchschnittliche Zeit zum Erwirken einer Datensatzsperre (in Millisekunden).

- `Innodb_row_lock_time_max`

  Die maximale Zeit zum Erwirken einer Datensatzsperre (in Millisekunden).

- `Innodb_row_lock_waits`

  Häufigkeit, mit der auf eine Datensatzsperre gewartet werden musste.

- `Innodb_rows_deleted`

  Anzahl der Datensätze, die aus `InnoDB`-Tabellen gelöscht wurden.

- `Innodb_rows_inserted`

  Anzahl der Datensätze, die in `InnoDB`-Tabellen eingefügt wurden.

- `Innodb_rows_read`

  Anzahl der Datensätze, die aus `InnoDB`-Tabellen gelesen wurden.

- `Innodb_rows_updated`

  Anzahl der Datensätze, die in `InnoDB`-Tabellen aktualisiert wurden.

- `Key_blocks_not_flushed`

  Anzahl der Schlüsselblöcke im Schlüssel-Cache, die geändert, aber noch nicht neu auf Festplatte geschrieben wurden.

- `Key_blocks_unused`

  Anzahl der unbenutzten Blöcke im Schlüssel-Cache. Sie können anhand dieses Wertes bestimmen, wie groß der verwendete Anteil des Schlüssel-Caches ist. Lesen Sie auch die Beschreibung zu `key_buffer_size` in Abschnitt 5.2.2, „Server-Systemvariablen“.

- `Key_blocks_used`

  Anzahl der benutzten Blöcke im Schlüssel-Cache. Dieser Wert ist eine Art Hochwassermarke, die die maximale Anzahl von Blöcken angibt, die jemals gleichzeitig verwendet wurden.

- `Key_read_requests`

  Anzahl der Anforderungen zum Auslesen eines Schlüsselblocks aus dem Cache.

- `Key_reads`

  Die Anzahl physischer Lesezugriffe eines Schlüsselblocks von der Festplatte. Wenn der Wert von `Key_reads` hoch ist, dann ist Ihr Wert für `key_buffer_size` wahrscheinlich zu niedrig. Die Cache-Fehlrate kann berechnet werden als `Key_reads` ÷ `Key_read_requests`.

- `Key_write_requests`

  Die Anzahl der Anforderungen zum Schreiben eines Schlüsselblocks in den Cache.

- `Key_writes`

  Anzahl physischer Schreibvorgänge eines Schlüsselblocks auf die Festplatte.

- `Last_query_cost`

  Gesamtkosten der letzten kompilierten Abfrage nach Berechnung durch den Abfrageoptimierer. Dieser Wert ist praktisch, um die Kosten verschiedener Abfragepläne für dieselbe Abfrage zu vergleichen. Der Vorgabewert 0 bedeutet, dass noch keine Abfrage kompiliert wurde. `Last_query_cost` hat sitzungsbezogen Geltung.

- `Max_used_connections`

  Maximale Anzahl von Verbindungen, die seit dem Start des Servers gleichzeitig in Verwendung waren.

- `Not_flushed_delayed_rows`

  Anzahl der Datensätze, die darauf warten, in `INSERT DELAY`-Warteschlangen geschrieben zu werden.

- `Open_files`

  Anzahl der offenen Dateien.

- `Open_streams`

  Anzahl der offenen Streams (hauptsächlich zum Loggen verwendet).

- `Open_tables`

  Anzahl der offenen Tabellen.

- `Opened_tables`

  Anzahl der Tabellen, die geöffnet wurden. Wenn der Wert von `Opened_tables` hoch ist, dann ist Ihr Wert für `table_open_cache` wahrscheinlich zu niedrig.

- `Qcache_free_blocks`

  Anzahl freier Speicherblöcke im Abfrage-Cache.

- `Qcache_free_memory`

  Menge des freien Speichers für den Abfrage-Cache.

- `Qcache_hits`

  Anzahl der Treffer im Abfrage-Cache.

- `Qcache_inserts`

  Anzahl der Abfragen, die zum Abfrage-Cache hinzugefügt wurden.

- `Qcache_lowmem_prunes`

  Anzahl der Abfragen, die wegen Speichermangels aus dem Abfrage-Cache gelöscht wurden.

- `Qcache_not_cached`

  Anzahl der nicht im Cache abgelegten Abfragen (weil diese entweder nicht speicherbar waren oder aufgrund der `query_cache_type`-Einstellung nicht abgelegt wurden).

- `Qcache_queries_in_cache`

  Anzahl der im Abfrage-Cache registrierten Abfragen.

- `Qcache_total_blocks`

  Gesamtzahl von Blöcken im Abfrage-Cache.

- `Questions`

  Anzahl der Anweisungen, die Clients an den Server gesendet haben.

- `Rpl_status`

  Status der ausfallsicheren Replikation (noch nicht implementiert).

- `Select_full_join`

  Anzahl der Joins, die Tabellenscans durchführen, weil sie keine Indizes verwenden. Wenn der Wert nicht 0 ist, sollten Sie die Indizes Ihrer Tabellen sorgfältig prüfen.

- `Select_full_range_join`

  Anzahl der Joins, die eine Bereichssuche in einer Referenztabelle verwendet haben.

- `Select_range`

  Anzahl der Joins, die Bereiche in der ersten Tabelle verwendet haben. Dies ist normalerweise auch dann kein kritisches Problem, wenn der Wert zu groß ist.

- `Select_range_check`

  Anzahl der Joins ohne Schlüssel, die nach jedem Datensatz auf Schlüsselverwendung prüfen. Wenn der Wert nicht 0 ist, sollten Sie die Indizes Ihrer Tabellen sorgfältig prüfen.

- `Select_scan`

  Anzahl der Joins, die einen vollständigen Scan der ersten Tabelle durchgeführt haben.

- `Slave_open_temp_tables`

  Anzahl der Temporärtabellen, die der Slave-SQL-Thread derzeit geöffnet hält.

- `Slave_running`

  Ist `ON`, wenn dieser Server ein Slave ist, der mit einem Master verbunden ist.

- `Slave_retried_transactions`

  Gesamthäufigkeit seit dem Serverstart, mit der der Replikations-Slave-SQL-Thread Transaktionen erneut versucht hat.

- `Slow_launch_threads`

  Anzahl der Threads, deren Erzeugung länger als die durch `slow_launch_time` angegebene Anzahl von Sekunden dauerte.

- `Slow_queries`

  Anzahl der Abfragen, die länger als die durch `long_query_time` angegebene Anzahl von Sekunden dauerten. Siehe auch Abschnitt 5.12.4, „Die Logdatei für langsame Anfragen“.

- `Sort_merge_passes`

  Anzahl der Merge-Durchgänge, die der Sortieralgorithmus durchführen musste. Wenn dieser Wert hoch ist, sollten Sie unter Umständen den Wert der Systemvariable `sort_buffer_size` erhöhen.

- `Sort_range`

  Anzahl der Sortiervorgänge, die mit Bereichen durchgeführt wurden.

- `Sort_rows`

  Anzahl der sortierten Datensätze.

- `Sort_scan`

  Anzahl der Sortiervorgänge, die durchgeführt wurden, indem die Tabelle gescannt wurde.

- `Ssl_`xxx``

  Für SSL-Verbindungen verwendete Variablen.

- `Table_locks_immediate`

  Häufigkeit, mit der eine Tabellensperre sofort erwirkt werden konnte.

- `Table_locks_waited`

  Häufigkeit, mit der eine Tabellensperre nicht sofort erwirkt werden konnte und ein Wartevorgang erforderlich wurde. Wenn dieser Wert hoch und die Leistung problematisch niedrig ist, sollten Sie zunächst Ihre Abfragen optimieren und dann Ihre Tabelle(n) entweder unterteilen oder die Replikation verwenden.

- `Threads_cached`

  Anzahl der Threads im Thread-Cache.

- `Threads_connected`

  Anzahl der momentan offenen Verbindungen.

- `Threads_created`

  Anzahl der Threads, die zur Verwaltung von Verbindungen erstellt wurden. Wenn der Wert von `Threads_created` hoch ist, sollten Sie den Wert von `thread_cache_size` erhöhen. Die Cache-Trefferrate kann berechnet werden als `Threads_created` ÷ `Connections`.

- `Threads_running`

  Anzahl nicht schlafender Threads.

- `Uptime`

  Dauer seit dem Serverstart (in Sekunden).

### 5.2.5. Der SQL-Modus des Servers

Der MySQL-Server kann in verschiedenen SQL-Modi betrieben werden und diese Modi auf unterschiedliche Weise für verschiedene Clients anwenden. Diese Funktionalität erlaubt es jeder Anwendung, den Betriebsmodus des Servers an die eigenen Anforderungen anzupassen.

Modi definieren, welche SQL-Syntax MySQL unterstützen soll und welche Art von Gültigkeitsprüfungen in Bezug auf die Daten durchgeführt werden sollen. Dies erleichtert die Verwendung von MySQL in verschiedenen Umgebungen und in Verbindung mit anderen Datenbankservern.

Sie stellen den SQL-Standardmodus ein, indem Sie mysqld mit der Option `--sql-mode="`modes`"` starten. `modes` ist hierbei eine Liste verschiedener Modi, die durch Kommata (‘`,`’) voneinander getrennt sind. Der Standardwert ist leer (d. h. es sind keine Modi ausgewählt). Der Wert `modes` kann ebenfalls als leer angegeben werden (`--sql-mode=""`), wenn Sie ihn explizit löschen wollen.

Sie können den SQL-Modus zur Laufzeit mithilfe der Anweisung `SET [GLOBAL|SESSION] sql_mode='`modes`'` zur Einstellung des Systemwertes `sql_mode` ändern. Die Einstellung der `GLOBAL`-Variable erfordert die Berechtigung `SUPER` und wirkt sich auf den Betrieb aller Clients aus, die nachfolgend eine Verbindung herstellen. Von der Änderung der `SESSION`-Variable ist nur der aktuelle Client betroffen. Jeder Client kann jederzeit seinen eigenen `sql_mode`-Sitzungswert ändern.

Sie können den globalen oder sitzungsspezifischen `sql_mode`-Wert mit den folgenden Anweisungen ändern:

    SELECT @@global.sql_mode;
    SELECT @@session.sql_mode;

Die wahrscheinlich wichtigsten `sql_mode`-Werte sind die folgenden:

- `ANSI`

  Ändert Syntax und Verhalten so, dass eine höhere Kompatibilität mit Standard-SQL erzielt wird.

- `STRICT_TRANS_TABLES`

  Wenn ein Wert nicht wie eingegeben in eine transaktionssichere Tabelle eingefügt werden konnte, wird die Anweisung abgebrochen. Bei nicht transaktionssicheren Tabellen wird die Anweisung abgebrochen, wenn der Wert in einer Anweisung für genau einen Datensatz oder im ersten Datensatz einer Anweisung für mehrere Datensätze erscheint. Weitere Informationen erhalten Sie im Verlauf dieses Abschnitts.

- `TRADITIONAL`

  Hierbei verhält sich MySQL wie ein „traditionelles“ SQL-Datenbanksystem. Eine einfache Beschreibung dieses Modus wäre: „Gib eine Fehlermeldung anstelle einer Warnung aus, wenn ein falscher Wert in eine Spalte eingefügt wird“. Hinweis: Die Anweisung `INSERT`/`UPDATE` wird abgebrochen, sobald der Fehler bemerkt wird. Wenn Sie eine nicht transaktionssichere Speicher-Engine verwenden, ist dies ein unter Umständen unerwünschtes Verhalten, weil Datenänderungen, die vor dem Fehler ausgeführt wurden, nicht rückgängig gemacht werden, was zu einer „unvollständigen“ Aktualisierung führt.

Wenn in diesem Handbuch vom „strikten Modus“ die Rede ist, bezeichnet dies einen Modus, in dem zumindest `STRICT_TRANS_TABLES` oder `STRICT_ALL_TABLES` aktiviert ist.

Die folgende Liste beschreibt alle unterstützten Modi:

- `ALLOW_INVALID_DATES`

  Führt keine vollständige Datumsüberprüfung durch. Geprüft wird nur, ob die Monatsangabe zwischen 1 und 12 und die Tagesangabe zwischen 1 und 31 liegt. Dies ist sehr praktisch für Webanwendungen, bei denen man die Jahres-, Monats- und Tagesangabe drei verschiedenen Feldern entnimmt und diese Angaben dann genau so gespeichert werden sollen, wie der Benutzer sie eingegeben hat (d. h. ohne Plausibilitätsprüfung). Dieser Modus betrifft `DATE`- und `DATETIME`-Spalten. Für `TIMESTAMP`-Spalten gilt er hingegen nicht, da diese immer ein gültiges Datum erfordern.

  Für den Server ist es erforderlich, dass Monats- und Tagesangaben gültig sind und sich nicht einfach nur in den Bereichen 1 bis 12 bzw. 1 bis 31 bewegen. Wenn der strikte Modus deaktiviert ist, werden ungültige Daten wie `'2004-04-31'` in `'0000-00-00'` umgewandelt, und es wird eine Warnung erzeugt. Ist der strikte Modus hingegen aktiviert, dann erzeugen ungültige Datumsangaben einen Fehler. Um derartige Daten zuzulassen, aktivieren Sie `ALLOW_INVALID_DATES`.

- `ANSI_QUOTES`

  Hierbei wird ‘`"`’ als Anführungszeichen für Bezeichner (wie ‘```’) und nicht als String-Anführungszeichen behandelt. Auch wenn dieser Modus aktiviert ist, können Sie ‘```’ als Anführungszeichen für Bezeichner verwenden. Ist `ANSI_QUOTES` aktiviert, dann dürfen Sie doppelte Anführungszeichen für einen literalen String verwenden, da dieser andernfalls als Bezeichner erkannt würde.

- `ERROR_FOR_DIVISION_BY_ZERO`

  Erzeugt im strikten Modus einen Fehler (sonst eine Warnung), wenn bei `INSERT`- oder `UPDATE`-Anweisungen eine Division durch Null (oder `MOD(X,0)`) auftritt. Wenn dieser Modus nicht aktiviert ist, gibt MySQL stattdessen `NULL` als Ergebnis einer Division durch Null zurück. Bei `INSERT IGNORE` oder `UPDATE IGNORE` erzeugt MySQL eine Warnung bezüglich einer Division durch Null, das Ergebnis des Vorgangs ist aber `NULL`.

- `HIGH_NOT_PRECEDENCE`

  Die Vorrangstellung des Operators `NOT` besteht darin, dass Ausdrücke wie `NOT a BETWEEN b AND c` als `NOT (a BETWEEN b AND c)` verarbeitet werden. Bei einigen älteren Versionen von MySQL wurde der Ausdruck hingegen als `(NOT a) BETWEEN b AND c` aufgefasst. Dieses ältere Vorrangsverhalten kann verwendet werden, indem man den SQL-Modus `HIGH_NOT_PRECEDENCE` aktiviert.

      mysql> SET sql_mode = '';
      mysql> SELECT NOT 1 BETWEEN -5 AND 5;
              -> 0
      mysql> SET sql_mode = 'broken_not';
      mysql> SELECT NOT 1 BETWEEN -5 AND 5;
              -> 1

- `IGNORE_SPACE`

  Gestattet Leerzeichen zwischen einem Funktionsnamen und dem Zeichen ‘`(`’. Hierdurch wird die Behandlung aller Funktionsnamen als reservierte Wörter erzwungen. Dies wiederum bedingt, dass Sie Datenbank-, Tabellen- oder Spaltennamen, die Sie verwenden wollen, als referenzierte Wörter in Anführungszeichen setzen müssen. Weil es beispielsweise eine Funktion `USER()` gibt, sind die Namen der Tabelle `user` in der `mysql`-Datenbank und der Spalte `User` in dieser Tabelle reservierte Wörter, müssen also in Anführungszeichen gesetzt werden:

      SELECT "User" FROM mysql."user";

  Der SQL-Modus `IGNORE_SPACE` gilt für integrierte Funktionen, nicht aber für gespeicherte Routinen. Nach einem Routinennamen müssen unabhängig davon, ob `IGNORE_SPACE` aktiviert ist oder nicht, immer Leerzeichen stehen dürfen.

- `NO_AUTO_CREATE_USER`

  Verhindert, dass `GRANT` automatisch neue Benutzer erstellt, sofern es dies tun würde (es sei denn, es wird ein nicht leeres Passwort angegeben).

- `NO_AUTO_VALUE_ON_ZERO`

  `NO_AUTO_VALUE_ON_ZERO` wirkt sich auf die Verarbeitung von `AUTO_INCREMENT`-Spalten aus. Normalerweise erzeugen Sie die nächste Sequenznummer für die Spalte, indem Sie entweder `NULL` oder `0` einfügen. `NO_AUTO_VALUE_ON_ZERO` unterdrückt dieses Verhalten für `0`, sodass nur `NULL` die nächste Sequenznummer erzeugt.

  Dieser Modus kann nützlich sein, wenn `0` in einer `AUTO_INCREMENT`-Spalte einer Tabelle gespeichert wurde. (Nebenbei gesagt: Das Speichern von `0` ist keine empfehlenswerte Vorgehensweise.) Wenn Sie beispielsweise die Tabelle mit mysqldump speichern und sie dann neu laden, erzeugt MySQL normalerweise neue Sequenznummern, sobald die `0`-Werte gefunden werden; das Ergebnis ist also eine Tabelle, deren Inhalt sich von dem ursprünglich gespeicherten unterscheidet. Die Aktivierung von `NO_AUTO_VALUE_ON_ZERO` vor dem Neuladen der Speicherauszugsdatei löst dieses Problem. mysqldump schließt nun automatisch eine Anweisung in seine Ausgabe mit ein, die `NO_AUTO_VALUE_ON_ZERO` aktiviert, um das Problem zu vermeiden.

- `NO_BACKSLASH_ESCAPES`

  Deaktiviert die Verwendung des Backslashs (‘`\`’) als Escape-Zeichen innerhalb von Strings. Wenn dieser Modus aktiviert ist, wird der Backslash zu einem ganz gewöhnlichen Zeichen.

- `NO_DIR_IN_CREATE`

  Wenn Sie eine Tabelle erstellen, werden in diesem Modus alle `INDEX DIRECTORY`- und `DATA DIRECTORY`-Direktiven ignoriert. Diese Option ist praktisch bei Slave-Replikationsservern.

- `NO_ENGINE_SUBSTITUTION`

  Verhindert die automatische Ersetzung der vorgabeseitigen Speicher-Engine, wenn eine Anweisung wie `CREATE TABLE` eine Speicher-Engine angibt, die deaktiviert oder nicht einkompiliert ist.

- `NO_FIELD_OPTIONS`

  Sorgt dafür, dass MySQL-spezifische Spaltenoptionen in der Ausgabe von `SHOW CREATE TABLE` nicht angegeben werden. Dieser Modus wird von mysqldump im Portabilitätsmodus verwendet.

- `NO_KEY_OPTIONS`

  Sorgt dafür, dass MySQL-spezifische Indexoptionen in der Ausgabe von `SHOW CREATE TABLE` nicht angegeben werden. Dieser Modus wird von mysqldump im Portabilitätsmodus verwendet.

- `NO_TABLE_OPTIONS`

  Sorgt dafür, dass MySQL-spezifische Tabellenoptionen (wie `ENGINE`) in der Ausgabe von `SHOW CREATE TABLE` nicht angegeben werden. Dieser Modus wird von mysqldump im Portabilitätsmodus verwendet.

- `NO_UNSIGNED_SUBTRACTION`

  Bei Subtraktionsoperationen wird das Ergebnis nicht als `UNSIGNED` gekennzeichnet, wenn einer der Operanden ohne Vorzeichen ist. Beachten Sie, dass hiermit `BIGINT UNSIGNED` nicht mehr in allen Kontexten hundertprozentig einsetzbar ist. Siehe auch Abschnitt 12.8, „Cast-Funktionen und Operatoren“.

- `NO_ZERO_DATE`

  Im strikten Modus wird `'0000-00-00'` nicht als gültiges Datum zugelassen. Mit der Option `IGNORE` können Sie trotzdem Nulldatumsangaben einfügen. Außerhalb des strikten Modus wird das Datum zwar akzeptiert, aber es wird eine Warnung erzeugt.

- `NO_ZERO_IN_DATE`

  Im strikten Modus werden Daten nicht akzeptiert, wenn die Monats- oder Tagesangabe 0 ist. Wenn der Modus mit der Option `IGNORE` verwendet wird, fügt MySQL das Datum `'0000-00-00'` für derartige Datumsangaben ein. Außerhalb des strikten Modus wird das Datum zwar akzeptiert, aber es wird eine Warnung erzeugt.

- `ONLY_FULL_GROUP_BY`

  Erlaubt keine Abfragen, bei denen die `GROUP BY`-Klausel auf eine Spalte verweist, die in der Ausgabespaltenliste nicht vorhanden ist.

- `PIPES_AS_CONCAT`

  Behandelt `||` als Operator zur String-Verkettung (also identisch mit `CONCAT()`) statt als Synonym von `OR`.

- `REAL_AS_FLOAT`

  Behandelt `REAL` als Synonym von `FLOAT`. Standardmäßig behandelt MySQL `REAL` als Synonym von `DOUBLE`.

- `STRICT_ALL_TABLES`

  Aktiviert den strikten Modus für alle Speicher-Engines. Ungültige Datenwerte werden abgewiesen. Zusätzliche Informationen folgen.

- `STRICT_TRANS_TABLES`

  Aktiviert den strikten Modus für transaktionssichere Speicher-Engines sowie – sofern möglich – für nicht transaktionssichere Speicher-Engines. Zusätzliche Informationen folgen.

Der strikte Modus steuert, wie MySQL Eingabewerte behandelt, die ungültig sind oder fehlen. Ein Wert kann aus mehreren Gründen ungültig sein. So kann er den falschen Datentyp für die Spalte aufweisen oder außerhalb des zulässigen Bereichs liegen. Ein Wert fehlt, wenn ein neuer Datensatz, der eingefügt werden soll, keinen Wert für eine Spalte enthält, für die keine explizite `DEFAULT`-Klausel definiert ist.

Bei transaktionssicheren Tabellen tritt bei ungültigen oder fehlenden Werten in einer Anweisung ein Fehler auf, wenn einer der Modi `STRICT_ALL_TABLES` oder `STRICT_TRANS_TABLES` aktiviert ist. Die Anweisung wird abgebrochen, und es erfolgt ein Rollback.

Bei nicht transaktionssicheren Tabellen ist das Verhalten in beiden Modi gleich, wenn der betreffende Wert im ersten einzufügenden oder zu aktualisierenden Datensatz auftritt. Die Anweisung wird abgebrochen, und die Tabelle bleibt unverändert. Wenn die Anweisung mehrere Datensätze einfügt oder ändert und der unpassende Wert im zweiten oder einem nachfolgenden Datensatz auftritt, dann hängt das Ergebnis davon ab, welche Option aktiviert ist:

- Bei `STRICT_ALL_TABLES` gibt MySQL einen Fehler zurück und ignoriert die verbleibenden Datensätze. Allerdings bleiben die zuvor durch Einfügung oder Aktualisierung an Datensätzen vorgenommenen Änderung erhalten. Das bedeutet, dass unter Umständen eine Teilaktualisierung erfolgt, was vielleicht nicht wünschenswert ist. Um dies zu vermeiden, sollten Sie am besten Anweisungen nur für jeweils einen Datensatz verwenden, da diese abgebrochen werden können, ohne die Tabelle zu verändern.

- Bei `STRICT_TRANS_TABLES` wandelt MySQL einen ungültigen Wert in den nächstgelegenen für die Spalte gültigen Wert um und fügt diesen umgewandelten Wert dann ein. Fehlt ein Wert, dann fügt MySQL den impliziten Vorgabewert für den Spaltendatentyp ein. In beiden Fällen erzeugt MySQL zudem eine Warnung (statt eines Fehlers) und fährt dann mit der Verarbeitung der Anweisung fort. Implizite Vorgabewerte sind in Abschnitt 11.1.4, „Vorgabewerte von Datentypen“, beschrieben.

Der strikte Modus untersagt ungültige Datumswerte wie `'2004-04-31'`. Nicht verboten sind hingegen Datumsangaben mit Nullbestandteilen wie etwa `'2004-04-00'` oder „Nulldaten“. Um auch diese zu unterbinden, aktivieren Sie die SQL-Modi `NO_ZERO_IN_DATE` und `NO_ZERO_DATE` zusätzlich zum strikten Modus.

Wenn Sie den strikten Modus nicht verwenden (d. h. weder `STRICT_TRANS_TABLES` noch `STRICT_ALL_TABLES` sind aktiviert), dann fügt MySQL korrigierte Werte für ungültige oder fehlende Angaben ein und erzeugt Warnungen. Im strikten Modus können Sie dieses Verhalten erzeugen, indem Sie `INSERT IGNORE` bzw. `UPDATE IGNORE` verwenden. Siehe auch Abschnitt 13.5.4.25, „`SHOW WARNINGS`“.

Die folgenden Spezialmodi sind als Abkürzungen für Kombinationen von Moduswerten aus obiger Liste aufzufassen.

Die Beschreibungen enthalten alle Moduswerte, die in der aktuellen MySQL-Version vorhanden sind. Bei älteren Versionen enthalten die Kombinationsmodi keine einzelnen Moduswerte, die erst in neueren Versionen verfügbar sind.

- `ANSI`

  Entspricht `REAL_AS_FLOAT`, `PIPES_AS_CONCAT`, `ANSI_QUOTES`, `IGNORE_SPACE`. Siehe auch Abschnitt 1.9.3, „MySQL im ANSI-Modus laufen lassen“.

- `DB2`

  Entspricht `PIPES_AS_CONCAT`, `ANSI_QUOTES`, `IGNORE_SPACE`, `NO_KEY_OPTIONS`, `NO_TABLE_OPTIONS`, `NO_FIELD_OPTIONS`.

- `MAXDB`

  Entspricht `PIPES_AS_CONCAT`, `ANSI_QUOTES`, `IGNORE_SPACE`, `NO_KEY_OPTIONS`, `NO_TABLE_OPTIONS`, `NO_FIELD_OPTIONS`, `NO_AUTO_CREATE_USER`.

- `MSSQL`

  Entspricht `PIPES_AS_CONCAT`, `ANSI_QUOTES`, `IGNORE_SPACE`, `NO_KEY_OPTIONS`, `NO_TABLE_OPTIONS`, `NO_FIELD_OPTIONS`.

- `MYSQL323`

  Entspricht `NO_FIELD_OPTIONS`, `HIGH_NOT_PRECEDENCE`.

- `MYSQL40`

  Entspricht `NO_FIELD_OPTIONS`, `HIGH_NOT_PRECEDENCE`.

- `ORACLE`

  Entspricht `PIPES_AS_CONCAT`, `ANSI_QUOTES`, `IGNORE_SPACE`, `NO_KEY_OPTIONS`, `NO_TABLE_OPTIONS`, `NO_FIELD_OPTIONS`, `NO_AUTO_CREATE_USER`.

- `POSTGRESQL`

  Entspricht `PIPES_AS_CONCAT`, `ANSI_QUOTES`, `IGNORE_SPACE`, `NO_KEY_OPTIONS`, `NO_TABLE_OPTIONS`, `NO_FIELD_OPTIONS`.

- `TRADITIONAL`

  Entspricht `STRICT_TRANS_TABLES`, `STRICT_ALL_TABLES`, `NO_ZERO_IN_DATE`, `NO_ZERO_DATE`, `ERROR_FOR_DIVISION_BY_ZERO`, `NO_AUTO_CREATE_USER`.

### 5.2.6. Herunterfahren des MySQL Servers

Beim Herunterfahren des Servers laufen die folgenden Vorgänge ab:

1. Das Herunterfahren wird eingeleitet.

   Das Herunterfahren des Servers kann auf mehreren Wegen veranlasst werden. So kann etwa ein Benutzer mit der Berechtigung `SHUTDOWN` den Befehl mysqladmin shutdown ausführen. mysqladmin kann auf jeder von MySQL unterstützen Plattform benutzt werden. Auch andere betriebssystemspezifische Methoden sind möglich, um das Herunterfahren einzuleiten: Unter Unix wird der Server heruntergefahren, wenn er ein `SIGTERM`-Signal empfängt. Unter Windows wird ein Server, der als Dienst ausgeführt wird, beendet, wenn der Dienste-Manager ihn dazu anweist.

2. Bei Bedarf erstellt der Server einen Abschaltungs-Thread.

   Je nachdem, wie das Herunterfahren eingeleitet wurde, erstellt der Server unter Umständen einen Thread, um den Abschaltvorgang zu verwalten. Wurde das Herunterfahren von einem Client angefordert, dann wird ein Abschaltungs-Thread erstellt. Ist das Herunterfahren Folge eines empfangenen `SIGTERM`-Signals, dann erledigt der Signal-Thread die Abschaltung entweder selbst oder erstellt zu diesem Zweck einen separaten Thread. Versucht der Server vergeblich einen Abschaltungs-Thread zu erstellen (etwa weil nicht genügend Speicher zur Verfügung steht), dann gibt er eine Diagnosemeldung aus, die im Fehlerlog erscheint:

       Error: Can't create thread to kill server

3. Der Server nimmt keine neuen Verbindungen mehr an.

   Um die Initialisierung neuer Aktivitäten während des Herunterfahrens zu vermeiden, beendet der Server die Annahme neuer Clientverbindungen. Er tut dies, indem er die Netzwerkverbindungen schließt, auf denen er normalerweise auf Verbindungen horcht: den TCP/IP-Port, die Unix-Socketdatei und die Named Pipe und den gemeinsamen Speicher unter Windows.

4. Der Server beendet alle aktuellen Aktivitäten.

   Für jeden Thread, der mit einer Clientverbindung verknüpft ist, wird die Verbindung zum Client abgebrochen, und der Thread wird als terminiert gekennzeichnet. Wenn ein Thread diese Kennzeichnung erkennt, beendet er sich. Threads leer laufender Verbindungen beenden sich sehr schnell. Threads hingegen, die zum betreffenden Zeitpunkt Anweisungen verarbeiten, überprüfen ihren Status regelmäßig und benötigen insofern länger, um sich zu beenden. Weitere Informationen zur Thread-Terminierung finden Sie in Abschnitt 13.5.5.3, „`KILL`“. Beachten Sie dort insbesondere die Erläuterungen zu terminierten `REPAIR TABLE`- und `OPTIMIZE TABLE`-Operationen an `MyISAM`-Tabellen.

   Wenn bei Threads eine Transaktion offen ist, wird diese via Rollback rückgängig gemacht. Beachten Sie, dass, wenn ein Thread eine nicht transaktionssichere Tabelle aktualisiert, Anweisungen für mehrere Datensätze wie `UPDATE` oder `INSERT` eine teilaktualisierte Tabelle entstehen lassen können, weil der Vorgang vor seinem Abschluss terminiert werden kann.

   Wenn der Server ein Master-Replikationsserver ist, werden Threads, die derzeit angeschlossenen Slaves zugeordnet sind, wie andere Client-Threads behandelt. Das bedeutet, dass jeder dieser Threads als terminiert gekennzeichnet wird und sich beendet, sobald er zum nächsten Mal seinen Status überprüft.

   Ist der Server ein Slave-Replikationsserver, dann werden die E/A- und SQL-Threads – sofern aktiv – beendet, bevor Client-Threads als terminiert gekennzeichnet werden. Der SQL-Thread darf seine aktuelle Anweisung abschließen, um Replikationsprobleme zu vermeiden, und wird dann beendet. Befand sich der SQL-Thread zu diesem Zeitpunkt mitten in einer Transaktion, dann wird diese Transaktion rückgängig gemacht.

5. Speicher-Engines werden heruntergefahren oder geschlossen.

   An dieser Stelle wird der Tabellen-Cache auf die Festplatte geschrieben, und alle offenen Tabellen werden geschlossen.

   Alle Speicher-Engines führen ggf. Vorgänge aus, die für die jeweils verwalteten Tabellen erforderlich sind. So synchronisiert `MyISAM` beispielsweise alle anhängigen Indexschreiboperationen für eine Tabelle. `InnoDB` schreibt seinen Pufferpool auf die Festplatte (sofern `innodb_fast_shutdown` nicht 2 ist), speichert die aktuelle LSN in den Tablespace und beendet seine eigenen internen Threads.

6. Der Server wird beendet.

## 5.3. mysqld-max, ein erweiterter mysqld-Server

Ein MySQL-Max-Server ist eine Version des MySQL-Servers mysqld, in die zusätzliche Funktionen integriert sind. Welche MySQL-Max-Distribution verwendet werden kann, hängt von Ihrer Plattform ab:

- Unter Windows enthalten MySQL-Binärdistributionen sowohl den Standardserver (`mysqld.exe`) als auch den MySQL-Max-Server (mysqld-max.exe), d. h. es ist keine gesonderte Distribution erforderlich; Sie verwenden einfach eine normale Windows-Distribution. Siehe auch Abschnitt 2.3, „Installation von MySQL unter Windows“.

- Wenn Sie MySQL unter Linux mithilfe von RPM-Distributionen installieren, setzt das `MySQL-Max`-RPM voraus, dass Sie das reguläre Server-RPM bereits installiert haben. Sie installieren also zunächst mithilfe des `MySQL-server`-RPM einen Standardserver namens mysqld und nachfolgend mit dem `MySQL-Max`-RPM einen Server namens mysqld-max. Weitere Informationen zu Linux-RPM-Paketen finden Sie in Abschnitt 2.4, „MySQL unter Linux installieren“.

- Alle anderen MySQL-Max-Distributionen enthalten einen einzelnen Server namens mysqld, der jedoch die Zusatzfunktionen enthält.

Sie finden die MySQL-Max-Binärdateien auf der MySQL AB-Website unter http://dev.mysql.com/downloads/.

MySQL AB erstellt MySQL-Max-Server unter Verwendung der folgenden configure-Optionen:

- `--with-server-suffix=-max`

  Diese Option fügt dem Versions-String mysqld das Suffix `-max` hinzu.

- `--with-innodb`

  Diese Option aktiviert die Unterstützung für die `InnoDB`-Speicher-Engine. MySQL-Max-Server enthalten die `InnoDB`-Unterstützung generell. Seit MySQL 4.0 ist `InnoDB` standardmäßig in allen Binärdistributionen enthalten, d. h. Sie benötigen zur `InnoDB`-Unterstützung keinen MySQL-Max-Server.

- `--with-bdb`

  Diese Option aktiviert die Unterstützung der `BDB`-Speicher-Engine (Berkeley DB) auf denjenigen Plattformen, für die `BDB` verfügbar ist. (Beachten Sie die nachfolgenden Hinweise.)

- `--with-blackhole-storage-engine`

  Diese Option aktiviert die Unterstützung für die `BLACKHOLE`-Speicher-Engine.

- `--with-csv-storage-engine`

  Diese Option aktiviert die Unterstützung für die `CSV`-Speicher-Engine.

- `--with-example-storage-engine`

  Diese Option aktiviert die Unterstützung für die `EXAMPLE`-Speicher-Engine.

- `--with-federated-storage-engine`

  Diese Option aktiviert die Unterstützung für die `FEDERATED`-Speicher-Engine.

- `--with-ndbcluster`

  Diese Option aktiviert die Unterstützung der `NDB Cluster`-Speicher-Engine auf denjenigen Plattformen, für die Cluster verfügbar sind. (Beachten Sie die nachfolgenden Hinweise.)

- `USE_SYMDIR`

  Diese Definition wird aktiviert, um die Unterstützung symbolischer Datenbankverknüpfungen unter Windows zu aktivieren. Seit MySQL 4.0 ist die Unterstützung symbolischer Verknüpfungen für alle Windows-Server aktiviert, d. h. Sie benötigen hierfür keinen MySQL-Max-Server.

MySQL-Max-Binärdistributionen sind praktisch für Benutzer, die vorkompilierte Programme installieren wollen. Wenn Sie MySQL unter Verwendung einer Quelldistribution erstellen, können Sie Ihren eigenen Max-Server erstellen, indem Sie zum Zeitpunkt der Konfiguration genau diejenigen Funktionen aktivieren, mit denen die MySQL-Max-Binärdistributionen erstellt werden.

Sofern möglich, enthalten MySQL-Max-Server die `BDB`-Speicher-Engine; diese wird jedoch nicht von allen Plattformen unterstützt.

Zurzeit werden MySQL-Cluster nur von Linux (auf den meisten Plattformen), Solaris und Mac OS X unterstützt. Einige Benutzer haben berichtet, dass sie einen aus einer Quelldistribution erstellten MySQL-Cluster erfolgreich unter BSD-Betriebssystemen zum Laufen bekommen haben; hierfür gibt es aber derzeit keinen offiziellen Support. Beachten Sie, dass auch dann, wenn die Server mit Cluster-Unterstützung kompiliert werden, die `NDB Cluster`-Speicher-Engine standardmäßig nicht aktiviert wird. Sie müssen den Server mit der Option `--ndbcluster` starten, um ihn als Teil eines MySQL-Clusters verwenden zu können. (Detaillierte Informationen finden Sie in Abschnitt 16.4, „MySQL Cluster: Konfiguration“.)

Die folgende Tabelle listet die Plattformen auf, deren MySQL-Max-Binärdateien Unterstützung für `BDB` und NDB-Cluster enthalten.

System | BDB-Unterstützung | NDB-Unterstützung
AIX 4.3 | Nein | Nein
HP-UX 11.0 | Nein | Nein
Linux-Alpha | Nein | Ja
Linux-IA-64 | Nein | Nein
Linux-Intel | Ja | Ja
Mac OS X | Nein | Ja
NetWare | Nein | Nein
SCO OSR5 | Ja | Nein
Solaris-SPARC | Ja | Ja
Solaris-Intel | Nein | Ja
UnixWare | Ja | Nein
Windows NT/2000/XP | Ja | Nein

Um herauszufinden, welche Speicher-Engines Ihr Server unterstützt, verwenden Sie die `SHOW ENGINES`-Anweisung. (Siehe auch Abschnitt 13.5.4.9, „`SHOW ENGINES`“.) Zum Beispiel:

    mysql> SHOW ENGINES\G
    *************************** 1. row ***************************
          Engine: MEMORY
         Support: YES
         Comment: Hash based, stored in memory, useful for temporary tables
    Transactions: NO
              XA: NO
      Savepoints: NO
    *************************** 2. row ***************************
          Engine: CSV
         Support: YES
         Comment: CSV storage engine
    Transactions: NO
              XA: NO
      Savepoints: NO
    *************************** 3. row ***************************
          Engine: MRG_MYISAM
         Support: YES
         Comment: Collection of identical MyISAM tables
    Transactions: NO
              XA: NO
      Savepoints: NO
    *************************** 4. row ***************************
          Engine: MyISAM
         Support: DEFAULT
         Comment: Default engine as of MySQL 3.23 with great performance
    Transactions: NO
              XA: NO
      Savepoints: NO
    ...

Die exakte Ausgabe von `SHOW ENGINES` kann je nach verwendeter MySQL-Version (und aktivierten Funktionen) variieren. Die `Support`-Werte in der Ausgabe geben den Umfang der Unterstützung für die jeweilige Funktion entsprechend nachfolgender Tabelle an:

Wert | Bedeutung
`YES` | Diese Funktion wird unterstützt und ist aktiv.
`NO` | Die Funktion wird nicht unterstützt.
`DISABLED` | Die Funktion wird unterstützt, wurde aber deaktiviert.

Der Wert `NO` bedeutet, dass der Server ohne Unterstützung für die Funktion kompiliert wurde; sie kann also zur Laufzeit nicht aktiviert werden.

Der Wert `DISABLED` tritt entweder auf, weil der Server mit einer Option gestartet wurde, die die Funktion deaktiviert, oder weil nicht alle Optionen angegeben wurden, die für die Aktivierung der Funktion erforderlich sind. Im zweiten Fall sollte im Fehlerlog ein Eintrag vorhanden sein, der angibt, warum die Option deaktiviert ist. Siehe auch Abschnitt 5.12.1, „Die Fehler-Logdatei“.

`DISABLED` wird unter Umständen auch für eine Speicher-Engine angezeigt, wenn der Server zwar mit Unterstützung für diese Engine kompiliert, aber mit der Option `--skip-`engine`` gestartet wurde. So deaktiviert beispielsweise `--skip-innodb` die `InnoDB`-Engine. Bei der `NDB Cluster`-Speicher-Engine bedeutet `DISABLED`, dass der Server mit Unterstützung für MySQL-Cluster kompiliert, aber nicht mit der Option `--ndb-cluster` gestartet wurde.

Alle MySQL-Server unterstützen `MyISAM`-Tabellen, weil `MyISAM` die vorgabeseitige Speicher-Engine ist.

## 5.4. Startprogramme für den MySQL-Server

Dieser Abschnitt beschreibt verschiedene Programme, die zum Starten des MySQL-Servers mysqld verwendet werden.

### 5.4.1. mysqld_safe — Startskript für den MySQL-Server

mysqld_safe ist die empfohlene Methode zum Starten eines mysqld-Servers unter Unix und NetWare. mysqld_safe fügt einige Sicherheitsfunktionen hin zu, so etwa das Neustarten des Servers bei Auftreten eines Fehlers und das Loggen von Laufzeitinformationen in eine Fehlerlogdatei. Das NetWare-spezifische Verhalten wird im weiteren Verlauf dieses Abschnitts beschrieben.

Hinweis: Um die Abwärtskompatibilität mit älteren Versionen von MySQL aufrechtzuerhalten, enthalten MySQL-Binärdistributionen auch weiterhin safe_mysqld als symbolische Verknüpfung mit mysqld_safe. Allerdings sollten Sie sich nicht fest darauf verlassen, da dieses Feature mit an Sicherheit grenzender Wahrscheinlichkeit in Zukunft entfernt werden wird.

Standardmäßig versucht mysqld_safe eine ausführbare Datei namens mysqld-max zu starten, sofern diese vorhanden ist; andernfalls wird mysqld gestartet. Beachten Sie die Auswirkungen dieses Verhaltens:

- Unter Linux ist das `MySQL-Max`-RPM auf dieses Verhalten von mysqld_safe angewiesen. Das RPM installiert eine ausführbare Datei namens mysqld-max; aufgrund dessen verwendet mysqld_safe ab sofort automatisch diese Datei anstelle von mysqld.

- Wenn Sie eine MySQL-Max-Distribution installieren, die einen Server namens mysqld-max enthält, und nachfolgend auf eine Nicht-Max-Version von MySQL aktualisieren wollen, dann beachten Sie, dass mysqld_safe nach wie vor versuchen wird, den alten Server mysqld-max auszuführen. Führen Sie ein solches Upgrade durch, dann sollten Sie den alten mysqld-max-Server manuell entfernen, um sicherzustellen, dass mysqld_safe den neuen Server mysqld ausführt.

Um dieses Standardverhalten außer Kraft zu setzen und den Namen des auszuführenden Servers explizit anzugeben, müssen Sie eine der Optionen `--mysqld` oder `--mysqld-version` für mysqld_safe angeben. Sie können auch `--ledir` verwenden, um das Verzeichnis anzugeben, in dem mysqld_safe nach dem Server suchen soll.

Viele der Optionen für mysqld_safe sind identisch mit den Optionen für mysqld. Siehe auch Abschnitt 5.2.1, „Befehlsoptionen für mysqld“.

Alle für mysqld_safe auf der Befehlszeile angegebenen Optionen werden an mysqld übergeben. Wenn Sie Optionen verwenden wollen, die für mysqld_safe spezifisch sind und von mysqld nicht unterstützt werden, dann geben Sie sie nicht über die Befehlszeile an. Stattdessen sollten Sie sie im Abschnitt `[mysqld_safe]` einer Optionsdatei auflisten. Siehe auch Abschnitt 4.3.2, „my.cnf-Optionsdateien“.

mysqld_safe liest alle Optionen aus den Abschnitten `[mysqld]`, `[server]` und `[mysqld_safe]` in Optionsdateien aus. Aus Gründen der Abwärtskompatibilität werden auch `[safe_mysqld]`-Abschnitte ausgelesen, aber Sie sollten diese Abschnitte bei MySQL 5.1-Installationen in `[mysqld_safe]` umbenennen.

mysqld_safe unterstützt die folgenden Optionen:

- `--help`

  Zeigt eine Hilfsmeldung an und wird dann beendet.

- `--autoclose`

  (Nur NetWare.) mysqld_safe stellt unter NetWare eine Bildschirmpräsenz bereit. Wenn Sie das NLM mysqld_safe entladen (herunterfahren), verschwindet der Bildschirm standardmäßig nicht. Stattdessen wird eine Benutzereingabe angefordert:

      *<NLM has terminated; Press any key to close the screen>*

  Wenn Sie hingegen wollen, dass NetWare den Bildschirm automatisch schließt, dann verwenden Sie die Option `--autoclose` für mysqld_safe.

- `--basedir=`path``

  Der Pfad zum MySQL-Installationsverzeichnis.

- `--core-file-size=`size``

  Größe der Speicherauszugsdatei, die mysqld erstellen können soll. Der Optionswert wird an ulimit -c übergeben.

- `--datadir=`path``

  Der Pfad zum Datenverzeichnis.

- `--defaults-extra-file=`path``

  Der Name einer Optionsdatei, die zusätzlich zu den normalen Optionsdateien ausgelesen wird. Wenn diese Option verwendet wird, muss Sie auf der Befehlszeile die erste angegebene Option sein.

- `--defaults-file=`file_name``

  Der Name einer Optionsdatei, die anstelle der normalen Optionsdateien ausgelesen wird. Wenn diese Option verwendet wird, muss Sie auf der Befehlszeile die erste angegebene Option sein.

- `--ledir=`path``

  Wenn mysqld_safe den Server nicht finden kann, können Sie diese Option verwenden, um einen Pfadnamen zu dem Verzeichnis anzugeben, in dem sich der Server befindet.

- `--log-error=`file_name``

  Schreibt das Fehlerlog in die angegebene Datei. Siehe auch Abschnitt 5.12.1, „Die Fehler-Logdatei“.

- `--mysqld=`prog_name``

  Name des Serverprogramms (im Verzeichnis `ledir`), das Sie starten wollen. Diese Option ist erforderlich, wenn Sie die MySQL-Binärdistribution verwenden, aber das Datenverzeichnis sich außerhalb der Binärdistribution befindet. Wenn mysqld_safe den Server nicht finden kann, können Sie die Option `--ledir` verwenden, um einen Pfadnamen zu dem Verzeichnis anzugeben, in dem sich der Server befindet.

- `--mysqld-version=`suffix``

  Diese Option ähnelt `--mysqld`, Sie geben aber nur das Suffix für den Serverprogrammnamen an. Als Basisname wird mysqld vorausgesetzt. Wenn Sie beispielsweise `--mysqld-version=max` verwenden, startet mysqld_safe das Programm mysqld-max im Verzeichnis `ledir`. Wenn das Argument für `--mysqld-version` leer ist, verwendet mysqld_safe mysqld im Verzeichnis `ledir`.

- `--nice=`priority``

  Stellt die Zeitplanungspriorität mit dem Programm `nice` auf den angegebenen Wert.

- `--no-defaults`

  Optionsdateien werden nicht auslesen. Wenn diese Option verwendet wird, muss Sie auf der Befehlszeile die erste angegebene Option sein.

- `--open-files-limit=`count``

  Anzahl der Dateien, die mysqld öffnen können sollte. Der Optionswert wird an ulimit -n übergeben. Beachten Sie, dass Sie mysqld_safe als `root` starten müssen, damit dies einwandfrei funktioniert!

- `--pid-file=`file_name``

  Der Pfadname der Prozesskennungsdatei.

- `--port=`port_num``

  Portnummer, die der Server beim Horchen auf TCP/IP-Verbindungen verwenden soll. Die Portnummer muss 1.024 oder höher sein, sofern der Server nicht vom Systembenutzer `root` gestartet wird.

- `--socket=`path``

  Unix-Socketdatei, die der Server bei Horchen auf lokale Verbindungen verwenden soll.

- `--timezone=`timezone``

  Weist der Zeitzonen-Umgebungsvariablen `TZ` den angegebenen Optionswert zu. Informationen zu zulässigen Formaten für Zeitzonenangaben finden Sie in der Dokumentation zu Ihrem Betriebssystem.

- `--user={`user_name` | `user_id`}`

  Führt den Server mysqld als Benutzer mit dem spezifizierten Benutzernamen (`user_name`) oder der numerischen Benutzerkennung (`user_id`) aus. („Benutzer“ bezeichnet in diesem Kontext ein Systemanmeldekonto und keinen in den Grant-Tabellen aufgeführten MySQL-Benutzer.)

Wenn Sie mysqld_safe mit den Optionen `--defaults-file` oder `--defaults-extra-option` ausführen, um eine Optionsdatei zu benennen, dann muss diese Option als erste auf der Befehlszeile angegeben werden, da die Optionsdatei andernfalls nicht benutzt wird. So wird die Optionsdatei etwa bei folgendem Befehl nicht verarbeitet:

    mysql> mysqld_safe --port=port_num --defaults-file=file_name

Verwenden Sie stattdessen den folgenden Befehl:

    mysql> mysqld_safe --defaults-file=file_name --port=port_num

Das Skript mysqld_safe ist so abgefasst, dass es normalerweise einen Server starten kann, der aus einer Quell- oder eine Binärdistribution von MySQL installiert wurde, auch wenn diese Distributionstypen den Server normalerweise an etwas anderen Positionen installieren. (Siehe auch Abschnitt 2.1.5, „Installationslayouts“.) mysqld_safe setzt voraus, dass eine der folgenden Bedingungen erfüllt ist:

- Server und Datenbanken befinden sich relativ zum Arbeitsverzeichnis (d. h. zu dem Verzeichnis, aus dem heraus mysqld_safe aufgerufen wurde). Bei Binärdistributionen sucht mysqld_safe in seinem Arbeitsverzeichnis nach den Verzeichnissen `bin` und `data`. Bei Quelldistributionen hingegen wird nach den Verzeichnissen `libexec` und `var` gesucht. Diese Bedingung sollte erfüllt sein, wenn Sie mysqld_safe aus Ihrem MySQL-Installationsverzeichnis heraus aufrufen (z. B. `/usr/local/mysql` bei einer Binärdistribution).

- Wenn der Server und die Datenbanken relativ zum Arbeitsverzeichnis nicht vorgefunden werden, versucht mysqld_safe sie anhand absoluter Pfadnamen zu ermitteln. Typische Positionen sind `/usr/local/libexec` und `/usr/local/var`. Die tatsächlichen Verzeichnisse werden den Werten entnommen, die bei der Erstellung in die Distribution einkonfiguriert wurden. Sie sollten korrekt sein, wenn MySQL im während der Konfiguration angegebenen Verzeichnis installiert ist.

Da mysqld_safe den Server und die Datenbanken relativ zum eigenen Arbeitsverzeichnis zu finden versucht, können Sie eine MySQL-Binärdistribution an beliebiger Stelle installieren, solange Sie mysqld_safe aus dem MySQL-Installationsverzeichnis heraus aufrufen:

    shell> cd mysql_installation_directory
    shell> bin/mysqld_safe &

Wenn mysqld_safe fehlschlägt, obwohl es aus dem MySQL-Installationsverzeichnis heraus aufgerufen wurde, können Sie die Optionen `--ledir` und `--datadir` angeben, um die Verzeichnisse anzuzeigen, in denen der Server und die Datenbanken auf Ihrem System vorhanden sind.

Normalerweise sollten Sie das Skript mysqld_safe nicht bearbeiten. Konfigurieren Sie stattdessen mysqld_safe über Befehlszeilenoptionen oder Optionen im Abschnitt `[mysqld_safe]` einer Optionsdatei `my.cnf`. In seltenen Fällen kann es unter Umständen erforderlich sein, mysqld_safe zu modifizieren, damit der Server korrekt startet. Beachten Sie allerdings, dass Ihre geänderte Version von mysqld_safe bei einem zukünftigen MySQL-Upgrade überschrieben werden könnte; deswegen sollten Sie eine Kopie der editierten Version erstellen, die Sie bei Bedarf neu installieren können.

Unter NetWare ist mysqld_safe ein NLM, das aus dem ursprünglichen Unix-Shell-Skript portiert wurde. Es startet den Server wie folgt:

1. Eine Reihe von System- und Optionstest wird ausgeführt.

2. Die `MyISAM`-Tabellen werden überprüft.

3. Es wird eine Bildschirmpräsenz für den MySQL-Server bereitgestellt.

4. mysqld wird gestartet und überwacht. Wird es mit einem Fehler beendet, so erfolgt ein Neustart.

5. Fehlermeldungen von mysqld werden in die Datei ``host_name`.err` im Datenverzeichnis geschrieben.

6. Bildschirmausgaben von mysqld_safe werden in die Datei ``host_name`.safe` im Datenverzeichnis geschrieben.

### 5.4.2. mysql.server — Startskript für den MySQL-Server

MySQL-Distributionen unter Unix enthalten ein Skript namens mysql.server. Dieses kann auf Systemen wie Linux oder Solaris verwendet werden, die Ausführungsverzeichnisse im System V-Stil verwenden. Ferner wird es vom Mac OS X-Startobjekt für MySQL benutzt.

Sie finden mysql.server im Verzeichnis `support-files`, das sich im MySQL-Installationsverzeichnis befindet, oder in einer MySQL-Quelldistribution.

Wenn Sie das Linux-Server-RPM-Paket (`MySQL-server-`VERSION`.rpm`) einsetzen, wird das Skript mysql.server im Verzeichnis `/etc/init.d` unter dem Namen `mysql` installiert. Sie müssen die Installation also nicht manuell vornehmen. Weitere Informationen zu Linux-RPM-Paketen finden Sie in Abschnitt 2.4, „MySQL unter Linux installieren“.

Manche Anbieter stellen RPM-Pakete bereit, die ein Startskript unter einem anderen Namen wie etwa mysqld installieren.

Wenn Sie MySQL aus einer Quelldistribution installieren oder ein Binärdistributionsformat verwenden, das mysql.server nicht automatisch installiert, können Sie es manuell installieren. Eine Anleitung finden Sie in Abschnitt 2.9.2.2, „MySQL automatisch starten und anhalten“.

mysql.server liest Optionen aus den Abschnitten `[mysql.server]` und `[mysqld]` der Optionsdateien aus. Aus Gründen der Abwärtskompatibilität werden auch `[mysql_server]`-Abschnitte ausgelesen, aber Sie sollten diese Abschnitte bei MySQL 5.1-Installationen in `[mysql.server]` umbenennen.

### 5.4.3. mysqld_multi — Verwalten mehrerer MySQL-Server

mysqld_multi wurde entwickelt, um mehrere mysqld-Prozesse zu verwalten, die auf Verbindungen über verschiedene Unix-Socketdateien oder TCP/IP-Ports horchen. Das Skript kann Server starten und beenden und den aktuellen Status melden. Eine Alternative zur Verwaltung mehrerer Server ist der MySQL Instance Manager (siehe auch Abschnitt 5.5, „mysqlmanager — Der MySQL Instance Manager“).

mysqld_multi sucht nach Abschnitten namens `[mysqld`N`]` in `my.cnf` (bzw. in der Datei, die mit der Option `--config-file` angegeben wurde). `N` kann eine beliebige positive Ganzzahl sein. Diese Zahl wird in der folgenden Abhandlung als Abschnittsnummer bzw. als `GNR` (vom Englischen „Group Number“) bezeichnet. Abschnittsnummern trennen Abschnitte in Optionsdateien voneinander und werden als Argumente für mysqld_multi verwendet. Sie geben an, welche Server Sie starten oder beenden bzw. zu welchen Servern Sie einen Statusbericht anfordern wollen. Die Optionen, die in diesen Abschnitten aufgelistet sind, sind identisch mit denen, die Sie im Abschnitt `[mysqld]` angeben würden, der zum Starten von mysqld verwendet wird. (Siehe z. B. Abschnitt 2.9.2.2, „MySQL automatisch starten und anhalten“.) Wenn Sie allerdings mehrere Server verwenden, ist es erforderlich, dass jeder dieser Server seinen eigenen Optionswert (z. B. die Unix-Socketdatei oder die TCP/IP-Portnummer) verwendet. Weitere Informationen dazu, welche Optionen in einer Multiserverumgebung für jeden Server eindeutig sein müssen, finden Sie in Abschnitt 5.13, „Mehrere MySQL-Server auf derselben Maschine laufen lassen“.

Um mysqld_multi aufzurufen, verwenden Sie folgende Syntax:

    shell> mysqld_multi [options] {start|stop|report} [GNR[,GNR] ...]

`start`, `stop` und `report` geben die jeweilig durchzuführende Operation an. Sie können die angegebene Operation für einen oder mehrere Server abhängig davon durchführen lassen, welche `GNR`-Liste auf die Option folgt. Ist keine Liste vorhanden, dann führt mysqld_multi den Vorgang für alle Server in der Optionsdatei aus.

Jeder `GNR`-Wert stellt eine Abschnittsnummer bzw. einen Abschnittsnummernbereich für Optionsdateien dar. Der Wert sollte die Zahl am Ende des Abschnittsnamens in der Optionsdatei sein. So lautet die `GNR` für einen Abschnitt namens `[mysqld17]` etwa `17`. Um einen Zahlenbereich anzugeben, trennen Sie die erste und die letzte Zahl durch einen Bindestrich. Der `GNR`-Wert `10-13` bezeichnet also die Abschnitte `[mysqld10]` bis `[mysqld13]`. Mehrere Abschnitte oder Abschnittsbereiche lassen sich – getrennt durch Kommata – auf der Befehlszeile angeben. Es dürfen keine Whitespace-Zeichen (d. h. Leerzeichen oder Tabulatoren) in der `GNR`-Liste erscheinen, da alle auf ein solches Zeichen folgenden Angaben ignoriert werden.

Der folgende Befehl startet einen einzelnen Server unter Verwendung des Optionsabschnitts `[mysqld17]`:

    shell> mysqld_multi start 17

Der folgende Befehl beendet mehrere Server unter Verwendung der Abschnittsgruppen `[mysqld8]` sowie `[mysqld10]` bis `[mysqld13]`:

    shell> mysqld_multi stop 8,10-13

Ein Beispiel, wie man eine Optionsdatei konfigurieren kann, bietet der folgende Befehl:

    shell> mysqld_multi --example

mysqld_multi unterstützt die folgenden Optionen:

- `--help`

  Zeigt eine Hilfsmeldung an und wird dann beendet.

- `--config-file=`name``

  Gibt den Namen einer alternativen Optionsdatei an. Die Option bestimmt, wo mysqld_multi nach `[mysqld`N`]`-Optionsabschnitten sucht. Ohne Angabe dieser Option werden alle Optionen aus der normalen Optionsdatei `my.cnf` ausgelesen. Die Option beeinflusst nicht, wo mysqld_multi seine eigenen Optionen ausliest (diese werden immer dem Abschnitt `[mysqld_multi]` in der normalen Datei `my.cnf` entnommen).

- `--example`

  Zeigt eine Beispieloptionsdatei an.

- `--log=`file_name``

  Gibt den Namen der Logdatei an. Wenn die Datei vorhanden ist, werden geloggte Einträge angehängt.

- `--mysqladmin=`prog_name``

  Gibt die mysqladmin-Binärdatei an, die zum Beenden von Servern verwendet wird.

- `--mysqld=`prog_name``

  Die zu verwendende mysqld-Binärdatei. Beachten Sie, dass Sie auch mysqld_safe als Wert angeben können. Wenn Sie den Server mit mysqld_safe starten, können Sie die Optionen `mysqld` oder `ledir` im entsprechenden Abschnitt `[mysqld`N`]` angeben. Diese Optionen bezeichnen den Namen des Servers, den mysqld_safe starten soll, und den Pfadnamen des Verzeichnisses, in dem der Server sich befindet. (Beschreibungen zu diesen Optionen finden Sie in Abschnitt 5.4.1, „mysqld_safe — Startskript für den MySQL-Server“.) Beispiel:

      [mysqld38]
      mysqld = mysqld-max
      ledir  = /opt/local/mysql/libexec

- `--no-log`

  Schreibt Loginformationen in `stdout` statt in die Logdatei. (Standardmäßig erfolgt die Ausgabe in die Logdatei.)

- `--password=`password``

  Passwort des MySQL-Kontos, das für den Aufruf von mysqladmin verwendet wird. Beachten Sie, dass der Passwortwert – anders als bei anderen MySQL-Programmen – bei dieser Option nicht optional ist.

- `--silent`

  Stummer Modus (Warnungen werden deaktiviert).

- `--tcp-ip`

  Alle betreffenden MySQL-Server werden statt über die Unix-Socketdatei über den TCP/IP-Port angebunden. (Wenn eine Socketdatei fehlt, kann der Server zwar unter Umständen noch laufen, ist aber nur über den TCP/IP-Port erreichbar.) Standardmäßig werden Verbindungen unter Verwendung der Unix-Socketdatei hergestellt. Diese Option wirkt sich auf alle `stop`- und `report`Operationen aus.

- `--user=`user_name``

  Benutzername des MySQL-Kontos, das für den Aufruf von mysqladmin verwendet wird.

- `--verbose`

  Zeigt mehr Informationen an.

- `--version`

  Zeigt die Versionsinformation an und wird dann beendet.

Einige Anmerkungen zu mysqld_multi:

- Extrem wichtig: Bevor Sie mysqld_multi verwenden, müssen Sie die Bedeutung der Optionen, die an die mysqld-Server übergeben werden, verstanden haben und genau wissen, warum Sie separate mysqld-Prozesse benutzen wollen. Die Verwendung mehrerer mysqld-Server mit demselben Datenverzeichnis ist extrem gefährlich. Sofern Sie nicht genauestens wissen, was Sie tun, verwenden Sie in jedem Fall getrennte Datenverzeichnisse. Das Starten mehrerer Server mit demselben Datenverzeichnis steigert die Leistungsfähigkeit eines Thread-basierten Systems nicht! Siehe auch Abschnitt 5.13, „Mehrere MySQL-Server auf derselben Maschine laufen lassen“.

- Wichtig: Vergewissern Sie sich, dass das Datenverzeichnis jedes Servers für das Unix-Konto, unter dem der jeweilige mysqld-Prozess gestartet wurde, uneingeschränkt zugänglich ist. Verwenden Sie hierfür keinesfalls das Unix-Konto `root`, sofern Sie nicht genauestens wissen, was Sie tun. Siehe auch Abschnitt 5.7.5, „Wie man MySQL als normaler Benutzer laufen läßt“.

- Vergewissern Sie sich, dass das MySQL-Konto, welches zum Beenden der mysqld-Server (mit dem Programm mysqladmin) verwendet wird, für jeden Server den gleichen Benutzernamen und das gleiche Passwort hat. Außerdem müssen Sie sicherstellen, dass das Konto über die Berechtigung `SHUTDOWN` verfügt. Wenn die Server, die Sie verwalten wollen, unterschiedliche Benutzernamen oder Passwörter für die Administrationskonten aufweisen, sollten Sie auf jedem Server ein Konto mit jeweils demselben Benutzernamen und Passwort einrichten. Sie könnten etwa ein gemeinsames Konto `multi_admin` erstellen, indem Sie auf jedem Server die folgenden Befehle ausführen:

      shell> mysql -u root -S /tmp/mysql.sock -p
      Enter password:
      mysql> GRANT SHUTDOWN ON *.*
          -> TO 'multi_admin'@'localhost' IDENTIFIED BY 'multipass';

  Siehe auch Abschnitt 5.8.2, „Wie das Berechtigungssystem funktioniert“. Sie müssen diesen Schritt für jeden mysqld-Server durchführen. Ändern Sie die Verbindungsparameter entsprechend, wenn Sie mit den einzelnen Servern Verbindungen herstellen. Beachten Sie, dass der Hostnamensteil des Kontonamens die Herstellung einer Verbindung als `multi_admin` von dem Host aus ermöglichen muss, auf dem sie mysqld_multi ausführen wollen.

- Die Unix-Socketdatei und die TCP/IP-Portnummer müssen für jeden mysqld-Server unterschiedlich sein.

- Die Option `--pid-file` ist sehr wichtig, wenn Sie mysqld_safe zum Starten von mysqld verwenden (z. B. `--mysqld=mysqld_safe`). Jeder mysqld-Server sollte seine eigene Prozesskennungsdatei haben. Der Vorteil der Verwendung von mysqld_safe anstelle von mysqld besteht darin, dass mysqld_safe seinen mysqld-Prozess überwacht und ihn neu startet, wenn der Prozess aufgrund eines Signals, welches mit `kill -9` gesendet wurde, oder aus einem anderen Grund (z. B. wegen eines Segmentierungsfehlers) terminiert wurde. Bitte beachten Sie, dass das Skript mysqld_safe unter Umständen erfordert, dass Sie es von einer bestimmten Position aus starten. Das bedeutet, dass Sie möglicherweise in ein bestimmtes Verzeichnis wechseln müssen, bevor Sie mysqld_multi ausführen. Wenn Sie Probleme mit dem Starten haben, rufen Sie das Skript mysqld_safe zur Anzeige auf. Suchen Sie dort die folgenden Zeilen:

      ----------------------------------------------------------------
      MY_PWD=`pwd`
      # Check if we are starting this relative (for the binary release)
      if test -d $MY_PWD/data/mysql -a -f ./share/mysql/english/errmsg.sys -a \
       -x ./bin/mysqld
      ----------------------------------------------------------------

  Der mit diesen Zeilen durchgeführte Test sollte erfolgreich sein, andernfalls könnten Probleme auftreten. Siehe auch Abschnitt 5.4.1, „mysqld_safe — Startskript für den MySQL-Server“.

- Sie sollten die Option `--user` für mysqld verwenden. Zu diesem Zweck müssen Sie das Skript mysqld_multi jedoch als Unix-Benutzer `root` ausführen. Das Einfügen der Option in die Optionsdatei ist irrelevant: Wenn Sie nicht der Superuser sind und die mysqld-Prozesse unter Ihrem eigenen Unix-Konto gestartet werden, erhalten Sie lediglich eine Warnung.

Das folgende Beispiel zeigt, wie Sie eine Optionsdatei zur Verwendung mit mysqld_multi einrichten könnten. Die Reihenfolge, in der die mysqld-Programme gestartet oder beendet werden, hängt von der Reihenfolge ab, in der sie in der Optionsdatei aufgeführt sind. Abschnittsnummern müssen keine durchgehende Folge bilden. Der erste und der fünfte `[mysqld`N`]`-Abschnitt wurden im Beispiel absichtlich weggelassen, um zu veranschaulichen, dass es „Lücken“ in der Optionsdatei geben darf. Dies erhöht die Flexibilität.

    # This file should probably be in your home dir (~/.my.cnf)
    # or /etc/my.cnf
    # Version 2.1 by Jani Tolonen

    [mysqld_multi]
    mysqld     = /usr/local/bin/mysqld_safe
    mysqladmin = /usr/local/bin/mysqladmin
    user       = multi_admin
    password   = multipass

    [mysqld2]
    socket     = /tmp/mysql.sock2
    port       = 3307
    pid-file   = /usr/local/mysql/var2/hostname.pid2
    datadir    = /usr/local/mysql/var2
    language   = /usr/local/share/mysql/english
    user       = john

    [mysqld3]
    socket     = /tmp/mysql.sock3
    port       = 3308
    pid-file   = /usr/local/mysql/var3/hostname.pid3
    datadir    = /usr/local/mysql/var3
    language   = /usr/local/share/mysql/swedish
    user       = monty

    [mysqld4]
    socket     = /tmp/mysql.sock4
    port       = 3309
    pid-file   = /usr/local/mysql/var4/hostname.pid4
    datadir    = /usr/local/mysql/var4
    language   = /usr/local/share/mysql/estonia
    user       = tonu

    [mysqld6]
    socket     = /tmp/mysql.sock6
    port       = 3311
    pid-file   = /usr/local/mysql/var6/hostname.pid6
    datadir    = /usr/local/mysql/var6
    language   = /usr/local/share/mysql/japanese
    user       = jani

Siehe auch Abschnitt 4.3.2, „my.cnf-Optionsdateien“.

## 5.5. mysqlmanager — Der MySQL Instance Manager

mysqlmanager ist der MySQL Instance Manager (IM). Es handelt sich bei diesem Programm um einen über einen TCP/IP-Port ausgeführten Daemon, der die Überwachung und Verwaltung von MySQL-Datenbankserverinstanzen ermöglicht. Der MySQL Instance Manager ist für Unix und verwandte Betriebssysteme sowie für Windows verfügbar.

Der MySQL Instance Manager kann anstelle des Skripts `mysqld_safe` verwendet werden, um den MySQL-Server sogar von einem Remotehost aus zu starten. Der MySQL Instance Manager implementiert ferner die Funktionalität (sowie beinahe die vollständige Syntax) des Skripts mysqld_multi. Eine detaillierte Beschreibung des MySQL Instance Managers folgt.

### 5.5.1. MySQL Instance Manager: MySQL-Server starten

In der Regel wird der MySQL-Datenbankserver mysqld mit dem Skript mysql.server gestartet, welches normalerweise im Ordner `/etc/init.d/` abgelegt ist. Das Skript ruft standardmäßig das Skript mysqld_safe auf. Sie können die Variable `use_mysqld_safe` im Skript aber auch auf `0` (Null) setzen, um mit dem MySQL Instance Manager einen Server zu starten.

In diesem Fall hängt das Verhalten des MySQL Instance Managers von den Optionen ab, die in der MySQL-Konfigurationsdatei angegeben sind. Wenn keine Konfigurationsdatei vorhanden ist, erstellt der MySQL Instance Manager eine Serverinstanz namens `mysqld` und versucht diese mit den vorgabeseitigen (d. h. einkompilierten) Konfigurationswerten zu starten. Das bedeutet, dass der IM die Position eines nicht an der Standardposition installierten mysqld nicht erschließen kann. Wenn Sie den MySQL-Server an einer anderen als der Standardposition installiert haben, sollten Sie eine Konfigurationsdatei verwenden. Siehe auch Abschnitt 2.1.5, „Installationslayouts“.

Ist eine Konfigurationsdatei vorhanden, dann liest der IM deren `[mysqld]`-Abschnitte (z. B. `[mysqld]`, `[mysqld1]`, `[mysqld2]` usw.) aus. Jeder dieser Abschnitte gibt eine Instanz an. Wenn der MySQL Instance Manager gestartet wird, versucht er seinerseits alle Serverinstanzen zu starten, die er finden kann. Wird er beendet, dann beendet er selbst standardmäßig alle laufenden Serverinstanzen.

Beachten Sie, dass es eine Sonderoption `--mysqld-path=`path-to-mysqld-binary`` gibt, die nur vom IM erkannt wird. Mit dieser Variable können Sie dem IM mitteilen, wo die mysqld-Binärdatei abgelegt ist. Sie sollten ferner die Optionen `basedir` und `datadir` für den Server angeben.

Der typische Ablauf beim Starten und Beenden eines MySQL-Servers mit dem MySQL Instance Manager sieht wie folgt aus:

1. Der MySQL Instance Manager wird mit dem Skript /etc/init.d/mysql gestartet.

2. Der MySQL Instance Manager startet alle Instanzen und überwacht sie.

3. Wenn eine Serverinstanz fehlschlägt, startet der MySQL Instance Manager sie neu.

4. Wird der MySQL Instance Manager heruntergefahren (z. B. mit dem Befehl /etc/init.d/mysql stop), dann fährt er seinerseits zunächst alle Serverinstanzen herunter.

### 5.5.2. MySQL Instance Manager: Verbinden und Anlegen von Benutzerkonten

Die Kommunikation mit dem MySQL Instance Manager wird mithilfe des MySQL-Client/Server-Protokolls verwaltet. Insofern können Sie mithilfe des mysql-Standardclientprogramms wie auch mit der MySQL-C-API eine Verbindung mit dem IM herstellen. Der IM unterstützt die Version des MySQL-Client/Server-Protokolls, das von den Client-Tools und -Bibliotheken verwendet wird, die den Distributionen seit MySQL 4.1 beiliegen.

#### 5.5.2.1. Instance Manager-Benutzer und Passwörter

Der MySQL Instance Manager speichert die Benutzerdaten in einer Passwortdatei. Der Standardname dieser Passwortdatei lautet `/etc/mysqlmanager.passwd`.

Passworteinträge haben das folgende Format:

    petr:*35110DC9B4D8140F5DE667E28C72DD2597B5C848

Sind keine Einträge in der Datei `/etc/mysqlmanager.passwd` vorhanden, dann können Sie keine Verbindung zum Instance Manager herstellen.

Um einen neuen Eintrag zu erzeugen, rufen Sie den Instance Manager mit der Option --passwd auf. Die Ausgabe kann nachfolgend an die Datei `/etc/mysqlmanager.passwd` angehängt werden, um einen neuen Benutzer hinzuzufügen. Hier ein Beispiel:

    shell> mysqlmanager --passwd >> /etc/mysqlmanager.passwd
    Creating record for new user.
    Enter user name: mike
    Enter password: password
    Re-type password: password

Der vorangegangene Befehl bewirkt das Hinzufügen der folgenden Zeile zur Datei `/etc/mysqlmanager.passwd`:

    mike:*00A51F3F48415C7D4E8908980D443C29C69B60C9

#### 5.5.2.2. MySQL-Serverkonten zur Statusüberwachung

Um den Serverstatus zu überwachen, versucht der MySQL Instance Manager in regelmäßigen Abständen eine Verbindung zur MySQL-Serverinstanz herzustellen. Hierzu verwendet er das Benutzerkonto `MySQL_Instance_Manager@localhost` mit dem Passwort `check_connection`.

Sie müssen kein Benutzerkonto `MySQL_Instance_M@localhost` erstellen, damit der MySQL Instance Manager den Serverstatus überwacht, denn eine fehlgeschlagene Anmeldung ist bereits ausreichend, um sicherzustellen, dass der Server betriebsbereit ist. Wenn allerdings dieses Konto nicht vorhanden ist, werden fehlgeschlagene Anmeldeversuche vom Server im allgemeinen Anfragelog vermerkt (siehe auch Abschnitt 5.12.2, „Die allgemeine Anfragen-Logdatei“).

### 5.5.3. MySQL Instance Manager: Befehlsoptionen

Der MySQL Instance Manager unterstützt eine Reihe von Befehlszeilenoptionen. Eine kurze Auflistung erhalten Sie, indem Sie mysqlmanager mit der Option `--help` aufrufen.

mysqlmanager unterstützt die folgenden Optionen:

- `--help`, `-?`

  Zeigt eine Hilfemeldung an und wird dann beendet.

- `--bind-address=`IP``

  Die IP-Adresse, zu der eine Bindung hergestellt wird.

- `--default-mysqld-path=`path``

  Unter Unix der Pfadname der MySQL-Serverbinärdatei, sofern kein Pfad im Instanzabschnitt angegeben ist. Beispiel: `--default-mysqld-path=/usr/sbin/mysqld`

- `--defaults-file=`file_name``

  Datei, aus der die Einstellungen für den Instance Manager und MySQL Server ausgelesen werden sollen. Alle Konfigurationsänderungen, die der Instance Manager durchführt, werden an dieser Datei vorgenommen. Wenn diese Option verwendet wird, muss Sie auf der Befehlszeile die erste angegebene Option sein.

- `--install`

  Gibt an, dass der Instance Manager unter Windows als Dienst installiert werden soll.

- `--log=`file_name``

  Der Pfad zur IM-Logdatei. Wird mit der Option --run-as-service verwendet.

- `--monitoring-interval=`seconds``

  Das Intervall zur Überwachung der Instanzen, angegeben in Sekunden. Der Vorgabewert beträgt 20 Sekunden. Der Instance Manager versucht mit jeder überwachten Instanz eine Verbindung herzustellen, um festzustellen, ob sie läuft bzw. nicht abgestürzt ist. Stellt der Instance Manager fest, dass die Instanz terminiert wurde, versucht er mehrfach, sie neu zu starten. Über die Option `nonguarded` im Abschnitt der betreffenden Instanz kann man dieses Verhalten für eine bestimmte Instanz deaktivieren.

- `--passwd`, `-P`

  Bereitet einen Eintrag für die Passwortdatei vor und beendet sich dann.

- `--password-file=`file_name``

  Datei, in der nach Instance Manager-Benutzern und -Passwörtern gesucht wird. Die Standarddatei ist `/etc/mysqlmanager.passwd`.

- `--pid-file=`file_name``

  Die zu verwendende Prozesskennung. Standardmäßig heißt die Datei `mysqlmanager.pid`.

- `--port=`port_num``

  Die TCP/IP-Portnummer, die für eingehende Verbindungen verwendet werden soll (der von der IANA vergebene Standardport ist 2273).

- `--print-defaults`

  Gibt die aktuellen Standardwerte an und beendet sich nachfolgend. Wenn diese Option verwendet wird, muss Sie auf der Befehlszeile die erste angegebene Option sein.

- `--remove`

  Gibt unter Windows an, dass der Instance Manager als Windows-Dienst entfernt wird. Dies setzt voraus, dass der Instance Manager zuvor mit der Option `--install` ausgeführt wurde.

- `--run-as-service`

  Gibt an, dass eine Daemonisierung durchgeführt und nachfolgend der Engelsprozess gestartet werden soll. Der Engelsprozess ist einfach und stürzt mit hoher Wahrscheinlichkeit nicht ab. Im Falle eines Absturzes startet er den Instance Manager selbst neu.

- `--socket=`path``

  Unter Unix die Socketdatei, die für eingehende Verbindungen verwendet werden soll. Standardmäßig heißt die Datei `/tmp/mysqlmanager.sock`.

- `--standalone`

  Führt den Instance Manager unter Windows im autarken Modus aus.

- `--user=`user_name``

  Benutzername, unter dem mysqlmanager gestartet und ausgeführt werden soll. Es wird empfohlen, mysqlmanager unter demselben Benutzerkonto auszuführen, unter dem auch der Server mysqld läuft. („Benutzer“ bezeichnet in diesem Kontext ein Systemanmeldekonto und keinen in den Grant-Tabellen aufgeführten MySQL-Benutzer.)

- `--version`, `-V`

  Gibt die Versionsinformation aus und wird dann beendet.

### 5.5.4. MySQL Instance Manager: Konfigurationsdateien

Der Instance Manager verwendet die Standarddatei `my.cnf`. Aus dem Abschnitt `[manager]` liest er Optionen für sich selbst, aus den `[mysqld]`-Abschnitten Optionen für die Erstellung von Instanzen aus. Der Abschnitt `[manager]` enthält Optionen, die unter Abschnitt 5.5.3, „MySQL Instance Manager: Befehlsoptionen“ aufgeführt sind. Hier ein Beispiel für einen `[manager]`-Abschnitt:

    # MySQL Instance Manager options section
    [manager]
    default-mysqld-path = /usr/local/mysql/libexec/mysqld
    socket=/tmp/manager.sock
    pid-file=/tmp/manager.pid
    password-file = /home/cps/.mysqlmanager.passwd
    monitoring-interval = 2
    port = 1999
    bind-address = 192.168.1.5

Der MySQL Instance Manager liest und verwaltet die Datei `/etc/my.cnf` nur unter Linux. Unter Windows liest der MySQL Instance Manager die Datei `my.ini` in dem Verzeichnis aus, in dem der Instance Manager installiert ist. Die Standardposition der Optionsdatei kann mit der Option `--defaults-file=`file_name`` geändert werden.

Instanzabschnitte geben Optionen an, die für jede Instanz beim Start festgelegt werden. Es handelt sich hierbei in erster Linie um normale MySQL-Serveroptionen, allerdings sind auch ein paar IM-spezifische Optionen vorhanden:

- `mysqld-path = `path``

  Pfadname zur Binärdatei des mysqld-Servers.

- `shutdown-delay = `seconds``

  Dauer (in Sekunden), die der IM auf das Herunterfahren der Instanz warten soll. Der Vorgabewert beträgt 35 Sekunden. Wird dieses Intervall überschritten, dann geht der IM davon aus, dass die Instanz abgestürzt ist, und versucht sie zu terminieren. Wenn Sie `InnoDB` mit großen Tabellen verwenden, sollten Sie diesen Wert erhöhen.

- `nonguarded`

  Diese Option sollte angegeben werden, wenn Sie die IM-Überwachungsfunktion für eine bestimmte Instanz deaktivieren wollen.

Es folgen einige Beispiele für Instanzabschnitte:

    [mysqld]
    mysqld-path=/usr/local/mysql/libexec/mysqld
    socket=/tmp/mysql.sock
    port=3307
    server_id=1
    skip-stack-trace
    core-file
    skip-bdb
    log-bin
    log-error
    log=mylog
    log-slow-queries

    [mysqld2]
    nonguarded
    port=3308
    server_id=2
    mysqld-path= /home/cps/mysql/trees/mysql-5.1/sql/mysqld
    socket     = /tmp/mysql.sock5
    pid-file   = /tmp/hostname.pid5
    datadir= /home/cps/mysql_data/data_dir1
    language=/home/cps/mysql/trees/mysql-5.1/sql/share/english
    log-bin
    log=/tmp/fordel.log

### 5.5.5. MySQL Instance Manager: Unterstützte Befehle

Wenn Sie eine Passwortdatei für den MySQL Instance Manager eingerichtet haben und dieser ausgeführt wird, können Sie mit ihm eine Verbindung herstellen. Sie können den Client mysql verwenden, um eine Verbindung über eine MySQL-Standard-API herzustellen. Die folgende Liste zeigt die vom Instance Manager derzeit verarbeiteten Befehle mit Beispielen.

- `START INSTANCE `instance_name``

  Dieser Befehl versucht eine Instanz zu starten.

      mysql> START INSTANCE mysqld4;
      Query OK, 0 rows affected (0,00 sec)

- `STOP INSTANCE `instance_name``

  Dieser Befehl versucht eine Instanz zu beenden.

      mysql> STOP INSTANCE mysqld4;
      Query OK, 0 rows affected (0,00 sec)

- `SHOW INSTANCES`

  Zeigt die Namen aller geladenen Instanzen an.

      mysql> SHOW INSTANCES;
      +---------------+---------+
      | instance_name | status  |
      +---------------+---------+
      | mysqld3       | offline |
      | mysqld4       | online  |
      | mysqld2       | offline |
      +---------------+---------+
      3 rows in set (0,04 sec)

- `SHOW INSTANCE STATUS `instance_name``

  Zeigt den Status und die Versionsinformation für eine Instanz an.

      mysql> SHOW INSTANCE STATUS mysqld3;
      +---------------+--------+---------+
      | instance_name | status | version |
      +---------------+--------+---------+
      | mysqld3       | online | unknown |
      +---------------+--------+---------+
      1 row in set (0.00 sec)

- `SHOW INSTANCE OPTIONS `instance_name``

  Zeigt die von der Instanz verwendeten Optionen an.

      mysql> SHOW INSTANCE OPTIONS mysqld3;
      +---------------+---------------------------------------------------+
      | option_name   | value                                             |
      +---------------+---------------------------------------------------+
      | instance_name | mysqld3                                           |
      | mysqld-path   | /home/cps/mysql/trees/mysql-4.1/sql/mysqld        |
      | port          | 3309                                              |
      | socket        | /tmp/mysql.sock3                                  |
      | pid-file      | hostname.pid3                                     |
      | datadir       | /home/cps/mysql_data/data_dir1/                   |
      | language      | /home/cps/mysql/trees/mysql-4.1/sql/share/english |
      +---------------+---------------------------------------------------+
      7 rows in set (0.01 sec)

- `SHOW `instance_name` LOG FILES`

  Dieser Befehl listet alle von der Instanz verwendeten Logdateien auf. Die Ergebnisliste enthält die Pfade und die Größe der Logdateien. Wird in der Konfigurationsdatei kein Logdateipfad (wie etwa `log=/var/mysql.log`) angegeben, dann versucht der Instance Manager, die Position der Logdatei zu erschließen. Wenn der IM die Position jedoch nicht erraten kann, dann sollten Sie sie unter Verwendung der entsprechenden Logoption explizit im Instanzabschnitt der Konfigurationsdatei angeben.

      mysql> SHOW mysqld LOG FILES;
      +-------------+------------------------------------+----------+
      | Logfile     | Path                               | Filesize |
      +-------------+------------------------------------+----------+
      | ERROR LOG   | /home/cps/var/mysql/owlet.err      | 9186     |
      | GENERAL LOG | /home/cps/var/mysql/owlet.log      | 471503   |
      | SLOW LOG    | /home/cps/var/mysql/owlet-slow.log | 4463     |
      +-------------+------------------------------------+----------+
      3 rows in set (0.01 sec)

- `SHOW `instance_name` LOG {ERROR | SLOW | GENERAL} `size`[,`offset_from_end`]`

  Dieser Befehl ruft einen Teil der angegebenen Logdatei ab. Da die meisten Benutzer wohl an den neuesten Logmeldungen interessiert sein werden, können Sie mit dem Parameter `size` die Anzahl der Bytes definieren, die Sie – rückwärts vom Ende der Logdatei ausgehend – abrufen wollen. Sie können Daten aber auch aus einem Bereich mitten in der Datei abrufen, indem Sie den optionalen Parameter `offset_from_end` angeben. Das folgende Beispiel ruft 21 Datenbytes ab, beginnend 23 Bytes vor dem Ende der Logdatei und zwei Bytes vor ihrem Ende endend:

      mysql> SHOW mysqld LOG GENERAL 21, 2;
      +---------------------+
      | Log                 |
      +---------------------+
      | using password: YES |
      +---------------------+
      1 row in set (0.00 sec)

- `SET `instance_name`.`option_name`=`option_value``

  Dieser Befehl bearbeitet die Konfigurationsdatei der angegebenen Instanz dahingehend, dass er Instanzoptionen ändert oder hinzufügt. Der IM geht dabei davon aus, dass die Konfigurationsdatei sich in `/etc/my.cnf` befindet. Sie sollten sicherstellen, dass die Datei existiert und die passenden Berechtigungen hat.

      mysql> SET mysqld2.port=3322;
      Query OK, 0 rows affected (0.00 sec)

  Änderungen, die an der Konfigurationsdatei vorgenommen werden, werden erst beim nächsten Start des MySQL-Servers umgesetzt. Außerdem werden diese Änderungen erst im lokalen Cache des Instance Managers für die Instanzeinstellungen gespeichert, wenn der Befehl `FLUSH INSTANCES` ausgeführt wird.

- `UNSET `instance_name`.`option_name``

  Dieser Befehl entfernt eine Option aus der Konfigurationsdatei einer Instanz.

      mysql> UNSET mysqld2.port;
      Query OK, 0 rows affected (0.00 sec)

  Änderungen, die an der Konfigurationsdatei vorgenommen werden, werden erst beim nächsten Start des MySQL-Servers umgesetzt. Außerdem werden diese Änderungen erst im lokalen Cache des Instance Managers für die Instanzeinstellungen gespeichert, wenn der Befehl `FLUSH INSTANCES` ausgeführt wird.

- `FLUSH INSTANCES`

  Dieser Befehl erzwingt das Neueinlesen der Konfigurationsdatei durch den IM und die Aktualisierung der internen Strukturen. Der Befehl sollte nach einer Bearbeitung der Konfigurationsdatei ausgeführt werden. Er startet Instanzen nicht neu.

      mysql> FLUSH INSTANCES;
      Query OK, 0 rows affected (0.04 sec)

## 5.6. mysql_fix_privilege_tables — Upgrade von MySQL-Systemtabellen

Einige Releases von MySQL enthalten Änderungen an der Struktur der Systemtabellen in der `mysql`-Datenbank, damit neue Berechtigungen oder Funktionen hinzugefügt werden können. Wenn Sie ein Update auf eine neue Version von MySQL durchführen, sollten Sie auch Ihre Systemtabellen aktualisieren, um sicherzustellen, dass ihre Struktur auf dem neuesten Stand ist. Andernfalls können Sie bestimmte Funktionen unter Umständen nicht nutzen. Erstellen Sie zunächst eine Sicherung der `mysql`-Datenbank und gehen Sie dann wie nachfolgend beschrieben vor.

Unter Unix und verwandten Systemen aktualisieren Sie die Systemtabellen, indem Sie das Skript mysql_fix_privilege_tables ausführen:

    shell> mysql_fix_privilege_tables

Sie müssen dieses Skript zur Laufzeit des Servers ausführen. Es versucht dann, eine Verbindung zu dem Server herzustellen, der auf dem lokalen Host als `root` ausgeführt wird. Wenn Ihr `root`-Konto ein Passwort erfordert, geben Sie dieses wie folgt auf der Befehlszeile an:

    shell> mysql_fix_privilege_tables --password=root_password

Das Skript mysql_fix_privilege_tables führt alle Vorgänge aus, die notwendig sind, um Ihre Systemtabellen in das aktuelle Format zu konvertieren. Unter Umständen wird mehrmals die Warnung `Duplicate column name` angezeigt, die Sie aber getrost ignorieren können.

Nach der Ausführung des Skripts beenden Sie den Server und starten ihn neu.

Auf Windows-Systemen enthalten MySQL-Distributionen ein SQL-Skript namens `mysql_fix_privilege_tables.sql`, das Sie mithilfe des Clients mysql ausführen können. Wenn Ihre MySQL-Installation sich beispielsweise im Verzeichnis `C:\Programme\MySQL\MySQL Server 5.1` befindet, sieht der Befehl wie folgt aus:

    C:\> cd "C:\Program Files\MySQL\MySQL Server 5.1"
    C:\> bin\mysql -u root -p mysql
    mysql> SOURCE scripts/mysql_fix_privilege_tables.sql

Der Befehl mysql fordert Sie dann auf, das `root`-Passwort einzugeben. Folgen Sie dieser Aufforderung.

Wenn Ihre Installation sich in einem anderen Verzeichnis befindet, geben Sie die entsprechenden Pfadnamen ein.

Wie bei der Vorgehensweise unter Unix können auch hier Warnungen vom Typ `Duplicate column name` angezeigt werden, während mysql die Anweisungen im Skript `mysql_fix_privilege_tables.sql` verarbeitet, und auch hier können Sie diese ignorieren.

Nach der Ausführung des Skripts beenden Sie den Server und starten ihn neu.

## 5.7. Absichern von MySQL gegen Angreifer

Dieser Abschnitt beschreibt einige allgemeine Sicherheitsfragen, die man beachten sollte, und erläutert, was Sie tun können, um Ihre MySQL-Installation besser gegen Angriffe und Missbrauch zu schützen. Informationen, die speziell das Zugriffssteuerungssystem betreffen, das MySQL zur Konfiguration von Benutzerkonten und zur Überprüfung des Datenbankzugriffs verwendet, finden Sie in Abschnitt 5.8, „Allgemeine Sicherheitsaspekte und das MySQL-Zugriffsberechtigungssystem“.

### 5.7.1. Allgemeine Sicherheitsrichtlinien

Jeder, der MySQL auf einem mit dem Internet verbundenen Computer betreibt, sollte diesen Abschnitt lesen, um die häufigsten sicherheitsspezifischen Fehler zu vermeiden.

In unserer Beschreibung zur Sicherheit wollen wir die Notwendigkeit betonen, den gesamten Serverhost (und nicht nur den MySQL-Server) gegen alle möglichen Angriffe zu schützen: Lauschangriffe, Modifikationen, Wiedergabe und DoS (Denial of Service, Dienstablehnung). Wir werden an dieser Stelle nicht alle Aspekte der Verfügbarkeit und Fehlertoleranz behandeln.

MySQL benutzt ein Sicherheitssystem, welches auf ACLs (Access Control Lists, Zugriffssteuerungslisten) basiert, für alle Verbindungen, Abfragen und anderen Operationen, die Benutzer durchzuführen versuchen können. Ferner unterstützt werden SSL-verschlüsselte Verbindungen zwischen MySQL-Clients und -Servern. Viele der hier beschriebenen Konzepte sind keineswegs MySQL-spezifisch, sondern gelten vielmehr für fast alle gängigen Anwendungen.

Wenn Sie MySQL ausführen, befolgen Sie, sofern irgendwie möglich, die folgenden Richtlinien:

- Gewähren Sie niemals irgendjemandem (mit Ausnahme von MySQL-`root`-Konten) Zugang zur Tabelle `user` in der `mysql`-Datenbank! Dies ist entscheidend. Das verschlüsselte Passwort ist das echte Passwort in MySQL. Jeder, der das Passwort kennt, welches in der Tabelle `user` aufgeführt ist, und Zugang zu dem für das betreffende Konto gelisteten Host hat, kann sich problemlos als dieser Benutzer anmelden.

- Machen Sie sich mit dem MySQL-Zugriffsberechtigungssystem vertraut. Die Anweisungen `GRANT` und `REVOKE` werden zur Steuerung des Zugriffs auf MySQL verwendet. Gewähren Sie nie mehr Berechtigungen als notwendig. Gewähren Sie Berechtigungen niemals allen Hosts.

  Checkliste:

  - Geben Sie `mysql -u root` ein. Wenn Sie mit dem Server erfolgreich eine Verbindung herstellen können, ohne nach einem Passwort gefragt worden zu sein, dann kann jede Person als MySQL-Benutzer `root` eine solche Verbindung mit Ihrem MySQL-Server herstellen und hat nachfolgend alle Berechtigungen! Lesen Sie noch einmal die MySQL-Installationsanleitung und achten Sie dabei insbesondere auf Informationen zur Einstellung eines `root`-Passworts. Siehe auch Abschnitt 2.9.3, „Einrichtung der anfänglichen MySQL-Berechtigungen“.

  - Überprüfen Sie mithilfe der Anweisung `SHOW GRANTS`, welche Konten worauf zugreifen können. Entfernen Sie dann nicht erforderliche Berechtigungen mit der `REVOKE`-Anweisung.

- Speichern Sie Passwörter nicht unverschlüsselt in Ihrer Datenbank. Wenn der Computer in die Hände eines Angreifers fällt, kann dieser die Passwortliste lesen und die Passwörter verwenden. Verwenden Sie stattdessen `MD5()`, `SHA1()` oder eine andere unidirektionale Hashing-Funktion und speichern Sie den Hash-Wert.

- Wählen Sie keine Passwörter aus Wörterbüchern aus. Es gibt Spezialprogramme zum Knacken von Passwörtern. Sogar Passwörter wie „fisch98“ sind ziemlich schlecht. Wesentlich besser ist „duaxg98“: Dieses Passwort enthält zwar auch das Wort „fisch“, jedoch wurde jeder Buchstabe auf einer QWERTZ-Standardtastatur durch die Taste zu seiner Linken ersetzt. Eine andere Methode, ein Passwort zu verwenden, besteht darin, die jeweils ersten Buchstaben jedes Wortes eines Satzes zu benutzen; so wird etwa aus „Hoch auf dem gelben Wagen“ ganz einfach das Passwort „HadgW“. Dieses Passwort ist vergleichsweise einfach zu merken und einzugeben, aber für jemanden, der den Satz gar nicht kennt, schwer zu erraten.

- Schaffen Sie eine Firewall an. Diese schützt Sie vor mindestens 50 Prozent aller Sicherheitslücken in jeder beliebigen Software. Setzen Sie MySQL hinter die Firewall oder in eine DMZ (De-Militarized Zone, entmilitarisierte Zone).

  Checkliste:

  - Scannen Sie Ihre Ports aus dem Internet heraus mithilfe eines Tools wie `nmap`. MySQL verwendet standardmäßig Port 3306. Dieser Port sollte für nicht vertrauenswürdige Hosts nicht zugänglich sein. Eine weitere einfache Möglichkeit zu prüfen, ob Ihr MySQL-Port offen ist oder nicht, besteht darin, den folgenden Befehl an einem entfernten System einzugeben. Hierbei ist `server_host` der Hostname oder die IP-Nummer des Hosts, auf dem Ihr MySQL-Server ausgeführt wird:

        shell> telnet server_host 3306

    Wenn Sie eine Verbindung erhalten und einige sinnlose Zeichen angezeigt werden, ist der Port geöffnet; Sie sollten ihn dann umgehend mit Ihrer Firewall oder Ihrem Router schließen, es sei denn, es gäbe einen guten Grund dafür, dass der Port offen ist. Wenn telnet hängt oder die Verbindung abgewiesen wird, dann ist der Port gesperrt – so soll es sein.

- Schenken Sie Daten, die von Benutzern Ihrer Anwendungen eingegeben wurden, kein Vertrauen. Benutzer können Ihren Code überlisten, indem Sie Sonderzeichen oder Zeichenfolgen mit vorangestelltem Escape-Zeichen in Webformulare, URLs oder andere Eingabemöglichkeiten der von Ihnen erstellten Anwendungen eintragen. Sie müssen sicherstellen, dass Ihre Anwendung auch dann sicher bleibt, wenn ein Benutzer so etwas wie „`; DROP DATABASE mysql;`“ eingibt. Dies ist natürlich ein Extrembeispiel, aber große Sicherheitslücken oder umfangreiche Datenverlust können die Folge sein, wenn Hacker ähnliche Methoden verwenden und Sie nicht darauf vorbereitet sind.

  Ein häufiger Fehler besteht darin, nur String-Datenwerte zu schützen. Denken Sie daran, auch numerische Daten abzusichern. Wenn eine Anwendung eine Abfrage wie `SELECT * FROM table WHERE ID=234` erzeugt, weil ein Benutzer den Wert `234` eingegeben hat, dann kann der Benutzer auch den Wert `234 OR 1=1` eingeben; hierauf generiert die Anwendung die Abfrage `SELECT * FROM table WHERE ID=234 OR 1=1`. Folge ist, dass der Server jeden Datensatz in der Tabelle abruft. Mithin wird jeder Datensatz angezeigt, zudem wird der Server extrem belastet. Die einfachste Möglichkeit, sich vor diesem Angriffstyp zu schützen, besteht darin, numerische Konstanten in Anführungszeichen zu setzen: `SELECT * FROM table WHERE ID='234'`. Gibt nämlich der Benutzer zusätzliche Daten an, so werden sie alle Teil des Strings. In einem numerischen Kontext wandelt MySQL diesen String automatisch in eine Zahl um und entfernt alle nachfolgenden nichtnumerischen Zeichen.

  Manche Leute gehen davon aus, dass eine Datenbank, die nur öffentlich verfügbare Daten enthält, nicht geschützt werden muss. Das stimmt nicht. Auch wenn jeder Datensatz in der Datenbank angezeigt werden dürfte, sollten Sie sich trotzdem etwa gegen DoS-Angriffe schützen (z. B. jene, die auf der im vorigen Absatz beschriebenen Methode basieren und den Server dazu bringen, Ressourcen zu vergeuden). Andernfalls kann Ihr Server für legitime Benutzer unerreichbar werden.

  Checkliste:

  - Geben Sie einfache und doppelte Anführungszeichen (‘`'`’ bzw. ‘`"`’) in all Ihre Webformulare ein. Wird irgendein MySQL-Fehler ausgegeben, dann untersuchen Sie das Problem umgehend.

  - Versuchen Sie, dynamische URLs durch Hinzufügen von `%22` (‘`"`’), `%23` (‘`#`’) und `%27` (‘`'`’) zu modifizieren.

  - Versuchen Sie, die Datentypen in dynamischen URLs von numerischen auf Zeichentypen umzustellen, indem Sie die in den obigen Beispielen verwendeten Zeichen eingeben. Ihre Anwendung sollte gegen solche und ähnliche Angriffe gewappnet sein.

  - Geben Sie Buchstaben, Leer- und Sonderzeichen statt Ziffern in numerische Felder ein. Ihre Anwendung sollte diese Zeichen entfernen, bevor Sie sie an MySQL übergibt, oder andernfalls einen Fehler erzeugen. Die Übergabe ungeprüfter Werte an MySQL ist extrem gefährlich!

  - Überprüfen Sie die Daten, bevor Sie sie an MySQL übergeben.

  - Lassen Sie Ihre Anwendung eine Verbindung mit der Datenbank unter Verwendung eines anderen Benutzernamens als desjenigen herstellen, den Sie für administrative Zwecke verwenden. Geben Sie Ihren Anwendungen nicht mehr Zugriffsberechtigungen als notwendig.

- Viele APIs stellen eine Methode bereit, um Sonderzeichen in Datenwerten zu kennzeichnen. Richtig verwendet, verhindert dies, dass Anwendungsbenutzer Werte eingeben können, die eine Erzeugung von Anweisungen durch die Anwendung verursachen könnten, welche einen anderen Effekt als von Ihnen erwünscht hervorrufen:

  - MySQL-C-API: Verwenden Sie den API-Aufruf `mysql_real_escape_string()`.

  - MySQL++: Verwenden Sie die Modifizierer `escape` und `quote` für Abfrage-Streams.

  - PHP: Verwenden Sie die Funktion `mysql_escape_string()`, die auf der gleichnamigen Funktion in der MySQL-C-API basiert. (Bei PHP vor Version 4.0.3 benutzen Sie stattdessen `addslashes()`.) In PHP 5 können Sie die Erweiterung `mysqli` einsetzen, die das verbesserte MySQL-Authentifizierungsprotokoll und Passwörter ebenso unterstützt wie vorbereitete Anweisungen mit Platzhaltern.

  - Perl DBI: Verwenden Sie die Methode `quote()` oder Platzhalter.

  - Ruby DBI: Verwenden Sie Platzhalter.

  - Java JDBC: Verwenden Sie ein `PreparedStatement`-Objekt und Platzhalter.

  Andere Programmierschnittstellen weisen möglicherweise ähnliche Funktionalitäten auf.

- Übertragen Sie keine unverschlüsselten Daten über das Internet. Auf solche Daten kann jeder zugreifen, der die Zeit und die Fähigkeiten hat, sie abzufangen und für eigene Zwecke zu verwenden. Verwenden Sie stattdessen ein verschlüsseltes Protokoll wie SSL oder SSH. MySQL unterstützt interne SSL-Verbindungen ab Version 4.0. Eine andere Methode besteht in der Verwendung der SSH-Portweiterleitung, mit der man einen verschlüsselten (und komprimierten) Kommunikationstunnel einrichten kann.

- Machen Sie sich mit den Hilfsprogrammen tcpdump und strings vertraut. In den meisten Fällen können Sie durch Absetzen eines Befehls wie des folgenden überprüfen, ob MySQL-Datenströme unverschlüsselt sind:

      shell> tcpdump -l -i eth0 -w - src or dst port 3306 | strings

  (Das funktioniert unter Linux und sollte mit kleinen Anpassungen auf unter anderen Betriebssystemen laufen.) Warnung: Wenn Sie keine Klartextdaten sehen, bedeutet dies nicht notwendigerweise, dass die Daten tatsächlich verschlüsselt sind. Sofern Sie ein hohes Maß an Sicherheit benötigen, sollten Sie sich an einen Sicherheitsexperten wenden.

### 5.7.2. Absichern von MySQL gegen Angreifer

Wenn Sie eine Verbindung mit einem MySQL-Server herstellen, sollten Sie ein Passwort verwenden. Dieses Passwort wird nicht unverschlüsselt über die Verbindung übertragen. Die Behandlung des Passworts während der Herstellung der Clientverbindung wurde in MySQL 4.1.1 so aktualisiert, dass sie nun sehr sicher ist. Wenn Sie immer noch Passwörter im alten Stil (d. h. vor MySQL 4.1.1) verwenden, beachten Sie, dass der Verschlüsselungsalgorithmus nicht so leistungsfähig ist wie der neuere Algorithmus. Mit ein wenig Aufwand kann ein cleverer Angreifer den Datenverkehr zwischen Client und Server abfangen und das Passwort knacken. (Eine Beschreibung der verschiedenen Methoden für den Umgang mit Passwörtern finden Sie in Abschnitt 5.8.9, „Kennwort-Hashing ab MySQL 4.1“.)

Alle übrigen Informationen werden unverschlüsselt übertragen und können von jedem gelesen werden, der die Verbindung überwachen kann. Wenn die Verbindung zwischen Client und Server durch ein nicht vertrauenswürdiges Netzwerk verläuft und Sie deswegen Bedenken haben, können Sie das komprimierte Protokoll verwenden, um die Entschlüsselung der Daten erheblich zu erschweren. Sie können auch den internen SSL-Support von MySQL verwenden, um die Sicherheit der Verbindung noch mehr zu erhöhen. Siehe auch Abschnitt 5.9.7, „Verwendung sicherer Verbindungen“. Alternativ stellen Sie mit SSH eine verschlüsselte TCP/IP-Verbindung zwischen einem MySQL-Server und einem MySQL-Client her. Einen Open-Source-SSH-Client finden Sie unter http://www.openssh.org/, eine kommerzielle Variante unter http://www.ssh.com/.

Um ein MySQL-System möglichst sicher zu machen, sollten Sie die folgenden Vorschläge dringend beachten:

- Verlangen Sie für alle MySQL-Konten die Nutzung eines Passworts. Ein Clientprogramm kennt die Identität seines Benutzers nicht unbedingt. Bei Client/Server-Anwendungen ist es durchaus üblich, dass der Benutzer einen beliebigen Benutzernamen für das Clientprogramm angeben kann. So kann beispielsweise jede beliebige Person das Programm mysql verwenden, um eine Verbindung als eine andere Person herzustellen, indem sie `mysql -u `other_user` `db_name`` aufruft, wenn für `other_user` kein Passwort konfiguriert ist. Wenn alle Konten ein Passwort besitzen, wird das Herstellen einer Verbindung unter Verwendung des Kontos eines anderen Benutzers erheblich schwieriger.

  Eine Beschreibung der Methoden zur Konfiguration von Passwörtern finden Sie in Abschnitt 5.9.5, „Kennwörter einrichten“.

- Führen Sie den MySQL-Server niemals als Unix-Benutzer `root` aus. Dies ist extrem gefährlich, weil jeder Benutzer mit der Berechtigung `FILE` in der Lage ist, auf dem Server die Erstellung von Dateien als `root` anzufordern (z. B. `~root/.bashrc`). Um dies zu verhindern, verweigert mysqld die Ausführung als `root`, sofern dies nicht ausdrücklich mit der Option `--user=root` festgelegt wurde.

  mysqld kann (und sollte) stattdessen als gewöhnlicher, nichtberechtigter Benutzer ausgeführt werden. Sie können ein separates Unix-Konto namens `mysql` einrichten, um die Sicherheit noch weiter zu erhöhen. Dieses Konto verwenden Sie dann nur zur Administration von MySQL. Um mysqld als ein anderer Unix-Benutzer zu starten, fügen Sie die Option `user` hinzu, die den Benutzernamen im Abschnitt `[mysqld]` der Optionsdatei `my.cnf` angibt, in der Sie die Serveroptionen konfigurieren. Zum Beispiel:

      [mysqld]
      user=mysql

  Hierdurch wird der Server unabhängig davon, ob Sie ihn manuell oder mithilfe von mysqld_safe oder mysql.server starten, als der angegebene Benutzer gestartet. Weitere Informationen finden Sie unter Abschnitt 5.7.5, „Wie man MySQL als normaler Benutzer laufen läßt“.

  Die Ausführung von mysqld als ein anderer Unix-Benutzer als `root` hat nicht zur Folge, dass Sie den Benutzernamen `root` in der Tabelle `user` ändern müssen. Benutzernamen für MySQL-Konten haben nichts mit den Benutzernamen für Unix-Konten zu tun.

- Unterbinden Sie die Verwendung von symbolischen Verknüpfungen mit Tabellen. (Diese Funktionalität kann mit der Option `--skip-symbolic-links` deaktiviert werden.) Dies ist insbesondere dann wichtig, wenn Sie mysqld als `root` ausführen, da jeder Benutzer, der Schreibzugriff auf das Datenverzeichnis des Servers hat, jede beliebige Datei im System löschen kann! Siehe auch Abschnitt 7.6.1.2, „Benutzung symbolischer Links für Tabellen“.

- Vergewissern Sie sich, dass der einzige Unix-Benutzer mit Lese- und Schreibberechtigungen in den Datenbankverzeichnissen der Benutzer ist, als der mysqld ausgeführt wird.

- Gewähren Sie die Berechtigungen `PROCESS` und `SUPER` ausschließlich Administratoren. Die Ausgabe von mysqladmin processlist und `SHOW PROCESSLIST` zeigt den Text aller Anweisungen, die gerade ausgeführt werden. Insofern kann jeder Benutzer, der die Serverprozessliste anzeigen kann, unter Umständen Anweisungen sehen, die von anderen Benutzern abgesetzt werden – z. B. auch `UPDATE user SET password=PASSWORD('not_secure')`.

  mysqld reserviert eine zusätzliche Verbindung für Benutzer mit der Berechtigung `SUPER`, sodass ein MySQL-Benutzer `root` sich auch dann anmelden und die Serveraktivitäten überprüfen kann, wenn alle normalen Verbindungen gerade verwendet werden.

  Die Berechtigung `SUPER` kann zur Terminierung von Clientverbindungen, zur Änderung des Serverbetriebs durch Modifikation von Systemvariablen und zur Steuerung von Replikationsservern verwendet werden.

- Gewähren Sie die Berechtigung `FILE` ausschließlich Administratoren. Jeder Benutzer mit dieser Berechtigung kann eine Datei an beliebiger Stelle im Dateisystem mit den Berechtigungen des mysqld-Daemons speichern. Um dies ein wenig sicherer zu gestalten, überschreiben Dateien, die mit `SELECT ... INTO OUTFILE` erzeugt wurden, keine vorhandenen Dateien und können von allen geschrieben werden.

  Die Berechtigung `FILE` kann auch eingesetzt werden, um jede Datei zu lesen, die von allen gelesen werden kann oder für den Unix-Benutzer, als der der Server ausgeführt wird, zugänglich ist. Mit dieser Berechtigung können Sie jede Datei in eine Datenbanktabelle einlesen. Dies könnte beispielsweise missbraucht werden, indem man mit `LOAD DATA` die Datei `/etc/passwd` in eine Tabelle einlädt, die dann mit `SELECT` angezeigt werden könnte.

- Wenn Sie Ihrem DNS nicht trauen, sollten Sie IP-Nummern statt Hostnamen in den Grant-Tabellen verwenden. In jedem Fall sollten Sie sehr vorsichtig mit der Erstellung von Einträgen in Grant-Tabellen unter Verwendung von Hostnamenswerten sein, die Jokerzeichen enthalten.

- Wenn Sie die Anzahl der für ein Konto verwendbaren Verbindungen einschränken wollen, können Sie dies tun, indem Sie die Variable `max_user_connections` in mysqld einstellen. Die `GRANT`-Anweisung unterstützt auch Ressourcensteuerungsoptionen, mit denen die Servernutzung durch ein Konto beschränkt werden kann. Siehe auch Abschnitt 13.5.1.3, „`GRANT` und `REVOKE`“.

### 5.7.3. Startoptionen für `mysqld` in Bezug auf Sicherheit

Die folgenden mysqld-Optionen sind sicherheitsrelevant:

- `--allow-suspicious-udfs`

  Diese Option bestimmt, ob UDFs (User-Defined Functions, benutzerdefinierte Funktionen), die nur ein `xxx`-Symbol für die Hauptfunktion aufweisen, geladen werden dürfen. Standardmäßig ist die Option deaktiviert, und es dürfen nur UDFs geladen werden, die mindestens ein Hilfssymbol aufweisen. Hierdurch soll das Laden von Funktionen aus solchen freigegebenen Objektdateien verhindert werden, die keine zulässigen UDFs enthalten. Siehe auch Abschnitt 26.3.4.6, „Vorsichtsmaßnahmen bei benutzerdefinierten Funktionen (UDF)“.

- `--local-infile[={0|1}]`

  Wenn Sie den Server mit `--local-infile=0` starten, können Clients `LOCAL` in `LOAD DATA`-Anweisungen nicht verwenden. Siehe auch Abschnitt 5.7.4, „Sicherheitsprobleme mit `LOAD DATA LOCAL`“.

- `--old-passwords`

  Erzwingt die Erzeugung kurzer Passwort-Hashes (wie vor Version 4.1) auch für neue Passwörter. Dies kann zu Kompatibilitätszwecken erforderlich sein, wenn der Server ältere Clientprogramme unterstützen muss. Siehe auch Abschnitt 5.8.9, „Kennwort-Hashing ab MySQL 4.1“.

- `--safe-show-database` (AUSGELAUFEN)

  In älteren MySQL-Versionen konnte mit dieser Option festgelegt werden, dass die `SHOW DATABASES`-Anweisung die Namen nur derjenigen Datenbanken anzeigte, für die der Benutzer eine entsprechende Berechtigung hatte. In MySQL 5.1 steht diese Option nicht mehr zur Verfügung, da dies nun das Standardverhalten ist und es eine `SHOW DATABASES`-Berechtigung gibt, die zur kontenspezifischen Steuerung des Zugriffs auf Datenbanknamen verwendet werden kann. Siehe auch Abschnitt 13.5.1.3, „`GRANT` und `REVOKE`“.

- `--safe-user-create`

  Wenn diese Option aktiviert ist, kann ein Benutzer nur dann neue Benutzer mit der `GRANT`-Anweisung erstellen, wenn er die Berechtigung `INSERT` für die Tabelle `mysql.user` hat. Wenn Sie wollen, dass ein bestimmter Benutzer die Möglichkeit zur Einrichtung neuer Benutzer hat, die diejenigen Berechtigungen haben, die der erstellende Benutzer gewähren darf, dann sollten Sie dem Benutzer die folgende Berechtigung gewähren:

      GRANT INSERT(user) ON mysql.user TO 'user_name'@'host_name';

  Hierdurch ist gewährleistet, dass der Benutzer Berechtigungsspalten nicht direkt ändern kann, sondern die `GRANT`-Anweisung zur Gewährung von Berechtigungen an andere Benutzer verwenden muss.

- `--secure-auth`

  Unterbindet die Authentifizierung für Konten, die alte Passwörter (d. h. solche im Stil vor MySQL 4.1) haben.

  Der Client mysql verfügt ebenfalls über eine Option namens `--secure-auth`, die Verbindungen mit einem Server verhindert, wenn dieser für das Clientkonto ein Passwort im alten Format anfordert.

- `--skip-grant-tables`

  Mit dieser Option verwendet der Server das Berechtigungssystem überhaupt nicht. Das bedeutet, dass jeder, der Zugriff auf den Server erhält, uneingeschränkten Zugang zu allen Datenbanken bekommt. Sie können einen laufenden Server dazu bringen, die Grant-Tabellen wieder zu verwenden, indem Sie mysqladmin flush-privileges oder mysqladmin reload über die System-Shell ausführen oder die MySQL-Anweisung `FLUSH PRIVILEGES` absetzen. Diese Option unterbindet auch das Laden von Plug-Ins und benutzerdefinierten Funktionen (UDFs).

- `--skip-name-resolve`

  Hostnamen werden nicht aufgelöst. Alle `Host`-Spaltenwerte in den Grant-Tabellen müssen IP-Nummern oder `localhost` sein.

- `--skip-networking`

  TCP/IP-Verbindungen über das Netzwerk werden unterbunden. Alle Verbindungen zu mysqld müssen über Unix-Socketdateien erfolgen.

- `--skip-show-database`

  Bei dieser Option darf die `SHOW DATABASES`-Anweisung nur von Benutzern verwendet werden, die die Berechtigung `SHOW DATABASES` haben. Die Anweisung zeigt dann alle Datenbanknamen an. Ohne diese Option dürfen alle Benutzer `SHOW DATABASES` verwenden, aber die Datenbanknamen werden nur angezeigt, wenn der Benutzer die Berechtigung `SHOW DATABASES` oder spezifische Berechtigungen für eine Datenbank hat. Beachten Sie, dass jede globale Berechtigung als Berechtigung für die Datenbank betrachtet wird.

### 5.7.4. Sicherheitsprobleme mit `LOAD DATA LOCAL`

Die `LOAD DATA`-Anweisung kann eine Datei, die sich auf dem Serverhost befindet, oder eine Datei laden, die auf dem Clienthost abgelegt ist, wenn das Schlüsselwort `LOCAL` angegeben ist.

Es gibt bei der Unterstützung der `LOCAL`-Version von `LOAD DATA` zwei potenzielle Sicherheitsrisiken:

- Die Übertragung der Datei vom Client- auf den Serverhost wird durch den MySQL-Server eingeleitet. Theoretisch ließe sich ein gepatchter Server erstellen, der das Clientprogramm anweisen könnte, eine Datei nach Maßgabe des Servers (statt der vom Client in der `LOAD DATA`-Anweisung festgelegten Datei) zu übertragen. Ein solcher Server könnte dann auf jede Datei auf dem Clienthost zugreifen, auf die der Clientbenutzer Lesezugriff hat.

- In einer Webumgebung, in der die Clients Verbindungen über einen Webserver herstellen, könnte ein Benutzer mit `LOAD DATA LOCAL` beliebige Dateien lesen, auf die der Webserverprozess Lesezugriff hat (vorausgesetzt, der Benutzer kann einen beliebigen Befehl den SQL-Server betreffend ausführen). In dieser Umgebung ist der Client aus Sicht des MySQL-Servers eigentlich der Webserver und nicht das entfernte Programm, das von dem Benutzer ausgeführt wird, der die Verbindung zum Webserver hergestellt hat.

Um diese Probleme zu beheben, haben wir die Verfahrensweise für `LOAD DATA LOCAL` beginnend mit MySQL 3.23.49 und MySQL 4.0.2 (4.0.13 unter Windows) wie folgt geändert:

- Standardmäßig werden alle MySQL-Clients und -Bibliotheken mit der Option `--enable-local-infile` kompiliert, um die Kompatibilität mit MySQL 3.23.48 und vorher aufrechtzuerhalten.

- Wenn Sie MySQL aus der Quelldistribution erstellt, aber configure nicht mit der Option `--enable-local-infile` aufgerufen haben, kann `LOAD DATA LOCAL` nicht von beliebigen Clients verwendet werden, sofern nicht ausdrücklich der Aufruf von `mysql_options(... MYSQL_OPT_LOCAL_INFILE, 0)` einkompiliert wurde. Siehe auch Abschnitt 24.2.3.48, „`mysql_options()`“.

- Sie können alle `LOAD DATA LOCAL`-Befehle auf der Serverseite deaktivieren, indem Sie mysqld mit der Option `--local-infile=0` starten.

- Für den Befehlszeilenclient mysql kann `LOAD DATA LOCAL` durch Angabe der Option `--local-infile[=1]` aktiviert bzw. mit der Option `--local-infile=0` deaktiviert werden. Ähnlich aktiviert die Option `--local` bzw. `-L` das Laden lokaler Dateien für mysqlimport. In jedem Fall setzt die erfolgreiche Verwendung einer lokalen Ladeoperation voraus, dass die Durchführung derartiger Operationen durch den Server zugelassen ist.

- Wenn Sie `LOAD DATA LOCAL` in Perl-Skripten oder anderen Programmen verwenden, die den Abschnitt `[client]` aus Optionsdateien auslesen, können Sie die Option `local-infile=1` in diesem Abschnitt hinzufügen. Allerdings sollten Sie sie mit dem Präfix `loose-` versehen, um Probleme mit Programmen zu vermeiden, die `local-infile` nicht verstehen:

      [client]
      loose-local-infile=1

- Wenn `LOAD DATA LOCAL INFILE` deaktiviert ist – sei es am Server oder am Client –, dann erhält ein Client, der eine solche Anweisung abzusetzen versucht, die folgende Fehlermeldung:

      ERROR 1148: The used command is not allowed with this MySQL version

### 5.7.5. Wie man MySQL als normaler Benutzer laufen läßt

Unter Windows können Sie den Server als Windows-Dienst über ein normales Benutzerkonto ausführen.

Unter Unix kann jeder Benutzer den MySQL-Server mysqld starten und ausführen. Allerdings sollten Sie aus Sicherheitsgründen eine Ausführung des Servers als Unix-Benutzer `root` unterbinden. Gehen Sie wie folgt vor, um den Server mysqld so zu ändern, dass er als normaler Unix-Benutzer `user_name` ohne spezielle Berechtigungen ausgeführt wird:

1. Beenden Sie mit mysqladmin shutdown den Server, sofern er ausgeführt wird.

2. Ändern Sie die Datenbankverzeichnisse und -dateien so ab, dass `user_name` Berechtigungen zum Lesen und Schreiben von Dateien in diese Verzeichnisse hat (dies müssen Sie unter Umständen als Unix-Benutzer `root` tun):

       shell> chown -R user_name /path/to/mysql/datadir

   Wenn Sie dies versäumen, kann der Server, wenn er als `user_name` ausgeführt wird, nicht auf Datenbanken oder Tabellen zugreifen.

   Wenn Verzeichnisse oder Dateien im MySQL-Datenverzeichnis symbolische Verknüpfungen sind, müssen Sie diese Verknüpfungen nachverfolgen und die Verzeichnisse und Dateien ändern, auf die sie verweisen. `chown -R` verfolgt die symbolischen Verknüpfungen möglicherweise nicht.

3. Starten Sie den Server als Benutzer `user_name`. Wenn Sie MySQL 3.22 oder höher verwenden, besteht eine Alternative darin, mysqld als Unix-Benutzer `root` zu starten und dabei die Option `--user=`user_name`` zu verwenden. mysqld wird gestartet und schaltet dann auf die Ausführung als Unix-Benutzer `user_name` um, bevor Verbindungen akzeptiert werden.

4. Um den Server beim Systemstart automatisch als der betreffende Benutzer zu starten, geben Sie den Benutzernamen durch Hinzufügen einer Option `user` im Abschnitt `[mysqld]` der Optionsdateien `/etc/my.cnf` oder `my.cnf` im Datenverzeichnis des Servers an. Zum Beispiel:

       [mysqld]
       user=user_name

Wenn Ihr Unix-System selbst nicht geschützt ist, sollten Sie für die MySQL-`root`-Konten Passwörter in den Grant-Tabellen konfigurieren. Andernfalls kann jeder Benutzer mit einem Anmeldekonto auf diesem Computer den Client mysql mit der Option `--user=root` ausführen und beliebige Operationen durchführen. (Es empfiehlt sich generell, MySQL-Konten mit Passwörtern zu verknüpfen, ist aber absolut erforderlich, wenn andere Anmeldekonten auf dem Serverhost vorhanden sind.) Siehe auch Abschnitt 2.9, „Einstellungen und Tests nach der Installation“.

## 5.8. Allgemeine Sicherheitsaspekte und das MySQL-Zugriffsberechtigungssystem

MySQL verfügt über ein fortschrittliches, aber nicht standardkonformes Sicherheits- und Berechtigungssystem. Im Folgenden wird beschrieben, wie dieses System funktioniert.

### 5.8.1. Was das Berechtigungssystem macht

Die wesentliche Funktion des MySQL-Berechtigungssystems ist die Authentifizierung von Benutzern, die von einem gegebenen Host eine Verbindung herstellen, und die Zuweisung von Berechtigungen für eine Datenbank wie `SELECT`, `INSERT`, `UPDATE` und `DELETE` an diesen Benutzer.

Weitere Funktionalitäten umfassen die Möglichkeit zur Authentifizierung anonymer Benutzer und die Gewährung von Berechtigungen für MySQL-spezifische Funktionen wie `LOAD DATA INFILE` und administrativen Operationen.

### 5.8.2. Wie das Berechtigungssystem funktioniert

Das MySQL-Berechtigungssystem stellt sicher, dass alle Benutzer nur diejenigen Operationen ausführen können, die sie auch ausführen dürfen. Wenn Sie als Benutzer eine Verbindung mit einem MySQL-Server herstellen, dann wird Ihre Identität über den Host, von dem aus Sie die Verbindung herstellen, und den angegebenen Benutzernamen bestimmt. Wenn Sie nach Herstellung der Verbindung Abfragen absetzen, gewährt das System Berechtigungen entsprechend Ihrer Identität und dem, was Sie tun wollen.

MySQL berücksichtigt bei der Identifizierung sowohl Ihren Host- als auch Ihren Benutzernamen, da es wenig Grund zu der Annahme gibt, dass ein bestimmter Benutzername überall im Internet jeweils derselben Person zuzuordnen ist. So muss beispielsweise der Benutzer `joe`, der eine Verbindung von `office.example.com` aus herstellt, keineswegs mit dem Benutzer `joe` identisch sein, der seine Verbindung von `home.example.com` aus aufbaut. MySQL löst diese Diskrepanz, indem es Ihnen gestattet, zwischen Benutzern auf unterschiedlichen Hosts zu unterscheiden, die zufällig den gleichen Namen haben: Sie können einen Satz mit Berechtigungen für Verbindungen von `joe` auf `office.example.com` und einen anderen Berechtigungssatz für Verbindungen von `joe` auf `home.example.com` gewähren.

Die MySQL-Zugriffssteuerung umfasst zwei Stufen, wenn Sie ein Clientprogramm ausführen, das eine Verbindung mit dem Server herstellt:

- Stufe 1: Der Server überprüft, ob er Ihnen die Verbindungsherstellung gestattet.

- Stufe 2: Sofern Sie eine Verbindung herstellen konnten, überprüft der Server nun jede von Ihnen abgesetzte Anweisung, um zu ermitteln, ob Sie ausreichende Berechtigungen für deren Durchführung genießen. Versuchen Sie beispielsweise, Datensätze aus einer Tabelle in einer Datenbank auszuwählen oder eine Tabelle aus der Datenbank zu löschen, dann vergewissert sich der Server, dass Sie die Berechtigung `SELECT` für die Tabelle bzw. die Berechtigung `DROP` für die Datenbank haben.

Werden Ihre Berechtigungen (sei es von Ihnen selbst oder jemandem anderes) geändert, während Sie eine Verbindung haben, dann haben diese Änderungen nicht unbedingt sofort für die nächste abgesetzte Anweisung Gültigkeit. Weitere Informationen finden Sie in Abschnitt 5.8.7, „Wann Berechtigungsänderungen wirksam werden“.

Der Server speichert Berechtigungsinformationen in den Grant-Tabellen der `mysql`-Datenbank (d. h. in der Datenbank namens `mysql`). Der MySQL-Server liest die Inhalte dieser Tabellen beim Start in den Speicher ein. Unter den in Abschnitt 5.8.7, „Wann Berechtigungsänderungen wirksam werden“, beschriebenen Umständen erfolgt zudem ein Neueinlesen der Inhalte. Entscheidungen der Zugriffssteuerung basieren auf den im Arbeitsspeicher vorhandenen Kopien der Grant-Tabellen.

Normalerweise manipulieren Sie die Inhalte der Grant-Tabellen indirekt, indem Sie mit Anweisungen wie `GRANT` oder `REVOKE` Konten einrichten und die Berechtigungen für jedes einzelne Konto steuern. Siehe auch Abschnitt 13.5.1, „Anweisungen zur Benutzerkontenverwaltung“. Die nachfolgende Beschreibung erläutert die den Grant-Tabellen zugrundeliegende Struktur und die Frage, wie der Server die Inhalte dieser Tabellen für die Interaktion mit Clients verwendet.

Der Server benutzt die Tabellen `user`, `db` und `host` in der Datenbank `mysql` für beide Stufen der Zugriffssteuerung. Die Spalten in den Tabellen `user` und `db` sind nachfolgend aufgeführt. Die Tabelle `host` ähnelt der Tabelle `db`, weist aber einen speziellen Einsatzbereich auf, der in Abschnitt 5.8.6, „Zugriffskontrolle, Phase 2: Anfrageüberprüfung“, beschrieben wird.

Tabellenname | user | db
Spalten für Gültigkeitsbereiche | `Host` | `Host`
| `User` | `Db`
| `Password` | `User`
Berechtigungsspalten | `Select_priv` | `Select_priv`
| `Insert_priv` | `Insert_priv`
| `Update_priv` | `Update_priv`
| `Delete_priv` | `Delete_priv`
| `Index_priv` | `Index_priv`
| `Alter_priv` | `Alter_priv`
| `Create_priv` | `Create_priv`
| `Drop_priv` | `Drop_priv`
| `Grant_priv` | `Grant_priv`
| `Create_view_priv` | `Create_view_priv`
| `Show_view_priv` | `Show_view_priv`
| `Create_routine_priv` | `Create_routine_priv`
| `Alter_routine_priv` | `Alter_routine_priv`
| `Execute_priv` | `Execute_priv`
| `Trigger_priv` | `Trigger_priv`
| `Event_priv` | `Event_priv`
| `Create_tmp_table_priv` | `Create_tmp_table_priv`
| `Lock_tables_priv` | `Lock_tables_priv`
| `References_priv` | `References_priv`
| `Reload_priv` |
| `Shutdown_priv` |
| `Process_priv` |
| `File_priv` |
| `Show_db_priv` |
| `Super_priv` |
| `Repl_slave_priv` |
| `Repl_client_priv` |
Sicherheitsspalten | `ssl_type` |
| `ssl_cipher` |
| `x509_issuer` |
| `x509_subject` |
Spalten zur Ressourcensteuerung | `max_questions` |
| `max_updates` |
| `max_connections` |
| `max_user_connections` |

Die Spalten `Event_priv` und `Trigger_priv` wurden in MySQL 5.1.6 hinzugefügt.

Während der zweiten Stufe der Zugriffssteuerung führt der Server eine Anforderungsverifizierung durch, um sicherzustellen, dass jeder Client über die erforderlichen Berechtigungen für jede abgesetzt Anforderung verfügt. Neben den Grant-Tabellen `user`, `db` und `host` kann der Server auch die Tabellen `tables_priv` und `columns_priv` für Anforderungen abfragen, die Tabellen betreffen. Die Tabellen `tables_priv` und `columns_priv` ermöglichen eine feiner abgestufte Berechtigungssteuerung auf der Tabellen- und Spaltenebene. Die Tabellen haben die folgenden Spalten:

Tabellenname | tables_priv | columns_priv
Spalten für Gültigkeitsbereiche | `Host` | `Host`
| `Db` | `Db`
| `User` | `User`
| `Table_name` | `Table_name`
|  | `Column_name`
Berechtigungsspalten | `Table_priv` | `Column_priv`
| `Column_priv` |
Weitere Spalten | `Timestamp` | `Timestamp`
| `Grantor` |

Die Spalten `Timestamp` und `Grantor` werden derzeit nicht benutzt und sollen deswegen an dieser Stelle nicht weiter behandelt werden.

Zur Verifizierung von Anforderungen, die gespeicherte Routinen betreffen, kann der Server auch die Tabelle `procs_priv` abfragen. Diese Tabelle weist die folgenden Spalten auf:

Tabellenname | procs_priv
Spalten für Gültigkeitsbereiche | `Host`
| `Db`
| `User`
| `Routine_name`
| `Routine_type`
Berechtigungsspalten | `Proc_priv`
Weitere Spalten | `Timestamp`
| `Grantor`

Die Spalte `Routine_type` ist eine `ENUM`-Spalte, die mit den Werten `'FUNCTION'` bzw. `'PROCEDURE'` den Typ der Routine angibt, auf die sich der Datensatz bezieht. Diese Spalte gestattet die separate Gewährung von Berechtigungen für eine Funktion oder Prozedur gleichen Namens.

Die Spalten `Timestamp` und `Grantor` werden derzeit nicht benutzt und sollen deswegen an dieser Stelle nicht weiter behandelt werden.

Jede Grant-Tabelle enthält Gültigkeitsbereichs- und Berechtigungsspalten:

- Bereichsspalten bestimmen den Gültigkeitsbereich aller Datensätze in den Tabellen, d. h. den Kontext, in dem der Datensatz gültig ist. So würde beispielsweise eine Tabelle `user` mit den `Host`- und `User`-Werten `'thomas.loc.gov'` bzw. `'bob'` zur Authentifizierung von Verbindungen verwendet, die vom Host `thomas.loc.gov` aus durch einen Client, der den Benutzernamen `bob` angibt, hergestellt würden. Ähnlich würde ein Datensatz in der Tabelle `db` mit den Werten `'thomas.loc.gov'`, `'bob'` und `'reports'` in den Spalten `Host`, `User` und `Db` verwendet werden, wenn der Benutzer `bob` vom Host `thomas.loc.gov` aus auf die Datenbank `reports` zuzugreifen versucht. Die Tabellen `tables_priv` und `columns_priv` enthalten Gültigkeitsbereichsspalten, die die Tabellen oder Tabellenkombinationen angeben, für die der jeweilige Datensatz gilt. Die Bereichsspalten in `procs_priv` geben die jeweilige gespeicherte Routine an, für die der Datensatz gilt.

- Berechtigungsspalten legen fest, welche Berechtigungen durch einen Datensatz gewährt werden, d. h. welche Operationen durchgeführt werden können. Der Server kombiniert die Daten in den verschiedenen Grant-Tabellen zu einer vollständigen Beschreibung der Berechtigungen eines Benutzers. Abschnitt 5.8.6, „Zugriffskontrolle, Phase 2: Anfrageüberprüfung“, beschreibt, welches Regeln hierbei zugrundegelegt werden.

Bereichsspalten enthalten Strings. Diese werden wie nachfolgend gezeigt deklariert, wobei der Vorgabewert jeweils der Leer-String ist:

Spaltenname | Typ
`Host` | `CHAR(60)`
`User` | `CHAR(16)`
`Password` | `CHAR(16)`
`Db` | `CHAR(64)`
`Table_name` | `CHAR(64)`
`Column_name` | `CHAR(64)`
`Routine_name` | `CHAR(64)`

Bei der Überprüfung der `Host`-Werte im Zuge der Berechtigungsverifizierung wird keine Unterscheidung der Groß-/Kleinschreibung vorgenommen. Die `User`-, `Password`-, `Db`- und `Table_name`-Werte hingegen unterscheiden die Groß-/Kleinschreibung. Nicht unterschieden wird sie wiederum bei `Column_name`- und `Routine_name`-Werten.

In den Tabellen `user`, `db` und `host` wird jede Berechtigung in einer separaten Spalte aufgeführt, die als `ENUM('N','Y') DEFAULT 'N'` deklariert ist. Anders gesagt: Jede Berechtigung lässt sich aktivieren oder deaktivieren, wobei sie vorgabeseitig immer deaktiviert ist.

In den Tabellen `tables_priv`, `columns_priv` und `procs_priv` sind die Berechtigungsspalten als `SET`-Spalten deklariert. Werte in diesen Spalten können eine beliebige Kombination der Berechtigungen enthalten, die von der Tabelle gesteuert werden:

Tabellenname | Spaltenname | Mögliche Elemente des Satzes
`tables_priv` | `Table_priv` | `'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter', 'Create View', 'Show view', 'Trigger'`
`tables_priv` | `Column_priv` | `'Select', 'Insert', 'Update', 'References'`
`columns_priv` | `Column_priv` | `'Select', 'Insert', 'Update', 'References'`
`procs_priv` | `Proc_priv` | `'Execute', 'Alter Routine', 'Grant'`

Kurz gesagt verwendet der Server die Grant-Tabellen wie folgt:

- Die Bereichsspalten in der Tabelle `user` bestimmen, ob eingehende Verbindungen abgewiesen oder zugelassen werden. Bei zulässigen Verbindungen geben alle in der Tabelle `user` gewährten Berechtigungen die globalen Berechtigungen (Superuser-Berechtigungen) des Benutzers an. Jede Berechtigung, die in dieser Tabelle gewährt wird, gilt für alle Datenbanken auf dem Server.

  Hinweis: Da alle globalen Berechtigungen als Berechtigungen für alle Datenbanken zu betrachten sind, erlaubt das Vorhandensein einer beliebigen globalen Berechtigung für einen Benutzer diesem, alle Datenbanknamen mit `SHOW DATABASES` oder durch Untersuchen der Tabelle `SCHEMATA` von `INFORMATION_SCHEMA` anzuzeigen.

- Die Bereichsspalten der Tabelle `db` bestimmen dabei, welche Benutzer von welchen Hosts aus auf welche Datenbanken zugreifen können. Die Berechtigungsspalten legen hingegen fest, welche Operationen zulässig sind. Eine auf der Datenbankebene gewährte Berechtigung gilt für die Datenbank und alle in ihr enthaltenen Tabellen.

- Die Tabelle `host` wird in Verbindung mit der Tabelle `db` benutzt, wenn ein bestimmte Datensatz in der Tabelle `db` für mehrere Hosts gelten soll. Wenn Sie beispielsweise einem Benutzer die Verwendung einer Datenbank von verschiedenen Hosts in Ihrem Netzwerk aus gestatten wollen, lassen Sie den Wert `Host` im Datensatz des betreffenden Benutzers in der Tabelle `db` frei und geben Sie dann einen Datensatz für jeden der betreffenden Hosts in die Tabelle `host` ein. Diese Vorgehensweise wird in Abschnitt 5.8.6, „Zugriffskontrolle, Phase 2: Anfrageüberprüfung“, genauer beschrieben.

  Hinweis: Die Tabelle `host` muss mit Anweisungen wie `INSERT`, `UPDATE` und `DELETE` direkt modifiziert werden. Anweisungen wie `GRANT` und `REVOKE`, die die Grant-Tabellen indirekt manipulieren, haben keine Auswirkungen auf diese Tabelle. Die meisten MySQL-Installationen verwenden die Tabelle ohnehin nicht.

- Die Tabellen `tables_priv` und `columns_priv` ähneln der Tabelle `db`, sind aber feiner abgestuft: Sie werden nicht auf Datenbankebene, sondern auf der Tabellen- und der Spaltenebene angewendet. Eine auf der Tabellenebene gewährte Berechtigung gilt für die Tabelle und alle in ihr enthaltenen Spalten. Eine auf der Spaltenebene gewährte Berechtigung gilt indes nur für eine bestimmte Spalte.

- Die Tabelle `procs_priv` gilt für gespeicherte Routinen. Eine auf der Routinenebene gewährte Berechtigung gilt nur für eine bestimmte Routine.

Administrative Berechtigungen (wie etwa `RELOAD` oder `SHUTDOWN`) werden nur in der Tabelle `user` festgelegt. Der Grund hierfür besteht darin, dass administrative Operationen auf dem Server selbst erfolgen und nicht datenbankspezifisch sind, d. h. es gibt keinen Grund, diese Berechtigungen in anderen Grant-Tabellen aufzuführen. Tatsächlich muss der Server, um zu ermitteln, ob Sie eine administrative Operation durchführen dürfen, nur die Tabelle `user` abfragen.

Die Berechtigung `FILE` wird ebenfalls nur in der Tabelle `user` festgelegt. Sie ist im Eigentlichen keine administrative Berechtigung, aber die Fähigkeit zum Lesen oder Schreiben von Dateien auf dem Serverhost hängt nicht von der Datenbank ab, auf die Sie zugreifen.

Der Server mysqld liest die Inhalte der Grant-Tabellen beim Start in den Speicher ein. Sie können ihn mit der Anweisung `FLUSH PRIVILEGES` oder durch Ausführen der Befehle mysqladmin flush-privileges oder mysqladmin reload anweisen, die Tabellen neu einzulesen. Änderungen an den Grant-Tabellen werden umgesetzt wie in Abschnitt 5.8.7, „Wann Berechtigungsänderungen wirksam werden“, beschrieben.

Wenn Sie die Inhalte der Grant-Tabellen ändern, empfiehlt es sich sicherzustellen, dass Ihre Änderungen die Berechtigungen so konfigurieren, wie Sie es auch wünschen. Um die Berechtigungen eines gegebenen Kontos zu überprüfen, verwenden Sie die Anweisung `SHOW GRANTS`. (Siehe auch Abschnitt 13.5.4.11, „`SHOW GRANTS`“.) Um also etwa die Berechtigungen zu ermitteln, die einem Konto mit den `Host`- und `User`-Werten `pc84.example.com` bzw. `bob` gewährt werden, setzen Sie folgende Anweisung ab:

    SHOW GRANTS FOR 'bob'@'pc84.example.com';

Weitere Hilfe zur Diagnose von Problemen in Zusammenhang mit Berechtigungen finden Sie in Abschnitt 5.8.8, „Gründe für `Access denied`-Fehler“. Allgemeine Richtlinien zu Sicherheitsfragen finden Sie außerdem in Abschnitt 5.7, „Absichern von MySQL gegen Angreifer“.

### 5.8.3. Von MySQL zur Verfügung gestellte Berechtigungen

Die Informationen zu Kontenberechtigungen sind in den Tabellen `user`, `db`, `host`, `tables_priv`, `columns_priv` und `procs_priv` in der `mysql`-Datenbank abgelegt. Der MySQL-Server liest die Inhalte dieser Tabellen beim Start in den Speicher ein. Unter den in Abschnitt 5.8.7, „Wann Berechtigungsänderungen wirksam werden“, beschriebenen Umständen erfolgt zudem ein Neueinlesen der Inhalte. Entscheidungen der Zugriffssteuerung basieren auf den im Arbeitsspeicher vorhandenen Kopien der Grant-Tabellen.

Die in den Anweisungen `GRANT` und `REVOKE` zur Bezeichnung von Berechtigungen verwendeten Namen sind in der folgenden Tabelle aufgeführt. Diese enthält außerdem Angaben zu dem mit der jeweiligen Berechtigung in den Grant-Tabellen verknüpften Spaltennamen und zum Kontext, in dem die Berechtigung gültig ist. Weitere Informationen zur Bedeutung der einzelnen Berechtigungen können Sie Abschnitt 13.5.1.3, „`GRANT` und `REVOKE`“, entnehmen.

Berechtigung | Spalte | Kontext
`CREATE` | `Create_priv` | Datenbanken, Tabellen oder Indizes
`DROP` | `Drop_priv` | Datenbanken oder Tabellen
`GRANT OPTION` | `Grant_priv` | Datenbanken, Tabellen oder gespeicherte Routinen
`REFERENCES` | `References_priv` | Datenbanken oder Tabellen
`EVENT` | `Event_priv` | Datenbanken
`ALTER` | `Alter_priv` | Tabellen
`DELETE` | `Delete_priv` | Tabellen
`INDEX` | `Index_priv` | Tabellen
`INSERT` | `Insert_priv` | Tabellen
`SELECT` | `Select_priv` | Tabellen
`UPDATE` | `Update_priv` | Tabellen
`TRIGGER` | `Trigger_priv` | Tabellen
`CREATE VIEW` | `Create_view_priv` | Views
`SHOW VIEW` | `Show_view_priv` | Views
`ALTER ROUTINE` | `Alter_routine_priv` | gespeicherte Routinen
`CREATE ROUTINE` | `Create_routine_priv` | gespeicherte Routinen
`EXECUTE` | `Execute_priv` | gespeicherte Routinen
`FILE` | `File_priv` | Dateizugriff auf dem Serverhost
`CREATE TEMPORARY TABLES` | `Create_tmp_table_priv` | Serveradministration
`LOCK TABLES` | `Lock_tables_priv` | Serveradministration
`CREATE USER` | `Create_user_priv` | Serveradministration
`PROCESS` | `Process_priv` | Serveradministration
`RELOAD` | `Reload_priv` | Serveradministration
`REPLICATION CLIENT` | `Repl_client_priv` | Serveradministration
`REPLICATION SLAVE` | `Repl_slave_priv` | Serveradministration
`SHOW DATABASES` | `Show_db_priv` | Serveradministration
`SHUTDOWN` | `Shutdown_priv` | Serveradministration
`SUPER` | `Super_priv` | Serveradministration

Einige Releases von MySQL enthalten Änderungen an der Struktur der Grant-Tabellen, damit neue Berechtigungen oder Funktionen hinzugefügt werden können. Wenn Sie ein Upgrade auf eine neue MySQL-Version durchführen, sollten Sie Ihre Grant-Tabellen aktualisieren, damit sichergestellt ist, dass diese auf der aktuellen Struktur basieren und auf diese Weise neue Funktionalitäten nutzen können. Siehe auch Abschnitt 5.6, „mysql_fix_privilege_tables — Upgrade von MySQL-Systemtabellen“.

Die Berechtigungen `EVENT` und `TRIGGER` wurden in MySQL 5.1.6 hinzugefügt.

Um gespeicherte Funktionen zu erstellen oder zu verändern, benötigen Sie bei aktiviertem binärem Loggen unter Umständen auch die Berechtigung `SUPER` (siehe auch Beschreibung in Abschnitt 19.4, „Binärloggen gespeicherter Routinen und Trigger“).

Die Berechtigungen `CREATE` und `DROP` gestatten Ihnen die Erstellung neuer bzw. das Löschen vorhandener Datenbanken und Tabellen. Wenn Sie einem Benutzer die Berechtigung `DROP` für die Datenbank `mysql` gewähren, kann dieser Benutzer die Datenbank löschen, in der die MySQL-Zugriffsberechtigungen gespeichert sind.

Die Berechtigungen `SELECT`, `INSERT`, `UPDATE` und `DELETE` gestatten Ihnen die Durchführung der betreffenden Operationen an Datensätzen in vorhandenen Tabellen einer Datenbank.

`SELECT`-Anweisungen erfordern die Berechtigung `SELECT` nur dann, wenn Sie sie tatsächlich Datensätze aus eine Tabelle abrufen. Einige `SELECT`-Anweisungen greifen nicht auf Tabellen zu und können deswegen ohne Berechtigung für eine bestimmte Datenbank ausgeführt werden. So können Sie etwa den Client mysql als einfachen Taschenrechner zur Auswertung von Ausdrücken verwenden, die keine Tabellen referenzieren:

    SELECT 1+1;
    SELECT PI()*2;

Die Berechtigung `INDEX` erlaubt Ihnen das Erstellen und Löschen von Indizes. `INDEX` gilt für vorhandene Tabellen. Wenn Sie die Berechtigung `CREATE` für eine Tabelle haben, können Sie Indexdefinitionen in die `CREATE TABLE`-Anweisung einfügen.

Die Berechtigung `ALTER` gestattet es Ihnen, mit `ALTER TABLE` die Struktur einer Tabelle zu ändern oder die Tabelle umzubenennen.

Die Berechtigung `CREATE ROUTINE` ist zur Erstellung gespeicherter Routinen (Funktionen und Prozeduren) erforderlich. Die Berechtigung `ALTER ROUTINE` benötigen Sie zum Ändern oder Löschen gespeicherter Routinen und die Berechtigung `EXECUTE` für deren Ausführung.

Die Berechtigung `TRIGGER` erlaubt Ihnen das Erstellen und Löschen von Triggern. Sie benötigen diese Berechtigung für eine Tabelle, um Trigger für diese Tabelle erstellen oder löschen zu dürfen. (Vor MySQL 5.1.6 erforderten diese Operationen die Berechtigung `SUPER`.)

Die Berechtigung `EVENT` erlaubt Ihnen die Erstellung von Ereignissen im Ereignisplaner.

Mit der Berechtigung `GRANT` können Sie anderen Benutzern die Berechtigungen gewähren, die Sie selbst besitzen. Sie kann für Datenbanken, Tabellen und gespeicherte Routinen verwendet werden.

Die Berechtigung `FILE` gibt Ihnen die Erlaubnis, Dateien auf dem Serverhost mit den `LOAD DATA INFILE`- und `SELECT ... INTO OUTFILE`-Anweisungen zu lesen bzw. zu schreiben. Ein Benutzer mit der Berechtigung `FILE` kann jede Datei auf dem Server lesen, die entweder von allen oder vom MySQL-Server gelesen werden kann. (Daraus folgt, dass der Benutzer jede Datei in jedem Datenbankverzeichnis lesen kann, da der Server auf all diese Dateien zugreifen darf.) Die Berechtigung `FILE` erlaubt dem Benutzer auch die Erstellung neuer Dateien in allen Verzeichnissen, auf die der MySQL-Server Schreibzugriff hat. Der Server kann vorhandene Dateien jedoch nicht überschreiben (dies ist eine Sicherheitsmaßnahme).

Die verbleibenden Berechtigungen werden für administrative Operationen verwendet. Viele von ihnen können mit dem Programm mysqladmin oder durch Absetzen von SQL-Anweisungen ausgeführt werden. Die folgende Tabelle zeigt, die Ausführung welcher mysqladmin-Befehle mit den einzelnen administrativen Berechtigungen möglich ist:

Berechtigung | Für Berechtigte verfügbare Befehle
`RELOAD` | `flush-hosts`, `flush-logs`, `flush-privileges`, `flush-status`, `flush-tables`, `flush-threads`, `refresh`, `reload`
`SHUTDOWN` | `shutdown`
`PROCESS` | `processlist`
`SUPER` | `kill`

Der Befehl `reload` weist den Server an, die Grant-Tabellen erneut in den Speicher einzulesen. `flush-privileges` ist ein Synonym für `reload`. Der Befehl `refresh` schließt die Logdateien und öffnet sie dann neu und schreibt zudem alle Tabellen neu auf Festplatte. Die übrigen `flush-`xxx``-Befehle führen Funktionen aus, die `refresh` ähneln, sind aber spezieller und in bestimmten Fällen vorzuziehen. Wenn Sie beispielsweise nur die Logdateien neu schreiben wollen, ist `flush-logs` eine bessere Wahl als `refresh`.

Der Befehl `shutdown` fährt den Server herunter. Eine entsprechende SQL-Anweisung gibt es nicht.

Der Befehl `processlist` zeigt Informationen zu den Threads an, die auf dem Server ausgeführt werden (und somit auch zu den Anweisungen, die von den Clients ausgeführt werden). Der Befehl `kill` terminiert Server-Threads. Eigene Threads können Sie immer anzeigen oder terminieren; zum Anzeigen von Threads, die von anderen Benutzern gestartet wurden, benötigen Sie die Berechtigung `PROCESS` und zum Terminieren solcher Threads die Berechtigung `SUPER`. Siehe auch Abschnitt 13.5.5.3, „`KILL`“.

Die Berechtigung `CREATE TEMPORARY TABLES` ermöglicht die Verwendung des Schlüsselwortes `TEMPORARY` in `CREATE TABLE`-Anweisungen.

Die Berechtigung `LOCK TABLES` gestattet die Verwendung expliziter `LOCK TABLES`-Anweisungen zum Sperren von Tabellen, für die Sie die Berechtigung `SELECT` haben. Dies umfasst auch das Setzen von Schreibsperren, wodurch das Lesen der Tabellen durch andere unterbunden wird.

Die Berechtigung `REPLICATION CLIENT` ermöglicht die Verwendung von `SHOW MASTER STATUS` und `SHOW SLAVE STATUS`.

Die Berechtigung `REPLICATION SLAVE` sollte Konten gewährt werden, die von Slave-Servern zum Herstellen einer Verbindung mit dem aktuellen Server als Master verwendet werden. Ohne diese Berechtigung kann der Slave keine Updates anfordern, die an den Datenbanken auf dem Master-Server vorgenommen wurden.

Die Berechtigung `SHOW DATABASES` ermöglicht dem Konto die Anzeige von Datenbanknamen durch Absetzen einer `SHOW DATABASE`-Anweisung. Konten, die diese Berechtigung nicht haben, sehen nur solche Datenbanken, für die sie Berechtigungen haben; wurde der Server mit der Option `--skip-show-database` gestartet, dann kann die Anweisung überhaupt nicht verwendet werden. Beachten Sie, dass jede globale Berechtigung eine Berechtigung für die Datenbank ist.

Es empfiehlt sich deswegen, einem Konto nur diejenigen Berechtigungen zu gewähren, die es tatsächlich braucht. Besondere Vorsicht sollten Sie bei Gewährung der Berechtigung `FILE` sowie administrativer Berechtigungen walten lassen:

- Die Berechtigung `FILE` kann missbraucht werden, um beliebige Dateien, die der MySQL-Server auf dem Serverhost lesen kann, in eine Datenbanktabelle einzulesen. Dies betrifft alle World-Readable-Dateien sowie Dateien im Datenverzeichnis des Servers. Die Tabelle kann dann mit `SELECT` aufgerufen und ihr Inhalt an den Clienthost übertragen werden.

- Die Berechtigung `GRANT` gestattet Benutzern, ihre Berechtigungen an andere Benutzer weiterzugeben. Zwei Benutzer, die unterschiedliche Berechtigungen haben und beide über die Berechtigung `GRANT` verfügen, können ihre Berechtigungen kombinieren.

- Die Berechtigung `ALTER` kann verwendet werden, um das Berechtigungssystem durch Umbenennen zu unterlaufen.

- Die Berechtigung `SHUTDOWN` kann verwendet werden, um durch Herunterfahren des Servers anderen Benutzern Dienste vollständig zu verweigern.

- Mit der Berechtigung `PROCESS` kann man aktuell ausgeführte Anweisungen einschließlich solcher, mit denen Passwörter eingestellt oder geändert werden, unverschlüsselt anzeigen.

- Mit der Berechtigung `SUPER` schließlich lassen sich andere Clients terminieren und die Betriebsweise des Servers ändern.

- Berechtigungen, die für die `mysql`-Datenbank selbst gewährt wurden, können zum Ändern von Passwörtern und anderen Daten benutzt werden, die für Zugriffsberechtigungen relevant sind. Passwörter werden verschlüsselt gespeichert, d. h. ein arglistiger Benutzer kann sie nicht einfach im Klartext auslesen. Allerdings kann ein Benutzer mit Schreibzugriff auf die Spalte `Password` der Tabelle `user` das Passwort eines Kontos ändern und dann unter Verwendung dieses Kontos eine Verbindung mit dem MySQL-Server herstellen.

Es gibt aber auch einige Dinge, die Sie mit dem MySQL-Berechtigungssystem nicht tun können:

- Sie können nicht explizit angeben, dass einem bestimmten Benutzer der Zugriff verweigert werden soll. Anders gesagt ist es nicht möglich, einen Benutzervergleich durchzuführen und bei Übereinstimmung die Verbindung zu verweigern.

- Sie können nicht festlegen, dass ein Benutzer Berechtigungen zum Erstellen oder Löschen von Tabellen in einer Datenbank hat, aber die Datenbank selbst nicht erstellen bzw. löschen darf.

- Ein Passwort gilt immer global für ein Konto. Sie können kein Passwort für ein bestimmtes Objekt wie eine Datenbank, eine Tabelle oder eine Routine vergeben.

### 5.8.4. Verbinden mit dem MySQL-Server

Wenn Sie auf einen MySQL-Server zugreifen wollen, erwarten MySQL-Clientprogramme im Allgemeinen die Angabe bestimmter Verbindungsparameter von Ihnen:

- den Namen des Hosts, auf dem der MySQL-Server ausgeführt wird

- Ihren Benutzernamen

- Ihr Passwort

Der Client mysql kann beispielsweise wie folgt über die Befehlszeile gestartet werden (die Eingabeaufforderung wird durch `shell>` repräsentiert):

    shell> mysql -h host_name -u user_name -pyour_pass

Alternative Formen der Optionen `-h`, `-u` und `-p` sind `--host=`host_name``, `--user=`user_name`` und `--password=`your_pass``. Beachten Sie, dass zwischen `-p` oder `--password=` und dem nachfolgenden Passwort kein Leerzeichen stehen darf.

Wenn Sie die Option `-p` oder `--password` verwenden, aber keinen Passwortwert angeben, fordert das Clientprogramm Sie zur Eingabe des Passworts auf. Das Passwort wird bei der Eingabe nicht angezeigt. Dies ist sicherer als die Angabe des Passworts über die Befehlszeile. Ein Benutzer auf Ihrem System kann ein über die Befehlszeile angegebenes Passwort unter Umständen anzeigen, indem er einen Befehl wie ps auxww ausführt. Siehe auch Abschnitt 5.9.6, „Wie Sie Ihre Kennwörter sicher halten“.

MySQL-Clientprogramme verwenden Standardwerte für alle Verbindungsparameteroptionen, die Sie nicht angeben:

- Der Standardhostname ist `localhost`.

- Der vorgabeseitige Benutzername heißt unter Windows `ODBC`, unter Unix ist es Ihr Anmeldename.

- Wenn weder die Option `-p` noch die Option `--password` angegeben wird, wird kein Passwort übergeben.

Das bedeutet für einen Unix-Benutzer mit dem Anmeldenamen `joe`, dass alle folgenden Befehle äquivalent sind:

    shell> mysql -h localhost -u joe
    shell> mysql -h localhost
    shell> mysql -u joe
    shell> mysql

Andere MySQL-Clients verhalten sich ähnlich.

Sie können andere Standardwerte festlegen, die zur Herstellung einer Verbindung verwendet werden sollen, damit Sie sie nicht jedes Mal auf der Befehlszeile angeben müssen, wenn Sie ein Clientprogramm aufrufen. Hierzu gibt es mehrere Möglichkeiten:

- Sie können die Verbindungsparameter im Abschnitt `[client]` einer Optionsdatei angeben. Der entsprechende Abschnitt der Datei kann etwa so aussehen:

      [client]
      host=host_name
      user=user_name
      password=your_pass

  Abschnitt 4.3.2, „my.cnf-Optionsdateien“, enthält eine eingehendere Beschreibung der Optionsdateien.

- Sie können bestimmte Verbindungsparameter auch über Umgebungsvariablen angeben. Der Host kann für mysql mithilfe von `MYSQL_HOST` festgelegt werden. Der MySQL-Benutzername kann über `USER` angegeben werden (dies gilt nur für Windows und NetWare). Das Passwort kann über `MYSQL_PWD` angegeben werden. Dies beeinträchtigt jedoch die Sicherheit (siehe auch Abschnitt 5.9.6, „Wie Sie Ihre Kennwörter sicher halten“). Eine Liste der Variablen finden Sie unter Anhang F, Umgebungsvariablen.

### 5.8.5. Zugriffskontrolle, Phase 1: Verbindungsüberprüfung

Wenn Sie eine Verbindung mit einem MySQL-Server herzustellen versuchen, kann dieser die Verbindungsanfrage basierend auf Ihrer Identität und darauf, ob Sie diese Identität durch Übermittlung nachgewiesen haben, annehmen oder abweisen. Im Falle der Abweisung verweigert Ihnen der Server jedweden Zugriff. Andernfalls akzeptiert der Server die Verbindung. Er schaltet dann auf Stufe 2 um und erwartet Ihre Anforderungen.

Ihre Identität basiert auf zwei Datenelementen:

- dem Clienthost, von dem aus Sie die Verbindung herstellen

- Ihrem MySQL-Benutzernamen

Die Identitätsprüfung wird mithilfe der drei Gültigkeitsbereichsspalten (`Host`, `User` und `Password`) der Tabelle `user` durchgeführt. Der Server akzeptiert die Verbindung nur dann, wenn die Werte in den Spalten `Host` und `User` eines Datensatzes in der Tabelle `user` mit dem vom Client übermittelten Host- und Benutzernamen übereinstimmen und der Client nachfolgend das Passwort für diesen Datensatz sendet.

Die `Host`-Werte in der Tabelle `user` können wie folgt angegeben werden:

- Ein `Host`-Wert kann ein Hostname oder eine IP-Adresse oder aber `'localhost'` (zur Bezeichnung des lokalen Hosts) sein.

- Sie können die Jokerzeichen ‘`%`’ und ‘`_`’ in `Host`-Spaltenwerten benutzen. Sie haben die gleiche Bedeutung wie bei Mustervergleichsoperationen, die mit dem Operator `LIKE` durchgeführt werden. So stimmt etwa der `Host`-Wert `'%'` mit allen Hostnamen überein, während der Wert `'%.mysql.com'` eine Übereinstimmung mit allen Hosts der Domäne `mysql.com` bedingt.

- Bei `Host`-Werten, die als IP-Nummern angegeben werden, können Sie ein Netzmaske angeben, die die Anzahl der Bits definiert, die für die Netzwerknummer verwendet werden. Zum Beispiel:

      GRANT ALL PRIVILEGES ON db.* TO david@'192.58.197.0/255.255.255.0';

  Hiermit kann `david` von jedem Clienthost aus eine Verbindung herstellen, der die IP-Nummer `client_ip` hat, sofern für diese die folgende Bedingung wahr ist:

      client_ip & netmask = host_ip

  Das bedeutet für die gerade gezeigte `GRANT`-Anweisung:

      client_ip & 255.255.255.0 = 192.58.197.0

  IP-Nummern, die dieser Bedingung genügen und eine Verbindung mit dem MySQL-Server herstellen können, sind mithin diejenigen im Bereich zwischen `192.58.197.0` und `192.58.197.255`.

  Hinweis: Die Netzmaske kann nur verwendet werden, um den Server anzuweisen, die ersten acht, 16, 24 oder alle 32 Bits der Adresse zu verwenden. Ein paar Beispiele:

  - `192.0.0.0/255.0.0.0`: Alle Hosts im Klasse-A-Netzwerk 192.

  - `192.168.0.0/255.255.0.0`: Alle Hosts im Klasse-B-Netzwerk 192.168.

  - `192.168.1.0/255.255.255.0`: Alle Hosts im Klasse-C-Netzwerk 192.168.1.

  - `192.168.1.1`: Nur die angegebene IP-Adresse.

  Die folgende Netzmaske (28 Bits) wird hingegen nicht funktionieren:

      192.168.0.1/255.255.255.240

- Ein leerer `Host`-Wert in einem Datensatz der Tabelle `db` bedeutet, dass die Berechtigungen mit denen im Datensatz in der `host`-Tabelle kombiniert werden sollen, der mit dem Hostnamen des Clients übereinstimmt. Diese Berechtigungen werden mithilfe des logischen UND (Schnittmenge), nicht des logischen ODER (Gesamtmenge) verknüpft. Abschnitt 5.8.6, „Zugriffskontrolle, Phase 2: Anfrageüberprüfung“, beschreibt die Verwendung der Tabelle `host` im Detail.

  Ein leerer `Host`-Wert in den anderen Grant-Tabellen entspricht `'%'`.

Da es möglich ist, Jokerwerte in den IP-Adressen der `Host`-Spalte zu verwenden (z. B. `'144.155.166.%'`, um eine Übereinstimmung mit jedem Host in einem bestimmten Subnetz zu erzielen), könnte jemand versuchen, diese Funktionalität auszunutzen, indem er einen Host `144.155.166.somewhere.com` nennt. Um derartige Versuche zu durchkreuzen, verbietet MySQL Mustervergleiche mit Hostnamen, die mit Ziffern und einem Punkt beginnen. Das bedeutet, dass ,wenn Sie einen Host mit dem Namen `1.2.foo.com` oder ähnlich haben, dieser Name niemals eine Übereinstimmung in der `Host`-Spalte der Grant-Tabellen finden wird. Ein IP-Jokerwert kann nur mit IP-Adressen, nicht jedoch mit Hostnamen übereinstimmen.

In der Spalte `User` sind Jokerzeichen nicht zulässig, Sie können jedoch einen leeren Wert angeben, der mit jedem Namen übereinstimmt. Wenn der Datensatz in der Tabelle `user`, der mit einer eingehenden Verbindung übereinstimmt, einen leeren Benutzernamen aufweist, dann wird der Benutzer als anonymer Benutzer ohne Namen und nicht als Benutzer mit dem Namen betrachtet, der eigentlich vom Client übergeben wurde. Folglich wird ein leerer Benutzername für alle weiteren Zugriffsüberprüfungen während der gesamten Dauer der Verbindung (also während der zweiten Stufe) verwendet.

Die Spalte `Password` darf leer sein. Dies ist kein Joker und bedeutet auch keine Übereinstimmung mit beliebigen Passwörtern. Vielmehr besagt dies, dass der Benutzer eine Verbindung ohne Angabe eines Passworts herstellen muss.

Nichtleere `Password`-Werte in der Tabelle `user` stehen für verschlüsselte Passwörter. MySQL speichert Passwörter nicht in unverschlüsselter, problemlos ersichtlicher Form. Stattdessen wird das von einem Benutzer, der eine Verbindung herstellen will, eingegebene Passwort verschlüsselt (und zwar mit der Funktion `PASSWORD()`). Dieses verschlüsselte Passwort wird dann während des Verbindungsaufbaus verwendet, um zu überprüfen, ob das Passwort korrekt ist. (Dieser Vorgang läuft ab, ohne dass das verschlüsselte Passwort jemals über die Verbindung übermittelt wird.) Aus der Sicht von MySQL ist das verschlüsselte Passwort das echte Passwort, d. h. Sie sollten niemals jemandem den Zugriff darauf ermöglichen. Insbesondere sollten Sie Nichtadministratoren niemals Lesezugriff auf die Tabellen in der `mysql`-Datenbank gewähren.

MySQL 5.1 verwendet eine stärkere, erstmals in MySQL 4.1 implementierte Authentifizierungsmethode, die während des Verbindungsvorgangs einen besseren Passwortschutz bietet als frühere Versionen. Sie ist auch dann sicher, wenn TCP/IP-Pakete abgefangen oder die `mysql`-Datenbank aufgezeichnet wird. Abschnitt 5.8.9, „Kennwort-Hashing ab MySQL 4.1“, enthält eine eingehendere Beschreibung der Passwortverschlüsselung.

Die folgende Tabelle zeigt, wie verschiedene Kombinationen von `Host`- und `User`-Werten in der Tabelle `user` auf eingehende Verbindungen angewendet werden.

`Host` Wert | `User` Wert | Zulässige Verbindungen
`'thomas.loc.gov'` | `'fred'` | `fred`, stellt Verbindung her über `thomas.loc.gov`
`'thomas.loc.gov'` | `''` | Beliebiger Benutzer, stellt Verbindung her über `thomas.loc.gov`
`'%'` | `'fred'` | `fred`, stellt Verbindung her über beliebigen Host
`'%'` | `''` | Beliebiger Benutzer, stellt Verbindung her über beliebigen Host
`'%.loc.gov'` | `'fred'` | `fred`, stellt Verbindung her über beliebigen Host in der Domäne `loc.gov`
`'x.y.%'` | `'fred'` | `fred`, stellt Verbindung her über `x.y.net`, `x.y.com`, `x.y.edu` und so weiter (dies ist wahrscheinlich nicht sehr sinnvoll)
`'144.155.166.177'` | `'fred'` | `fred`, stellt Verbindung her vom Host mit der IP-Adresse `144.155.166.177`
`'144.155.166.%'` | `'fred'` | `fred`, stellt Verbindung her über beliebigen Host im Klasse-C-Subnetz `144.155.166`
`'144.155.166.0/255.255.255.0'` | `'fred'` | wie oben

Es kann durchaus vorkommen, dass für die Host- und Benutzernamen einer eingehenden Verbindung mehrere passende Datensätze in der Tabelle `user` vorhanden sind. Die obigen Beispiele demonstrieren dies: Mehrere der angezeigten Einträge stimmen mit einer Verbindung von `fred` über `thomas.loc.gov` überein.

Wenn mehrere Übereinstimmungen möglich sind, muss der Server ermitteln, welche davon er verwenden soll. Dieses Problem löst er wie folgt:

- Wenn der Server die Tabelle `user` in den Speicher einliest, sortiert er die Datensätze.

- Versucht nun ein Client eine Verbindung herzustellen, dann durchsucht der Server die Datensätze in der Sortierreihenfolge.

- Der Server verwendet den ersten mit dem Host- und Benutzernamen des Clients übereinstimmenden Datensatz.

Um zu verstehen, wie dies funktioniert, nehmen wir einmal an, dass die Tabelle `user` wie folgt aussieht:

    +-----------+----------+-
    | Host      | User     | ...
    +-----------+----------+-
    | %         | root     | ...
    | %         | jeffrey  | ...
    | localhost | root     | ...
    | localhost |          | ...
    +-----------+----------+-

Wenn der Server die Tabelle in den Speicher einliest, sortiert er die Datensätze mit den spezifischsten `Host`-Werten nach oben. Literale Hostnamen und IP-Nummern sind am spezifischsten. Das Muster `'%'` bedeutet „jeder Host“ und ist am wenigsten spezifisch. Datensätze mit demselben `Host`-Wert werden nach den spezifischsten `User`-Werten sortiert (wobei ein leerer `User`-Wert die Bedeutung „beliebiger Benutzer“ hat und am wenigsten spezifisch ist). Bei der oben gezeigten Tabelle `user` sieht das Ergebnis nach der Sortierung wie folgt aus:

    +-----------+----------+-
    | Host      | User     | ...
    +-----------+----------+-
    | localhost | root     | ...
    | localhost |          | ...
    | %         | jeffrey  | ...
    | %         | root     | ...
    +-----------+----------+-

Wenn ein Client eine Verbindung herzustellen versucht, durchsucht der Server die sortierten Datensätze und verwendet die erste gefundene Übereinstimmung. Stellt `jeffrey` über `localhost` eine Verbindung her, dann liegt bei zwei Datensätzen in der Tabelle eine Übereinstimmung vor: zum einen der Datensatz mit den `Host`- und `User`-Werten `'localhost'` und `''`, zum anderen der Datensatz mit den Werten `'%'` und `'jeffrey'`. Der Datensatz `'localhost'` taucht jedoch in der sortierten Tabelle zuerst auf, wird also vom Server verwendet.

Es folgt ein weiteres Beispiel. Angenommen, die Tabelle `user` sähe so aus:

    +----------------+----------+-
    | Host           | User     | ...
    +----------------+----------+-
    | %              | jeffrey  | ...
    | thomas.loc.gov |          | ...
    +----------------+----------+-

Die sortierte Tabelle hat dann folgendes Aussehen:

    +----------------+----------+-
    | Host           | User     | ...
    +----------------+----------+-
    | thomas.loc.gov |          | ...
    | %              | jeffrey  | ...
    +----------------+----------+-

Für eine Verbindung von `jeffrey` an `thomas.loc.gov` liegt eine Übereinstimmung gleich beim ersten Datensatz vor; bei einer Verbindung von `jeffrey` an `whitehouse.gov` trifft dies für den zweiten Datensatz zu.

Die Ansicht ist weitverbreitet, dass für einen gegebenen Benutzernamen alle Datensätze, die diesen Namen ausdrücklich angeben, zuerst verwendet werden, wenn der Server eine Übereinstimmung für die Verbindung sucht. Dies ist allerdings unzutreffend. Das obige Beispiel veranschaulicht dies: Eine Verbindung von `jeffrey` an `thomas.loc.gov` findet ihre erste Übereinstimmung nicht bei dem Datensatz, der `'jeffrey'` als Wert in der Spalte `User` enthält, sondern beim Datensatz ohne Benutzernamen. Hieraus folgt, dass `jeffrey` als anonymer Benutzer authentifiziert wird, obwohl er bei der Verbindungsherstellung einen Benutzernamen angegeben hat.

Wenn Sie eine Verbindung mit dem Server herstellen können, aber Ihre Berechtigungen nicht dem entsprechen, was Sie erwarten, dann wurden Sie wahrscheinlich über ein anderes Konto authentifiziert. Um zu ermitteln, welches Konto der Server für Ihre Authentifizierung verwendet hat, verwenden Sie die Funktion `CURRENT_USER()`. (Siehe auch Abschnitt 12.10.3, „Informationsfunktionen“.) Sie gibt einen Wert im Format ``user_name`@`host_name`` zurück, der die Werte `User` und `Host` des entsprechenden Datensatzes in der Tabelle `user` angibt. Angenommen, `jeffrey` hat eine Verbindung hergestellt und setzt die folgende Abfrage ab:

    mysql> SELECT CURRENT_USER();
    +----------------+
    | CURRENT_USER() |
    +----------------+
    | @localhost     |
    +----------------+

Das hier gezeigte Ergebnis gibt an, dass der übereinstimmende Datensatz in der Tabelle `user` einen leeren Wert in der Spalte `User` aufweist. Mit anderen Worten behandelt der Server `jeffrey` als anonymen Benutzer.

Ein anderer Schritt, den Sie zur Diagnose von Authentifizierungsproblemen anwenden können, besteht darin, die Tabelle `user` auszudrucken und sie manuell zu sortieren, um zu ermitteln, wo die erste Übereinstimmung auftritt.

### 5.8.6. Zugriffskontrolle, Phase 2: Anfrageüberprüfung

Nachdem Sie eine Verbindung hergestellt haben, wechselt der Server zu Stufe 2 der Zugriffssteuerung. Für jede Anforderung, die Sie über die Verbindung absetzen, ermittelt der Server, welche Operation Sie durchführen wollen, und überprüft dann, ob Sie die zu diesem Zweck erforderlichen Berechtigungen besitzen. Hier nun kommen die Berechtigungsspalten in den Grant-Tabellen ins Spiel. Diese Berechtigungen können aus den folgenden Tabellen stammen: `user`, `db`, `host`, `tables_priv`, `columns_priv` oder `procs_priv`. (An dieser Stelle kann es unter Umständen hilfreich sein, noch einmal Abschnitt 5.8.2, „Wie das Berechtigungssystem funktioniert“, zu lesen. Dort sind die Spalten aufgelistet, die in den verschiedenen Grant-Tabellen vorhanden sind.)

Die Tabelle `user` gewährt Berechtigungen, die Ihnen auf globaler Basis zugewiesen werden und die unabhängig von der gewählten Standarddatenbank gelten. Wenn die Tabelle `user` Ihnen beispielsweise die Berechtigung `DELETE` gewährt, können Sie Datensätze aus allen Tabellen in allen Datenbanken auf dem Serverhost löschen! Anders gesagt sind Berechtigungen für die Tabelle `user` Superuser-Berechtigungen. Es ist klug, Berechtigungen in der Tabelle `user` nur Superusern wie beispielsweise Datenbankadministratoren zu gewähren. Bei allen anderen Benutzern sollten Sie die Berechtigungen in der Tabelle `user` auf `'N'` stehen lassen und Berechtigungen nur auf spezifischeren Ebenen gewähren. Sie können Berechtigungen für bestimmte Datenbanken, Tabellen, Spalten und Routinen gewähren.

Die Tabellen `db` und `host` gewähren datenbankspezifische Berechtigungen. Werte in den Bereichsspalten dieser Tabellen können die folgende Form annehmen:

- Die Jokerzeichen ‘`%`’ und ‘`_`’ können in den Spalten `Host` und `Db` dieser Tabellen verwendet werden. Sie haben die gleiche Bedeutung wie bei Mustervergleichsoperationen, die mit dem Operator `LIKE` durchgeführt werden. Wenn Sie eines der Zeichen beim Gewähren von Berechtigungen literal verwenden wollen, müssen Sie es mit einem Backslash kennzeichnen. Um beispielsweise den Unterstrich (‘`_`’) als Teil eines Datenbanknamens zu verwenden, geben Sie ihn als ‘`\_`’ in der `GRANT`-Anweisung an.

- Der Wert `'%'` in der Spalte `Host` der Tabelle `db` bedeutet „ein beliebiger Host“. Ein leerer `Host`-Wert in der Tabelle `db` hat die Bedeutung „Weitere Informationen der Tabelle `host` entnehmen“ (dieser Vorgang wird im weiteren Verlauf dieses Abschnitts noch beschrieben).

- Der Wert `'%'` oder ein leerer Wert in der Spalte `Host` der Tabelle `host` bedeutet „ein beliebiger Host“.

- Der Wert `'%'` oder ein leerer Wert in der Spalte `Db` in einer dieser Tabellen bedeutet „eine beliebige Datenbank“.

- Ein leerer `User`-Wert in einer der Tabellen führt zur Übereinstimmung mit dem anonymen Benutzer.

Der Server liest die Tabellen `db` und `host` in den Speicher ein und sortiert sie, während er gleichzeitig die Tabelle `user` einliest. Der Server sortiert die Tabelle `db` nach den Bereichsspalten `Host`, `Db` und `User` und die Tabelle `host` nach den Bereichsspalten `Host` und `Db`. Wie bei der Sortierung der Tabelle `user` werden auch hier die spezifischeren Werte an den Anfang und die weniger spezifischen an das Ende der Tabelle gesetzt, und auch hier verwendet der Server bei der Suche nach Übereinstimmungen das erste passende Ergebnis.

Die Tabellen `tables_priv` `columns_priv` und `proc_priv` gewähren tabellenspezifische, spaltenspezifische und routinenspezifische Berechtigungen. Werte in den Bereichsspalten dieser Tabellen können die folgende Form annehmen:

- Die Jokerzeichen ‘`%`’ und ‘`_`’ können in der Spalte `Host` verwendet werden. Sie haben die gleiche Bedeutung wie bei Mustervergleichsoperationen, die mit dem Operator `LIKE` durchgeführt werden.

- Der Wert `'%'` oder ein leerer Wert in der Spalte `Host` bedeutet „ein beliebiger Host“.

- Die Spalten `Db`, `Table_name` und `Column_name` dürfen weder Jokerzeichen enthalten noch leer sein.

Der Server sortiert die Tabellen `tables_priv`, `columns_priv` und `procs_priv` nach den Spalten `Host`, `Db` und `User`. Dies ähnelt der Sortierung der Tabelle `db`, ist aber einfacher, da nur die Spalte `Host` Jokerzeichen enthalten darf.

Der Server verwendet die sortierten Tabellen zur Verifizierung aller empfangenen Anforderungen. Bei Anforderungen, die administrative Berechtigungen voraussetzen (z. B. `SHUTDOWN` oder `RELOAD`), überprüft der Server nur den Datensatz in der Tabelle `user`, weil dies die einzige Tabelle ist, die administrative Berechtigungen angibt. Der Server gewährt den Zugriff, wenn der Datensatz die angeforderte Operation gestattet; andernfalls wird der Zugriff abgewiesen. Wenn Sie also beispielsweise mysqladmin shutdown ausführen wollen, aber Ihr Datensatz in der Tabelle `user` Ihnen die Berechtigung `SHUTDOWN` nicht gewährt, dann verweigert der Server Ihnen den Zugriff, ohne die Tabellen `db` oder `host` auch nur abgefragt zu haben. (Da diese Tabellen keine `Shutdown_priv`-Spalte enthalten, ist dies ohnehin unnötig.)

Bei datenbankbezogenen Anforderungen (`INSERT`, `UPDATE` usw.) überprüft der Server zuerst die globalen Berechtigungen (Superuser-Berechtigungen), indem er den Datensatz in der Tabelle `user` abfragt. Gestattet der Datensatz die angeforderte Operation, dann wird der Zugriff gewährt. Wenn die globalen Berechtigungen in der Tabelle `user` nicht ausreichend sind, ermittelt der Server die datenbankspezifischen Berechtigungen, indem er die Tabellen `db` und `host` überprüft:

1. Der Server sucht in der Tabelle `db` nach einer Übereinstimmung der Spalten `Host`, `Db` und `User`. Die Spalten `Host` und `User` werden auf Übereinstimmung mit dem Hostnamen und dem MySQL-Benutzernamen des Benutzers geprüft, der die Verbindung herstellen will. Die Spalte `Db` wird mit der Datenbank verglichen, auf die der Benutzer zugreifen will. Kann kein Datensatz für `Host` und `User` gefunden werden, dann wird der Zugriff verweigert.

2. Ist ein übereinstimmender Datensatz in der Tabelle `db` vorhanden und ist die Spalte `Host` nicht leer, dann definiert der Datensatz die datenbankspezifischen Berechtigungen für den Benutzer.

3. Ist die Spalte `Host` im übereinstimmenden Datensatz der Tabelle `db` leer, dann bedeutet dies, dass die Tabelle `host` auflistet, welche Hosts auf die Datenbank zugreifen dürfen. In diesem Fall wird in der Tabelle `host` erneut eine Übereinstimmung mit den Spalten `Host` und `Db` gesucht. Wird kein passender Datensatz in der Tabelle `host` gefunden, dann wird der Zugriff verweigert. Wird allerdings eine Übereinstimmung gefunden, dann werden die datenbankspezifischen Berechtigungen des Benutzers als Schnittmenge (nicht als Gesamtmenge!) der Berechtigungen in den Einträgen der Tabellen `db` und `host` berechnet, d. h. die Berechtigungen müssen in beiden Einträgen jeweils `'Y'` sein. (Auf diese Weise können Sie allgemeine Berechtigungen im Datensatz der Tabelle `db` gewähren und diese dann über die Tabelle `host` auf Hostbasis selektiv einschränken.)

Nachdem er die datenbankspezifischen Berechtigungen ermittelt hat, die durch die Einträge in den Tabellen `db` und `host` gewährt werden, fügt der Server diese den durch die Tabelle `user` gewährten Berechtigungen hinzu. Gestattet das Ergebnis die angeforderte Operation, dann wird der Zugriff gewährt. Andernfalls überprüft der Server nachfolgend die Tabellen- und Spaltenberechtigungen des Benutzers in den Tabellen `tables_priv` bzw. `columns_priv`, fügt diese den Benutzerberechtigungen hinzu und gestattet oder verweigert auf der Basis des Ergebnisses den Zugriff. Bei Operationen in Zusammenhang mit gespeicherten Routinen verwendet der Server die Tabelle `procs_priv` statt `tables_priv` und `columns_priv`.

Ausgedrückt in booleschen Termini, lässt sich die vorangegangene Beschreibung der Berechnung von Benutzerberechtigungen wie folgt zusammenfassen:

    global privileges
    OR (database privileges AND host privileges)
    OR table privileges
    OR column privileges
    OR routine privileges

Es ist vielleicht nicht einleuchtend, warum der Server, wenn die globalen Berechtigungen im Datensatz der Tabelle `user` zunächst nicht als ausreichend für die angeforderte Operation erachtet werden, diese Berechtigungen später zu den Berechtigungen für die Datenbanken, Tabellen und Spalten hinzufügt. Der Grund hierfür besteht darin, dass eine Anforderung mehrere Berechtigungstypen erfordern kann. Wenn Sie beispielsweise eine `INSERT INTO ... SELECT`-Anweisung ausführen, benötigen Sie sowohl die Berechtigung `INSERT` als auch die Berechtigung `SELECT`. Ihre Berechtigungen sehen unter Umständen so aus, dass der Datensatz in der Tabelle `user` eine dieser Berechtigungen und der Datensatz in der Tabelle `db` die andere Berechtigung gewährt. In diesem Fall besitzen Sie die erforderlichen Berechtigungen, um die Anforderung durchzuführen, aber der Server kann dies nicht mithilfe nur einer Tabelle bestimmen; vielmehr müssen die von den Einträgen in beiden Tabellen gewährten Berechtigungen kombiniert werden.

Die Tabelle `host` wird von `GRANT`- und `REVOKE`-Anweisungen nicht beeinflusst, liegt also in den meisten MySQL-Installationen brach. Wenn Sie sie jedoch manuell modifizieren, können Sie sie für bestimmte Spezialzwecke einsetzen, z. B. um eine Liste sicherer Server zu führen. Bei TcX beispielsweise enthält die Tabelle `host` eine Liste aller Systeme im lokalen Netzwerk. Diesen sind alle Berechtigungen gewährt.

Sie können die Tabelle `host` auch verwenden, um Hosts anzugeben, die nicht sicher sind. Nehmen wir an, dass Sie einen Computer namens `public.your.domain` haben, der sich in einem öffentlichen Bereich befindet, den Sie als nicht sicher erachten. Sie können Zugriff auf alle Hosts in Ihrem Netzwerk mit Ausnahme dieses Computers gewähren, indem Sie die Einträge der Tabelle `host` wie folgt verwenden:

    +--------------------+----+-
    | Host               | Db | ...
    +--------------------+----+-
    | public.your.domain | %  | ... (all privileges set to 'N')
    | %.your.domain      | %  | ... (all privileges set to 'Y')
    +--------------------+----+-

Natürlich sollten Sie Ihre Änderungen an den Grant-Tabellen immer testen (z. B. mit `SHOW GRANTS`), um sicherzustellen, dass Ihre Zugriffsberechtigungen tatsächlich so konfiguriert sind, wie Sie es wünschen.

### 5.8.7. Wann Berechtigungsänderungen wirksam werden

Beim Start liest mysqld den gesamten Inhalt der Grant-Tabellen in den Speicher. Die Tabellen im Arbeitsspeicher werden zu diesem Zeitpunkt für die Zugriffssteuerung verbindlich.

Wenn der Server die Grant-Tabellen neu lädt, sind Berechtigungen für vorhandene Clientverbindungen hiervon wie folgt betroffen:

- Änderungen an Berechtigungen für Tabellen und Spalten werden beginnend mit der nächsten Anforderung des Clients gültig.

- Datenbankberechtigungen werden bei der nächsten `USE `db_name``-Anweisung gültig.

- Änderungen an globalen Berechtigungen und Passwörtern werden gültig, wenn der Client beim nächsten Mal eine Verbindung herstellen will.

Wenn Sie die Grant-Tabellen indirekt mit Anweisungen wie `GRANT`, `REVOKE` oder `SET PASSWORD` modifizieren, bemerkt der Server diese Änderungen und lädt die Grant-Tabellen sofort wieder neu in den Speicher.

Ändern Sie die Grant-Tabellen hingegen direkt mit Anweisungen wie `INSERT`, `UPDATE` oder `DELETE`, dann werden Ihre berechtigungsbezogenen Änderungen erst umgesetzt, wenn Sie den Server neu starten oder ihn zum Neuladen der Tabellen anweisen. Um die Grant-Tabellen manuell neu zu laden, setzen Sie eine `FLUSH PRIVILEGES`-Anweisung ab oder führen den Befehl mysqladmin flush-privileges oder mysqladmin reload aus.

Wenn Sie die Grant-Tabellen ändern, aber vergessen, sie neu zu laden, dann werden Ihre Änderungen erst dann umgesetzt, wenn Sie den Server neu starten. Unter Umständen wundern Sie sich aus diesem Grund darüber, dass Ihre Änderungen überhaupt keinen Unterschied zu machen scheinen!

### 5.8.8. Gründe für `Access denied`-Fehler

Wenn beim Versuch, eine Verbindung zum MySQL-Server herzustellen, Probleme auftreten, dann können Sie die in diesem Abschnitt beschriebenen Schritte ausführen, um diese Probleme zu beseitigen.

- Vergewissern Sie sich zunächst, dass der Server auch ausgeführt wird. Läuft er nicht, dann können Sie auch keine Verbindung herstellen. Wenn Sie beispielsweise versuchen, eine Verbindung zum Server herzustellen, und eine Meldung wie die folgende angezeigt wird, dann kann Ursache hierfür auch sein, dass der Server schlichtweg nicht läuft:

      shell> mysql
      ERROR 2003: Can't connect to MySQL server on 'host_name' (111)
      shell> mysql
      ERROR 2002: Can't connect to local MySQL server through socket
      '/tmp/mysql.sock' (111)

  Ferner ist es möglich, dass der Server zwar ausgeführt wird, Sie aber eine Verbindung über einen TCP/IP-Port, eine Named Pipe oder eine Unix-Socketdatei herstellen wollen, die nicht mit der Ressource übereinstimmt, auf der der Server horcht. Um dieses Problem zu beheben, geben Sie beim Aufruf eines Clientprogramms eine Option `--port` oder `--socket` an, um die korrekte Portnummer bzw. Named Pipe oder Unix-Socketdatei anzugeben. Mithilfe des folgenden Befehls ermitteln Sie, wo die Socketdatei sich befindet:

      shell> netstat -ln | grep mysql

- Die Grant-Tabellen müssen korrekt konfiguriert sein, damit der Server sie zur Zugriffssteuerung verwenden kann. Bei einigen Distributionstypen (z. B. Binärdistributionen für Windows oder RPM-Distributionen für Linux) initialisiert der Installationsvorgang die `mysql`-Datenbank, die die Grant-Tabellen enthält. Wenn Ihre Distribution dies nicht tut, dann müssen Sie die Grant-Tabellen manuell initialisieren, indem Sie das Skript mysql_install_db ausführen. Detaillierte Informationen finden Sie in Abschnitt 2.9.2, „Schritte nach der Installation unter Unix“.

  Eine Möglichkeit, zu ermitteln, ob Sie die Grant-Tabellen initialisieren müssen, besteht darin, nach einem Verzeichnis `mysql` zu suchen, das sich im Datenverzeichnis befindet. (Das Datenverzeichnis heißt normalerweise `data` oder `var` und befindet sich seinerseits im MySQL-Installationsverzeichnis.) Vergewissern Sie sich, dass eine Datei namens `user.MYD` im Datenverzeichnis `mysql` vorhanden ist. Sollte dies nicht der Fall sein, dann führen Sie das Skript mysql_install_db aus. Nach Ausführung des Skripts und dem Starten des Servers können Sie die anfänglich vorhandenen Berechtigungen durch Ausführung des folgenden Befehls überprüfen:

      shell> mysql -u root test

  Der Server sollte die Herstellung dieser Verbindung ohne Fehler gestatten.

- Nach einer frischen Installation sollten Sie eine Verbindung mit dem Server herstellen und Ihre Benutzer und deren Zugriffsberechtigungen einrichten:

      shell> mysql -u root mysql

  Der Server sollte diese Verbindung gestatten, da der MySQL-Benutzer `root` anfänglich kein Passwort hat. Dies ist natürlich auch ein Sicherheitsrisiko d. h. Sie sollten das Passwort für das `root`-Konto einrichten, während Sie auch die übrigen MySQL-Konten konfigurieren. Anweisungen zur Einstellung der anfänglichen Passwörter finden Sie in Abschnitt 2.9.3, „Einrichtung der anfänglichen MySQL-Berechtigungen“.

- Haben Sie, sofern Sie eine vorhandene MySQL-Installation auf eine neuere Version aktualisiert haben, das Skript mysql_fix_privilege_tables ausgeführt? Wenn nicht, holen Sie dies schleunigst nach. Die Struktur der Grant-Tabellen ändert sich ab und an, wenn neue Funktionalitäten hinzugefügt werden. Deswegen sollten Sie nach einem Upgrade immer sicherstellen, dass Ihre Tabellen die aktuell gültige Struktur aufweisen. Informationen zur Vorgehensweise finden Sie in Abschnitt 5.6, „mysql_fix_privilege_tables — Upgrade von MySQL-Systemtabellen“.

- Wenn ein Clientprogramm beim Verbindungsversuch die folgende Fehlermeldung erhält, bedeutet dies, dass der Server Passwörter in einem neueren Format als dem erwartet, das der Client erzeugen kann:

      shell> mysql
      Client does not support authentication protocol requested
      by server; consider upgrading MySQL client

  Informationen dazu, wie Sie in diesem Fall verfahren, finden Sie in Abschnitt 5.8.9, „Kennwort-Hashing ab MySQL 4.1“, und Abschnitt A.2.3, „`Client does not support authentication protocol`“.

- Wenn Sie eine Verbindung als `root` herstellen und die folgende Fehlermeldung erhalten, dann heißt das, dass kein Datensatz in der Tabelle `user` gefunden wurde, der in der Spalte `User` den Wert `'root'` aufweist – mysqld kann den Hostnamen Ihres Clients in diesem Fall nicht auflösen:

      Access denied for user ''@'unknown' to database mysql

  Sie müssen den Server in einem solchen Fall mit der Option `--skip-grant-tables` neu starten und in Ihrer Datei `/etc/hosts` bzw. `\windows\hosts` einen Eintrag für den Host hinzufügen.

- Zur Erinnerung: Clientprogramme verwenden Verbindungsparameter, die in Optionsdateien oder über Umgebungsvariablen angegeben sind. Wenn ein Clientprogramm offensichtlich unzutreffende Standardverbindungsparameter sendet, weil Sie auf der Befehlszeile keine entsprechenden Informationen angegeben haben, überprüfen Sie die Umgebung und alle relevanten Optionsdateien. Wenn Sie beispielsweise bei der Ausführung eines Clients ohne Optionen die Fehlermeldung `Access denied` erhalten, vergewissern Sie sich, dass Sie in keiner Ihrer Optionsdateien ein altes Passwort angegeben haben!

  Sie können die Verwendung von Optionsdateien durch ein Clientprogramm unterdrücken, indem Sie es mit der Option `--no-defaults` aufrufen. Zum Beispiel:

      shell> mysqladmin --no-defaults -u root version

  Die von Clients verwendeten Optionsdateien sind in Abschnitt 4.3.2, „my.cnf-Optionsdateien“ aufgelistet. Umgebungsvariablen werden in Anhang F, Umgebungsvariablen beschrieben.

- Wenn Sie die folgende Fehlermeldung erhalten, bedeutet dies, dass Sie das falsche `root`-Passwort benutzen:

      shell> mysqladmin -u root -pxxxx ver
      Access denied for user 'root'@'localhost' (using password: YES)

  Wenn dieser Fehler auftritt, obwohl Sie gar kein Passwort angegeben haben, ergibt sich daraus, dass ein falsches Passwort in irgendeiner Optionsdatei aufgeführt sein muss. Probieren Sie in diesem Fall die Option `--no-defaults` wie im vorhergehenden Abschnitt beschrieben aus.

  Informationen zur Änderung von Passwörtern finden Sie in Abschnitt 5.9.5, „Kennwörter einrichten“.

  Haben Sie das `root`-Passwort verloren oder vergessen, dann können Sie mysqld mit `--skip-grant-tables` neu starten, um das Passwort zu ändern. Siehe auch Abschnitt A.4.1, „Wie ein vergessenes Kennwort zurückgesetzt wird“.

- Wenn Sie ein Passwort mit `SET PASSWORD`, `INSERT` oder `UPDATE` ändern, müssen Sie es mit der Funktion `PASSWORD()` verschlüsseln. Verwenden Sie `PASSWORD()` für diese Anweisungen nicht, dann funktioniert das Passwort nicht. So wird mit der folgenden Anweisung ein Passwort zwar eingestellt, aber nicht verschlüsselt – und der Benutzer kann nachfolgend keine Verbindung herstellen:

      SET PASSWORD FOR 'abe'@'host_name' = 'eagle';

  Stattdessen muss das Passwort wie folgt eingestellt werden:

      SET PASSWORD FOR 'abe'@'host_name' = PASSWORD('eagle');

  Die Funktion `PASSWORD()` ist entbehrlich, wenn Sie ein Passwort mit `GRANT`- oder `CREATE USER`-Anweisungen oder dem Befehl mysqladmin password festlegen. Sie alle verschlüsseln das Passwort automatisch mit `PASSWORD()`. Siehe auch Abschnitt 5.9.5, „Kennwörter einrichten“, und Abschnitt 13.5.1.1, „`CREATE USER`“.

- `localhost` ist ein Synonym für Ihren lokalen Hostnamen und zudem der standardmäßige Host, mit dem Clients eine Verbindung herzustellen versuchen, wenn Sie keinen Host explizit angeben.

  Um dieses Problem auf solchen Systemen zu umgehen, können Sie die Option `--host=127.0.0.1` verwenden, um den Serverhost explizit anzugeben. Hierdurch wird eine TCP/IP-Verbindung mit dem lokalen mysqld-Server hergestellt. Sie können TCP/IP auch verwenden, indem Sie eine Option `--host` angeben, die den eigentlichen Hostnamen des lokalen Hosts verwendet. In diesem Fall muss der Hostname in einem Datensatz in der Tabelle `user` auf dem Serverhost angegeben sein, auch wenn Sie das Clientprogramm auf demselben Host wie den Server ausführen.

- Wenn Sie die Fehlermeldung `Access denied` erhalten, wenn Sie mit `mysql -u `user_name`` eine Verbindung zur Datenbank herstellen, liegt unter Umständen ein Problem mit der Tabelle `user` vor. Sie können dies überprüfen, indem Sie `mysql -u root mysql` ausführen und die folgende SQL-Anweisung absetzen:

      SELECT * FROM user;

  Das Ergebnis sollte einen Datensatz mit `Host`- und `User`-Spaltenwerten enthalten, die mit dem Hostnamen Ihres Computers bzw. Ihrem MySQL-Benutzernamen übereinstimmen.

- Die Fehlermeldung `Access denied` sagt Ihnen, als wer Sie eine Verbindung herzustellen versuchen, von welchem Clienthost Sie diese Verbindung herzustellen versuchen und ob Sie ein Passwort angegeben haben. Normalerweise sollte genau ein Datensatz in der Tabelle `user` vorhanden sein, für den eine Übereinstimmung mit dem Host- und dem Benutzernamen vorliegt, die in der Fehlermeldung angegeben werden. Erhalten Sie beispielsweise eine Fehlermeldung, die `using password: NO` enthält, dann bedeutet dies, dass Sie versucht haben, sich ohne Passwort anzumelden.

- Tritt der folgende Fehler auf, wenn Sie versuchen, eine Verbindung von einem anderen als dem Host herzustellen, auf dem der MySQL-Server ausgeführt wird, dann bedeutet dies, dass in der Tabelle `user` kein Datensatz mit einem zum Clienthost passenden `Host`-Wert gefunden wurde:

      Host ... is not allowed to connect to this MySQL server

  Sie können dieses Problem beheben, indem Sie ein Konto für die Kombination aus Clienthostname und Benutzername erstellen, die Sie zur Verbindungsherstellung verwenden.

  Wenn Sie IP-Adresse oder Hostname des Computers, von dem aus Sie die Verbindung herstellen, nicht kennen, dann sollten Sie einen Datensatz mit dem Wert `'%'` in die Spalte `Host` der Tabelle `user` einfügen. Nachdem Sie versucht haben, eine Verbindung vom Clientsystem herzustellen, ermitteln Sie mit einer `SELECT USER()`-Abfrage, wie Sie die Verbindung tatsächlich hergestellt haben. (Ändern Sie nachfolgend den Eintrag `'%'` im betreffenden Datensatz der Tabelle `user` zu dem im Log angegebenen Hostnamen. Wenn Sie dies versäumen, bleibt Ihr System unsicher, da es dem angegebenen Benutzernamen Verbindungen von jedem Host aus gestattet.)

  Unter Linux kann ein anderer Grund für diese Fehlermeldung darin bestehen, dass Sie eine aus einer Binärdistribution stammende MySQL-Version verwenden, die mit einer anderen Version der `glibc`-Bibliothek als der von Ihnen verwendeten kompiliert wurde. In diesem Fall sollten Sie entweder Ihr Betriebssystem oder `glibc` aktualisieren oder eine Quelldistribution der MySQL-Version herunterladen und selbst kompilieren. Dies ist kein Problem, da Kompilierung und Installation eines Quellcode-RPM in der Regel einfach und schnell erledigt sind.

- Wenn Sie beim Verbindungsversuch einen Hostnamen angeben, aber eine Fehlermeldung erhalten, in der der Hostname nicht oder an seiner Stelle eine IP-Adresse angegeben ist, dann bedeutet dies, dass am MySQL-Server bei dem Versuch, die IP-Adresse des Clients in einen Namen aufzulösen, ein Fehler aufgetreten ist:

      shell> mysqladmin -u root -pxxxx -h some_hostname ver
      Access denied for user 'root'@'' (using password: YES)

  Dies weist auf ein DNS-Problem hin. Um es zu beheben, setzen Sie den internen DNS-Hostnamens-Cache durch Ausführen von mysqladmin flush-hosts zurück. Siehe auch Abschnitt 7.5.6, „Wie MySQL DNS benutzt“.

  Die folgenden Lösungen versprechen dauerhaften Erfolg:

  - Ermitteln Sie, was bei Ihrem DNS-Server nicht stimmt, und beheben Sie das Problem.

  - Geben Sie in den MySQL-Grant-Tabellen IP-Adressen statt Hostnamen an.

  - Fügen Sie für den Namen des Clientcomputers einen Eintrag in `/etc/hosts` bzw. `\windows\hosts` hinzu.

  - Starten Sie mysqld mit der Option `--skip-name-resolve`.

  - Starten Sie mysqld mit der Option `--skip-host-cache`.

  - Stellen Sie eine Verbindung mit `localhost` her, wenn Sie unter Unix den Server und den Client auf demselben Computer ausführen. Für Verbindungen mit `localhost` verwendet Unix statt TCP/IP eine Unix-Socketdatei.

  - Stellen Sie eine Verbindung mit dem Hostnamen `.` (Punkt) her, wenn Sie unter Windows den Server und den Client auf demselben Computer ausführen und der Server Named Pipes unterstützt. Verbindungen mit `.` verwenden statt TCP/IP eine Named Pipe.

- Wenn `mysql -u root test` funktioniert, aber `mysql -h `your_hostname` -u root test` zur Fehlermeldung `Access denied` führt (wobei `your_hostname` der tatsächliche Hostname des lokalen Hosts ist), dann steht unter Umständen für Ihren Host nicht der korrekte Name in der Tabelle `user`. Ein häufig auftretendes Problem besteht hier darin, dass der `Host`-Wert des Datensatzes in der Tabelle `user` einen unqualifizierten Hostnamen angibt, die Namensauflösungsroutinen Ihres Systems aber einen vollqualifizierten Domänennamen zurückgeben (oder umgekehrt). Wenn Sie also beispielsweise einen Eintrag mit dem Host `'tcx'` in der Tabelle `user` haben, aber Ihr DNS MySQL meldet, dass Ihr Hostname `'tcx.subnet.se'` lautet, dann funktioniert der Eintrag nicht. Versuchen Sie, der Tabelle `user` einen Eintrag hinzufügen, der die IP-Adresse Ihres Hosts als `Host`-Spaltenwert enthält. (Alternativ können Sie einen Eintrag in der Tabelle `user` mit einem `Host`-Wert hinzufügen, der ein Jokerzeichen enthält – z. B. `'tcx.%'`. Allerdings ist die Verwendung von Hostnamen, die auf ‘`%`’ enden, ein Sicherheitsrisiko. Wir raten dringend davon ab!)

- Wenn `mysql -u `user_name` test` funktioniert, `mysql -u `user_name` `other_db_name`` aber nicht, dann haben Sie dem betreffenden Benutzer keinen Datenbankzugriff auf `other_db_name` gewährt.

- Wenn `mysql -u `user_name`` bei einer Ausführung auf dem Serverhost funktioniert, `mysql -h `host_name` -u `user_name`` jedoch bei der Ausführung auf dem Clienthost jedoch nicht, dann haben Sie für den betreffenden Benutzernamen den Zugriff vom entfernten Host auf den Server nicht aktiviert.

- Wenn Sie nicht feststellen können, warum Sie den Fehler `Access denied` erhalten, entfernen Sie aus der Tabelle `user` alle Einträge, die `Host`-Werte mit Jokerzeichen aufweisen (d. h. Einträge, die ‘`%`’ oder ‘`_`’ enthalten). Ein sehr häufiger Fehler besteht darin, einen neuen Eintrag mit `Host`=`'%'` und `User`=`'`some_user`'` einzufügen, weil man der Ansicht ist, dass dies die Angabe von `localhost` zur Verbindung von demselben Computer aus ermöglicht. Der Grund dafür, dass dies nicht funktioniert, ist, dass die Standardberechtigungen einen Eintrag mit `Host`=`'localhost'` und `User`=`''` enthalten. Da dieser Eintrag einen `Host`-Wert `'localhost'` aufweist, der spezifischer ist als `'%'`, wird er anstelle des neuen Eintrags verwendet, wenn eine Verbindung von `localhost` aus hergestellt wird! Die korrekte Vorgehensweise besteht darin, einen zweiten Eintrag mit `Host`=`'localhost'` und `User`=`'`some_user`'` einzufügen oder den Eintrag mit `Host`=`'localhost'` und `User`=`''` zu löschen. Nach dem Löschen des Eintrags dürfen Sie nicht vergessen, eine `FLUSH PRIVILEGES`-Anweisung abzusetzen, um die Grant-Tabellen neu zu laden.

- Wenn Sie den folgenden Fehler erhalten, liegt unter Umständen ein Problem mit den Tabellen `db` oder `host` vor:

      Access to database denied

  Wenn der in der Tabelle `db` gewählte Eintrag einen leeren Wert in der Spalte `Host` aufweist, müssen Sie sicherstellen, dass mindestens ein entsprechender Eintrag in der Tabelle `host` vorhanden ist, der angibt, für welche Hosts der Eintrag in der Tabelle `db` gilt.

- Wenn Sie eine Verbindung mit dem MySQL-Server herstellen können, aber immer dann eine Fehlermeldung `Access denied` erhalten, wenn Sie eine `SELECT ... INTO OUTFILE`- oder `LOAD DATA INFILE`-Anweisung absetzen, ist für Ihren Eintrag in der Tabelle `user` die Berechtigung `FILE` nicht aktiviert.

- Ändern Sie die Grant-Tabellen direkt (z. B. mit `INSERT`, `UPDATE` oder `DELETE`) und werden Ihre Änderungen offenbar ignoriert, dann dürfen Sie nicht vergessen, eine `FLUSH PRIVILEGES`-Anweisung oder den Befehl mysqladmin flush-privileges auszuführen, damit der Server Ihre Berechtigungstabellen neu einliest. Andernfalls werden Ihre Änderungen erst beim nächsten Neustart des Servers umgesetzt. Denken Sie auch immer daran, dass Sie, wenn Sie das `root`-Passwort mit einem `UPDATE`-Befehl geändert haben, das neue Passwort erst nach dem Schreiben der Berechtigungen angeben müssen, da der Server vorher gar nicht weiß, dass Sie Ihr Passwort geändert haben!

- Wenn Ihre Berechtigungen im Verlauf einer Sitzung offensichtlich geändert werden, besteht die Möglichkeit, dass ein MySQL-Administrator die Änderungen vorgenommen hat. Das Neuladen der Grant-Tabellen wirkt sich auf neue Clientverbindungen, aber auch auf vorhandene Verbindungen aus (siehe auch Abschnitt 5.8.7, „Wann Berechtigungsänderungen wirksam werden“).

- Wenn Sie bei einem Perl-, PHP-, Python- oder ODBC-Programm Probleme mit dem Zugriff haben, sollten Sie versuchen, eine Serververbindung mit `mysql -u `user_name` `db_name`` oder `mysql -u `user_name` -p`your_pass` `db_name`` herzustellen. Wenn Sie eine Verbindung mit dem mysql-Client herstellen können, wird das Problem von Ihrem Programm und nicht von den Zugriffsberechtigungen verursacht. (Zwischen `-p` und dem Passwort ist kein Leerzeichen vorhanden; Sie können auch die Syntax `--password=`your_pass`` zur Angabe des Passworts verwenden. Wenn Sie die Option `-p` bzw. `--password` ohne Passwortwert benutzen, fordert Sie MySQL zur Eingabe des Passworts auf.)

- Zu Testzwecken starten Sie den mysqld-Server mit der Option `--skip-grant-tables`. Sie können dann die MySQL-Grant-Tabellen ändern und das Skript mysqlaccess zur Überprüfung verwenden, ob Ihre Änderungen die gewünschte Wirkung hervorrufen. Wenn Sie mit den Änderungen zufrieden sind, führen Sie mysqladmin flush-privileges aus, um dem mysqld-Server anzuweisen, die neuen Grant-Tabellen ab sofort zu verwenden. (Das Neuladen der Grant-Tabellen hat Vorrang vor der Option `--skip-grant-tables`. Dies ermöglicht Ihnen, den Server zur sofortigen Verwendung der neuen Grant-Tabellen anzuweisen, ohne dass ein Serverneustart erforderlich wäre.)

- Wenn alles andere fehlschlägt, starten Sie den mysqld-Server mit einer Debug-Option (z. B. `--debug=d,general,query`). Hierdurch werden Host- und Benutzerinformationen zu Verbindungsversuchen sowie Angaben zu allen abgesetzten Befehlen ausgegeben. Siehe auch Abschnitt E.1.2, „Trace-Dateien erzeugen“.

- Wenn Sie andere Probleme mit den MySQL-Grant-Tabellen haben und diese der Mailingliste beschreiben wollen, fügen Sie auch immer einen Speicherauszug der MySQL-Grant-Tabellen bei. Diesen können Sie mit dem Befehl mysqldump mysql erstellen. Verwenden Sie zum Übermitteln eines Fehlerberichts die in Abschnitt 1.8, „Wie man Bugs oder Probleme meldet“ beschriebenen Anweisungen. In manchem Fällen müssen Sie mysqld unter Umständen mit der Option `--skip-grant-tables` neu starten, um mysqldump ausführen zu können.

### 5.8.9. Kennwort-Hashing ab MySQL 4.1

MySQL-Benutzerkonten sind in der Tabelle `user` der Datenbank `mysql` aufgelistet. Jedem MySQL-Konto wird ein Passwort zugewiesen. Allerdings wird in der Spalte `Password` der Tabelle `user` nicht die unverschlüsselte Version des Passworts gespeichert, sondern ein auf dessen Basis berechneter Hash-Wert. Die Hash-Werte für Passwörter werden mit der Funktion `PASSWORD()` berechnet.

MySQL verwendet die Passwörter in zwei Phasen der Client/Server-Kommunikation:

- Wenn ein Client eine Verbindung zum Server herstellen will, gibt es einen ersten Authentifizierungsschritt, bei dem der Client ein Passwort mit einem Hash-Wert vorweisen muss, der mit dem Hash-Wert übereinstimmt, welcher in der Tabelle `user` für das vom Client verwendete Konto gespeichert ist.

- Wenn der Client die Verbindung hergestellt hat, kann er – sofern er über ausreichende Berechtigungen verfügt – die Passwort-Hashes für die in der Tabelle `user` gelisteten Konten einstellen oder ändern. Der Client kann dies tun, indem er mithilfe der Funktion `PASSWORD()` einen Passwort-Hash erzeugt oder die Anweisungen `GRANT` oder `SET PASSWORD` verwendet.

Mit anderen Worten benutzt der Server die Hash-Werte während der Authentifizierung, wenn der Client erstmals eine Verbindung herzustellen versucht. Dagegen erzeugt der Server Hash-Werte, wenn ein verbundener Client die Funktion `PASSWORD()` aufruft oder eine `GRANT`- oder `SET PASSWORD`-Anweisung benutzt, um ein Passwort einzustellen oder zu ändern.

Die Methode für das Passwort-Hashing wurde in MySQL 4.1 geändert, um mehr Sicherheit zu bieten und das Risiko zu verringern, dass Passwörter abgefangen werden. Allerdings wird diese neue Methode nur von Servern und Clients unter MySQL 4.1 und höher verstanden, was Kompatibilitätsprobleme verursachen kann. Ein Client unter Version 4.1 oder höher kann mit einem Server unter einer Version vor 4.1 eine Verbindung herstellen, da der Client sowohl die alte als auch die neue Hashing-Methode versteht. Allerdings kann es zu Schwierigkeiten kommen, wenn ein Client unter einer alten Version mit einem Server unter Version 4.1 oder höher einen Verbindungsaufbau probiert. So kann eine Verbindung, die ein mysql-Client unter Version 3.23 mit einem Server unter 5.1 herzustellen versucht, mit der folgenden Fehlermeldung fehlschlagen:

    shell> mysql -h localhost -u root
    Client does not support authentication protocol requested
    by server; consider upgrading MySQL client

Ein anderes häufiges Beispiel für dieses Phänomen tritt auf, wenn nach einem Upgrade auf MySQL 4.1 versucht wird, die ältere PHP-`mysql`-Erweiterung zu verwenden. (Siehe auch Abschnitt 24.3.1, „Allgemeine Probleme mit MySQL und PHP“.)

Im Folgenden werden die Unterschiede zwischen der alten und der neuen Passwortmethode beschrieben. Ferner werden wir erläutern, was Sie tun müssen, wenn Sie Ihren Server unter Beibehaltung der Abwärtskompatibilität mit Clients unter Versionen vor 4.1 aktualisieren wollen. Zusätzliche Informationen finden Sie unter Abschnitt A.2.3, „`Client does not support authentication protocol`“. Diese Hinweise sind besonders wichtig für PHP-Programmierer, die ihre MySQL-Datenbanken von einer Version vor 4.1 auf Version 4.1 oder höher migrieren.

Hinweis: In der Beschreibung wird das Verhalten von Version 4.1 und höher dem Verhalten älterer Versionen gegenübergestellt. Tatsächlich aber wurde das hier beschriebene Verhalten erst mit Version 4.1.1 implementiert. MySQL 4.1.0 ist eine „merkwürdige“ Version, denn sie weist eine etwas andere Methode auf als die Versionen 4.1.1 und folgende. Die Unterschiede zwischen 4.1.0 und den neueren Versionen sind im MySQL 5.0 Reference Manual ausführlicher beschrieben.

In MySQL vor Version 4.1 sind die Passwort-Hashes, die mit der Funktion `PASSWORD()` berechnet werden, 16 Bytes lang. Solche Hashes sehen etwa so aus:

    mysql> SELECT PASSWORD('mypass');
    +--------------------+
    | PASSWORD('mypass') |
    +--------------------+
    | 6f8c114b58f2ce9e   |
    +--------------------+

Die Spalte `Password` in der Tabelle `user` (in der diese Hashes gespeichert werden) ist bei MySQL vor Version 4.1 ebenfalls 16 Bytes lang.

Seit MySQL 4.1 erzeugt die geänderte `PASSWORD()`-Funktion einen 41 Byte langen Hash-Wert:

    mysql> SELECT PASSWORD('mypass');
    +-------------------------------------------+
    | PASSWORD('mypass')                        |
    +-------------------------------------------+
    | *6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4 |
    +-------------------------------------------+

Entsprechend muss die Spalte `Password` in der Tabelle `user` ebenfalls 41 Byte lang sein, um diese Werte aufnehmen zu können:

- Wenn Sie eine Neuinstallation von MySQL 5.1 durchführen, wird die Spalte `Password` automatisch auf 41 Byte verlängert.

- Die Aktualisierung von MySQL 4.1 (4.1.1 oder höher in der Serie 4.1) auf MySQL 5.1 sollte diesbezüglich unproblematisch zu sein, da beide Versionen dieselbe Hashing-Methode für Passwörter einsetzen. Wollen Sie hingegen von einem älteren MySQL-Release auf Version 5.1 aktualisieren, dann sollten Sie zunächst ein Upgrade auf 4.1 durchführen und diese 4.1-Installation dann auf 5.1 aktualisieren.

Die verbreiterte `Password`-Spalte kann Passwort-Hashes im alten wie im neuen Format aufnehmen. Das Format eines gegebenen Hash-Wertes kann auf zweierlei Art und Weise bestimmt werden:

- Der offensichtliche Unterschied ist die Länge (16 Bytes im Vergleich zu 41 Bytes).

- Ein zweiter Unterschied besteht darin, dass Passwort-Hashes im neuen Format immer mit dem Zeichen ‘`*`’ beginnen, was bei alten Passwörtern nie der Fall ist.

Das längere Format für Passwort-Hashes hat bessere kryptografische Eigenschaften, und die auf langen Hashes basierende Clientauthentifizierung ist sicherer als die alte, auf kurzen Hashes basierende Methode.

Die Unterschiede zwischen kurzen und langen Passwort-Hashes sind sowohl dafür, wie der Server Passwörter während der Authentifizierung verwendet, als auch dafür relevant, wie er Passwort-Hashes für verbundene Clients erzeugt, die Operationen zur Passwortänderung durchführen.

Die Breite der `Password`-Spalte wirkt sich auf die Art und Weise aus, wie der Server Passwort-Hashes während der Authentifizierung benutzt:

- Wenn die Spalte kurz ist, wird die Authentifizierung mit kurzen Hashes verwendet.

- Ist die Spalte hingegen lang, dann kann sie kurze wie auch lange Hashes aufnehmen, und der Server kann beide Formate verwenden:

  - Clients unter einer Version vor 4.1 können zwar Verbindungen herstellen, aber sie können, weil sie nur die alte Hashing-Methode kennen, eine Authentifizierung nur für Konten mit kurzen Hashes durchführen.

  - Clients unter 4.1 und höher können sich mit Konten authentifizieren, die kurze oder lange Hashes haben.

Auch bei Konten mit kurzen Hashes ist der Authentifizierungsvorgang eigentlich ein bisschen sicherer für Clients unter 4.1 und höher als bei älteren Clients. Aus sicherheitstechnischer Sicht sieht der Übergang von der geringsten zur höchsten Sicherheit wie folgt aus:

- Clients unter Versionen vor 4.1 mit kurzem Passwort-Hash

- Clients unter Versionen ab 4.1 mit kurzem Passwort-Hash

- Clients unter Versionen ab 4.1 mit langem Passwort-Hash

Die Art und Weise, wie der Server Passwort-Hashes für verbundene Clients erzeugt, wird von der Breite der Spalte `Password` und von der Option `--old-passwords` beeinflusst. Ein Server unter 4.1 oder höher erzeugt lange Hashes nur, wenn bestimmte Bedingungen erfüllt werden: Die Spalte `Password` muss breit genug für lange Werte sein, und die Option `--old-passwords` darf nicht angegeben worden sein. Diese Bedingungen gelten wie folgt:

- Die Spalte `Password` muss breit genug sein, um lange Hashes (41 Bytes) aufzunehmen. Wenn die Spalte nicht aktualisiert wurde und noch die Breite von 16 Bytes hat, stellt der Server fest, dass lange Hashes nicht in die Spalte passen. Insofern werden nur kurze Hashes erzeugt, wenn ein Client passwortändernde Operationen mit `PASSWORD()`, `GRANT` oder `SET PASSWORD` durchführt. Dieses Verhalten tritt auf, wenn Sie auf Version 4.1 aktualisiert, aber das Skript mysql_fix_privilege_tables zur Verbreiterung der Spalte `Password` noch nicht ausgeführt haben.

- Ist die Spalte `Password` breit, dann kann sie kurze und lange Passwort-Hashes speichern. In diesem Fall erzeugen `PASSWORD()`, `GRANT` und `SET PASSWORD` lange Hashes, sofern der Server nicht mit der Option `--old-passwords` gestartet wurde. Diese Option erzwingt am Server die Erzeugung kurzes Hashes.

Der Zweck der Option `--old-passwords` besteht darin, Ihnen die Beibehaltung der Abwärtskompatibilität mit Clients unter Versionen vor 4.1 unter solchen Umständen zu ermöglichen, unter denen der Server andernfalls lange Passwort-Hashes erzeugen würde. Die Option beeinträchtigt die Authentifizierung nicht (denn Clients unter 4.1 und höher können weiterhin Konten mit langen Passwort-Hashes verwenden), verhindert aber die Erstellung eines langen Passwort-Hashes in der Tabelle `user` als Folge einer passwortändernden Operation. Andernfalls könnte das Konto nicht länger von Clients unter einer alten MySQL-Version verwendet werden. Ohne die Option `--old-passwords` wäre das folgende, nicht wünschenswerte Szenario möglich:

- Ein alter Client stellt eine Verbindung zu einem Konto her, das einen kurzen Passwort-Hash hat.

- Der Client ändert sein eigenes Passwort. Ohne die Option `--old-passwords` führt dies dazu, dass das Konto einen langen Passwort-Hash erhält.

- Beim nächsten Verbindungsversuch des alten Clients mit dem betreffenden Konto schlägt die Verbindung fehl, weil das Konto einen langen Passwort-Hash aufweist, der zur Authentifizierung die neue Hashing-Methode benötigt. (Sobald für ein Konto ein langer Passwort-Hash in der Tabelle `user` gespeichert wird, können nur Clients unter Version 4.1 und höher eine Authentifizierung durchführen, weil ältere Clients die langen Hashes nicht verstehen.)

Dieses Szenario veranschaulicht, dass es, wenn Sie Clients unter Versionen vor 4.1 unterstützen müssen, gefährlich ist, einen Server unter 4.1 oder höher ohne die Option `--old-passwords` zu verwenden. Bei Ausführung des Servers mit der Option `--old-passwords` erzeugen passwortändernde Optionen keine langen Passwort-Hashes, d. h. Konten geraten für ältere Clients nicht außer Reichweite. (Diese Clients können sich nicht versehentlich selbst aussperren, indem sie ihr Passwort ändern und am Ende einen langen Passwort-Hash erhalten.)

Der Nachteil der Option `--old-passwords` besteht darin, dass alle von Ihnen erstellten oder geänderten Passwörter kurze Hashes verwenden – auch die Clients unter Version 4.1 und höher. Auf diese Weise verlieren Sie die zusätzliche Sicherheit, die lange Passwort-Hashes bieten. Wenn Sie ein Konto erstellen wollen, das einen langen Hash hat (etwa zur Verwendung durch Clients unter 4.1), dann müssen Sie dies tun, während der Server ohne die Option `--old-passwords` läuft.

Die folgenden Szenarios sind bei Ausführung eines Servers unter Version 4.1 möglich:

Szenario 1: Kurze `Password`-Spalte in der Tabelle `user`

- In der Spalte `Password` können nur kurze Hashes gespeichert werden.

- Der Server verwendet nur kurze Hashes zur Clientauthentifizierung.

- Bei verbundenen Clients verwenden Operationen, die Passwort-Hashes mithilfe von `PASSWORD()`, `GRANT` oder `SET PASSWORD` erzeugen, ausschließlich kurzes Hashes. Änderungen am Passwort eines Kontos führen dazu, dass dieses Konto einen kurzen Passwort-Hash erhält.

- Die Option `--old-passwords` kann verwendet werden, ist aber überflüssig, weil der Server bei einer kurzen `Password`-Spalte ohnehin nur kurze Passwort-Hashes erzeugt.

Szenario 2: Lange `Password`-Spalte, Server wurde nicht mit der Option `--old-passwords` gestartet

- In der Spalte `Password` können kurze wie auch lange Hashes gespeichert werden.

- Clients unter 4.1 und höher können sich mit Konten authentifizieren, die kurze oder lange Hashes haben.

- Clients vor 4.1 können sich nur mithilfe von Konten authentifizieren, die kurze Hashes haben.

- Bei verbundenen Clients verwenden Operationen, die Passwort-Hashes mithilfe von `PASSWORD()`, `GRANT` oder `SET PASSWORD` erzeugen, ausschließlich lange Hashes. Änderungen am Passwort eines Kontos führen dazu, dass dieses Konto einen langen Passwort-Hash hat.

Wie weiter oben beschrieben, besteht die Gefahr bei diesem Szenario darin, dass Konten, die einen kurzen Passwort-Hash aufweisen, für Clients unter einer Version vor 4.1 unzugänglich werden. Eine Änderung am Passwort eines solchen Kontos, die mithilfe von `GRANT`, `PASSWORD()` oder `SET PASSWORD` vorgenommen wird, führt dazu, dass das Konto einen langen Passwort-Hash erhält. Von diesem Punkt an kann ein Client unter einer Version vor 4.1 eine Authentifizierung über dieses Konto erst dann durchführen, wenn er seinerseits auf 4.1 oder höher aktualisiert wurde.

Um dieses Problem zu beseitigen, können Sie das Passwort auf eine spezielle Art und Weise ändern. So verwenden Sie etwa normalerweise `SET PASSWORD` wie folgt, um ein Kontopasswort zu ändern:

    SET PASSWORD FOR 'some_user'@'some_host' = PASSWORD('mypass');

Um das Passwort zu ändern, aber einen kurzen Hash zu erstellen, verwenden Sie stattdessen die Funktion `OLD_PASSWORD()`:

    SET PASSWORD FOR 'some_user'@'some_host' = OLD_PASSWORD('mypass');

`OLD_PASSWORD()` ist in Situationen nützlich, in denen Sie ausdrücklich einen kurzen Hash erzeugen wollen.

Szenario 3: Lange `Password`-Spalte, Server unter Version 4.1 oder höher wurde mit der Option `--old-passwords` gestartet

- In der Spalte `Password` können kurze wie auch lange Hashes gespeichert werden.

- Clients unter 4.1 oder höher können sich mit Konten authentifizieren, die kurze oder lange Hashes haben. (Beachten Sie aber, dass die Erzeugung langer Hashes nur dann möglich ist, wenn der Server ohne die Option `--old-passwords` gestartet wurde.)

- Clients vor 4.1 können sich nur mit Konten authentifizieren, die kurze Hashes haben.

- Bei verbundenen Clients verwenden Operationen, die Passwort-Hashes mithilfe von `PASSWORD()`, `GRANT` oder `SET PASSWORD` erzeugen, ausschließlich kurzes Hashes. Änderungen am Passwort eines Kontos führen dazu, dass dieses Konto einen kurzen Passwort-Hash erhält.

In diesem Szenario können Sie keine Konten mit langen Passwort-Hashes erstellen, weil die Option `--old-passwords` deren Erzeugung verhindert. Ferner wird, wenn Sie ein Konto mit einem langem Hash vor Verwendung der Option `--old-passwords` erstellen, eine Änderung dieses Passworts bei aktivierter Option `--old-passwords` dazu führen, dass das Konto ein kurzes Passwort erhält, wodurch die sicherheitstechnischen Vorzüge eines langen Hashs verloren gehen.

Die Nachteile dieser Szenarien lassen sich wie folgt zusammenfassen:

In Szenario 1 müssen Sie auf die Vorteile langer Hashes verzichten, die eine sicherere Authentifizierung ermöglichen.

In Szenario 2 werden Konten mit kurzen Hashes für Clients unter einer Version vor 4.1 unzugänglich, wenn sie ihre Passwörter ändern, ohne die Option `OLD_PASSWORD()` ausdrücklich zu verwenden.

In Szenario 3 verhindert `--old-passwords`, dass Konten mit kurzen Hashes unzugänglich werden; passwortändernde Operationen setzen allerdings Konten mit langen Hashes auf kurze Hashes herunter, was Sie auch nicht ändern können, solange die Option `--old-passwords` gültig bleibt.

#### 5.8.9.1. Auswirkungen der Änderungen beim Kennwort-Hashing auf Applikationen

Ein Upgrade auf MySQL 4.1 oder höher kann Kompatibilitätsprobleme für Anwendungen verursachen, die `PASSWORD()` zur Erzeugung von Passwörter für eigene Zwecke verwenden. Anwendungen sollten dies möglichst nicht tun, weil `PASSWORD()` einzig und allein zur Verwaltung von Passwörtern für MySQL-Konten eingesetzt werden sollten. Manche Anwendungen verwenden `PASSWORD()` allerdings trotzdem für ihre eigenen Zwecke.

Wenn Sie von einer alten MySQL-Version auf 4.1 oder höher aktualisieren und den Server unter Bedingungen ausführen, bei denen er lange Passwort-Hashes erzeugt, wird eine Anwendung, die `PASSWORD()` für eigene Passwörter verwendet, beschädigt. Die empfohlene Vorgehensweise besteht in solchen Fällen darin, die Anwendung so zu ändern, dass sie eine andere Funktion wie `SHA1()` oder `MD5()` zur Erzeugung von Hash-Werten verwendet. Sollte dies nicht möglich sei, dann können Sie die Funktion `OLD_PASSWORD()` benutzen, die zur Erzeugung von Passwörtern im alten Format bereitsteht. Allerdings sollten Sie beachten, dass `OLD_PASSWORD()` unter Umständen nicht auf Dauer unterstützt werden wird.

Läuft der Server unter Umständen, unter denen er kurze Hashes erzeugt, steht `OLD_PASSWORD()` zwar zur Verfügung, ist aber äquivalent zu `PASSWORD()`.

PHP-Programmierer, die ihre MySQL-Datenbanken von Version 4.0 oder älter auf 4.1 oder höher migrieren, sollten Abschnitt 24.3, „MySQLs PHP-API“, lesen.

## 5.9. MySQL-Benutzerkontenverwaltung

Dieser Abschnitt beschreibt, wie Konten für Clients auf Ihrem MySQL-Server eingerichtet werden. Behandelt werden die folgenden Themen:

- Bedeutung von Kontennamen und Passwörtern bei der Verwendung in MySQL im Vergleich zu den vom Betriebssystem verwendeten Namen und Passwörtern

- Einrichtung neuer und Entfernung vorhandener Konten

- Ändern von Passwörtern

- Richtlinien zur sicheren Passwortverwendung

- Verwenden sicherer Verbindungen mit SSL

### 5.9.1. MySQL-Benutzernamen und -Kennwörter

Ein MySQL-Konto wird durch einen Benutzernamen und den oder die Clienthosts definiert, von denen aus der Benutzer eine Verbindung zum Server herstellen kann. Ein Konto hat auch ein Passwort. Es gibt mehrere Unterschiede zwischen der Verwendung von Benutzernamen und Passwörtern unter MySQL und der Verwendung durch Ihr Betriebssystem:

- Benutzernamen, die MySQL zu Authentifizierungszwecken verwendet, haben nicht mit den von Windows oder Unix eingesetzten Benutzernamen (Anmeldenamen) zu tun. Unter Unix versuchen die meisten MySQL-Clients standardmäßig, eine Anmeldung unter Verwendung des aktuellen Unix-Benutzernamens als MySQL-Benutzername durchzuführen, aber dies dient lediglich der Bequemlichkeit. Diese Voreinstellung kann ganz einfach außer Kraft gesetzt werden, da Clientprogramme die Angabe beliebiger Benutzernamen mit der Option `-u` bzw. `--user` erlauben. Da dies impliziert, dass jeder versuchen kann, unter Verwendung eines beliebigen Benutzernamens eine Serververbindung herzustellen, können Sie eine Datenbank nur schützen, indem Sie für alle MySQL-Konten Passwörter konfigurieren. Jeder, der einen Benutzernamen für ein Konto angibt, welches über kein Passwort verfügt, kann erfolgreich eine Verbindung zum Server herstellen.

- MySQL-Benutzernamen dürfen bis zu 16 Zeichen lang sein. Diese Beschränkung ist bei MySQL-Servern und -Clients fest vorgegeben; sie durch Änderung der Tabellendefinitionen in der `mysql`-Datenbank zu umgehen, funktioniert nicht.

  Hinweis: Sie sollten die Tabellen in der `mysql`-Datenbank grundsätzlich nicht auf eine andere als die von MySQL AB vorgeschriebene, in Abschnitt 5.6, „mysql_fix_privilege_tables — Upgrade von MySQL-Systemtabellen“, geschilderte Weise ändern. Jeder Versuch, die Systemtabellen von MySQL auf eine andere Weise zu ändern, führt zu undefiniertem (und nicht unterstütztem!) Verhalten.

  Die Benutzernamen des Betriebssystems haben überhaupt keine Beziehung zu den MySQL-Benutzernamen und können sogar eine ganz andere Maximallänge aufweisen. So sind etwa Unix-Benutzernamen normalerweise auf acht Zeichen beschränkt.

- Auch haben MySQL-Passwörter nichts mit den Passwörtern zu tun, mit denen Sie sich an Ihrem Betriebssystem anmelden. Es gibt also keine notwendige Verbindung zwischen dem Passwort, mit dem Sie sich an einem Windows- oder Unix-Computer anmelden, und dem Passwort, das Sie für den Zugriff auf den MySQL-Server auf diesem Computer verwenden.

- MySQL verschlüsselt Passwörter mit einem eigenen Algorithmus. Diese Verschlüsselung unterscheidet sich von der, die während des Anmeldevorgangs unter Unix eingesetzt wird. Die MySQL-Passwortverschlüsselung ist identisch mit der durch die SQL-Funktion `PASSWORD()` implementierten. Die Unix-Passwortverschlüsselung hingegen ist identisch mit der durch die SQL-Funktion `ENCRYPT()` implementierten. Details finden Sie in den Beschreibungen zu den Funktionen `PASSWORD()` und `ENCRYPT()` in Abschnitt 12.10.2, „Verschlüsselungs- und Kompressionsfunktionen“. Seit Version 4.1 verwendet MySQL eine stärkere Authentifizierungsmethode, die während des Anmeldevorgangs einen besseren Passwortschutz gewährleistet als frühere Versionen. Sie ist auch dann sicher, wenn TCP/IP-Pakete abgefangen oder die `mysql`-Datenbank aufgezeichnet wird. (Bei den früheren Versionen wurden die Passwörter zwar in verschlüsselter Form in der Tabelle `user` abgelegt, aber die Kenntnis des verschlüsselten Passwortwertes konnte zur Verbindung mit dem MySQL-Server bereits genügen.)

Wenn Sie MySQL installieren, werden einige Vorgabekonten in die Grant-Tabellen eingetragen. Die Namen und Zugriffsberechtigungen dieser Konten sind in Abschnitt 2.9.3, „Einrichtung der anfänglichen MySQL-Berechtigungen“, beschrieben. Dort finden Sie auch eine Erläuterung, wie Sie Passwörter für diese Konten konfigurieren. Nachfolgend werden MySQL-Konten normalerweise mit Anweisungen wie `GRANT` oder `REVOKE` eingerichtet, geändert und entfernt. Siehe auch Abschnitt 13.5.1, „Anweisungen zur Benutzerkontenverwaltung“.

Wenn Sie über einen Befehlszeilenclient eine Verbindung mit einem MySQL-Server herstellen, sollten Sie den Benutzernamen und das Passwort des zu verwendenden Kontos angeben:

    shell> mysql --user=monty --password=guess db_name

Verwenden Sie lieber kurze Optionen, dann sieht der Befehl wie folgt aus:

    shell> mysql -u monty -pguess db_name

Zwischen der Option `-p` und dem nachfolgenden Passwortwert darf kein Leerzeichen vorhanden sein. Siehe auch Abschnitt 5.8.4, „Verbinden mit dem MySQL-Server“.

Obige Befehle enthalten den Passwortwert in der Befehlszeile. Dies kann ein Sicherheitsrisiko darstellen. Siehe auch Abschnitt 5.9.6, „Wie Sie Ihre Kennwörter sicher halten“. Um dieses Problem zu umgehen, geben Sie die Option `--password` bzw. `-p` ohne nachfolgenden Passwortwert an:

    shell> mysql --user=monty --password db_name
    shell> mysql -u monty -p db_name

Wenn die Passwortoption keinen Passwortwert enthält, zeigt das Clientprogramm eine Eingabeaufforderung an und wartet auf die Eingabe des Passworts. (In diesen Beispielen wird `db_name` nicht als Passwort interpretiert, da es von der vorangegangenen Passwortoption durch ein Leerzeichen getrennt ist.)

Auf manchen Systemen beschränkt die von MySQL zur Passworteingabe verwendete Bibliotheksroutine die Eingabe auf acht Zeichen. Dies ist ein Problem der Systembibliothek und nicht von MySQL. Intern beschränkt MySQL die Länge des Passworts nicht. Um dieses Problem zu umgehen, setzen Sie das MySQL-Passwort entweder auf einen Wert, der maximal acht Zeichen umfasst, oder legen es in einer Optionsdatei ab.

### 5.9.2. Hinzufügen neuer MySQL-Benutzer

Es gibt zwei Vorgehensweisen zum Hinzufügen von MySQL-Konten:

- Verwenden von Anweisungen zur Erstellung von Konten (z. B. `CREATE USER` oder `GRANT`)

- direktes Modifizieren der MySQL-Grant-Tabellen mit Anweisungen wie `INSERT`, `UPDATE` oder `DELETE`

Die zu bevorzugende Methode ist die Verwendung von Anweisungen zur Kontenerstellung, denn diese sind knapper und zudem weniger fehleranfällig. `CREATE USER` und `GRANT` sind in Abschnitt 13.5.1.1, „`CREATE USER`“, und Abschnitt 13.5.1.3, „`GRANT` und `REVOKE`“, beschrieben.

Eine weitere Option zur Erstellung von Konten besteht in der Verwendung eines der vielen erhältlichen Drittanbieterprogramme, die Funktionen zur MySQL-Kontenverwaltung anbieten. `phpMyAdmin` ist ein solches Programm.

Die folgenden Beispiele zeigen, wie man mit dem mysql-Client neue Benutzer einrichtet. Die Beispiele setzen voraus, dass die Berechtigungen entsprechend der Beschreibung in Abschnitt 2.9.3, „Einrichtung der anfänglichen MySQL-Berechtigungen“, auf die Vorgabewerte gesetzt sind. Das bedeutet, dass Sie, um Änderungen vornehmen zu können, eine Verbindung zum MySQL-Server als MySQL-Benutzer `root` herstellen müssen und das `root`-Konto die Berechtigung `INSERT` für die `mysql`-Datenbank sowie die administrative Berechtigung `RELOAD` benötigt.

Verwenden Sie zunächst das Programm mysql, um als MySQL-Benutzer `root` eine Verbindung zum Server herzustellen:

    shell> mysql --user=root mysql

Wenn Sie für das Konto `root` ein Passwort konfiguriert haben, müssen Sie auch eine Option `--password` bzw. `-p` für diesen und alle weiteren in diesem Abschnitt folgenden mysql-Befehle angeben.

Wenn Sie die Verbindung zum Server als `root` hergestellt haben, können Sie neue Konten hinzufügen. Die folgenden Anweisungen richten mit `GRANT` vier neue Benutzerkonten ein:

    mysql> GRANT ALL PRIVILEGES ON *.* TO 'monty'@'localhost'
        ->     IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
    mysql> GRANT ALL PRIVILEGES ON *.* TO 'monty'@'%'
        ->     IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
    mysql> GRANT RELOAD,PROCESS ON *.* TO 'admin'@'localhost';
    mysql> GRANT USAGE ON *.* TO 'dummy'@'localhost';

Die mit diesen `GRANT`-Anweisungen erstellten Konten haben die folgenden Eigenschaften:

- Zwei der Konten haben den Benutzernamen `monty` und das Passwort `some_pass`. Beide Konten sind Superuser-Konten mit allen Berechtigungen für beliebige Operationen. Eines der Konten (`'monty'@'localhost'`) kann nur für eine Verbindung vom lokalen Host verwendet werden. Das andere Konto (`'monty'@'%'`) erlaubt die Verbindung von einem beliebigen anderen Host. Beachten Sie, dass beide Konten erforderlich sind, damit `monty` von einem beliebigen Host aus als `monty` eine Verbindung herstellen kann. Würde das `localhost`-Konto nicht eingerichtet, dann hätte das anonyme Benutzerkonto für `localhost`, welches von mysql_install_db eingerichtet wird, Vorrang für die Anmeldung von `monty` am lokalen Host. Die Folge wäre, dass `monty` als anonymer Benutzer behandelt würde. Grund hierfür ist, dass das Konto für anonyme Benutzer einen spezifischeren Wert in der `Host`-Spalte aufweist als das Konto `'monty'@'%'` und deswegen in der Tabelle `user` weiter oben einsortiert wird. (Die Sortierung der Tabelle `user` ist in Abschnitt 5.8.5, „Zugriffskontrolle, Phase 1: Verbindungsüberprüfung“, beschrieben.)

- Ein Konto hat den Benutzernamen `admin` und kein Passwort. Dieses Konto kann nur für eine Verbindung vom lokalen Host verwendet werden. Gewährt werden die administrativen Berechtigungen `RELOAD` und `PROCESS`. Diese Berechtigungen gestatten dem Benutzer `admin` die Ausführung der Befehle mysqladmin reload, mysqladmin refresh und mysqladmin flush-`xxx` sowie des Befehls mysqladmin processlist . Für den Zugriff auf Datenbanken werden keine Berechtigungen gewährt. Sie können solche Berechtigungen später durch Absetzen zusätzlicher `GRANT`-Anweisungen hinzufügen.

- Ein Konto hat den Benutzernamen `dummy` und kein Passwort. Dieses Konto kann nur für eine Verbindung vom lokalen Host verwendet werden. Es werden keine Berechtigungen gewährt. Die Berechtigung `USAGE` in der `GRANT`-Anweisung erlaubt Ihnen die Erstellung eines Kontos ohne Gewährung von Berechtigungen. Es werden also alle globalen Berechtigungen auf `'N'` gesetzt. Es ist davon auszugehen, dass Sie diesem Konto später gewisse Berechtigungen gewähren werden.

Als Alternative zu `GRANT` können Sie dieselben Konten auch direkt durch Absetzen von `INSERT`-Anweisungen und ein nachfolgendes Neuladen der Grant-Tabellen durch den Server mithilfe von `FLUSH PRIVILEGES` erstellen:

    shell> mysql --user=root mysql
    mysql> INSERT INTO user
        ->     VALUES('localhost','monty',PASSWORD('some_pass'),
        ->     'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
    mysql> INSERT INTO user
        ->     VALUES('%','monty',PASSWORD('some_pass'),
        ->     'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
    mysql> INSERT INTO user SET Host='localhost',User='admin',
        ->     Reload_priv='Y', Process_priv='Y';
    mysql> INSERT INTO user (Host,User,Password)
        ->     VALUES('localhost','dummy','');
    mysql> FLUSH PRIVILEGES;

Der Grund für die Verwendung von `FLUSH PRIVILEGES` bei der Erstellung von Konten mit `INSERT` besteht darin, dass der Server zum Neuladen der Grant-Tabellen angewiesen werden muss. Andernfalls wird Ihre Änderung erst umgesetzt, wenn Sie den Server neu starten. Bei `GRANT` ist das Absetzen von `FLUSH PRIVILEGES` nicht erforderlich.

Die Funktion `PASSWORD()` wird bei `INSERT` zur Verschlüsselung des Passwortes verwendet. Die Anweisung `GRANT` verschlüsselt das Passwort direkt, d. h. `PASSWORD()` ist hier nicht erforderlich.

Die `'Y'`-Werte aktivieren die Berechtigungen für die Konten. Je nach MySQL-Version müssen Sie unter Umständen eine unterschiedliche Anzahl von `'Y'`-Werten in den ersten beiden `INSERT`-Anweisungen verwenden. Für das `admin`-Konto sollten Sie vielleicht eher die besser lesbare erweiterte `INSERT`-Syntax unter Verwendung von `SET` benutzen.

In der `INSERT`-Anweisung für das Konto `dummy` sind nur die Spalten `Host`, `User` und `Password` in der Tabelle `user` zugewiesene Werte. Keine der Berechtigungsspalten wird explizit eingestellt, weswegen MySQL ihnen allen den Standardwert `'N'` zuweist. Dies entspricht dem, was auch `GRANT USAGE` tut.

Beachten Sie, dass es zur Einrichtung eines Superuser-Kontos erforderlich ist, einen Eintrag in der Tabelle `user` zu erstellen, bei dem die Berechtigungsspalten auf `'Y'` gesetzt sind. Berechtigungen in der Tabelle `user` sind global, d. h. es sind keine anderen Einträge in einer anderen Grant-Tabelle erforderlich.

Die nächsten Beispiele erstellen drei Konten und gewähren ihnen Zugang zu bestimmten Datenbanken. Alle haben den Benutzernamen `custom` und das Passwort `obscure`.

Um die Konten mit `GRANT` zu erstellen, verwenden Sie die folgenden Anweisungen:

    shell> mysql --user=root mysql
    mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
        ->     ON bankaccount.*
        ->     TO 'custom'@'localhost'
        ->     IDENTIFIED BY 'obscure';
    mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
        ->     ON expenses.*
        ->     TO 'custom'@'whitehouse.gov'
        ->     IDENTIFIED BY 'obscure';
    mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
        ->     ON customer.*
        ->     TO 'custom'@'server.domain'
        ->     IDENTIFIED BY 'obscure';

Die drei Konten können wie folgt verwendet werden:

- Das erste Konto kann auf die Datenbank `bankaccount` zugreifen, dies allerdings nur vom lokalen Host aus.

- Das zweite Konto kann auf die Datenbank `expenses` zugreifen, dies allerdings nur vom Host `whitehouse.gov` aus.

- Das dritte Konto kann auf die Datenbank `customer` zugreifen, dies allerdings nur vom Host `server.domain` aus.

Um die `custom`-Konten ohne `GRANT` einrichten zu können, verwenden Sie wie folgt `INSERT`-Anweisungen zur direkten Änderung der Grant-Tabellen:

    shell> mysql --user=root mysql
    mysql> INSERT INTO user (Host,User,Password)
        ->     VALUES('localhost','custom',PASSWORD('obscure'));
    mysql> INSERT INTO user (Host,User,Password)
        ->     VALUES('whitehouse.gov','custom',PASSWORD('obscure'));
    mysql> INSERT INTO user (Host,User,Password)
        ->     VALUES('server.domain','custom',PASSWORD('obscure'));
    mysql> INSERT INTO db
        ->     (Host,Db,User,Select_priv,Insert_priv,
        ->     Update_priv,Delete_priv,Create_priv,Drop_priv)
        ->     VALUES('localhost','bankaccount','custom',
        ->     'Y','Y','Y','Y','Y','Y');
    mysql> INSERT INTO db
        ->     (Host,Db,User,Select_priv,Insert_priv,
        ->     Update_priv,Delete_priv,Create_priv,Drop_priv)
        ->     VALUES('whitehouse.gov','expenses','custom',
        ->     'Y','Y','Y','Y','Y','Y');
    mysql> INSERT INTO db
        ->     (Host,Db,User,Select_priv,Insert_priv,
        ->     Update_priv,Delete_priv,Create_priv,Drop_priv)
        ->     VALUES('server.domain','customer','custom',
        ->     'Y','Y','Y','Y','Y','Y');
    mysql> FLUSH PRIVILEGES;

Die ersten drei `INSERT`-Anweisungen fügen Einträge in der Tabelle `user` hinzu, die dem Benutzer `custom` die Verbindungsherstellung an den verschiedenen Hosts unter Verwendung des betreffenden Passwortes gestatten, gewähren aber keine globale Berechtigungen (alle Berechtigungen erhalten den Standardwert `'N'`). Die nachfolgenden drei `INSERT`-Anweisungen fügen Einträge in der Tabelle `db` hinzu, die `custom` Berechtigungen für die Datenbanken `bankaccount`, `expenses` und `customer` unter der Voraussetzung gewähren, dass der Zugriff vom angegebenen Host aus erfolgt. Wie bei der direkten Änderung der Grant-Tabellen üblich, müssen Sie den Server auch hier mit `FLUSH PRIVILEGES` zum Neuladen der Grant-Tabellen anweisen, damit die Änderungen an den Berechtigungen übernommen werden.

Wenn Sie einem bestimmten Benutzer den Zugriff von allen Computern in einer bestimmten Domäne (z. B. `mydomain.com`) gestatten wollen, können Sie eine `GRANT`-Anweisung absetzen, die das Jokerzeichen ‘`%`’ im Hostpart des Kontennamens verwendet:

    mysql> GRANT ...
        ->     ON *.*
        ->     TO 'myname'@'%.mydomain.com'
        ->     IDENTIFIED BY 'mypass';

Um das gleiche Ergebnis durch direkte Modifikation der Grant-Tabellen zu erzielen, tun Sie folgendes:

    mysql> INSERT INTO user (Host,User,Password,...)
        ->     VALUES('%.mydomain.com','myname',PASSWORD('mypass'),...);
    mysql> FLUSH PRIVILEGES;

### 5.9.3. Entfernen von Benutzerkonten in MySQL

Um ein Konto zu entfernen, verwenden Sie die Anweisung `DROP USER`, die in Abschnitt 13.5.1.2, „`DROP USER`“, beschrieben ist.

### 5.9.4. Begrenzen von Benutzer-Ressourcen

Eine Möglichkeit, die Nutzung der MySQL-Serverressourcen einzuschränken, besteht in der Einstellung der Systemvariablen `max_user_connections` auf einen Wert ungleich Null. Allerdings arbeitet diese Methode streng global und ermöglicht keine Verwaltung einzelner Konten. Außerdem wird hierbei nur die Anzahl der Verbindungen beschränkt, die gleichzeitig über ein einzelnes Konto verwendet werden, nicht jedoch, was ein Client tun kann, sobald die Verbindung hergestellt ist. Diese beiden Steuerungsformen sind für viele MySQL-Administratoren interessant – insbesondere für solche, die für Internetprovider tätig sind.

In MySQL 5.1 können Sie die folgenden Serverressourcen für einzelne Konten einschränken:

- Anzahl der Abfragen, die ein Konto pro Stunde absetzen kann

- Anzahl der Updates, die ein Konto pro Stunde durchführen kann

- Häufigkeit, mit der ein Konto pro Stunde Verbindungen herstellen kann

Jede Anweisung, die ein Client absetzen kann, erhöht den Zähler für das Abfragelimit. Der Updatezähler hingegen wird nur bei Anweisungen hochgezählt, die Datenbanken oder Tabellen ändern.

Es ist auch möglich, die Anzahl gleichzeitiger Verbindungen zum Server pro Konto zu beschränken.

In diesem Kontext ist unter einem Konto ein Datensatz in der Tabelle `user` zu verstehen. Jedes Konto wird durch die `User`- und `Host`-Spaltenwerte eindeutig bezeichnet.

Voraussetzung für die Verwendung dieser Funktion ist, dass die Tabelle `user` in der `mysql`-Datenbank die ressourcenspezifischen Spalten enthält. Ressourcenbeschränkungen sind in den Spalten `max_questions`, `max_updates`, `max_connections` und `max_user_connections` abgelegt. Wenn Ihre Tabelle `user` diese Spalten nicht aufweist, muss sie aktualisiert werden. Siehe auch Abschnitt 5.6, „mysql_fix_privilege_tables — Upgrade von MySQL-Systemtabellen“.

Um Ressourcenbeschränkungen mit einer `GRANT`-Anweisung einzustellen, verwenden Sie eine `WITH`-Klausel, die alle zu beschränkenden Ressourcen und einen stundenbezogenen Zähler benennt, der den jeweiligen Maximalwert angibt. Um also etwa ein neues Konto zu erstellen, das auf die Datenbank `customer` in eingeschränkter Weise zugreifen kann, setzen Sie folgende Anweisung ab:

    mysql> GRANT ALL ON customer.* TO 'francis'@'localhost'
        ->     IDENTIFIED BY 'frank'
        ->     WITH MAX_QUERIES_PER_HOUR 20
        ->          MAX_UPDATES_PER_HOUR 10
        ->          MAX_CONNECTIONS_PER_HOUR 5
        ->          MAX_USER_CONNECTIONS 2;

Nicht alle Beschränkungstypen müssen in der `WITH`-Klausel aufgeführt sein. Zudem ist die Reihenfolge der aufgeführten Typen beliebig. Der Wert des Stundenlimits sollte eine ganze Zahl sein, die den Wert pro Stunde angibt. Wird die `GRANT`-Anweisung ohne `WITH`-Klausel abgesetzt, dann werden alle Beschränkungen auf den Standardwert Null gesetzt (d. h. es gibt keine Beschränkungen). Bei `MAX_USER_CONNECTIONS` ist der Höchstwert eine ganze Zahl, die die maximale Anzahl der Verbindungen angibt, die das Konto gleichzeitig halten kann. Wenn der Wert auf die Vorgabe Null gesetzt ist, bestimmt die Systemvariable `max_user_connections` die maximale Anzahl gleichzeitiger Verbindungen für das Konto.

Um die Beschränkungen für ein vorhandenes Konto einzustellen oder zu ändern, verwenden Sie eine `GRANT USAGE`-Anweisung auf der globalen Ebene (`ON *.*`). Die folgende Anweisung setzt das Abfragelimit für `francis` auf 100:

    mysql> GRANT USAGE ON *.* TO 'francis'@'localhost'
        ->     WITH MAX_QUERIES_PER_HOUR 100;

Diese Anweisung ändert nicht die vorhandenen Berechtigungen des Kontos, sondern nur die vorhandenen Maximalwerte.

Um eine vorhandene Beschränkung zu entfernen, setzen Sie den Wert auf Null. Um etwa die Beschränkung der Häufigkeit aufzuheben, mit der `francis` eine Verbindung herstellen kann, verwenden Sie folgende Anweisung:

    mysql> GRANT USAGE ON *.* TO 'francis'@'localhost'
        ->     WITH MAX_CONNECTIONS_PER_HOUR 0;

Eine Zählung der Ressourcennutzung findet statt, wenn für ein Konto ein Wert ungleich Null für die Beschränkung einer bestimmten Ressource konfiguriert ist.

Wenn der Server läuft, ermittelt er, wie häufig jedes Konto welche Ressourcen verwendet. Wenn ein Konto die höchste Anzahl zulässiger Verbindungen innerhalb einer Stunde erreicht, werden weitere Verbindungsanfragen des Kontos abgewiesen, bis die Stunde verstrichen ist. Ähnlich werden weitere Abfragen oder Updates abgewiesen, wenn für diese der jeweilige Maximalwert durch ein Konto erreicht wird. In all diesen Fällen wird eine entsprechende Fehlermeldung angezeigt.

Die Zählung der Ressourcennutzungen erfolgt auf Konten- und nicht auf Clientbasis. Wenn Ihr Konto beispielsweise eine Beschränkung von 50 Abfragen pro Stunde hat, dann können Sie diese nicht verdoppeln, indem Sie gleichzeitig zwei Clientverbindungen zum Server herstellen. Die Abfragen, die über die beiden Verbindungen abgesetzt werden, werden zusammengezählt.

Die aktuellen Ressourcenzähler können global oder auch für einzelne Konten zurückgesetzt werden:

- Um die aktuellen Zähler für alle Konten zu nullen, setzen Sie eine `FLUSH USER_RESOURCES`-Anweisung ab. Die Werte können auch durch Neuladen der Grant-Tabellen (etwa mit einer `FLUSH PRIVILEGES`-Anweisung oder dem Befehl mysqladmin reload) zurückgesetzt werden.

- Zähler eines bestimmten Kontos können auf Null gesetzt werden, indem eine beliebige Beschränkung erneut definiert wird. Verwenden Sie zu diesem Zweck wie oben beschrieben die Anweisung `GRANT USAGE` und geben Sie den Wert, der für das Konto bereits festgelegt ist, erneut an.

Das Zurücksetzen der Zähler wirkt sich nicht auf die Beschränkung `MAX_USER_CONNECTIONS` aus.

Beim Serverstart beginnen alle Zähler bei Null zu zählen, d. h. vorhandene Werte lassen sich nicht über einen Neustart hinweg übertragen.

### 5.9.5. Kennwörter einrichten

Passwörter können mit mysqladmin über die Befehlszeile zugewiesen werden:

    shell> mysqladmin -u user_name -h host_name password "newpwd"

Der Befehl setzt das Passwort des Kontos zurück, bei dessen Datensatz in der Tabelle `user` eine Übereinstimmung mit `user_name` in der Spalte `User` und eine Übereinstimmung des Clienthosts, von dem aus Sie die Verbindung herstellen, in der Spalte `Host` vorliegt.

Eine weitere Möglichkeit, einem Konto ein Passwort zuzuweisen, besteht im Absetzen einer `SET PASSWORD`-Anweisung:

    mysql> SET PASSWORD FOR 'jeffrey'@'%' = PASSWORD('biscuit');

Nur Benutzer wie `root`, die die `mysql`-Datenbank aktualisieren dürfen, können die Passwörter anderer Benutzer ändern. Sofern Sie nicht als anonymer Benutzer verbunden sind, können Sie Ihr eigenes Passwort durch Weglassen der `FOR`-Klausel ändern:

    mysql> SET PASSWORD = PASSWORD('biscuit');

Sie können auch eine `GRANT USAGE`-Anweisung auf der globalen Ebene (`ON *.*`) verwenden, um einem Konto ein Passwort zuzuweisen, ohne die aktuellen Berechtigungen dieses Kontos zu beeinträchtigen:

    mysql> GRANT USAGE ON *.* TO 'jeffrey'@'%' IDENTIFIED BY 'biscuit';

Zwar ist die Zuweisung von Passwörtern unter Verwendung einer der zuvor beschriebenen Methoden generell vorzuziehen, aber Sie können die Tabelle `user` auch direkt ändern:

- Um bei Erstellung eines neuen Kontos ein Passwort zuzuweisen, setzen Sie einen Wert in die Spalte `Password`:

      shell> mysql -u root mysql
      mysql> INSERT INTO user (Host,User,Password)
          -> VALUES('%','jeffrey',PASSWORD('biscuit'));
      mysql> FLUSH PRIVILEGES;

- Wollen Sie das Passwort eines vorhandenen Kontos ändern, dann weisen Sie mit `UPDATE` den `Password`-Spaltenwert zu:

      shell> mysql -u root mysql
      mysql> UPDATE user SET Password = PASSWORD('bagel')
          -> WHERE Host = '%' AND User = 'francis';
      mysql> FLUSH PRIVILEGES;

Wenn Sie einem Konto mit `SET PASSWORD`, `INSERT` oder `UPDATE` ein nichtleeres Passwort zuweisen, müssen Sie die Funktion `PASSWORD()` zur Verschlüsselung verwenden. `PASSWORD()` ist erforderlich, weil die Tabelle `user` Passwörter nicht als Klartext, sondern in verschlüsselter Form speichert. Wenn Sie dies vergessen, werden Sie Passwörter wahrscheinlich so einstellen:

    shell> mysql -u root mysql
    mysql> INSERT INTO user (Host,User,Password)
        -> VALUES('%','jeffrey','biscuit');
    mysql> FLUSH PRIVILEGES;

Die Folge ist, dass der literale Wert `'biscuit'` und nicht der verschlüsselte Wert als Passwort in der Tabelle `user` gespeichert wird. Wenn `jeffrey` dann unter Angabe dieses Passworts eine Verbindung zum Server herzustellen versucht, wird der Wert verschlüsselt und dann mit dem in der Tabelle `user` gespeicherten Wert verglichen. Dieser gespeicherte Wert ist jedoch der literale String `'biscuit'` – der Vergleich schlägt fehl, und der Server weist die Verbindungsanfrage ab:

    shell> mysql -u jeffrey -pbiscuit test
    Access denied

Bei der Zuweisung von Passwörtern mit der Anweisung `GRANT ... IDENTIFIED BY` oder dem Befehl mysqladmin password wird die Verschlüsselung des Passworts automatisch erledigt. In diesen Fällen ist die Verwendung der Funktion `PASSWORD()` nicht erforderlich.

Hinweis: Die `PASSWORD()`-Verschlüsselung unterscheidet sich von der Unix-Passwortverschlüsselung. Siehe auch Abschnitt 5.9.1, „MySQL-Benutzernamen und -Kennwörter“.

### 5.9.6. Wie Sie Ihre Kennwörter sicher halten

Auf der administrativen Ebene sollten Sie nichtadministrativen Konten niemals Zugriff auf die Grant-Tabelle `user` gestatten.

Wenn Sie ein Clientprogramm ausführen, um eine Verbindung mit dem MySQL-Server herzustellen, ist es nicht ratsam, Ihr Passwort so einzugeben, dass es von anderen Benutzern erraten werden könnte. Die Methoden, die Sie zur Angabe Ihres Passworts bei Ausführung von Clientprogrammen verwenden können, sind einschließlich einer Risikoeinschätzung jeder Methode nachfolgend aufgeführt:

- Sie verwenden die Option `-p`your_pass`` bzw. `--password=`your_pass`` auf der Befehlszeile. Zum Beispiel:

      shell> mysql -u francis -pfrank db_name

  Dies ist praktisch, aber unsicher, weil Ihr Passwort für Systemstatusprogramme wie ps sichtbar wird, die von anderen Benutzern zur Anzeige von Befehlszeilen aufgerufen werden können. MySQL-Clients überschreiben das befehlszeilenbasierte Passwortargument bei der Initialisierung normalerweise mit Nullen. Es gibt allerdings noch einen ganz kurzen Zeitraum, für den der Wert sichtbar ist. Auf einigen Systemen ist diese Strategie ohnehin ohne Wirkung, und die Passwörter bleiben für ps sichtbar. (Das Problem tritt etwa bei System V-Unix und unter Umständen auch bei anderen Systemen auf.)

- Sie verwenden die Option `-p` bzw. `--password` ohne Passwortangabe. In diesem Fall fordert das Clientprogramm zur Eingabe des Passworts über das Terminal auf:

      shell> mysql -u francis -p db_name
      Enter password: ********

  Die Zeichen ‘`*`’ geben an, wo Sie Ihr Passwort eingegeben haben. Das Passwort wird bei der Eingabe nicht angezeigt.

  Diese Methode zur Passworteingabe ist sicherer als die Angabe über die Befehlszeile, da das Passwort anderen Benutzern nicht angezeigt wird. Allerdings ist diese Eingabemethode nur für Programme geeignet, die Sie interaktiv ausführen. Wollen Sie einen Client aus einem Skript heraus aufrufen, das nicht interaktiv läuft, dann gibt es keine Möglichkeit, das Passwort über das Terminal einzugeben. Bei manchen Systemen werden Sie sogar feststellen, dass die erste Zeile Ihres Skript gelesen und irrtümlich als Passwort interpretiert wird.

- Sie speichern Ihr Passwort in einer Optionsdatei. Unter Unix etwa können Sie Ihr Passwort im Abschnitt `[client]` der Datei `.my.cnf` im Stammverzeichnis auflisten:

      [client]
      password=your_pass

  Wenn Sie Ihr Passwort in `.my.cnf` speichern, dann sollte diese Datei ausschließlich für Sie zugänglich sein. Um dies sicherzustellen, setzen Sie die Dateizugriffsmethode auf `400` oder `600`. Zum Beispiel:

      shell> chmod 600 .my.cnf

  Abschnitt 4.3.2, „my.cnf-Optionsdateien“, erläutert Optionsdateien im Detail.

- Sie speichern Ihr Passwort in der Umgebungsvariable `MYSQL_PWD`. Diese Methode der Angabe eines MySQL-Passworts muss als extrem unsicher betrachtet werden und sollte nicht verwendet werden. Einige Versionen von ps enthalten eine Option zur Anzeige der Umgebung laufender Prozesse. Wenn Sie `MYSQL_PWD` einstellen, wird Ihr Passwort allen Benutzern zugänglich gemacht, die ps ausführen. Sogar auf Systemen ohne eine solche Version von ps ist es nicht ratsam, davon auszugehen, dass keine andere Methoden vorhanden sind, mit denen Benutzer Prozessumgebungen untersuchen können. Siehe auch Anhang F, Umgebungsvariablen.

Insgesamt betrachtet sind die sichersten Methoden die Aufforderung des Clientprogramms zur Eingabe des Passwortes oder die Angabe des Passwortes in einer angemessen geschützten Optionsdatei.

### 5.9.7. Verwendung sicherer Verbindungen

MySQL unterstützt sichere (verschlüsselte) Verbindungen zwischen MySQL-Clients und dem Server unter Verwendung des SSL-Protokolls (Secure Sockets Layer). Dieser Abschnitt beschreibt, wie man SSL-Verbindungen verwendet. Ferner wird eine Möglichkeit beschrieben, SSH unter Windows einzurichten. Informationen dazu, wie man die Verwendung von SSL-Verbindungen durch die Benutzer erzwingt, finden Sie in Abschnitt 13.5.1.3, „`GRANT` und `REVOKE`“.

Die Standardkonfiguration von MySQL ist auf Geschwindigkeit optimiert, weswegen verschlüsselte Verbindungen standardmäßig nicht verwendet werden. Andernfalls wäre das Client/Server-Protokoll erheblich langsamer. Die Verschlüsselung von Daten ist ein prozessorintensiver Vorgang, der zusätzliche Operationen seitens des Computers erfordert und andere MySQL-Aufgaben verzögern kann. Bei Anwendungen hingegen, die die Sicherheit verschlüsselter Verbindungen erfordern, ist der zusätzliche Rechenaufwand in jedem Fall gerechtfertigt.

MySQL gestattet die Aktivierung der Verschlüsselung auf der Basis einzelner Verbindungen. Sie können je nach Anforderungen einzelner Anwendungen zwischen einer normalen unverschlüsselten Verbindung oder einer sicheren verschlüsselten SSL-Verbindung wählen.

#### 5.9.7.1. Grundlegende SSL-Konzepte

Um verstehen zu können, wie MySQL SSL verwendet, ist es notwendig, einige grundlegende Konzepte zu SSL und X509 zu kennen. Leser, die mit diesen Konzepten vertraut sind, können diesen Teil des Handbuchs überspringen.

Standardmäßig verwendet MySQL unverschlüsselte Verbindungen zwischen Client und Server. Das bedeutet, dass jemand, der Zugriff auf das Netzwerk hat, den gesamten Datenverkehr überwachen und die Daten bei Versand oder Empfang überprüfen könnte. Schlimmer noch: Selbst eine Modifikation der Daten während der Übertragung zwischen Client und Server ist möglich. Um die Sicherheit ein wenig zu erhöhen, können Sie den Client/Server-Datenverkehr durch Angabe der Option `--compress` beim Aufruf des Clientprogramms komprimieren. Ein entschlossener Angreifer würde sich hiervon jedoch nicht abhalten lassen.

Wenn Sie Daten in sicherer Form über ein Netzwerk übertragen müssen, ist eine unverschlüsselte Verbindung nicht akzeptabel. Die Verschlüsselung stellt eine Möglichkeit dar, beliebige Daten unlesbar zu machen. Tatsächlich erfordert die moderne Praxis viele zusätzliche Sicherheitselemente von Verschlüsselungsalgorithmen. Sie sollten viele bekannte Angriffstypen abwehren können, z. B. eine Änderung der Reihenfolge verschlüsselter Daten oder die zweimalige Wiedergabe von Daten.

SSL ist ein Protokoll, welches mithilfe verschiedener Verschlüsselungsalgorithmen sicherstellen soll, dass Daten, die über ein öffentliches Netzwerk übertragen wurden, vertrauenswürdig sind. SSL verfügt über Methoden zur Erkennung von Änderungen, Verlusten oder Wiedergabe von Daten. Ferner enthalten sind Algorithmen, die eine Identitätsprüfung unter Verwendung des X509-Standards ermöglichen.

X509 erlaubt eine Identifizierung über das Internet. Der bevorzugte Anwendungsfall hierfür ist der E-Commerce. Einfach gesagt wird ein Unternehmen benötigt, welches als „Zertifizierungsstelle“ (Certificate Authority, CA) elektronische Zertifikate an Antragssteller vergibt. Zertifikate basieren auf asymmetrischen Verschlüsselungsalgorithmen mit zwei Schlüsseln: einem öffentlichen und einem Geheimschlüssel. Der Halter eines Zertifikats kann einem Gegenüber das Zertifikat als Identitätsnachweis vorlegen. Das Zertifikat besteht aus dem öffentlichen Schlüssel seines Besitzers. Daten, die mit diesem öffentlichen Schlüssel verschlüsselt wurden, können nur mit dem entsprechenden Geheimschlüssel wieder entschlüsselt werden. Dieser Geheimschlüssel befindet sich im Besitz des Zertifikatshalters.

Wenn Sie weitere Informationen zu SSL, X509 oder zum Thema Verschlüsselung suchen, geben Sie die entsprechenden Begriffe in die Internetsuchmaschine Ihrer Wahl ein.

#### 5.9.7.2. Verwendung von SSL-Verbindungen mit OpenSSL

Um SSL-Verbindungen zwischen dem MySQL-Server und den Clientprogrammen zu verwenden, muss Ihr System entweder OpenSSL oder yaSSL unterstützen. In diesem Abschnitt behandeln wir OpenSSL. Wenn sie yaSSL verwenden, lesen Sie stattdessen Abschnitt 5.9.7.3, „Verwendung von SSL-Verbindungen mit yaSSL“.

Gehen Sie wie folgt vor, um mithilfe von OpenSSL sichere Verbindungen für MySQL zu erstellen:

1. Installieren Sie, soweit nicht bereits vorhanden, die OpenSSL-Bibliothek. Wir haben MySQL mit OpenSSL 0.9.6 getestet. Wenn Sie OpenSSL benötigen, besuchen Sie die Site http://www.openssl.org.

2. Wenn Sie MySQL konfigurieren, rufen Sie das Skript configure mit den Optionen `--with-vio` und `--with-openssl` auf:

       shell> ./configure --with-vio --with-openssl

3. Stellen Sie sicher, dass Sie Ihre Grant-Tabellen so aktualisiert haben, dass die SSL-spezifischen Spalten in der Tabelle `mysql.user` enthalten sind. Dies ist erforderlich, wenn Ihre Grant-Tabellen aus einer Version vor MySQL 4.0.0 stammen. Der Aktualisierungsvorgang ist in Abschnitt 5.6, „mysql_fix_privilege_tables — Upgrade von MySQL-Systemtabellen“, beschrieben.

4. Um zu überprüfen, ob ein laufender mysqld-Server OpenSSL unterstützt, prüfen Sie den Wert der Systemvariable `have_openssl`:

       mysql> SHOW VARIABLES LIKE 'have_openssl';
       +---------------+-------+
       | Variable_name | Value |
       +---------------+-------+
       | have_openssl  | YES   |
       +---------------+-------+

   Ist der Wert `YES`, dann unterstützt der Server OpenSSL-Verbindungen.

#### 5.9.7.3. Verwendung von SSL-Verbindungen mit yaSSL

Die in MySQL integrierte yaSSL-Unterstützung erleichtert die Verwendung sicherer Verbindungen. Sie müssen OpenSSL nicht installieren und auch die anderen in Abschnitt 5.9.7.2, „Verwendung von SSL-Verbindungen mit OpenSSL“, beschriebenen Schritte nicht durchführen. Außerdem verwenden MySQL und yaSSL dasselbe Lizenzmodell.

Zurzeit wird yaSSL auf den folgenden Plattformen unterstützt:

- Linux/x86-64 Red Hat Enterprise 3.0

- Linux RHAS21 Itanium-2 mit gcc, statisch verknüpft

- Linux Itanium-2 mit gcc

- Windows (alle Builds)

Um beim Erstellen von MySQL aus einer Quelldistribution yaSSL zu aktivieren, sollten Sie MySQL wie folgt konfigurieren:

    shell> ./configure --with-yassl

Beachten Sie, dass die yaSSL-Unterstützung auf Unix-Plattformen die Installation von `/dev/urandom` oder `/dev/random` erfordert, damit echte Zufallszahlen abgerufen werden können. Weitere Informationen (insbesondere zu yaSSL auf Solaris-Versionen vor 2.8 und HP-UX) finden Sie im Bug Nr. 13164.

Um den MySQL-Server mit yaSSL-Unterstützung zu starten, verwenden Sie dieselben Optionen wie beim OpenSSL-Support und geben die zur Herstellung einer sicheren Verbindung erforderlichen Zertifikate an:

    shell> mysqld --ssl-ca=cacert.pem \
           --ssl-cert=server-cert.pem \
           --ssl-key=server-key.pem

- `--ssl-ca` benennt das CA-Zertifikat.

- `--ssl-cert` benennt das Serverzertifikat.

- `--ssl-key` benennt das Clientzertifikat.

Um eine sichere Verbindung zu einem MySQL-Server mit yaSSL-Unterstützung herzustellen, starten Sie Ihren Client wie folgt:

    shell> mysql --ssl-ca=cacert.pem \
           --ssl-cert=server-cert.pem \
           --ssl-key=server-key.pem

Mit anderen Worten sind die Optionen dieselben wie beim Server, und das Zertifikat der Zertifizierungsstelle muss das gleiche sein.

Wenn Sie eine sichere Verbindung von einem Anwendungsprogramm aus herstellen wollen, stellen Sie mit der `mysql_ssl_set()`-API-Funktion die passenden Zertifikatsoptionen ein, bevor Sie `mysql_real_connect()` aufrufen. Siehe auch Abschnitt 24.2.3.64, „`mysql_ssl_set()`“.

#### 5.9.7.4. Einrichtung von SSL-Zertifikaten für MySQL

An dieser Stelle folgt ein Beispiel zur Konfiguration von SSL-Zertifikaten für MySQL mit OpenSSL:

    DIR=`pwd`/openssl
    PRIV=$DIR/private

    mkdir $DIR $PRIV $DIR/newcerts
    cp /usr/share/ssl/openssl.cnf $DIR
    replace ./demoCA $DIR -- $DIR/openssl.cnf

    # Create necessary files: $database, $serial and $new_certs_dir
    # directory (optional)

    touch $DIR/index.txt
    echo "01" > $DIR/serial

    #
    # Generation of Certificate Authority(CA)
    #

    openssl req -new -x509 -keyout $PRIV/cakey.pem -out $DIR/cacert.pem \
        -config $DIR/openssl.cnf

    # Sample output:
    # Using configuration from /home/monty/openssl/openssl.cnf
    # Generating a 1024 bit RSA private key
    # ................++++++
    # .........++++++
    # writing new private key to '/home/monty/openssl/private/cakey.pem'
    # Enter PEM pass phrase:
    # Verifying password - Enter PEM pass phrase:
    # -----
    # You are about to be asked to enter information that will be
    # incorporated into your certificate request.
    # What you are about to enter is what is called a Distinguished Name
    # or a DN.
    # There are quite a few fields but you can leave some blank
    # For some fields there will be a default value,
    # If you enter '.', the field will be left blank.
    # -----
    # Country Name (2 letter code) [AU]:FI
    # State or Province Name (full name) [Some-State]:.
    # Locality Name (eg, city) []:
    # Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
    # Organizational Unit Name (eg, section) []:
    # Common Name (eg, YOUR name) []:MySQL admin
    # Email Address []:

    #
    # Create server request and key
    #
    openssl req -new -keyout $DIR/server-key.pem -out \
        $DIR/server-req.pem -days 3600 -config $DIR/openssl.cnf

    # Sample output:
    # Using configuration from /home/monty/openssl/openssl.cnf
    # Generating a 1024 bit RSA private key
    # ..++++++
    # ..........++++++
    # writing new private key to '/home/monty/openssl/server-key.pem'
    # Enter PEM pass phrase:
    # Verifying password - Enter PEM pass phrase:
    # -----
    # You are about to be asked to enter information that will be
    # incorporated into your certificate request.
    # What you are about to enter is what is called a Distinguished Name
    # or a DN.
    # There are quite a few fields but you can leave some blank
    # For some fields there will be a default value,
    # If you enter '.', the field will be left blank.
    # -----
    # Country Name (2 letter code) [AU]:FI
    # State or Province Name (full name) [Some-State]:.
    # Locality Name (eg, city) []:
    # Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
    # Organizational Unit Name (eg, section) []:
    # Common Name (eg, YOUR name) []:MySQL server
    # Email Address []:
    #
    # Please enter the following 'extra' attributes
    # to be sent with your certificate request
    # A challenge password []:
    # An optional company name []:

    #
    # Remove the passphrase from the key (optional)
    #

    openssl rsa -in $DIR/server-key.pem -out $DIR/server-key.pem

    #
    # Sign server cert
    #
    openssl ca  -policy policy_anything -out $DIR/server-cert.pem \
        -config $DIR/openssl.cnf -infiles $DIR/server-req.pem

    # Sample output:
    # Using configuration from /home/monty/openssl/openssl.cnf
    # Enter PEM pass phrase:
    # Check that the request matches the signature
    # Signature ok
    # The Subjects Distinguished Name is as follows
    # countryName           :PRINTABLE:'FI'
    # organizationName      :PRINTABLE:'MySQL AB'
    # commonName            :PRINTABLE:'MySQL admin'
    # Certificate is to be certified until Sep 13 14:22:46 2003 GMT
    # (365 days)
    # Sign the certificate? [y/n]:y
    #
    #
    # 1 out of 1 certificate requests certified, commit? [y/n]y
    # Write out database with 1 new entries
    # Data Base Updated

    #
    # Create client request and key
    #
    openssl req -new -keyout $DIR/client-key.pem -out \
        $DIR/client-req.pem -days 3600 -config $DIR/openssl.cnf

    # Sample output:
    # Using configuration from /home/monty/openssl/openssl.cnf
    # Generating a 1024 bit RSA private key
    # .....................................++++++
    # .............................................++++++
    # writing new private key to '/home/monty/openssl/client-key.pem'
    # Enter PEM pass phrase:
    # Verifying password - Enter PEM pass phrase:
    # -----
    # You are about to be asked to enter information that will be
    # incorporated into your certificate request.
    # What you are about to enter is what is called a Distinguished Name
    # or a DN.
    # There are quite a few fields but you can leave some blank
    # For some fields there will be a default value,
    # If you enter '.', the field will be left blank.
    # -----
    # Country Name (2 letter code) [AU]:FI
    # State or Province Name (full name) [Some-State]:.
    # Locality Name (eg, city) []:
    # Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
    # Organizational Unit Name (eg, section) []:
    # Common Name (eg, YOUR name) []:MySQL user
    # Email Address []:
    #
    # Please enter the following 'extra' attributes
    # to be sent with your certificate request
    # A challenge password []:
    # An optional company name []:

    #
    # Remove a passphrase from the key (optional)
    #
    openssl rsa -in $DIR/client-key.pem -out $DIR/client-key.pem

    #
    # Sign client cert
    #

    openssl ca  -policy policy_anything -out $DIR/client-cert.pem \
        -config $DIR/openssl.cnf -infiles $DIR/client-req.pem

    # Sample output:
    # Using configuration from /home/monty/openssl/openssl.cnf
    # Enter PEM pass phrase:
    # Check that the request matches the signature
    # Signature ok
    # The Subjects Distinguished Name is as follows
    # countryName           :PRINTABLE:'FI'
    # organizationName      :PRINTABLE:'MySQL AB'
    # commonName            :PRINTABLE:'MySQL user'
    # Certificate is to be certified until Sep 13 16:45:17 2003 GMT
    # (365 days)
    # Sign the certificate? [y/n]:y
    #
    #
    # 1 out of 1 certificate requests certified, commit? [y/n]y
    # Write out database with 1 new entries
    # Data Base Updated

    #
    # Create a my.cnf file that you can use to test the certificates
    #

    cnf=""
    cnf="$cnf [client]"
    cnf="$cnf ssl-ca=$DIR/cacert.pem"
    cnf="$cnf ssl-cert=$DIR/client-cert.pem"
    cnf="$cnf ssl-key=$DIR/client-key.pem"
    cnf="$cnf [mysqld]"
    cnf="$cnf ssl-ca=$DIR/cacert.pem"
    cnf="$cnf ssl-cert=$DIR/server-cert.pem"
    cnf="$cnf ssl-key=$DIR/server-key.pem"
    echo $cnf | replace " " '
    ' > $DIR/my.cnf

Um SSL-Verbindungen zu testen, starten Sie den Server wie folgt, wobei `$DIR` der Pfadname zu dem Verzeichnis ist, in dem sich die Beispieloptionsdatei `my.cnf` befindet:

    shell> mysqld --defaults-file=$DIR/my.cnf &

Danach rufen Sie ein Clientprogramm mit derselben Optionsdatei auf:

    shell> mysql --defaults-file=$DIR/my.cnf

Wenn Sie eine MySQL-Quelldistribution haben, können Sie Ihre Konfiguration auch durch eine dahingehende Änderung der genannten Datei `my.cnf` testen, dass diese auf das Demozertifikat und die Schlüsseldateien im Verzeichnis `SSL` der Distribution verweist.

#### 5.9.7.5. SSL-Befehlsoptionen

Die folgende Liste beschreibt Optionen, die zur Angabe der SSL-Nutzung, der Zertifikatsdateien und der Schlüsseldateien dienen. Diese Optionen können über die Befehlszeile oder in einer Optionsdatei angegeben werden.

- `--ssl`

  Am Server legt diese Option fest, dass der Server SSL-Verbindungen zulässt. Bei einem Clientprogramm gestattet sie dem Client die Herstellung einer Serververbindung unter Verwendung von SSL. Die Angabe der Option allein reicht nicht aus, um die Verwendung einer SSL-Verbindung zu bewirken. Sie müssen auch die Optionen `--ssl-ca`, `--ssl-cert` und `--ssl-key` angeben.

  Diese Option wird häufiger in ihrer negativen Form angegeben, um festzulegen, dass SSL nicht verwendet werden soll. Zu diesem Zweck geben Sie `--skip-ssl` oder `--ssl=0` an.

  Beachten Sie, dass die Verwendung von `--ssl` das Vorhandensein einer SSL-Verbindung nicht erfordert. Werden beispielsweise Server oder Client ohne SSL-Unterstützung kompiliert, dann wird eine normale unverschlüsselte Verbindung verwendet.

  Die sichere Art, die Verwendung einer SSL-Verbindung zu gewährleisten, besteht in der Erstellung eines Kontos auf dem Server mit einer `REQUIRE SSL`-Klausel in der `GRANT`-Anweisung. Danach stellen Sie über dieses Konto eine Verbindung zum Server her, wobei die SSL-Unterstützung sowohl am Server als auch am Client aktiviert sein muss.

- `--ssl-ca=`file_name``

  Pfad zu einer Datei, die eine Liste vertrauenswürdiger SSL-CAs enthält.

- `--ssl-capath=`directory_name``

  Pfad zu einem Verzeichnis, welches Zertifikate vertrauenswürdiger SSL-CAs im PEM-Format enthält.

- `--ssl-cert=`file_name``

  Name der SSL-Zertifikatsdatei, die zur Herstellung einer sicheren Verbindung verwendet wird.

- `--ssl-cipher=`cipher_list``

  Eine Liste zulässiger Chiffren, die für die SSL-Verschlüsselung verwendet werden dürfen. `cipher_list` hat das gleiche Format wie der Befehl `openssl ciphers`.

  Beispiel: `--ssl-cipher=ALL:-AES:-EXP`

- `--ssl-key=`file_name``

  Name der SSL-Schlüsseldatei, die zur Herstellung einer sicheren Verbindung verwendet wird.

#### 5.9.7.6. Verbinden mit einem entfernten MySQL-Server von Windows mit SSH aus

Der folgende Hinweise beschreibt, wie man unter Verwendung von SSH eine sichere Verbindung mit einem entfernte MySQL-Server herstellt (von David Carlson, `<dcarlson@mplcomm.com>`):

1. Installieren Sie einen SSH-Client auf Ihrem Windows-Computer. Für Benutzer ist der beste nicht kostenlose Client, den ich gefunden habe, `SecureCRT` von http://www.vandyke.com/. Eine weitere Option ist `f-secure` von http://www.f-secure.com/. Es gibt auch kostenlose Varianten, die Sie via Google finden können (http://directory.google.com/Top/Computers/Security/Products_and_Tools/Cryptography/SSH/Clients/Windows/).

2. Starten Sie Ihren Windows-SSH-Client. Nehmen Sie folgende Einstellung vor: `Host_Name = `yourmysqlserver_URL_or_IP``. Setzen Sie ferner `userid=`your_userid``, um sich an Ihrem Server anzumelden. Dieser `userid`-Wert ist unter Umständen nicht mit dem Benutzernamen Ihres MySQL-Kontos identisch.

3. Konfigurieren Sie die Portweiterleitung. Sie können entweder eine Remote-Weiterleitung (via `local_port: 3306`, `remote_host: `yourmysqlservername_or_ip``, `remote_port: 3306` ) oder eine lokale Weiterleitung einstellen (über `port: 3306`, `host: localhost`, `remote port: 3306`).

4. Speichern Sie alles (ansonsten müssen Sie die Schritte beim nächsten Mal wiederholen).

5. Melden Sie sich mit der gerade erstellten SSH-Sitzung an Ihrem Server an.

6. Starten Sie auf Ihrem Windows-Computer eine ODBC-Anwendung (z. B. Microsoft Access).

7. Erstellen Sie unter Windows eine neue Datei und stellen Sie mithilfe des ODBC-Treibers wie gewöhnlich die Verbindung zu MySQL her; der einzige Unterschied besteht darin, dass Sie `localhost` statt `yourmysqlservername` als MySQL-Hostserver angeben.

An diesem Punkt nun sollte eine ODBC-Verbindung zu MySQL vorhanden sein, die mit SSH verschlüsselt wird.

## 5.10. Datensicherung und Wiederherstellung

Dieser Abschnitt erläutert, wie man (vollständige und inkrementelle) Datenbanksicherungen durchführt und Tabellen pflegt. Die Syntax der hier beschriebenen SQL-Anweisungen wird in Kapitel 13, SQL-Anweisungssyntax, beschrieben. Ein Großteil der hier vermittelten Informationen bezieht sich in erster Linie auf `MyISAM`-Tabellen. Weitere Informationen zu Sicherungsvorgängen für `InnoDB`-Tabellen können Sie Abschnitt 14.2.8, „Sichern und Wiederherstellen einer `InnoDB`-Datenbank“ entnehmen.

### 5.10.1. Datenbank-Datensicherungen

Da MySQL-Tabellen als Dateien gespeichert werden, ist die Durchführung einer Datensicherung recht einfach. Um ein konsistentes Backup zu erhalten, führen Sie für die gewünschten Tabellen nacheinander die Anweisungen `LOCK TABLES` und `FLUSH TABLES` aus. Siehe auch Abschnitt 13.4.5, „`LOCK TABLES` und `UNLOCK TABLES`“, und Abschnitt 13.5.5.2, „`FLUSH`“. Sie benötigen lediglich eine Lesesperre, d. h. andere Clients können die Tabellen weiterhin abfragen, während Sie eine Kopie der Dateien im Datenbankverzeichnis erstellen. Die Anweisung `FLUSH TABLES` ist erforderlich, um sicherzustellen, dass alle aktiven Indexseiten auf Festplatte geschrieben werden, bevor Sie die Sicherung starten.

Um eine Tabelle auf SQL-Ebene zu sichern, können Sie `SELECT INTO ... OUTFILE` verwenden. Bei dieser Anweisung darf die Ausgabedatei nicht bereits vorhanden sein, da das Überschreiben vorhandener Dateien ein Sicherheitsrisiko darstellen würde. Siehe auch Abschnitt 13.2.7, „`SELECT`“.

Eine weitere Methode zur Sicherung einer Datenbank besteht in der Verwendung des Programms mysqldump oder des Skripts mysqlhotcopy. Siehe auch Abschnitt 8.10, „mysqldump — Programm zur Datensicherung“, und Abschnitt 8.11, „mysqlhotcopy — Backup-Programm für Datenbanken“.

1. Erstellen Sie eine vollständige Sicherung Ihrer Datenbank:

       shell> mysqldump --tab=/path/to/some/dir --opt db_name

   Oder:

       shell> mysqlhotcopy db_name /path/to/some/dir

   Sie können auch eine binäre Sicherung erstellen, indem Sie einfach alle Tabellendateien (`*.frm`, `*.MYD` und `*.MYI`) kopieren, während der Server keine Aktualisierungen vornimmt. Das Skript mysqlhotcopy verwendet diese Methode. (Beachten Sie aber, dass diese Methoden nicht funktionieren, wenn Ihre Datenbank `InnoDB`-Tabellen enthält. `InnoDB` speichert die Tabelleninhalte nicht in Datenbankverzeichnissen, und mysqlhotcopy funktioniert nur bei `MyISAM`-Tabellen.)

2. Wenn mysqld läuft, beenden Sie es und starten Sie es dann mit der Option `--log-bin[=`file_name`]` neu. Siehe auch Abschnitt 5.12.3, „Die binäre Update-Logdatei“. Die Binärlogdateien vermitteln Ihnen die Informationen, die Sie zur Replikation von Änderungen an der Datenbank benötigen, die nach dem Punkt, an dem Sie mysqldump ausgeführt haben, durchgeführt wurden.

Bei `InnoDB`-Tabellen können Sie ein Onlinebackup durchführen, bei dem die Tabellen nicht gesperrt werden; siehe auch Abschnitt 8.10, „mysqldump — Programm zur Datensicherung“.

MySQL unterstützt inkrementelle Backups: Zu diesem Zweck müssen Sie den Server mit der Option `--log-bin` starten (Abschnitt 5.12.3, „Die binäre Update-Logdatei“). Sobald Sie ein inkrementelles Backup erstellen wollen (d. h. eine Sicherung, die alle seit dem letzten vollständigen oder inkrementellen Backup vorgenommenen Änderungen enthält), dann sollten Sie das Binärlog mit `FLUSH LOGS` rotieren. Danach müssen Sie alle Binärlogs, die aus dem Zeitraum zwischen dem letzten vollständigen oder inkrementellen Backup und dem vorletzten erstellten Log stammen, an die Sicherungsposition kopieren. Diese Binärlogs bilden die inkrementelle Sicherung; wenn eine Wiederherstellung erforderlich ist, wenden Sie sie wie weiter unten erläutert an. Wenn Sie beim nächsten Mal eine vollständige Sicherung durchführen, sollten Sie das Binärlog ebenfalls mit `FLUSH LOGS`, `mysqldump --flush-logs` oder `mysqlhotcopy --flushlog` rotieren. Siehe auch Abschnitt 8.10, „mysqldump — Programm zur Datensicherung“, und Abschnitt 8.11, „mysqlhotcopy — Backup-Programm für Datenbanken“.

Wenn Ihr MySQL-Server ein Slave-Replikationsserver ist, dann sollten Sie unabhängig von der gewählten Sicherungsmethode auch die Dateien `master.info` und `relay-log.info` sichern, wenn Sie ein Backup der Daten auf Ihrem Slave durchführen. Diese Dateien werden immer benötigt, um die Replikation nach Wiederherstellung der Daten auf dem Slave fortzusetzen. Wenn Ihr Slave Gegenstand der Replikation von `LOAD DATA INFILE`-Befehlen ist, sollten Sie auch alle `SQL_LOAD-*`-Dateien sichern, die ggf. in dem mit der Option `--slave-load-tmpdir` angegebenen Verzeichnis vorhanden sind. (Sofern die Option nicht angegeben wurde, ist die Position standardmäßig der Wert der Variable `tmpdir`.) Der Slave benötigt diese Dateien, um die Replikation unterbrochener `LOAD DATA INFILE`-Operationen fortzusetzen.

Wenn Sie `MyISAM`-Tabellen wiederherstellen müssen, probieren Sie dies zunächst mit `REPAIR TABLE` oder myisamchk -r. Dies sollte in 99,9 Prozent aller Fälle funktionieren. Schlägt der Befehl myisamchk fehl, dann probieren Sie die nachfolgend beschriebene Vorgehensweise aus. Beachten Sie, dass dies nur funktioniert, wenn Sie durch Starten von MySQL mit der Option `--log-bin` das binäre Loggen aktiviert haben.

1. Stellen Sie das ursprüngliche mysqldump-Backup oder das binäre Backup wieder her.

2. Führen Sie den folgenden Befehl aus, um die Aktualisierungen in den Binärlogs erneut auszuführen:

       shell> mysqlbinlog binlog.[0-9]* | mysql

   In manchen Fällen wollen Sie unter Umständen nur bestimmte Binärlogs in bestimmten Verzeichnissen erneut ausführen (wobei Sie in der Regel alle Binärlogs ab dem Datum der wiedergestellten Sicherung wiederherstellen sollten – möglicherweise abgesehen von einigen falschen Anweisungen). Weitere Informationen zum Hilfsprogramm mysqlbinlog und seiner Verwendung finden Sie in Abschnitt 8.8, „mysqlbinlog — Hilfsprogramm für die Verarbeitung binärer Logdateien“.

Sie können auch selektive Sicherungen einzelner Dateien vornehmen:

- Um einen Speicherauszug einer Tabelle zu erstellen, verwenden Sie `SELECT * INTO OUTFILE '`file_name`' FROM `tbl_name``.

- Um die Tabelle wieder zu laden, verwenden Sie `LOAD DATA INFILE '`file_name`' REPLACE ...`. Um Datensatzdubletten zu verhindern, muss die Tabelle einen `PRIMARY KEY`- oder einen `UNIQUE`-Index aufweisen. Das Schlüsselwort `REPLACE` sorgt dafür, dass alte Datensätze durch neue ersetzt werden, wenn ein eindeutiger Schlüsselwert in einem neuen Datensatz dem eines alten Datensatzes entspricht.

Wenn Sie bei der Durchführung von Sicherungen Probleme mit der Serverleistung haben, besteht eine mögliche Abhilfe darin, die Replikation zu konfigurieren und Backups auf dem Slave statt auf dem Master durchzuführen. Siehe auch Abschnitt 6.1, „Einführung in die Replikation“.

Wenn Sie ein Veritas-Dateisystem verwenden, können Sie das Backup wie folgt erstellen:

1. Führen Sie im Clientprogramm `FLUSH TABLES WITH READ LOCK` aus.

2. Führen Sie unter einer anderen Shell `mount vxfs snapshot` aus.

3. Führen Sie nun wiederum auf dem ersten Client `UNLOCK TABLES` aus.

4. Kopieren Sie die Dateien aus dem Schnappschuss.

5. Trennen Sie den Schnappschuss ab.

### 5.10.2. Beispielhaftes Vorgehen zur Datensicherung und Wiederherstellung

Dieser Abschnitt erläutert eine Vorgehensweise zur Durchführung von Backups, die eine Wiederherstellung von Daten nach mehreren Arten von Abstürzen gestattet:

- Absturz des Betriebssystems

- Stromausfall

- Absturz des Dateisystems

- Hardwareproblem (Festplatte, Hauptplatine usw.)

Die Befehlsbeispiele enthalten keine Optionen wie `--user` und `--password` für die Programme mysqldump und mysql. Sie sollten diese Optionen nach Bedarf hinzufügen, sodass der MySQL-Server Ihnen das Herstellen einer Verbindung gestattet.

Wir setzen voraus, dass die Daten in der `InnoDB`-Speicher-Engine gespeichert sind, die Transaktionen und automatische Wiederherstellung nach einem Absturz unterstützt. Ferner wird vorausgesetzt, dass der MySQL-Server zum Zeitpunkt des Absturzes Daten verarbeitet; wäre dies nicht der Fall, dann wäre keine Wiederherstellung erforderlich.

In Fällen von Betriebssystemabstürzen oder Stromausfällen können wir davon ausgehen, dass die Festplattendaten von MySQL nach einem Neustart wieder verfügbar sind. Die `InnoDB`-Datendateien enthalten unter Umständen aufgrund des Absturzes keine konsistenten Daten, aber `InnoDB` liest seine Logs aus und findet darin die Liste der anhängigen abgeschlossenen und nicht abgeschlossenen Transaktionen, die noch nicht in die Datendateien geschrieben wurden. `InnoDB` führt für die nicht abgeschlossenen Transaktionen automatisch einen Rollback aus, die abgeschlossenen Transaktionen hingegen werden in die Datendateien geschrieben. Informationen zum Wiederherstellungsprozess erhält der Benutzer über das MySQL-Fehlerlog. Hier ein Beispielauszug aus einem Log:

    InnoDB: Database was not shut down normally.
    InnoDB: Starting recovery from log files...
    InnoDB: Starting log scan based on checkpoint at
    InnoDB: log sequence number 0 13674004
    InnoDB: Doing recovery: scanned up to log sequence number 0 13739520
    InnoDB: Doing recovery: scanned up to log sequence number 0 13805056
    InnoDB: Doing recovery: scanned up to log sequence number 0 13870592
    InnoDB: Doing recovery: scanned up to log sequence number 0 13936128
    ...
    InnoDB: Doing recovery: scanned up to log sequence number 0 20555264
    InnoDB: Doing recovery: scanned up to log sequence number 0 20620800
    InnoDB: Doing recovery: scanned up to log sequence number 0 20664692
    InnoDB: 1 uncommitted transaction(s) which must be rolled back
    InnoDB: Starting rollback of uncommitted transactions
    InnoDB: Rolling back trx no 16745
    InnoDB: Rolling back of trx no 16745 completed
    InnoDB: Rollback of uncommitted transactions completed
    InnoDB: Starting an apply batch of log records to the database...
    InnoDB: Apply batch completed
    InnoDB: Started
    mysqld: ready for connections

In Fällen von Dateisystemabstürzen oder Hardwareproblemen können wir davon ausgehen, dass die MySQL-Festplattendaten nach einem Neustart nicht verfügbar sind. Das bedeutet wiederum, dass MySQL nicht erfolgreich gestartet werden kann, da einige Datenblöcke auf der Festplatte nicht mehr lesbar sind. In diesem Fall ist es erforderlich, die Festplatte neu zu formatieren, eine neue Festplatte zu installieren oder das zugrundeliegende Problem anderweitig zu beheben. Danach müssen wir unsere MySQL-Daten aus Backups wiederherstellen, d. h. es sollten bereits Backups vorhanden sein. Um dies sicherzustellen, sollten wir eine Sicherungsrichtlinie erstellen.

#### 5.10.2.1. Richtlinien für die Datensicherung

Wir alle wissen, dass die regelmäßige Durchführung von Sicherungen geplant werden muss. Ein vollständiges Backup (d. h. ein Schnappschuss der Daten zu einem gegebenen Zeitpunkt) kann in MySQL mit verschiedenen Tools erfolgen. So ermöglicht etwa `InnoDB Hot Backup` eine online durchgeführte physische Sicherung der `InnoDB`-Datendateien ohne Sperre, und mysqldump erlaubt ein online erstelltes logisches Backup. Wir werden an dieser Stelle mysqldump beschreiben.

Nehmen wir an, Sie erstellen am Sonntag um 13:00 Uhr ein Backup. Dies ist ein Zeitpunkt, an dem die Serverlast niedrig ist. Der folgende Befehl erstellt ein vollständiges Backup all Ihrer `InnoDB`-Tabellen in allen Datenbanken:

    shell> mysqldump --single-transaction --all-databases > backup_sunday_1_PM.sql

Dies ist eine online ausgeführte, nicht sperrende Sicherung, die Lese- und Schreibvorgänge in den Tabellen nicht beeinträchtigt. Wir haben bereits weiter oben gesagt, dass unsere Tabellen `InnoDB`-Tabellen sind, d. h. `--single-transaction` verwendet eine konsistente Leseoperation und gewährleistet, dass die von mysqldump erkannten Daten nicht geändert werden. (Änderungen, die von anderen Clients an den `InnoDB`-Tabellen durchgeführt werden, werden vom mysqldump-Prozess nicht erkannt.) Wenn auch andere Tabellentypen vorhanden sind, müssen wir davon ausgehen, dass diese während des Sicherungsvorgangs nicht geändert werden. So müssen wir beispielsweise für die `MyISAM`-Tabellen in der `mysql`-Datenbank voraussetzen, dass während der Sicherung keine administrativen Änderungen an den MySQL-Konten vorgenommen werden.

Am Ende steht eine `.sql`-Datei, die von mysqldump erzeugt wird. Sie enthält einen Satz von `INSERT`-SQL-Anweisungen, die zum Neuladen der gespeicherten Tabellen zu einem späteren Zeitpunkt verwendet werden können.

Vollständige Backups sind erforderlich, aber manchmal unpraktisch. Sie erzeugen große Sicherungsdateien, und die Erstellung dauert recht lange. Außerdem sind sie nicht optimal in dem Sinn, dass alle aufeinanderfolgenden Sicherungen alle Daten enthalten – d. h. auch solche, die seit dem letzten vollständigen Backup nicht geändert wurden. Wenn wir also ein vollständiges Backup als Ausgangspunkt erstellt haben, ist es effektiver, nachfolgend inkrementelle Sicherungen zu erstellen. Diese sind kleiner, und ihre Erstellung verläuft schneller. Der Nachteil besteht darin, dass Sie im Fehlerfall nicht einfach ein einziges vollständiges Backup aufspielen können, um Ihre Daten wiederherzustellen. Sie müssen vielmehr auch die inkrementellen Sicherungen aufspielen, um die dort gespeicherten Änderungen wiederherzustellen.

Um inkrementelle Sicherungen zu erstellen, müssen wir die inkrementellen Änderungen speichern. Der MySQL-Server sollte immer mit der Option `--log-bin` gestartet werden, damit er diese Änderungen beim Aktualisieren von Daten in einer Datei speichert. Diese Option aktiviert das binäre Loggen, d. h. der Server schreibt jede SQL-Anweisung, die Daten ändert, in eine Datei: das MySQL-Binärlog. Wenn man einen Blick in das Datenverzeichnis eines MySQL-Servers wirft, der mit der Option `--log-bin` gestartet wurde und schon ein paar Tage läuft, dann findet man dort die folgenden MySQL-Binärlogdateien:

    -rw-rw---- 1 guilhem  guilhem   1277324 Nov 10 23:59 gbichot2-bin.000001
    -rw-rw---- 1 guilhem  guilhem         4 Nov 10 23:59 gbichot2-bin.000002
    -rw-rw---- 1 guilhem  guilhem        79 Nov 11 11:06 gbichot2-bin.000003
    -rw-rw---- 1 guilhem  guilhem       508 Nov 11 11:08 gbichot2-bin.000004
    -rw-rw---- 1 guilhem  guilhem 220047446 Nov 12 16:47 gbichot2-bin.000005
    -rw-rw---- 1 guilhem  guilhem    998412 Nov 14 10:08 gbichot2-bin.000006
    -rw-rw---- 1 guilhem  guilhem       361 Nov 14 10:07 gbichot2-bin.index

Bei jedem Neustart erstellt der MySQL-Server eine neue Binärlogdatei, für deren Benennung er die nächste Nummer in der Nummernfolge verwendet. Solange der Server ausgeführt wird, können Sie ihn auch manuell anweisen, die aktuelle Binärlogdatei zu schließen und eine neue zu erstellen. Hierzu verwenden Sie die SQL-Anweisung `FLUSH LOGS` oder geben den Befehl mysqladmin flush-logs ein. Auch mysqldump bietet eine Option zum Schreiben der Logs auf die Festplatte. Die `.index`-Datei im Datenverzeichnis enthält eine Liste aller MySQL-Binärlogs in diesem Verzeichnis. Die Datei wird zur Replikation verwendet.

Die MySQL-Binärlogs sind für die Wiederherstellung wichtig, denn sie bilden den Satz inkrementeller Backups. Wenn Sie die Logs beim Erstellen einer vollständigen Sicherung auf Festplatte schreiben, dann enthält ein ggf. nachfolgend erstelltes Backup alle Änderungen seit dem Backup. Wir wollen den obigen mysqldump-Befehl ein wenig abändern, damit er die MySQL-Binärlogs zum Zeitpunkt einer vollständigen Sicherung auf die Festplatte schreibt und die Speicherauszugsdatei den Namen des neuen aktuellen Binärlogs enthält:

    shell> mysqldump --single-transaction --flush-logs --master-data=2 \
             --all-databases > backup_sunday_1_PM.sql

Nach Ausführung dieses Befehls enthält das Datenverzeichnis eine neue Binärlogdatei namens `gbichot2-bin.000007`. Die am Ende erstellte `.sql`-Datei enthält die folgenden Zeilen:

    -- Position to start replication or point-in-time recovery from
    -- CHANGE MASTER TO MASTER_LOG_FILE='gbichot2-bin.000007',MASTER_LOG_POS=4;

Weil der mysqldump-Befehl ein vollständiges Backup erstellt hat, bedeuten diese Zeilen zweierlei:

- Die `.sql`-Datei enthält alle Änderungen, die vorgenommen wurden, bevor Änderungen in die Binärlogdatei `gbichot2-bin.000007` oder eine neuere Binärlogdatei geschrieben wurden.

- Alle nach dem Backup geloggten Datenänderungen sind noch nicht in der `.sql`-Datei, wohl aber in der Binärlogdatei `gbichot2-bin.000007` oder einer neueren Binärlogdatei vorhanden.

Am Montag um 13:00 Uhr erstellen wir eine inkrementelle Sicherungsdatei, indem wir die Logdateien auf die Festplatte schreiben, um so eine neue Binärlogdatei zu erstellen. So erstellt beispielsweise der Befehl mysqladmin flush-logs die Datei `gbichot2-bin.000008`. Alle Änderungen, die zwischen Sonntag, 13:00 Uhr (Erstellung des vollständigen Backups), und Montag, 13:00 Uhr, vorgenommen wurden, sind in der Datei `gbichot2-bin.000007` enthalten. Diese inkrementelle Sicherung ist wichtig, weswegen sie an einen sicheren Ort kopiert werden sollte. (Sie können sie etwa auf Band oder DVD sichern oder auf einen anderen Computer kopieren.) Am Dienstag um 13:00 Uhr wird der Befehl mysqladmin flush-logs erneut ausgeführt. Alle Änderungen, die zwischen Montag, 13:00 Uhr, und Dienstag, 13:00 Uhr, angefallen sind, sind in der Datei `gbichot2-bin.000008` vermerkt (auch diese sollten Sie an einen sicheren Ort kopieren).

Die MySQL-Binärlogs benötigen Festplattenspeicher. Um Speicher freizugeben, sollten Sie sie von Zeit zu Zeit bereinigen. Eine Möglichkeit, dies zu tun, besteht im Löschen von Binärlogs, die nicht mehr benötigt werden (beispielsweise nachdem ein vollständiges Backup erstellt wurde):

    shell> mysqldump --single-transaction --flush-logs --master-data=2 \
             --all-databases --delete-master-logs > backup_sunday_1_PM.sql

Hinweis: Das Löschen von MySQL-Binärlogs mit mysqldump --delete-master-logs kann gefährlich sein, wenn Ihr Server ein Replikations-Master ist, denn unter Umständen haben die Slave-Server den Inhalt des Binärlogs noch nicht vollständig verarbeitet. Die Beschreibung der `PURGE MASTER LOGS`-Anweisung erläutert, was zu prüfen ist, bevor die MySQL-Binärlogs gelöscht werden. Siehe auch Abschnitt 13.6.1.1, „`PURGE MASTER LOGS`“.

#### 5.10.2.2. Verwenden von Datensicherungen zur Wiederherstellung

Nehmen wir nun an, dass es am Mittwoch um 8:00 Uhr zu einem folgenschweren Absturz kommt, der eine Wiederherstellung aus den Sicherungen erfordert. Zu diesem Zweck stellen wir zunächst das letzte vollständige Backup (von Sonntag, 13:00 Uhr) wieder her. Da die vollständige Sicherungsdatei nichts anderes als eine Sammlung von SQL-Anweisungen ist, ist die Wiederherstellung sehr einfach:

    shell> mysql < backup_sunday_1_PM.sql

An dieser Stelle sind die Daten auf dem Stand von Sonntag, 13:00 Uhr. Um nun die seitdem vorgenommenen Änderungen wiederherzustellen, müssen wir die inkrementellen Sicherungen verwenden, d. h. die Binärlogdateien `gbichot2-bin.000007` und `gbichot2-bin.000008`. Besorgen Sie sich diese Dateien nun von dort, wo Sie sie gesichert hatten, und verarbeiten Sie ihren Inhalt wie folgt:

    shell> mysqlbinlog gbichot2-bin.000007 gbichot2-bin.000008 | mysql

Wir haben nun die Daten auf dem Stand von Dienstag, 13:00 Uhr, wiederhergestellt. Noch aber fehlen die Daten zwischen diesem Zeitpunkt und dem des Absturzes. Um diese nicht zu verlieren, hätten wir den MySQL-Server so konfiguriert haben müssen, dass er seine MySQL-Binärlogs an einem sicheren Ort (RAID-Festplatten, SAN, usw.) speichert – nicht aber auf der Festplatte, wo er seine Datendateien speichert, damit die Logs sich im Schadensfalls nicht auf der zerstörten Festplatte befinden. (Zu diesem Zweck können wir den Server mit der Option `--log-bin` starten, die eine Position auf einem anderen physischen Gerät als demjenigen angibt, auf dem das Datenverzeichnis liegt. Auf diese Weise gehen die Logs nicht verloren, wenn das Gerät mit dem Datenverzeichnis zerstört wird.) Hätten wir das gemacht, dann hätten wir jetzt die Datei `gbichot2-bin.000009` zur Hand und könnten sie einfach mit mysqlbinlog und mysql aufspielen, um die letzten Datenänderungen bis zum Moment des Absturzes verlustfrei wiederherzustellen.

#### 5.10.2.3. Backup-Strategien

Bei einem Betriebssystemabsturz oder einem Stromausfall erledigt `InnoDB` die gesamte Datenwiederherstellung automatisch. Um jedoch ruhig schlafen zu können, sollten Sie unbedingt folgende Richtlinien beachten:

- Führen Sie den MySQL-Server immer mit der Option `--log-bin` oder sogar `--log-bin=`log_name`` aus. Der angegebene Logdateiname befindet sich dabei auf einem anderen Medium als dem Laufwerk, auf dem das Datenverzeichnis gespeichert ist. Sofern Sie solche sicheren Medien haben, können Sie sie unter Umständen auch gut für eine Festplattenlastverteilung einsetzen (was sich positiv auf die Leistung auswirkt).

- Erstellen Sie regelmäßig vollständige Backups. Verwenden Sie dazu den letzten der oben angegebenen mysqldump-Befehle, um ein Online-Backup ohne Sperren durchzuführen.

- Erstellen Sie regelmäßig inkrementelle Backups, indem Sie die Logs mit `FLUSH LOGS` oder mysqladmin flush-logs auf die Festplatte schreiben.

### 5.10.3. Zeitpunktbezogene Wiederherstellung

Wenn am MySQL-Server das binäre Loggen aktiviert ist, können Sie mit dem Hilfsprogramm mysqlbinlog Daten ab dem angegebenen Zeitpunkt („Point in Time“) bis zum aktuellen oder einem anderen angegebenen Zeitpunkt wiederherstellen. Informationen zur Aktivierung des Binärlogs und zur Verwendung von mysqlbinlog finden Sie in Abschnitt 5.12.3, „Die binäre Update-Logdatei“, und Abschnitt 8.8, „mysqlbinlog — Hilfsprogramm für die Verarbeitung binärer Logdateien“.

Um Daten aus einem Binärlog wiederherzustellen, müssen Sie den Pfad und den Namen der aktuellen Binärlogdatei kennen. Sie finden den Pfad normalerweise in der Optionsdatei (also je nach System `my.cnf` oder `my.ini`). Ist der Pfad nicht in der Optionsdatei enthalten, dann wurde er unter Umständen beim Serverstart als Option auf der Befehlszeile angegeben. Die Option zur Aktivierung des binären Loggens heißt `--log-bin`. Den Namen der aktuellen Binärlogdatei ermitteln Sie mit der folgenden Anweisung:

    mysql> SHOW BINLOG EVENTS \G

Sie können, wenn Sie dies vorziehen, auch folgenden Befehl über die Befehlszeile ausführen:

    shell> mysql --user=root -p -E -e "SHOW BINLOG EVENTS"

Geben Sie das `root`-Passwort für Ihren Server ein, wenn mysql Sie dazu auffordert.

#### 5.10.3.1. Angabe von Zeitpunkten für die Wiederherstellung

Um die Start- und Endzeitpunkte für die Wiederherstellung festzulegen, geben Sie für mysqlbinlog die Optionen `--start-date` und `--stop-date` im `DATETIME` an. Nehmen wir beispielsweise an, dass am 20. April 2005 um genau 10:00 Uhr eine SQL-Anweisung ausgeführt wurde, mit der eine große Tabelle gelöscht wurde. Um die Tabelle und ihre Daten wiederherzustellen, könnten Sie das Backup der vorhergehenden Nacht wiederherstellen und dann den folgenden Befehl ausführen:

    shell> mysqlbinlog --stop-date="2005-04-20 9:59:59" \
             /var/log/mysql/bin.123456 | mysql -u root -p

Dieser Befehl stellt alle Daten bis zum durch die Option `--stop-date` angegebenen Zeitpunkt wieder her. Haben Sie die fehlerhafte SQL-Anweisung, die zum Löschen der Tabellen eingegeben wurde, erst Stunden später entdeckt, dann werden Sie wahrscheinlich auch die nachfolgenden durchgeführten Operationen wiederherstellen wollen. Davon ausgehend könnten Sie mysqlbinlog noch einmal unter Angabe eines Startzeitpunkts ausführen:

    shell> mysqlbinlog --start-date="2005-04-20 10:01:00" \
             /var/log/mysql/bin.123456 | mysql -u root -p

In diesem Befehl werden die SQL-Anweisungen, die ab 10:01 Uhr aufgezeichnet wurden, erneut aufgeführt. Die Kombination aus der Wiederherstellung der Speicherauszugsdatei der vorangegangenen Nacht und der Ausführung der beiden mysqlbinlog-Befehle stellt alle Aktionen mit Ausnahme derjenigen wieder her, die im Zeitraum zwischen 9:59:59 Uhr und 10:01:00 Uhr ausgeführt wurden. Überprüfen Sie die Logdatei, um die exakten Zeiten angeben zu können. Der nächste Abschnitt beschreibt die erforderlichen Abläufe.

#### 5.10.3.2. Angabe von Positionsnummern für die Wiederherstellung

Statt Datums- und Zeitangaben anzugeben, können Sie die Optionen `--start-position` und `--stop-position` für mysqlbinlog zur Angabe von Logpositionen verwenden. Diese Optionen arbeiten genauso wie die Optionen für Start- und Endzeitpunkt, nur werden Positionsangaben aus dem Log spezifiziert. Die Angabe dieser Logposition ist unter Umständen eine exaktere Wiederherstellungsmethode – insbesondere dann, wenn viele Transaktionen zur gleichen Zeit wie die schädliche SQL-Anweisung auftraten. Zur Bestimmung der Positionsnummer können Sie mysqlbinlog für einen Zeitbereich in der Umgebung des Zeitpunkts ausführen, an dem die unerwünschte Transaktion durchgeführt wurde, die Ergebnisse aber zur Überprüfung in einer Textdatei umleiten. Dies wird wie folgt gemacht:

    shell> mysqlbinlog --start-date="2005-04-20 9:55:00" \
             --stop-date="2005-04-20 10:05:00" \
             /var/log/mysql/bin.123456 > /tmp/mysql_restore.sql

Dieser Befehl erstellt eine kleine Textdatei im Verzeichnis `/tmp`, die die im zeitlichen Bereich der misslichen SQL-Anweisung abgesetzten Anweisungen enthält. Öffnen Sie diese Datei mit einem Texteditor und suchen Sie nach der Anweisung, die nicht wiederholt werden soll. Bestimmen Sie die Positionen im Binärlog für das Beenden und Wiederaufnehmen der Wiederherstellung und notieren Sie sich diese. Die Positionen sind gekennzeichnet mit `log_pos`, gefolgt von einer Zahl. Nach der Wiederherstellung der vorherigen Sicherungsdatei verarbeiten Sie die Binärlogdatei unter Verwendung der Positionsnummern. So würden Sie z. B. Befehle in der Art der folgenden verwenden:

    shell> mysqlbinlog --stop-position="368312" /var/log/mysql/bin.123456 \
             | mysql -u root -p

    shell> mysqlbinlog --start-position="368315" /var/log/mysql/bin.123456 \
             | mysql -u root -p

Der erste Befehl stellt alle Transaktionen bis zur angegebenen Endposition wieder her. Der zweite Befehl führt die Wiederherstellung aller Transaktionen vom angegebenen Fortsetzungspunkt bis zum Ende des Binärlogs durch. Da die Ausgabe von mysqlbinlog vor jeder aufgezeichneten SQL-Anweisung `SET TIMESTAMP`-Anweisungen enthält, finden sich in den wiederhergestellten Daten und den zugehörigen MySQL-Logs die ursprünglichen Ausführungszeitpunkte der Transaktionen wieder.

### 5.10.4. Benutzung von `myisamchk` für Tabellenwartung und Absturzreparatur

Dieser Abschnitt beschreibt, wie man mit myisamchk `MyISAM`-Tabellen überprüft oder repariert (also Tabellen, für die `.MYD`- und `.MYI`-Dateien zur Speicherung von Daten und Indizes vorhanden sind). Allgemeine Hinweise zu myisamchk finden Sie in Abschnitt 8.2, „myisamchk — Hilfsprogramm für die Tabellenwartung von MyISAM“.

Sie können mit myisamchk Informationen zu Ihren Datenbanktabellen abrufen oder sie überprüfen, reparieren oder optimieren. Die folgenden Abschnitte erläutern, wie Sie diese Operationen durchführen und wie man einen Wartungsplan für Tabellen einrichtet.

Auch wenn die Tabellenreparatur mit myisamchk verhältnismäßig sicher ist, sollten Sie immer ein Backup erstellen, bevor Sie eine Reparatur oder Wartungsoperationen durchführen, bei denen viele Änderungen an einer Tabelle vorgenommen werden.

myisamchk-Operationen, die sich auf Indizes auswirken, können die Neuerstellung von `FULLTEXT`-Indizes mit Volltextparametern auslösen, die nicht mit den vom MySQL-Server verwendeten Werten kompatibel sind. Um dieses Problem zu umgehen, beachten Sie die Hinweise in Abschnitt 8.2.1, „Allgemeine Optionen für `myisamchk`“.

In vielen Fällen kann es auch einfacher sein, die Wartung einer `MyISAM`-Tabelle mit SQL-Anweisungen durchzuführen, die Operationen ausführen, wie Sie auch von myisamchk unterstützt werden:

- Um `MyISAM`-Tabellen zu überprüfen oder zu reparieren, verwenden Sie `CHECK TABLE` oder `REPAIR TABLE`.

- Um `MyISAM`-Tabellen zu optimieren, benutzen Sie `OPTIMIZE TABLE`.

- Um `MyISAM`-Tabellen zu analysieren, benutzen Sie `ANALYZE TABLE`.

Diese Anweisungen können wahlweise direkt oder mithilfe des Clientprogramms mysqlcheck eingesetzt werden. Ein Vorteil dieser Anweisungen im Vergleich zu myisamchk besteht darin, dass der Server die gesamte Arbeit erledigt. Bei myisamchk müssen Sie sicherstellen, dass der Server die Tabellen nicht zur selben Zeit verwendet, damit es nicht zu unerwünschten Interaktionen zwischen myisamchk und dem Server kommt. Siehe auch Abschnitt 13.5.2.1, „`ANALYZE TABLE`“, Abschnitt 13.5.2.3, „`CHECK TABLE`“, Abschnitt 13.5.2.5, „`OPTIMIZE TABLE`“, und Abschnitt 13.5.2.6, „`REPAIR TABLE`“.

#### 5.10.4.1. Benutzung von `myisamchk` für die Fehlerbeseitigung nach Abstürzen

Dieser Abschnitt beschreibt, wie Sie MySQL-Datenbanken auf beschädigte Daten überprüfen und mit diesen ggf. verfahren können. Wenn Ihre Tabellen häufig beschädigt werden, sollten Sie die Ursache hierfür ermitteln. Siehe auch Abschnitt A.4.2, „Was zu tun ist, wenn MySQL andauernd abstürzt“.

Eine Erklärung, wie Schäden an `MyISAM`-Tabellen auftreten können, finden Sie in Abschnitt 14.1.4, „MyISAM-Tabellenprobleme“.

Wenn Sie mysqld mit deaktivierter externer Sperre ausführen (was ab MySQL 4.0 das Standardverhalten ist), dann können Sie myisamchk nicht für das zuverlässige Überprüfen einer Tabelle verwenden, wenn mysqld genau diese Tabelle benutzt. Wenn Sie ganz sicher sind, dass niemand über mysqld auf die Tabellen zugreifen kann, während Sie myisamchk ausführen, müssen Sie lediglich mysqladmin flush-tables ausführen, bevor Sie die Überprüfung der Tabellen starten. Können Sie dies nicht gewährleisten, dann müssen Sie mysqld stoppen, solange Sie die Tabellen überprüfen. Führen Sie myisamchk zur Überprüfung von Tabellen aus, die gleichzeitig von mysqld aktualisiert werden, dann erhalten Sie unter Umständen eine Warnung, dass eine Tabelle beschädigt sei, obwohl dies gar nicht stimmt.

Wenn der Server mit aktivierter externer Sperrung ausgeführt wird, können Sie die Tabellen jederzeit mit myisamchk überprüfen. In diesem Fall muss der Server, wenn er eine Tabelle zu aktualisieren versucht, die myisamchk gerade verwendet, warten, bis myisamchk den Vorgang abgeschlossen hat, bevor er fortfährt.

Verwenden Sie myisamchk zur Reparatur oder Optimierung von Tabellen, dann müssen Sie immer sicherstellen, dass der Server mysqld die Tabelle nicht verwendet. (Dies gilt auch bei deaktivierter externer Sperrung.) Beenden Sie mysqld nicht, dann sollten Sie zumindest mysqladmin flush-tables ausführen, bevor Sie myisamchk starten. Wenn der Server und myisamchk gleichzeitig auf die Tabellen zugreifen, können Ihre Tabellen beschädigt werden.

Wenn Sie eine Wiederherstellung nach einem Absturz durchführen, müssen Sie beachten, dass zu jeder `MyISAM`-Tabelle `tbl_name` in einer Datenbank drei Dateien im Datenbankverzeichnis gehören:

Datei | Zweck
``tbl_name`.frm` | Definitionsdatei (Formatdatei)
``tbl_name`.MYD` | Datendatei
``tbl_name`.MYI` | Indexdatei

Jeder dieser drei Dateitypen kann auf unterschiedliche Weise beschädigt werden, meistens treten Probleme aber in Zusammenhang mit Daten- und Indexdateien auf.

myisamchk erstellt datensatzweise eine Kopie der `.MYD`-Datendatei. Die Reparatur wird beendet, indem die alte `.MYD`-Datei entfernt und der neuen Daten dann der ursprüngliche Dateiname zugewiesen wird. Wenn Sie `--quick` verwenden, erstellt myisamchk keine temporäre `.MYD`-Datei, sondern setzt stattdessen voraus, dass die `.MYD`-Datei korrekt ist, und erstellt nur eine neue Indexdatei – die vorhandene `.MYD`-Datei wird nicht angerührt. Dies ist sicher, da myisamchk automatisch erkennt, ob die `.MYD`-Datei beschädigt ist (in diesem Fall wird diese Reparatur abgebrochen). Sie können für myisamchk auch zweimal die Option `--quick` angeben. In diesem Fall bricht myisamchk bei einigen Fehlern (z. B. Schlüsseldubletten) nicht ab, sondern versucht diese zu beheben, indem die `.MYD`-Datei modifiziert wird. Normalerweise ist die Verwendung zweier `--quick`-Optionen nur dann sinnvoll, wenn zu wenig freier Festplattenspeicher für eine normale Reparatur vorhanden ist. In diesem Fall sollten Sie zumindest ein Backup der Tabelle erstellen, bevor Sie myisamchk ausführen.

#### 5.10.4.2. Wie Tabellen auf Fehler überprüft werden

Verwenden Sie die folgenden Befehle, um eine `MyISAM`-Tabelle auf Fehler zu prüfen:

- `myisamchk `tbl_name``

  Hierdurch werden 99,99 Prozent aller Fehler gefunden. Nicht gefunden werden lediglich Datenschäden, bei denen nur die Datendatei betroffen ist (dies kommt ausgesprochen selten vor). Wenn Sie eine Tabelle überprüfen wollen, sollten Sie normalerweise myisamchk ohne Optionen oder aber mit der Option `-s` (stumm) ausführen.

- `myisamchk -m `tbl_name``

  Hierdurch werden 99,999 Prozent aller Fehler gefunden. Zunächst werden alle Indexeinträge auf Fehler geprüft, dann werden alle Datensätze gelesen. Für alle Schlüsselwerte in den Datensätzen wird eine Prüfsumme berechnet, die mit der Prüfsumme der Schlüssel im Indexbaum übereinstimmen muss.

- `myisamchk -e `tbl_name``

  Führt eine vollständige und umfassende Überprüfung aller Daten durch (`-e` bedeutet „Extended Check“, also erweiterte Überprüfung). Jeder Schlüssel in jedem Datensatz wird prüfweise gelesen, um sicherzustellen, dass er tatsächlich auf den korrekten Datensatz verweist.Das kann bei umfangreichen Tabellen mit vielen Indizes recht lange dauern. Normalerweise wird myisamchk nach dem ersten gefundenen Fehler beendet. Wenn Sie weitere Informationen benötigen, können Sie die Option `-v` (ausführlicher Modus) hinzufügen. In diesem Fall läuft myisamchk weiter, bis maximal 20 Fehler gefunden wurden.

- `myisamchk -e -i `tbl_name``

  Dies ähnelt dem vorherigen Befehl, aber die Option `-i` weist myisamchk an, zusätzliche Statistikinformationen auszugeben.

In den meisten Fällen ist ein einfacher myisamchk-Befehl ohne andere Argumente als den Tabellennamen zum Überprüfen einer Tabelle ausreichend.

#### 5.10.4.3. Wie Tabellen repariert werden

In diesem Abschnitt wird beschrieben, wie man myisamchk für `MyISAM`-Tabellen (Erweiterungen `.MYI` und `.MYD`) verwendet.

Sie können (und sollten möglichst auch) `MyISAM`-Tabellen mit `CHECK TABLE`- und `REPAIR TABLE`-Anweisungen überprüfen bzw. reparieren. Siehe auch Abschnitt 13.5.2.3, „`CHECK TABLE`“, und Abschnitt 13.5.2.6, „`REPAIR TABLE`“.

Zu den Symptomen beschädigter Tabellen gehören auch Abfragen, die unerwartet abgebrochen werden, und wahrnehmbare Fehler wie die folgenden:

- ``tbl_name`.frm` ist gegen Änderungen gesperrt

- Die Datei ``tbl_name`.MYI` kann nicht gefunden werden (Fehlercode: `nnn`)

- Unerwartetes Ende der Datei

- Aufzeichnungsdatei ist abgestürzt

- Fehler `nnn` vom Tabellen-Handler erhalten

Um weitere Informationen zum Fehler zu erhalten, führen Sie perror `nnn` aus, wobei `nnn` die Fehlernummer ist. Die folgenden Beispiele zeigen, wie man mit perror die Bedeutungen der häufigsten Fehlernummern ermittelt, die ein Problem mit einer Tabelle angeben:

    shell> perror 126 127 132 134 135 136 141 144 145
    126 = Index file is crashed / Wrong file format
    127 = Record-file is crashed
    132 = Old database file
    134 = Record was already deleted (or record file crashed)
    135 = No more room in record file
    136 = No more room in index file
    141 = Duplicate unique key or constraint on write or update
    144 = Table is crashed and last repair failed
    145 = Table was marked as crashed and should be repaired

Beachten Sie, dass die Fehler 135 („No more room in record file“) und 136 („No more room in index file“) nicht mit einer einfachen Tabellenreparatur behoben werden können. In diesem Fall müssen Sie mit `ALTER TABLE` die Tabellenoptionswerte `MAX_ROWS` und `AVG_ROW_LENGTH` erhöhen:

    ALTER TABLE tbl_name MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;

Wenn Sie die aktuellen Tabellenoptionswerte nicht kennen, verwenden Sie `SHOW CREATE TABLE`.

Bei Auftreten anderer Fehler müssen Sie Ihre Tabellen reparieren. myisamchk erkennt und behebt normalerweise die meisten Probleme.

Der Reparaturvorgang umfasst die nachfolgend beschriebenen vier Stufen. Bevor Sie anfangen, sollten Sie in das Datenbankverzeichnis wechseln und die Berechtigungen für die Tabellendateien überprüfen. Unter Unix müssen Sie sicherstellen, dass diese von dem Benutzer gelesen werden können, als der mysqld ausgeführt wird (und von Ihnen natürlich auch, denn schließlich müssen Sie auf die Dateien zugreifen können, die Sie überprüfen wollen). Sollte sich herausstellen, dass Sie Dateien ändern müssen, dann sollten diese auch von Ihnen geschrieben werden können.

Dieser Abschnitt ist für Fälle vorgesehen, in denen die Überprüfung einer Tabelle fehlschlägt (siehe auch die Beschreibung in Abschnitt 5.10.4.2, „Wie Tabellen auf Fehler überprüft werden“) oder Sie die erweiterten Funktionen einsetzen wollen, die myisamchk bereitstellt.

Die Optionen, die Sie zur Wartung von Tabellen mit myisamchk verwenden können, sind in Abschnitt 8.2, „myisamchk — Hilfsprogramm für die Tabellenwartung von MyISAM“, beschrieben.

Wenn Sie eine Tabelle über die Befehlszeile reparieren wollen, müssen Sie den Server mysqld zunächst beenden. Beachten Sie, dass, wenn Sie mysqladmin shutdown auf einem entfernten Server ausführen, der Server mysqld auch nach der entsprechenden Meldung von mysqladmin noch eine Weile weiterläuft, bis die gesamte Anweisungsbearbeitung beendet wurde und alle Änderungen auf Festplatte geschrieben wurden.

Stufe 1: Tabellen überprüfen

Führen Sie myisamchk *.MYI oder – wenn genug Zeit vorhanden ist – myisamchk -e *.MYI aus. Verwenden Sie die Option `-s` (stumm) zur Unterdrückung nicht benötigter Informationen.

Wenn der Server mysqld beendet ist, sollten Sie die Option `--update-state` verwenden, um myisamchk anzuweisen, die Tabelle als „geprüft“ zu kennzeichnen.

Sie müssen nur diejenigen Tabellen reparieren, für die myisamchk einen Fehler meldet. Fahren Sie bei solchen Tabellen mit Stufe 2 fort.

Erhalten Sie bei der Überprüfung unerwartete Fehler (z. B. `out of memory`) oder stürzt myisamchk ab, dann fahren Sie mit Stufe 3 fort.

Stufe 2: Einfache und sichere Reparatur

Probieren Sie zunächst myisamchk -r -q `tbl_name` aus (`-r -q` bedeutet „schneller Wiederherstellungsmodus“). Hierbei wird versucht, die Indexdatei zu reparieren, ohne die Datendatei anzurühren. Wenn die Datendatei alles Erforderliche enthält und die Löschverknüpfungen auf die korrekten Positionen innerhalb der Datendatei verweisen, sollte diese Vorgehensweise funktionieren, d. h. die Tabelle sollte nachfolgend repariert sein. Fahren Sie nun mit der Reparatur der nächsten Tabelle fort. Andernfalls wenden Sie folgende Vorgehensweise an:

1. Erstellen Sie ein Backup der Datendatei, bevor Sie fortfahren.

2. Verwenden Sie myisamchk -r `tbl_name` (`-r` bedeutet „Wiederherstellungsmodus“). Hierdurch werden falsche und gelöschte Datensätze aus der Datendatei entfernt, und die Indexdatei wird neu erstellt.

3. Schlägt der vorherige Schritt fehl, dann setzen Sie myisamchk --safe-recover `tbl_name` ab. Der sichere Wiederherstellungsmodus verwendet eine alte Wiederherstellungsmethode, die ein paar Fälle behebt, die im normalen Wiederherstellungsmodus unberücksichtigt bleiben; sie ist aber langsamer.

Hinweis: Wenn Sie eine Reparaturoption erheblich beschleunigen wollen, sollten Sie die Werte der Variablen `sort_buffer_size` und `key_buffer_size` jeweils auf 25 Prozent Ihres verfügbaren Speichers setzen, wenn Sie myisamchk ausführen.

Erhalten Sie bei der Reparatur unerwartete Fehler (z. B. `out of memory`) oder stürzt myisamchk ab, dann fahren Sie mit Stufe 3 fort.

Stufe 3: Schwierige Reparatur

Diese Stufe sollten Sie nur erreichen, wenn der erste 16-Kbyte-Block der Indexdatei zerstört ist oder falsche Daten enthält oder aber die Indexdatei ganz fehlt. In diesem Fall muss eine neue Indexdatei erstellt werden. Gehen Sie wie folgt vor:

1. Verschieben Sie die Datendatei an einen sicheren Ort.

2. Erstellen Sie unter Verwendung der Tabellenbeschreibungsdatei neue (leere) Daten- und Indexdateien:

       shell> mysql db_name
       mysql> SET AUTOCOMMIT=1;
       mysql> TRUNCATE TABLE tbl_name;
       mysql> quit

3. Kopieren Sie die alte Datendatei wieder auf die neu erstellte Datendatei. (Verschieben Sie die alte Datei nicht einfach auf die neue, sondern behalten Sie eine Kopie für den Fall, dass etwas fehlschlägt.)

Kehren Sie zurück zu Stufe 2. myisamchk -r -q sollte nun funktionieren. (Das heißt, die Stufen sollten sich nicht in endloser Abfolge wiederholen.)

Sie können auch die SQL-Anweisung `REPAIR TABLE `tbl_name` USE_FRM` verwenden, die den gesamten Vorgang automatisch ausführt. Es gibt außerdem nicht die Möglichkeit unerwünschter Interaktion zwischen einem Hilfsprogramm und dem Server, weil der Server gar nicht läuft, wenn Sie `REPAIR TABLE` verwenden. Siehe auch Abschnitt 13.5.2.6, „`REPAIR TABLE`“.

Stufe 4: Sehr schwierige Reparatur

Diese Stufe sollten Sie nur erreichen, wenn die `.frm`-Beschreibungsdatei ebenfalls abgestürzt ist. Dies sollte eigentlich nie passieren, da die Beschreibungsdatei nach Erstellung der Tabelle nicht mehr geändert wird:

1. Stellen Sie die Beschreibungsdatei aus einer Sicherungskopie wieder her und kehren Sie zu Stufe 3 zurück. Sie können auch die Indexdatei wiederherstellen und dann bei Stufe 2 fortfahren; in diesem Fall sollten Sie allerdings mit myisamchk -r beginnen.

2. Wenn Sie über keine Sicherungskopie verfügen, aber genau wissen, wie die Tabelle erstellt worden war, erstellen Sie eine Kopie der Tabelle in einer andere Datenbank. Entfernen Sie die neue Datendatei und verschieben Sie die `.frm`-Beschreibungsdatei und die `.MYI`-Indexdatei aus der anderen Datenbank in die abgestürzte Datenbank. Auf diese Weise erhalten Sie eine neue Beschreibungs- und Indexdatei, während die `.MYD`-Datendatei nicht angerührt wird. Kehren Sie zu Stufe 2 zurück und versuchen Sie, die Indexdatei neu zu erstellen.

#### 5.10.4.4. Tabellenoptimierung

Um fragmentierte Datensätze zu vereinigen und die infolge des Löschens und Aktualisierens von Datensätzen entstandene Platzvergeudung zu beseitigen, führen Sie myisamchk im Wiederherstellungsmodus aus:

    shell> myisamchk -r tbl_name

Sie können eine Tabelle auf die gleiche Weise optimieren, indem Sie die SQL-Anweisung `OPTIMIZE TABLE` verwenden. `OPTIMIZE TABLE` führt eine Reparatur der Tabelle und eine Schlüsselanalyse durch und sortiert zudem den Indexbaum, sodass die Schlüsselsuche beschleunigt wird. Es gibt außerdem nicht die Möglichkeit unerwünschter Interaktion zwischen einem Hilfsprogramm und dem Server, weil der Server gar nicht läuft, wenn Sie `OPTIMIZE TABLE` verwenden. Siehe auch Abschnitt 13.5.2.5, „`OPTIMIZE TABLE`“.

myisamchk bietet eine Reihe weiterer Optionen, die Sie zur Optimierung der Leistungsfähigkeit einer Tabelle verwenden können:

- `--analyze`, `-a`

- `--sort-index`, `-S`

- `--sort-records=`index_num``, `-R `index_num``

Eine vollständige Beschreibung der verfügbaren Optionen finden Sie in Abschnitt 8.2, „myisamchk — Hilfsprogramm für die Tabellenwartung von MyISAM“.

#### 5.10.4.5. Informationen über eine Tabelle erhalten

Um die Beschreibung einer Tabelle oder Statistiken zu ihr zu erhalten, verwenden Sie die hier beschriebenen Befehle. Einige der Informationen werden wir im weiteren Verlauf näher erläutern.

- myisamchk -d `tbl_name`

  Führt myisamchk im „Beschreibungsmodus“ aus, um eine Beschreibung Ihrer Tabelle zu erzeugen. Wenn Sie den MySQL-Server mit deaktivierter externer Sperrung starten, meldet myisamchk unter Umständen einen Fehler für eine Tabelle, die aktualisiert wird, während es ausgeführt wird. Da myisamchk die Tabelle im Beschreibungsmodus allerdings nicht ändert, besteht kein Risiko der Beschädigung von Daten.

- myisamchk -d -v `tbl_name`

  Wenn Sie `-v` hinzufügen, läuft myisamchk im ausführlichen Modus, d. h. es werden mehr Informationen zu den ablaufenden Vorgängen erzeugt.

- myisamchk -eis `tbl_name`

  Zeigt nur die wichtigsten Informationen zu einer Tabelle an. Dieser Vorgang ist langsam, da die gesamte Tabelle gelesen werden muss.

- myisamchk -eiv `tbl_name`

  Ähnlich wie `-eis`, aber Sie erfahren jeweils, was gerade getan wird.

Eine Beispielausgabe für einige dieser Befehle folgt. Sie basieren auf einer Tabelle mit den folgenden Größen für die Daten- und die Indexdatei:

    -rw-rw-r--   1 monty    tcx     317235748 Jan 12 17:30 company.MYD
    -rw-rw-r--   1 davida   tcx      96482304 Jan 12 18:35 company.MYI

Beispielausgabe von myisamchk -d:

    MyISAM file:     company.MYI
    Record format:   Fixed length
    Data records:    1403698  Deleted blocks:         0
    Recordlength:    226

    table description:
    Key Start Len Index   Type
    1   2     8   unique  double
    2   15    10  multip. text packed stripped
    3   219   8   multip. double
    4   63    10  multip. text packed stripped
    5   167   2   multip. unsigned short
    6   177   4   multip. unsigned long
    7   155   4   multip. text
    8   138   4   multip. unsigned long
    9   177   4   multip. unsigned long
        193   1           text

Beispielausgabe von myisamchk -d -v:

    MyISAM file:         company
    Record format:       Fixed length
    File-version:        1
    Creation time:       1999-10-30 12:12:51
    Recover time:        1999-10-31 19:13:01
    Status:              checked
    Data records:            1403698  Deleted blocks:              0
    Datafile parts:          1403698  Deleted data:                0
    Datafile pointer (bytes):      3  Keyfile pointer (bytes):     3
    Max datafile length:  3791650815  Max keyfile length: 4294967294
    Recordlength:                226

    table description:
    Key Start Len Index   Type                  Rec/key     Root Blocksize
    1   2     8   unique  double                      1 15845376      1024
    2   15    10  multip. text packed stripped        2 25062400      1024
    3   219   8   multip. double                     73 40907776      1024
    4   63    10  multip. text packed stripped        5 48097280      1024
    5   167   2   multip. unsigned short           4840 55200768      1024
    6   177   4   multip. unsigned long            1346 65145856      1024
    7   155   4   multip. text                     4995 75090944      1024
    8   138   4   multip. unsigned long              87 85036032      1024
    9   177   4   multip. unsigned long             178 96481280      1024
        193   1           text

Beispielausgabe von myisamchk -eis:

    Checking MyISAM file: company
    Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
    Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
    Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
    Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
    Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
    Total:    Keyblocks used:  98%  Packed:   17%

    Records:          1403698    M.recordlength:     226
    Packed:             0%
    Recordspace used:     100%   Empty space:          0%
    Blocks/Record:   1.00
    Record blocks:    1403698    Delete blocks:        0
    Recorddata:     317235748    Deleted data:         0
    Lost space:             0    Linkdata:             0

    User time 1626.51, System time 232.36
    Maximum resident set size 0, Integral resident set size 0
    Non physical pagefaults 0, Physical pagefaults 627, Swaps 0
    Blocks in 0 out 0, Messages in 0 out 0, Signals 0
    Voluntary context switches 639, Involuntary context switches 28966

Beispielausgabe von myisamchk -eiv:

    Checking MyISAM file: company
    Data records: 1403698   Deleted blocks:       0
    - check file-size
    - check delete-chain
    block_size 1024:
    index  1:
    index  2:
    index  3:
    index  4:
    index  5:
    index  6:
    index  7:
    index  8:
    index  9:
    No recordlinks
    - check index reference
    - check data record references index: 1
    Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
    - check data record references index: 2
    Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
    - check data record references index: 3
    Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
    - check data record references index: 4
    Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
    - check data record references index: 5
    Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    - check data record references index: 6
    Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    - check data record references index: 7
    Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    - check data record references index: 8
    Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    - check data record references index: 9
    Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
    Total:    Keyblocks used:   9%  Packed:   17%

    - check records and index references
    *** LOTS OF ROW NUMBERS DELETED ***

    Records:         1403698   M.recordlength:   226   Packed:           0%
    Recordspace used:    100%  Empty space:        0%  Blocks/Record: 1.00
    Record blocks:   1403698   Delete blocks:      0
    Recorddata:    317235748   Deleted data:       0
    Lost space:            0   Linkdata:           0

    User time 1639.63, System time 251.61
    Maximum resident set size 0, Integral resident set size 0
    Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0
    Blocks in 4 out 0, Messages in 0 out 0, Signals 0
    Voluntary context switches 10604, Involuntary context switches 122798

Erläuterungen zu den Informationstypen, die myisamchk erzeugt, folgen an dieser Stelle. „Keyfile“ bezeichnet dabei die Indexdatei. „Eintrag“ und „Datensatz“ sind Synonyme.

- `MyISAM file`

  Name der `MyISAM`-Datei (Indexdatei).

- `File-version`

  Version des `MyISAM`-Formats. Ist derzeit immer 2.

- `Creation time`

  Zeitpunkt der Erstellung der Datendatei.

- `Recover time`

  Letzte Neuerstellung der Index- oder Datendatei.

- `Data records`

  Anzahl der Datensätze in der Tabelle.

- `Deleted blocks`

  Anzahl der gelöschten Blöcke, für die noch Speicher reserviert ist. Sie können Ihre Tabelle optimieren, um diesen Speicherbedarf zu minimieren. Siehe auch Abschnitt 5.10.4.4, „Tabellenoptimierung“.

- `Datafile parts`

  Beim dynamischen Datensatzformat die Anzahl der vorhandenen Datenblöcke. Bei einer optimierten Tabelle ohne fragmentierte Datensätze entspricht der Wert `Data records`.

- `Deleted data`

  Anzahl der Bytes unbeanspruchter gelöschter Daten. Sie können Ihre Tabelle optimieren, um diesen Speicherbedarf zu minimieren. Siehe auch Abschnitt 5.10.4.4, „Tabellenoptimierung“.

- `Datafile pointer`

  Größe des Datendateizeigers in Byte. Beträgt normalerweise zwischen zwei und fünf Bytes. Den meisten Tabellen reichen zwei Bytes aus. Dies lässt sich allerdings von MySQL noch nicht steuern. Bei festen Tabellen ist dies eine Datensatzadresse. Bei dynamischen Tabellen ist es hingegen eine Byteadresse.

- `Keyfile pointer`

  Größe des Indexdateizeigers in Byte. Beträgt normalerweise zwischen ein und drei Bytes. Den meisten Tabellen reichen zwei Bytes aus, der Wert wird jedoch von MySQL automatisch berechnet. Es handelt sich immer um eine Blockadresse.

- `Max datafile length`

  Maximaler Umfang der Datendatei in Bytes.

- `Max keyfile length`

  Maximaler Umfang der Indexdatei in Bytes.

- `Recordlength`

  Maximaler Speicherbedarf je Datensatz in Bytes.

- `Record format`

  Format, in dem die Datensätze in den Tabellen gespeichert werden. Die obigen Beispiele verwenden `Fixed length`. Weitere mögliche Werte sind `Compressed` und `Packed`.

- `table description`

  Eine Liste aller Schlüssel in der Tabelle. Für jeden Schlüssel zeigt myisamchk einige maschinennahe Informationen an:

  - `Key`

    Die Schlüsselnummer.

  - `Start`

    Startposition des Index im Datensatz.

  - `Len`

    Länge des Indexbestandteils. Bei gepackten Zahlen sollte dies immer die Gesamtbreite der Spalte sein. Bei Strings hingegen kann der Wert kürzer sein als die volle Breite der indizierten Spalte, weil Sie das Präfix einer String-Spalte indizieren können.

  - `Index`

    Gibt an, ob ein Schlüsselwert mehrfach im Index enthalten sein kann. Mögliche Werte sind `unique` (eindeutig) oder `multip.` (mehrfach).

  - `Type`

    Gibt den Datentyp an, den dieser Indexbestandteil hat. Dies ist ein `MyISAM`-Datentyp mit den möglichen Werten `packed`, `stripped` oder `empty`.

  - `Root`

    Adresse des Stammindexblocks.

  - `Blocksize`

    Größe jedes Indexblocks. Ist standardmäßig 1024, der Wert kann aber bei der Kompilierung geändert werden, sofern MySQL aus einer Quelldistribution erstellt wird.

  - `Rec/key`

    Diese ist ein statistischer Wert, der vom Optimierer verwendet wird. Er besagt, wie viele Datensätze pro Wert für diesen Index vorhanden sind. Bei einem eindeutigen Index ist der Wert immer 1. Dies kann aber geändert werden, nachdem eine Tabelle mit myisamchk -a geladen (oder erheblich verändert) wurde. Erfolgt überhaupt keine Änderung, dann wird ein Standardwert von 30 zugewiesen.

  In der in den Beispielen gezeigten Tabelle gibt es zwei `table description`-Zeilen für den neunten Index. Hierdurch wird signalisiert, dass es sich um einen mehrteiligen Index mit zwei Teilen handelt.

- `Keyblocks used`

  Prozentualer Anteil der verwendeten Schlüsselblöcke. Wenn eine Tabelle gerade erst mit myisamchk neu organisiert wurde (wie die Tabelle in den Beispielen), dann sind die Werte sehr hoch und reichen fast an das theoretische Maximum heran.

- `Packed`

  MySQL versucht, Schlüsselwerte mit gemeinsamem Suffix zu packen. Dies ist nur bei Indizes für `CHAR`- und `VARCHAR`-Spalten möglich. Bei langen indizierten Strings mit ähnlichen führenden Bestandteilen kann dies die Menge des verwendeten Speichers erheblich reduzieren. Im dritten der obigen Beispiele ist der vierte Schlüssel zehn Zeichen lang, und es wird eine Speicherersparnis in Höhe von 60 Prozent erzielt.

- `Max levels`

  Tiefe des B-Trees für diesen Schlüssel. Große Tabellen mit langen Schlüsselwerten erhalten hohe Werte.

- `Records`

  Anzahl der Datensätze in der Tabelle.

- `M.recordlength`

  Durchschnittliche Länge eines Datensatzes. Bei Tabellen mit Datensätzen fester Länge ist dies die exakte Länge des Datensatzes, da alle Datensätze die gleiche Länge haben.

- `Packed`

  MySQL schneidet Leerzeichen am Ende von Strings ab. Der Wert `Packed` gibt den prozentualen Anteil der hierdurch erzielten Einsparungen an.

- `Recordspace used`

  Verwendeter Anteil der Datendatei in Prozent.

- `Empty space`

  Nicht verwendeter Anteil der Datendatei in Prozent.

- `Blocks/Record`

  Durchschnittliche Anzahl der Blöcke je Datensatz (d. h. aus wie vielen Verknüpfungen ein fragmentierter Datensatz besteht). Bei festen Tabellen ist dies immer 1.0. Der Wert sollte möglichst nah an 1,0 herankommen. Wird er zu groß, dann können Sie die Tabelle reorganisieren. Siehe auch Abschnitt 5.10.4.4, „Tabellenoptimierung“.

- `Recordblocks`

  Anzahl der verwendeten Blöcke (Verknüpfungen). Bei festen Tabellen ist dieser Wert identisch mit der Anzahl der Datensätze.

- `Deleteblocks`

  Anzahl der gelöschten Blöcke (Verknüpfungen).

- `Recorddata`

  Anzahl der verwendeten Bytes in der Datendatei.

- `Deleted data`

  Anzahl der gelöschten (d. h. nicht verwendeten) Bytes in der Datendatei.

- `Lost space`

  Wenn ein Datensatz aktualisiert wird und sich seine Länge verringert, geht Speicherplatz verloren. Dies ist die Summe dieser Verluste in Byte.

- `Linkdata`

  Wenn das dynamische Tabellenformat verwendet wird, werden die Datensatzfragmente durch Zeiger miteinander verknüpft. Die Zeiger haben eine Länge zwischen vier und sieben Bytes. `Linkdata` gibt den gesamten von diesen Zeigern verwendeten Speicherplatz an.

Wurde eine Tabelle mit myisampack komprimiert, dann zeigt myisamchk -d zusätzliche Informationen zu allen Tabellenspalten an. In Abschnitt 8.4, „myisampack — Erzeugung komprimierter, schreibgeschützter MyISAM Tabellen“, finden Sie ein Beispiel für diese Informationen und eine Beschreibung ihrer Bedeutung.

#### 5.10.4.6. Erstellen eines Wartungsplans für Tabellen

Statt abzuwarten, bis Probleme auftreten, bietet es sich an, Tabellen regelmäßig zu überprüfen. Eine Möglichkeit, `MyISAM`-Tabellen zu überprüfen und zu reparieren, besteht in der Verwendung der Anweisungen `CHECK TABLE` und `REPAIR TABLE`. Siehe auch Abschnitt 13.5.2.3, „`CHECK TABLE`“, und Abschnitt 13.5.2.6, „`REPAIR TABLE`“.

Eine weitere Methoden ist die Nutzung von myisamchk. Bei Wartungsproblemen können Sie myisamchk -s verwenden. Mit der Option `-s` (`--silent`) läuft myisamchk im stummen Modus, d. h. Meldungen werden nur ausgegeben, wenn Fehler auftreten.

Auch die Aktivierung der automatisierten Überprüfung von `MyISAM`-Tabellen ist empfehlenswert. Wann immer ein Computer beispielsweise im Verlauf eines Updates einen Neustart durchführt, müssen Sie jede Tabelle, die hiervon betroffen sein könnte, überprüfen, bevor Sie sie weiter verwenden. (Man bezeichnet solche Tabellen auch als „voraussichtlich abgestürzte Tabellen“.) Um `MyISAM`-Tabellen automatisch zu überprüfen, starten Sie den Server mit der Option `--myisam-recover`. Siehe auch Abschnitt 5.2.1, „Befehlsoptionen für mysqld“.

Doch auch im normalen Systembetrieb sollten Sie die Tabellen regelmäßig überprüfen. Bei MySQL AB führen wir einmal wöchentlich einen cron-Job zur Überprüfung wichtiger Tabellen durch, wobei wir eine Zeile ähnlich der folgenden in einer Datei `crontab` verwenden:

    35 0 * * 0 /path/to/myisamchk --fast --silent /path/to/datadir/*/*.MYI

Hierbei werden Informationen zu abgestürzten Tabellen ausgegeben, die wir untersuchen können, um ggf. erforderliche Reparaturen durchzuführen.

Da seit Jahren kein Fall unerwartet abgestürzter Tabellen aufgetreten ist (also Tabellen, die aus anderen Gründen als Problemen mit der Hardware beschädigt wurden), betrachten wir die wöchentliche Überprüfung als ausreichend.

Wir empfehlen, myisamchk -s anfangs in jeder Nacht für alle Tabellen auszuführen, die während der jeweils letzten 24 Stunden aktualisiert wurden, bis Sie MySQL so weit trauen, wie wir es tun.

Normalerweise erfordern MySQL-Tabellen recht wenig Pflege. Wenn Sie `MyISAM`-Tabellen mit Datensätzen dynamischer Größe (also Tabellen mit `VARCHAR`-, `BLOB`- oder `TEXT`-Spalten) oder Tabellen mit vielen gelöschten Datensätzen haben, dann sollten Sie diese Tabellen von Zeit zu Zeit defragmentieren, d. h. den unbenutzten Speicher wieder zur Benutzung freigeben. Dies können Sie tun, indem Sie die fraglichen Tabellen mit einer `OPTIMIZE TABLE`-Anweisung verarbeiten. Alternativ können Sie, wenn Sie den mysqld-Server eine Zeitlang anhalten können, in das Datenverzeichnis wechseln und den folgenden Befehl bei angehaltenem Server ausführen:

    shell> myisamchk -r -s --sort-index --sort_buffer_size=16M */*.MYI

## 5.11. Lokalisierung und internationaler Gebrauch von MySQL

Dieser Abschnitt beschreibt, wie Sie den Server für die Verwendung anderer Zeichensätze konfigurieren. Ferner werden wir erläutern, wie Sie die Zeitzone des Servers einstellen und die Unterstützung verbindungsspezifischer Zeitzonen aktivieren.

### 5.11.1. Der für Daten und zum Sortieren benutzte Zeichensatz

Standardmäßig verwendet MySQL den Zeichensatz `latin1` (cp1252 West European) und die Sortierung `latin1_swedish_ci`, die gemäß den in Schweden und Finnland gültigen Regeln sortiert. Diese Standardeinstellungen sind für die Vereinigten Staaten und die meisten Länder Westeuropas angemessen.

Alle MySQL-Binärdistributionen werden mit der Option `--with-extra-charsets=complex` kompiliert. Hierdurch wird allen Standardprogrammen ein Code hinzugefügt, der es ihnen gestattet, `latin1` und alle Multibyte-Zeichensätze in der Binärdatei zu verarbeiten. Andere Zeichensätze werden bei Bedarf aus einer Zeichensatzdefinitionsdatei geladen.

Der Zeichensatz bestimmt, welche Zeichen in Bezeichnern zulässig sind. Die Sortierung hingegen definiert die Art und Weise, wie Strings von den Klauseln `ORDER BY` und `GROUP BY` der `SELECT`-Anweisung sortiert werden.

Sie können den Standardzeichensatz und die Standardsortierung auf dem Server mit den Optionen `--character-set-server` bzw. `--collation-server` beim Serverstart ändern. Die Sortierung muss für den gewählten Standardzeichensatz zulässig sein. (Mit der Anweisung `SHOW COLLATION` können Sie die für den jeweiligen Zeichensatz zulässige Sortierung ermitteln.) Siehe auch Abschnitt 5.2.1, „Befehlsoptionen für mysqld“.

Welche Zeichensätze verfügbar sind, hängt von den Optionen `--with-charset=`charset_name`` und `--with-extra-charsets=`list-of-charsets` | complex | all | none` des Befehls configure sowie von den in ``SHAREDIR`/charsets/Index` gelisteten Zeichensatz-Konfigurationsdateien ab. Siehe auch Abschnitt 2.8.2, „Typische configure-Optionen“.

Wenn Sie den Zeichensatz während der Ausführung von MySQL ändern, kann sich dies auch auf die Sortierreihenfolge auswirken. Das bedeutet, dass Sie myisamchk -r -q --set-collation=`collation_name` für alle Tabellen ausführen müssen, da andernfalls Ihre Indizes nicht korrekt sortiert sind.

Wenn ein Client eine Verbindung mit einem MySQL-Server herstellt, gibt der Server dem Client seinen Standardzeichensatz an. Der Client schaltet dann für diese Verbindung auf den betreffenden Zeichensatz um.

Sie sollten `mysql_real_escape_string()` verwenden, wenn Sie Strings für eine SQL-Abfrage kennzeichnen. `mysql_real_escape_string()` ist identisch mit der alten Funktion `mysql_escape_string()`, nur nimmt es den `MYSQL`-Verbindungs-Handle als ersten Parameter entgegen, sodass der korrekte Zeichensatz bei der Kennzeichnung von Zeichen berücksichtigt werden kann.

Wird der Client mit anderen als den Pfaden kompiliert, unter denen der Server installiert ist, und hat der Benutzer, der MySQL konfiguriert hat, nicht alle Zeichensätze in die MySQL-Binärdatei eingefügt, dann müssen Sie dem Client angeben, wo er die zusätzlichen Zeichensätze finden kann, die er braucht, wenn der Server mit einem anderen Zeichensatz ausgeführt wird als der Client.

Dies können Sie durch Angabe der Option `--character-sets-dir` tun, die den Pfad zu dem Verzeichnis angibt, in dem die dynamischen MySQL-Zeichensätze gespeichert sind. Sie können beispielsweise in einer Optionsdatei folgende Angaben machen:

    [client]
    character-sets-dir=/usr/local/mysql/share/mysql/charsets

Die Verwendung eines bestimmten Zeichensatzes durch den Client erzwingen Sie wie folgt:

    [client]
    default-character-set=charset_name

Allerdings ist dies normalerweise nicht erforderlich.

#### 5.11.1.1. Deutscher Zeichensatz

In MySQL 5.1 werden Zeichensatz und Sortierung normalerweise getrennt angegeben. Wenn Sie also die deutsche Sortierreihenfolge verwenden wollen, sollten Sie den Zeichensatz `latin1` und die Sortierung `latin1_german1_ci` oder `latin1_german2_ci` auswählen. Um den Server beispielsweise mit der Sortierung `latin1_german1_ci` zu starten, verwenden Sie die Optionen `--character-set-server=latin1` und `--collation-server=latin1_german1_ci`.

Informationen zu den Unterschieden zwischen diesen beiden Sortierungen finden Sie in Abschnitt 10.9.2, „Westeuropäische Zeichensätze“.

### 5.11.2. Nicht englische Fehlermeldungen

Standardmäßig erzeugt mysqld seine Fehlermeldungen auf Englisch, die Anzeige kann aber auch in den folgenden Sprachen erfolgen: Dänisch, Deutsch, Estnisch, Französisch, Griechisch, Italienisch, Japanisch, Koreanisch, Niederländisch, Norwegisch und Neunorwegisch, Polnisch, Portugiesisch, Rumänisch, Russisch, Schwedisch, Slowakisch, Spanisch, Tschechisch und Ungarisch.

Um in mysqld Fehlermeldungen in einer bestimmten Sprache zu erhalten, starten Sie den Server mit der Option `--language` bzw. `-L`. Der Optionswert kann entweder ein Sprachenname oder der vollständige Pfad zu einer Fehlermeldungsdatei sein. Zum Beispiel:

    shell> mysqld --language=swedish

Oder:

    shell> mysqld --language=/usr/local/share/swedish

Der Sprachname sollte in Kleinbuchstaben angegeben werden.

Standardmäßig befinden sich die Sprachdateien im Unterverzeichnis `share/`LANGUAGE`` des MySQL-Basisverzeichnisses.

Sie können den Inhalt der vom Server erzeugten Fehlermeldungen auch ändern. Details hierzu finden Sie im Handbuch MySQL Internals unter http://dev.mysql.com/doc/. Wenn Sie Änderungen an den Fehlermeldungen vorgenommen haben und dann auf eine neuere Version von MySQL aktualisieren, müssen Sie diese Änderungen nach dem Upgrade erneut eintragen.

### 5.11.3. Einen neuen Zeichensatz hinzufügen

In diesem Abschnitt beschreiben wir den Vorgang des Hinzufügens eines neuen Zeichensatzes zu MySQL. Für die folgende Anleitung benötigen Sie eine MySQL-Quelldistribution. Um die korrekte Vorgehensweise zu bestimmen, ermitteln Sie zunächst, ob der gewünschte Zeichensatz einfach oder komplex ist:

- Benötigt der Zeichensatz keine speziellen Routinen für die String-Sortierung und keine Multibyteunterstützung, dann handelt es sich um einen einfachen Zeichensatz.

- Benötigt der Zeichensatz eine dieser Funktionen, dann ist er komplex.

Beispielsweise sind `latin1` und `danish` einfache Zeichensätze, `big5` und `czech` hingegen sind komplexe Zeichensätze.

In der folgenden Anleitung wird der Name des Zeichensatzes als `MYSET` angegeben.

Bei einem einfachen Zeichensatz verfahren Sie wie folgt:

1. Fügen Sie `MYSET` am Ende der Datei `sql/share/charsets/Index` ein. Weisen Sie ihm eine eindeutige Nummer zu.

2. Erstellen Sie die Datei `sql/share/charsets/`MYSET`.conf`. (Sie können eine Kopie von `sql/share/charsets/latin1.conf` als Basis für diese Datei verwenden.)

   Die Syntax für diese Datei ist sehr einfach:

   - Kommentare beginnen mit dem Rautenzeichen ‘`#`’ und erstrecken sich bis zum Ende der Zeile.

   - Wörter werden durch eine beliebige Anzahl von Whitespace-Zeichen voneinander getrennt.

   - Bei der Definition des Zeichensatzes muss jedes Wort eine Zahl im Hexadezimalformat sein.

   - Das Array `ctype` enthält die ersten 257 Wörter. Die Arrays `to_lower[]`, `to_upper[]` und `sort_order[]` nehmen nachfolgend je 256 Wörter entgegen.

   Siehe auch Abschnitt 5.11.4, „Die Zeichendefinitionsarrays“.

3. Fügen Sie den Namen des Zeichensatzes zu den Listen `CHARSETS_AVAILABLE` und `COMPILED_CHARSETS` in der Datei `configure.in` hinzu.

4. Führen Sie Konfiguration und Kompilierung aus und testen Sie die Distribution.

Bei einem komplexen Zeichensatz verfahren Sie wie folgt:

1. Erstellen Sie die Datei `strings/ctype-`MYSET`.c` in der MySQL-Quelldistribution.

2. Fügen Sie `MYSET` am Ende der Datei `sql/share/charsets/Index` ein. Weisen Sie ihm eine eindeutige Nummer zu.

3. Suchen Sie nach vorhandenen `ctype-*.c`-Dateien (z. B. `strings/ctype-big5.c`), um den Definitionsbedarf zu ermitteln Beachten Sie, dass die Arrays in Ihrer Datei Namen wie `ctype_`MYSET``, `to_lower_`MYSET`` usw. aufweisen müssen. Diese entsprechen den Arrays eines einfachen Zeichensatzes. Siehe auch Abschnitt 5.11.4, „Die Zeichendefinitionsarrays“.

4. Fügen Sie weit oben in der Datei einen speziellen Kommentar wie den folgenden ein:

       /*
        * This comment is parsed by configure to create ctype.c,
        * so don't change it unless you know what you are doing.
        *
        * .configure. number_MYSET=MYNUMBER
        * .configure. strxfrm_multiply_MYSET=N
        * .configure. mbmaxlen_MYSET=N
        */

   Das Programm configure verwendet diesen Kommentar, um den Zeichensatz automatisch in die MySQL-Bibliothek einzufügen.

   Die Zeilen `strxfrm_multiply` und `mbmaxlen` werden in den folgenden Abschnitten erläutert. Sie müssen sie nur einfügen, wenn Sie die Funktionen für die String-Sortierung bzw. für Multibytezeichensätze benötigen.

5. Danach sollten Sie einige der folgenden Funktionen erstellen:

   - `my_strncoll_`MYSET`()`

   - `my_strcoll_`MYSET`()`

   - `my_strxfrm_`MYSET`()`

   - `my_like_range_`MYSET`()`

   Siehe auch Abschnitt 5.11.5, „Unterstützung für String-Vergleiche“.

6. Fügen Sie den Namen des Zeichensatzes zu den Listen `CHARSETS_AVAILABLE` und `COMPILED_CHARSETS` in der Datei `configure.in` hinzu.

7. Führen Sie Konfiguration und Kompilierung aus und testen Sie die Distribution.

Die Datei `sql/share/charsets/README` enthält weitere Anweisungen.

Wenn der Zeichensatz in die MySQL-Distribution eingefügt werden soll, schicken Sie einen Patch an die MySQL-Mailingliste `internals`. Siehe auch Abschnitt 1.7.1, „Die MySQL-Mailinglisten“.

### 5.11.4. Die Zeichendefinitionsarrays

`to_lower[]` und `to_upper[]` sind einfache Arrays, die die Klein- bzw. Großbuchstaben enthalten, die den einzelnen Mitgliedszeichen des Zeichensatzes entsprechen. Zum Beispiel:

    to_lower['A'] should contain 'a'
    to_upper['a'] should contain 'A'

`sort_order[]` bildet die Art und Weise ab, wie Zeichen zu Vergleichs- und Sortierzwecken anzuordnen sind. Recht häufig – aber nicht immer – ist dies identisch mit `to_upper[]`, was bedeutet, dass bei der Sortierung die Groß-/Kleinschreibung unterschieden wird. MySQL sortiert Zeichen basierend auf den Werten von `sort_order[]`-Elementen. Informationen zu komplexeren Sortierregeln entnehmen Sie der Beschreibung der String-Sortierung in Abschnitt 5.11.5, „Unterstützung für String-Vergleiche“.

`ctype[]` ist ein Array mit Bitwerten, wobei jeweils ein Element für ein Zeichen vorhanden ist. (Beachten Sie, dass `to_lower[]`, `to_upper[]` und `sort_order[]` über den Zeichenwert indiziert werden, `ctype[]` hingegen über den Zeichenwert + 1. Dies ist eine Altkonvention zur Verarbeitung von `EOF`.)

In `m_ctype.h` finden Sie die folgenden Bitmaskendefinitionen:

    #define _U      01      /* Uppercase */
    #define _L      02      /* Lowercase */
    #define _N      04      /* Numeral (digit) */
    #define _S      010     /* Spacing character */
    #define _P      020     /* Punctuation */
    #define _C      040     /* Control character */
    #define _B      0100    /* Blank */
    #define _X      0200    /* heXadecimal digit */

Der Eintrag `ctype[]` eines Zeichens sollte die Union der anwendbaren Bitmaskenwerte sein, die das Zeichen beschreiben. Beispielsweise ist `'A'` sowohl ein Großbuchstabe (`_U`) als auch eine Hexadezimalziffer (`_X`), d. h. `ctype['A'+1]` sollte folgenden Wert enthalten:

    _U + _X = 01 + 0200 = 0201

### 5.11.5. Unterstützung für String-Vergleiche

Wenn die Sortierregeln Ihrer Sprache zu komplex sind, um mit der einfachen `sort_order[]`-Tabelle verarbeitet zu werden, dann müssen Sie die String-Sortierfunktionen verwenden.

Die beste Dokumentation hierfür sind die vorhandenen Zeichensätze. Sehen Sie sich beispielsweise die Zeichensätze `big5`, `czech`, `gbk`, `sjis` und `tis160` einmal an.

Sie müssen den Wert `strxfrm_multiply_`MYSET`=`N`` in dem speziellen Kommentar oben in der Datei angeben. `N` sollte dabei auf das maximale Verhältnis gesetzt werden, auf das die Strings bei `my_strxfrm_`MYSET`` anwachsen dürfen (es muss sich dabei um einen positiven Integer handeln).

### 5.11.6. Unterstützung für Multi-Byte-Zeichen

Wenn Sie Unterstützung für einen neuen Zeichensatz hinzufügen wollen, der Multibytezeichen enthält, dann müssen Sie die Multibytezeichenfunktionen verwenden.

Die beste Dokumentation hierfür sind die vorhandenen Zeichensätze. Sehen Sie sich beispielsweise die Zeichensätze `euc_kr`, `gb2312`, `gbk`, `sjis` und `ujis` einmal an. Diese sind in den `ctype-`charset_name`.c`-Dateien im Verzeichnis `strings` implementiert.

Sie müssen den Wert `mbmaxlen_`MYSET`=`N`` in dem speziellen Kommentar oben in der Quelldatei angeben. `N` sollte auf die Größe (in Byte) des größten Zeichens im Zeichensatz gesetzt werden.

### 5.11.7. Probleme mit Zeichensätzen

Wenn Sie einen Zeichensatz verwenden wollen, der nicht in Ihre Binärdatei einkompiliert ist, können die folgenden Probleme auftreten:

- Ihr Programm verwendet einen falschen Pfad für die Speicherposition der Zeichensätze (Vorgabe ist `/usr/local/mysql/share/mysql/charsets`). Dies kann mit der Option `--character-sets-dir` behoben werden, wenn Sie das fragliche Programm ausführen.

- Der Zeichensatz ist ein Multibytezeichensatz, der nicht dynamisch geladen werden kann. In diesem Fall müssen Sie das Programm mit Unterstützung für den Zeichensatz neu kompilieren.

- Der Zeichensatz ist ein dynamischer Zeichensatz, aber Sie haben keine Konfigurationsdatei für ihn. In diesem Fall sollten Sie die Konfigurationsdatei für den Zeichensatz aus einer neuen MySQL-Distribution installieren.

- Wenn Ihre Datei `Index` den Namen für diesen Zeichensatz nicht enthält, zeigt Ihr Programm die folgende Fehlermeldung an:

      ERROR 1105: File '/usr/local/share/mysql/charsets/?.conf'
      not found (Errcode: 2)

  In diesem Fall sollten Sie sich entweder eine neue Datei `Index` beschaffen oder die Namen fehlender Zeichensätze manuell in die aktuelle Datei eintragen.

Bei `MyISAM`-Tabellen können Sie Name und Nummer des Zeichensatzes für eine Tabelle mit myisamchk -dvv `tbl_name` überprüfen.

### 5.11.8. Zeitzonen-Unterstützung des MySQL-Servers

Beim MySQL-Server gibt es mehrere verschiedene Zeitzoneneinstellungen:

- Die Systemzeitzone. Wenn der Server startet, versucht er die Zeitzone des Hostcomputers zu ermitteln und weist diesen Wert dann der Systemvariable `system_time_zone` zu. Der Wert wird nachfolgend nicht mehr geändert.

- Die aktuelle Zeitzone des Servers. Die globale Systemvariable `time_zone` gibt die Zeitzone an, in der der Server derzeit läuft. Der Startwert für `time_zone` ist `'SYSTEM'`, d. h. die Serverzeitzone ist mit der Systemzeitzone identisch. Der Ausgangswert lässt sich mit der Option `--default-time-zone=`timezone`` auch ausdrücklich festlegen. Wenn Sie die Berechtigung `SUPER` haben, können Sie den globalen Wert mit folgender Anweisung zur Laufzeit ändern:

      mysql> SET GLOBAL time_zone = timezone;

- Verbindungsspezifische Zeitzonen. Jeder Client, der eine Verbindung herstellt, hat eine eigene Zeitzoneneinstellung, die von der Sitzungsvariablen `time_zone` vorgegeben wird. Standardmäßig erhält die Sitzungsvariable den Wert von der globalen Variable `time_zone`, der Client kann seine Zeitzone aber mit folgender Anweisung ändern:

      mysql> SET time_zone = timezone;

Die aktuellen Werte der globalen und der clientspezifischen Zeitzone lassen sich wie folgt abrufen:

    mysql> SELECT @@global.time_zone, @@session.time_zone;

`timezone`-Werte können als Strings angegeben werden, die einen Offset zur UTC angeben (z. B. `'+10:00'` oder `'-6:00'`). Wenn die Zeitzonen-Informationstabellen in der `mysql`-Datenbank erstellt und ausgefüllt wurden, können Sie auch benannte Zeitzonen wie etwa `'Europe/Helsinki'`, `'US/Eastern'` oder `'MET'` verwenden. Mit dem Wert `'SYSTEM'` kann angegeben werden, dass die Zeitzone denselben Wert haben sollte wie die Systemzeitzone. Bei den Zeitzonennamen wird die Groß-/Kleinschreibung nicht unterschieden.

Der MySQL-Installationsvorgang erzeugt Zeitzonentabellen in der `mysql`-Datenbank, lädt diese aber nicht. Dies müssen Sie manuell tun. (Wenn Sie von einer früheren Version auf MySQL 4.1.3 oder höher aktualisieren, sollten Sie die Tabellen erstellen, indem Sie ein Upgrade Ihrer `mysql`-Datenbank durchführen. Verwenden Sie hierzu die Anleitung in Abschnitt 5.6, „mysql_fix_privilege_tables — Upgrade von MySQL-Systemtabellen“.)

Wenn Ihr System eine eigene zoneinfo-Datenbank hat (dies ist ein Satz von Dateien, die die Zeitzonen beschreiben), dann sollten Sie das Programm mysql_tzinfo_to_sql zum Ausfüllen der Zeitzonentabellen verwenden. Beispiele für solche Systeme sind Linux, FreeBSD, Sun Solaris und Mac OS X. Eine wahrscheinliche Position für diese Dateien ist das Verzeichnis `/usr/share/zoneinfo`. Verfügt Ihr System nicht über eine zoneinfo-Datenbank, dann können Sie das im weiteren Verlauf dieses Abschnitts genannte Paket herunterladen und verwenden.

Das Programm mysql_tzinfo_to_sql wird zum Laden der Zeitzonentabellen verwendet. Auf der Befehlszeile übergeben Sie den Pfadnamen des zoneinfo-Verzeichnisses an mysql_tzinfo_to_sql und leiten die Ausgabe in das Programm mysql. Zum Beispiel:

    shell> mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql

mysql_tzinfo_to_sql liest die Zeitzonendateien Ihres Systems aus und erzeugt daraus SQL-Anweisungen. mysql verarbeitet diese Anweisungen, um die Zeitzonentabellen zu laden.

mysql_tzinfo_to_sql kann auch zum Laden einer einzelnen Zeitzonendatei und zur Erzeugung von Schaltsekunden verwendet werden:

- Um eine einzelne Zeitzonendatei `tz_file` zu laden, die einem Zeitzonennamen `tz_name` entspricht, rufen Sie mysql_tzinfo_to_sql wie folgt auf:

      shell> mysql_tzinfo_to_sql tz_file tz_name | mysql -u root mysql

- Wenn Ihre Zeitzone Schaltsekunden berücksichtigen muss, initialisieren Sie die Schaltsekundeninformation wie folgt (hierbei ist `tz_file` der Name der Zeitzonendatei):

      shell> mysql_tzinfo_to_sql --leap tz_file | mysql -u root mysql

Verfügt Ihr System über keine zoneinfo-Datenbank (dies gilt beispielsweise für Windows oder HP-UX), dann können Sie das Paket mit den vorerstellten Zeitzonentabellen verwenden, welches unter http://dev.mysql.com/downloads/timezones.html heruntergeladen werden kann. Dieses Paket enthält `.frm`-, `.MYD`- und `.MYI`-Dateien für die `MyISAM`-Zeitzonentabellen. Diese Tabellen sollten Teil der `mysql`-Datenbank sein, d. h. Sie sollten Sie Dateien im Unterverzeichnis `mysql` des Datenverzeichnisses Ihres MySQL-Servers ablegen. Währenddessen sollte der Server beendet sein.

Warnung: Verwenden Sie das herunterzuladende Paket nicht, wenn Ihr System über eine zoneinfo-Datenbank verfügt. Benutzen Sie stattdessen das Hilfsprogramm mysql_tzinfo_to_sql. Andernfalls kann es zu Diskrepanzen in der Verarbeitung von Datum und Uhrzeit zwischen MySQL und anderen Anwendungen auf Ihrem System kommen.

Informationen zu Zeitzoneneinstellungen in der Replikationskonfiguration finden Sie in Abschnitt 6.8, „Replikation: Features und bekannte Probleme“.

## 5.12. Die MySQL-Logdateien

MySQL schreibt mehrere verschiedene Logdateien, mit deren Hilfe Sie ermitteln können, was in mysqld abläuft:

Logdatei | Geloggte Informationen
Fehlerlog | Probleme beim Starten, Ausführen oder Beenden von mysqld
Abfragelog | hergestellte Clientverbindungen, ausgeführte Anweisungen
Binärlog | alle datenändernden Anweisungen (wird auch zur Replikation verwendet)
Logdatei für langsame Abfragen | Abfragen, die länger als in `long_query_time` (in Sekunden) angegeben zur Ausführung benötigen oder keine Indizes verwendet haben

Standardmäßig werden alle Logdateien im Datenverzeichnis mysqld erstellt. Sie können das Schließen und Neuöffnen der Logdateien (in manchen Fällen auch das Wechseln zu einer neuen Logdatei) erzwingen, indem Sie die Logdateien auf die Festplatte schreiben. Das Schreiben der Logdateien auf Festplatte erfolgt, wenn Sie eine `FLUSH LOGS`-Anweisung absetzen oder mysqladmin flush-logs oder mysqladmin refresh ausführen. Siehe auch Abschnitt 13.5.5.2, „`FLUSH`“.

Wenn Sie die Replikationsfunktionen von MySQL verwenden, erstellen die Slave-Replikationsserver weitere Logdateien, die Relay-Logs heißen. Diese werden in Kapitel 6, Replikation bei MySQL, beschrieben.

### 5.12.1. Die Fehler-Logdatei

Die Fehlerlogdatei enthält Informationen, die angeben, wann mysqld gestartet und beendet wurde und welche kritischen Fehler während der Laufzeit des Servers ggf. aufgetreten sind. Wenn mysqld feststellt, dass eine Tabelle automatisch überprüft oder repariert werden muss, dann schreibt es eine Meldung in das Fehlerlog.

Bei einigen Betriebssystemen enthält das Fehlerlog einen Stapel-Trace, wenn mysqld abstürzt. Mit dem Trace kann bestimmt werden, wo mysqld abgestürzt ist. Siehe auch Abschnitt E.1.4, „Einen Stack-Trace benutzen“.

Wenn mysqld unerwartet abstürzt und mysqld_safe den Server neu starten muss, schreibt mysqld_safe die Meldung `restarted mysqld` in das Fehlerlog.

Mit der Option `--log-error[=`file_name`]` können Sie angeben, wo mysqld das Fehlerlog speichern soll. Wird für `file_name` kein Wert angegeben, dann verwendet mysqld den Namen ``host_name`.err` und schreibt die Datei in das Datenverzeichnis. Wenn Sie `FLUSH LOGS` ausführen, wird das Fehlerlog durch Ergänzung des Suffixes `-old` umbenannt, und mysqld erzeugt eine neue leere Logdatei. (Wenn die Option `--log-error` nicht angegeben wird, erfolgt keine Umbenennung.)

Wenn Sie `--log-error` nicht angeben oder (unter Windows) die Option `--console` verwenden, werden Fehler in `stderr` (Standardfehlerausgabe) geschrieben. Normalerweise ist dies Ihr Terminal.

Unter Windows wird die Fehlerausgabe in die `.err`-Datei geschrieben, sofern `--console` nicht angegeben ist.

### 5.12.2. Die allgemeine Anfragen-Logdatei

Wenn Sie wissen wollen, was bei mysqld intern vor sich geht, sollten Sie es mit der Option `--log[=`file_name`]` oder `-l [`file_name`]` starten. Wird keine Wert `file_name` angegeben, dann lautet der Vorgabename ``host_name`.log`. Aufgezeichnet werden alle Verbindungen und Anweisungen. Dieses Log kann sehr praktisch sein, wenn Sie einen Fehler bei einem Client vermuten und genau wissen wollen, was dieser Client an mysqld gesendet hat.

mysqld schreibt die Anweisungen in der Reihenfolge in das Abfragelog, in der sie empfangen werden. Diese Reihenfolge kann sich von der Ausführungsreihenfolge unterscheiden. Dies steht im Gegensatz zum Binärlog, bei dem Anweisungen nach ihrer Ausführung, aber vor dem Aufheben von Sperren geschrieben werden. (Außerdem enthält das Abfragelog alle Anweisungen, wogegen das Binärlog keine Anweisungen enthält, die nur Daten auswählen.)

Bei Serverneustarts und beim Schreiben des Logs auf Festplatte wird keine neue allgemeine Abfragelogdatei erstellt (auch wenn sie beim Schreiben auf Festplatte geschlossen und neu geöffnet wird). Unter Unix können Sie die Datei mit den folgenden Befehlen umbenennen und eine neue Datei erstellen:

    shell> mv host_name.log host_name-old.log
    shell> mysqladmin flush-logs
    shell> cp host_name-old.log backup-directory
    shell> rm host_name-old.log

Unter Windows können Sie die Logdatei nicht umbenennen, solange sie vom Server geöffnet ist. Sie müssen zunächst den Server beenden, die Datei umbenennen und den Server dann neu starten, um eine neue Logdatei zu erstellen.

### 5.12.3. Die binäre Update-Logdatei

Das Binärlog enthält alle Anweisungen, die Daten aktualisieren oder hätten aktualisieren können (beispielsweise eine `DELETE`-Anweisung ohne zutreffenden Datensatz). Die Anweisungen werden in Form von „Ereignissen“ gespeichert, die die Änderungen beschreiben. Ferner enthält das Binärlog auch Informationen dazu, wie lange die Ausführung datenverändernder Anweisungen jeweils gedauert hat.

Hinweis: Das Binärlog hat beginnend mit MySQL 5.0 das alte Update-Log ersetzt, welches nun nicht mehr vorhanden ist. Das Binärlog enthält alle Informationen, die bereits im Update-Log vorhanden waren, in einem effizienteren Format und ist zudem transaktionssicher. Wenn Sie Transaktionen verwenden, müssen Sie für Backups das MySQL-Binärlog statt des alten Update-Logs verwenden.

Das Binärlog enthält keine Anweisungen, die keine Daten ändern. Wenn Sie alle Anweisungen aufzeichnen wollen (um etwa eine problematische Abfrage zu ermitteln), dann verwenden Sie das allgemeine Abfragelog. Siehe auch Abschnitt 5.12.2, „Die allgemeine Anfragen-Logdatei“.

Der primäre Zweck des Binärlogs besteht darin, eine möglichst vollständige Aktualisierung von Datenbanken im Zuge eines Wiederherstellungsvorgangs zu ermöglichen, denn das Binärlog enthält alle Updates, die nach Erstellung einer Sicherung erfolgten. Außerdem wird das Binärlog auf Master-Replikationsservern zur Aufzeichnung von Anweisungen verwendet, die an Slave-Server gesendet werden. Siehe auch Kapitel 6, Replikation bei MySQL.

Die Ausführung des Servers mit aktiviertem Binärlog verringert die Leistungsfähigkeit um ca. 1 Prozent. Die vom Binärlog in Zusammenhang mit der Datenwiederherstellung und der Replikationskonfiguration gebotenen Vorteile machen diese vernachlässigbare Leistungseinbuße jedoch mehr als wett.

Wenn mysqld mit der Option `--log-bin[=`base_name`]` gestartet wird, schreibt es eine Logdatei mit allen SQL-Befehlen, die Daten aktualisieren. Wird kein `base_name`-Wert angegeben, dann wird als Name der Datei standardmäßig der Name des Hostcomputers gefolgt von `-bin` gewählt. Wenn der Basisname angegeben wird, jedoch nicht als absoluter Pfadname, dann schreibt der Server die Datei in das Datenverzeichnis. Die Angabe eines Basisnamens wird empfohlen (siehe Abschnitt A.8.1, „Offene Probleme in MySQL“ zu den Gründen).

Wenn Sie eine Erweiterung im Lognamen angeben (z. B. `--log-bin=`base_name.extension``), dann wird diese stillschweigend entfernt und ignoriert.

mysqld hängt eine numerische Erweiterung an den Basisnamen des Binärlogs an. Diese Zahl wird jedes Mal erhöht, wenn der Server eine neue Logdatei erstellt. Hierdurch entsteht eine geordnete Abfolge von Dateien. Der Server erstellt bei jedem Neustart und beim Schreiben der Logs jedes Mal eine neue Logdatei. Ferner wird ein neues Binärlog automatisch erstellt, wenn die Größe der aktuellen Logdatei den Wert `max_binlog_size` erreicht. Ein Binärlog kann, wenn Sie große Transaktionen verwenden, unter Umständen auch größer werden als durch `max_binlog_size` angegeben. Das liegt daran, dass eine Transaktion vollständig in eine Datei geschrieben und niemals auf mehrere Dateien verteilt wird.

Um im Überblick zu behalten, welche Binärlogdateien bereits verwendet wurden, erstellt mysqld außerdem eine Indexdatei, die die Namen aller verwendeten Binärlogdateien enthält. Standardmäßig hat diese denselben Basisnamen wie die Binärlogdatei zuzüglich der Erweiterung `'.index'`. Sie können den Namen der Indexdatei für Binärlogs mit der Option `--log-bin-index[=`file_name`]` ändern. Solange mysqld ausgeführt wird, sollten Sie diese Datei nicht manuell bearbeiten, da dies mysqld durcheinander bringen könnte.

Schreibvorgänge in die Binärlogdatei und die Indexdatei für Binärlogs werden auf identische Weise verarbeitet, nämlich als Schreiboperationen in `MyISAM`-Tabellen. Siehe auch Abschnitt A.4.3, „Wie MySQL mit vollen Festplatten umgeht“.

Mit der Anweisung `RESET MASTER` können Sie alle Binärlogdateien löschen, mit der Anweisung `PURGE MASTER LOGS` einen Teil davon. Siehe auch Abschnitt 13.5.5.5, „`RESET`“, und Abschnitt 13.6.1, „SQL-Anweisungen für die Steuerung von Master-Servern“.

Das Binärlogformat hat einige bekannte Beschränkungen, die sich auf die Wiederherstellung aus Backups auswirken können. Siehe auch Abschnitt 6.8, „Replikation: Features und bekannte Probleme“.

Das binäre Loggen für gespeicherte Routinen und Trigger erfolgt wie in Abschnitt 19.4, „Binärloggen gespeicherter Routinen und Trigger“, beschrieben.

Sie können die folgenden Optionen für mysqld verwenden, um zu beeinflussen, was in der Binärlogdatei aufgezeichnet wird. Beachten Sie auch die auf die Liste folgenden Erläuterungen.

Wenn Sie die Replikation verwenden, beeinflussen die hier beschriebenen Optionen, welche Anweisungen vom Master-Server an die Slaves gesendet werden. Es gibt auch Optionen für Slave-Server, mit denen gesteuert wird, welche vom Master empfangenen Anweisungen ausgeführt und welche ignoriert werden. Detaillierte Informationen finden Sie in Abschnitt 6.9, „Replikationsoptionen in my.cnf“.

- `--binlog-do-db=`db_name``

  Weist den Server an, das binäre Loggen auf Updates zu beschränken, für die die Standarddatenbank `db_name` heißt (d. h. die mit `USE` gewählte Datenbank). Alle anderen nicht ausdrücklich erwähnten Datenbanken werden ignoriert. Wenn Sie diese Option verwenden, sollten Sie sicherstellen, dass Sie Aktualisierungen nur in der Standarddatenbank durchführen.

  Hierzu gibt es eine Ausnahme für die Anweisungen `CREATE DATABASE`, `ALTER DATABASE` und `DROP DATABASE`. Der Server entscheidet auf der Basis der in der Anweisung genannten Datenbank (nicht der Standarddatenbank), ob die Anweisungen protokolliert werden sollen oder nicht.

  Hier ein Beispiel für etwas, das nicht so funktioniert, wie Sie es vielleicht erwarten: Wenn der Server mit `binlog-do-db=sales` gestartet wird und Sie `USE prices; UPDATE sales.january SET amount=amount+1000;` ausführen, wird diese Anweisung nicht in das Binärlog geschrieben.

  Um mehrere Datenbanken zu loggen, verwenden Sie mehrere Optionen, wobei die Option einmal für jede Datenbank angegeben werden muss.

- `--binlog-ignore-db=`db_name``

  Weist den Server an, das binäre Loggen von Updates zu unterdrücken, für die die Standarddatenbank `db_name` heißt (d. h. die mit `USE` gewählte Datenbank). Wenn Sie diese Option verwenden, sollten Sie sicherstellen, dass Sie Aktualisierungen nur in der Standarddatenbank durchführen.

  Wie bei der Option `--binlog-do-db` gibt es auch hier eine Ausnahme für die Anweisungen `CREATE DATABASE`, `ALTER DATABASE` und `DROP DATABASE`. Der Server entscheidet auf der Basis der in der Anweisung genannten Datenbank (nicht der Standarddatenbank), ob die Anweisungen protokolliert werden sollen oder nicht.

  Hier ein Beispiel für etwas, das nicht so funktioniert, wie Sie es vielleicht erwarten: Wenn der Server mit `binlog-ignore-db=sales` gestartet wird und Sie `USE prices; UPDATE sales.january SET amount=amount+1000;` ausführen, wird diese Anweisung in das Binärlog geschrieben.

  Um mehrere Datenbanken zu ignorieren, verwenden Sie mehrere Optionen, wobei die Option einmal für jede Datenbank angegeben werden muss.

Der Server wertet die Optionen zum Loggen von Updates im Binärlog oder zum Ignorieren der Updates entsprechend den folgenden Regeln aus. Wie bereits erwähnt, gibt es eine Ausnahme für die Anweisungen `CREATE DATABASE`, `ALTER DATABASE` und `DROP DATABASE`. In solchen Fällen ersetzt die Datenbank, die erstellt, geändert oder gelöscht wird, in den folgenden Regeln die Standarddatenbank.

1. Sind `--binlog-do-db`- oder `--binlog-ignore-db`-Regeln vorhanden?

   - Nein: Anweisung in Binärlog schreiben und beenden.

   - Ja: Mit nächstem Schritt fortfahren.

2. Es sind Regeln vorhanden (`--binlog-do-db`, `--binlog-ignore-db` oder beide). Gibt es eine Standarddatenbank (d. h. wurde eine Datenbank mit `USE` ausgewählt)?

   - Nein: Anweisung nicht schreiben, sondern beenden.

   - Ja: Mit nächstem Schritt fortfahren.

3. Es gibt eine Standarddatenbank. Gibt es `--binlog-do-db`-Regeln?

   - Ja: Liegt eine Übereinstimmung der Standarddatenbank mit einer der `--binlog-do-db`-Regeln vor?

     - Ja: Anweisung schreiben und beenden.

     - Nein: Anweisung nicht schreiben, sondern beenden.

   - Nein: Mit nächstem Schritt fortfahren.

4. Es gibt `--binlog-ignore-db`-Regeln. Liegt eine Übereinstimmung der Standarddatenbank mit einer der `--binlog-ignore-db`-Regeln vor?

   - Ja: Anweisung nicht schreiben, sondern beenden.

   - Nein: Abfrage schreiben und beenden.

So schreibt beispielsweise ein Slave, der nur mit `--binlog-do-db=sales` ausgeführt wird, keine Anweisungen in das Binärlog, bei der sich die Standarddatenbank von `sales` unterscheidet (anders gesagt kann `--binlog-do-db` auch manchmal „andere Datenbanken ignorieren“ bedeuten).

Wenn Sie die Replikation verwenden, sollten Sie alte Binärlogdateien erst dann löschen, wenn Sie ganz sicher sind, dass kein Slave sie mehr benötigt. Laufen Ihre Slaves also etwa nie länger als drei Tage am Stück, dann können Sie einmal täglich mysqladmin flush-logs auf dem Master ausführen und dann alle Logs entfernen, die älter als drei Tage sind. Sie können die Dateien dabei zwar manuell entfernen, aber die Verwendung von `PURGE MASTER LOGS` ist vorzuziehen, weil diese Anweisung gleichzeitig auch die Indexdatei für die Binärlogs sicher aktualisiert (und weil sie auch ein Datumsargument entgegennehmen kann). Siehe auch Abschnitt 13.6.1, „SQL-Anweisungen für die Steuerung von Master-Servern“.

Ein Client, der die Berechtigung `SUPER` hat, kann das binäre Loggen seiner eigenen Anweisungen mithilfe einer `SET SQL_LOG_BIN=0`-Anweisung deaktivieren. Siehe auch Abschnitt 13.5.3, „`SET`“.

Sie können den Inhalt von Binärlogdateien mit dem Hilfsprogramm mysqlbinlog anzeigen. Die kann praktisch sein, wenn Sie die Anweisungen im Log neu verarbeiten wollen. So können Sie einen MySQL-Server beispielsweise aus dem Binärlog heraus wie folgt aktualisieren:

    shell> mysqlbinlog log_file | mysql -h server_name

Weitere Informationen zum Hilfsprogramm mysqlbinlog und seiner Verwendung finden Sie in Abschnitt 8.8, „mysqlbinlog — Hilfsprogramm für die Verarbeitung binärer Logdateien“. mysqlbinlog kann auch mit Relay-Logs verwendet werden, da diese im selben Format wie Binärlogdateien geschrieben sind.

Das binäre Loggen erfolgt unmittelbar nach Abschluss einer Anweisung, aber vor dem Aufheben ggf. vorhandener Sperren und dem Schreiben in die Datenbank. Auf diese Weise ist sichergestellt, dass die Anweisungen in der Reihenfolge ihrer Ausführung geloggt werden.

Aktualisierungen nicht transaktionssicherer Tabellen werden im Binärlog unmittelbar nach ihrer Ausführung gespeichert. Im Verlauf einer noch nicht geschriebenen Transaktion werden alle Änderungen (`UPDATE`, `DELETE` oder `INSERT`), die transaktionssichere Tabellen wie etwa `BDB`- oder `InnoDB`-Tabellen betreffen, zwischengespeichert, bis vom Server eine `COMMIT`-Anweisung empfangen wird. Dann schreibt mysqld die gesamte Transaktion in das Binärlog, bevor die `COMMIT`-Anweisung ausgeführt wird. Wenn der Thread, der die Transaktion verarbeitet, startet, reserviert er zur Zwischenspeicherung von Anweisungen einen Puffer der mit `binlog_cache_size` angegebenen Größe. Ist eine Anweisung größer, dann öffnet der Thread eine Temporärdatei, um die Transaktion zu speichern. Endet der Thread, dann wird auch die Temporärdatei wieder gelöscht.

Für Modifikationen an nicht transaktionssicheren Tabellen kann kein Rollback durchgeführt werden. Wenn eine Transaktion, für die ein Rollback erfolgt, Änderungen an nicht transaktionssicheren Tabellen enthält, dann wird die gesamte Transaktionen am Ende mit einer `ROLLBACK`-Anweisung geloggt, um sicherzustellen, dass die Modifikationen an diesen Tabellen repliziert werden.

Die Statusvariable `Binlog_cache_use` zeigt die Anzahl der Transaktionen an, die diesen Puffer (und möglicherweise auch eine Temporärdatei) zur Speicherung von Anweisungen verwendet haben. Die Statusvariable `Binlog_cache_disk_use` gibt an, wie viele dieser Transaktionen tatsächlich eine Temporärdatei erstellen mussten. Mithilfe dieser beiden Variablen kann die Größe von `binlog_cache_size` optimiert werden: Wählen Sie einen ausreichend hohen Wert, damit die Verwendung von Temporärdateien möglichst vermieden wird.

Die Systemvariable `max_binlog_cache_size` kann benutzt werden, um die Gesamtspeicherkapazität zu begrenzen, die zur Zwischenspeicherung einer Transaktion mit mehreren Anweisungen verwendet wird (Standardwert: 4 Gbyte). Ist eine Transaktion größer als dieser Wert, dann schlägt sie fehl, und es wird ein Rollback durchgeführt.

Wenn Sie das Binärlog verwenden, werden nebenläufige in normale Einfügeoperationen für die Anweisungen `CREATE ... SELECT` oder `INSERT ... SELECT` umgewandelt. Hierdurch wird gewährleistet, dass Sie eine exakte Kopie Ihrer Tabellen neu erstellen können, indem Sie das Log während eines Sicherungsvorgangs anwenden.

Beachten Sie, dass sich das Binärlogformat in MySQL 5.1 von dem in vorherigen MySQL-Versionen unterscheidet. Grund hierfür sind Erweiterungen bei der Replikation. Siehe auch Abschnitt 6.6, „Replikation: Kompatibilität zwischen MySQL-Versionen“.

Standardmäßig wird das Binärlog nicht bei jeder Schreiboperation auf Festplatte synchronisiert. Wenn also das Betriebssystem oder der Computer selbst (d. h. nicht nur der MySQL-Server) abstürzen, dann sind die letzten Änderungen im Binärlog unter Umständen verloren gegangen. Um dies zu verhindern, können Sie mithilfe der Systemvariablen `sync_binlog` die Synchronisierung des Binärlogs nach jeder `N`-Schreiboperation erzwingen. Siehe auch Abschnitt 5.2.2, „Server-Systemvariablen“. Der sicherste – aber auch langsamste – Wert für `sync_binlog` ist 1. Aber auch dann, wenn `sync_binlog` auf 1 steht, besteht die Möglichkeit von Inkonsistenzen zwischen dem Tabelleninhalt und dem Inhalt des Binärlogs im Falle eines Absturzes. Wenn Sie beispielsweise `InnoDB`-Tabellen benutzen und der MySQL-Server eine `COMMIT`-Anweisung verarbeitet, dann schreibt er die gesamte Transaktion in das Binärlog und übergibt sie dann an `InnoDB`. Stürzt der Server zwischen diesen beiden Vorgängen ab, dann erfolgt beim Neustart ein Rollback der Transaktion durch `InnoDB`; sie ist aber weiterhin im Binärlog vorhanden. Dieses Problem lässt sich mit der Option `--innodb-safe-binlog` beheben, die die Konsistenz zwischen `InnoDB`-Tabellen und dem Binärlog herstellt. (Hinweis: `--innodb-safe-binlog` wird ab MySQL 5.0 nicht mehr benötigt, weil die XA-Transaktionsunterstützung implementiert wurde.)

Damit diese Option ein höheres Maß an Sicherheit gewähren kann, sollte der MySQL-Server auch so konfiguriert werden, dass das Binär- und die `InnoDB`-Logs bei jeder Transaktion synchronisiert werden. Die `InnoDB`-Logs werden standardmäßig synchronisiert, und das Binärlog kann mit der Option `sync_binlog=1` synchronisiert werden. Diese Option bewirkt, dass der MySQL-Server nach einem Absturz und dem beim folgenden Neustart ausgeführten Rollback die betreffenden Transaktionen aus dem Binärlog ausschneidet. Hierdurch ist sichergestellt, dass das Binärlog die exakten Daten der `InnoDB`-Tabellen widerspiegelt und der Slave insofern immer synchron zum Master bleibt (d. h. keine Anweisung empfängt, für die ein Rollback durchgeführt wurde).

Beachten Sie, dass die Option `--innodb-safe-binlog` auch dann verwendet werden kann, wenn der MySQL-Server andere Speicher-Engines als `InnoDB` aktualisiert. Aus dem Binärlog entfernt werden durch die Wiederherstellungsfunktionen von `InnoDB` nur Anweisungen und Transaktionen, die `InnoDB`-Tabellen betreffen. Wenn der MySQL-Server bei der Wiederherstellung nach einem Absturz feststellt, dass das Binärlog kürzer als erwartet ist, dann fehlt ihm mindestens eine erfolgreich übermittelte `InnoDB`-Transaktion. Dies sollte normalerweise nicht passieren, wenn die Synchronisierung gezielt über `sync_binlog=1` und das Festplatten-/Dateisystem geregelt wurde (was nicht immer klappt); der Server gibt also die Fehlermeldung `The binary log <name> is shorter than its expected size.` aus. In diesem Fall ist das Binärlog nicht korrekt, und die Replikation sollte mit einem neuen Schnappschuss der Master-Daten neu gestartet werden.

### 5.12.4. Die Logdatei für langsame Anfragen

Wenn mysqld mit der Option `--log-slow-queries[=`file_name`]` gestartet wird, schreibt es eine Logdatei mit allen SQL-Befehlen, deren Ausführung länger gedauert hat als durch `long_query_time` (in Sekunden) angegeben. Die Zeit zum Erwirken der ersten Tabellensperren wird dabei nicht als Ausführungszeit berücksichtigt. Der Mindestwert von `long_query_time` ist 1.

Wird kein `file_name`-Wert angegeben, dann wird als Name der Datei standardmäßig der Name des Hostcomputers gefolgt von `-slow.log` gewählt. Wenn ein Dateiname zwar angegeben ist, jedoch nicht als absoluter Pfadname, dann schreibt der Server die Datei in das Datenverzeichnis.

Eine Anweisung wird in das Log für langsame Abfragen geschrieben, nachdem sie abgeschlossen wurde und alle Sperren aufgehoben wurden. Die Reihenfolge, in der die Anweisungen ins Log geschrieben werden, kann sich mithin von der Ausführungsreihenfolge unterscheiden.

Das Log für langsame Abfragen kann zum Ermitteln von Abfragen verwendet werden, deren Ausführung sehr lange dauert und die deswegen für Optimierungen prädestiniert sind. Allerdings kann die Überprüfung dieses Logs eine recht schwierige Aufgabe sein. Um sie zu vereinfachen, können Sie das Log für langsame Abfragen mit dem Befehl mysqldumpslow verarbeiten, um Abfragen zusammenzufassen, die im Log erscheinen.

Bei MySQL 5.1 werden langsame Abfragen, die keine Indizes verwenden, ebenso im Log aufgezeichnet wie solche, die Indizes benutzen. Um zu verhindern, dass Abfragen ohne Indizes in das Log geschrieben werden, verwenden Sie die Option `--log-queries-not-using-indexes`. Siehe auch Abschnitt 5.2.1, „Befehlsoptionen für mysqld“.

Bei MySQL 5.1 können Sie mit der Serveroption `--log-slow-admin-statements` festlegen, dass langsame administrative Anweisungen wie `OPTIMIZE TABLE`, `ANALYZE TABLE` und `ALTER TABLE` ebenfalls in das Log für langsame Abfragen geschrieben werden.

Abfragen, die vom Abfrage-Cache verarbeitet werden, werden im Log für langsame Abfragen nicht aufgezeichnet. Gleiches gilt für Abfragen, die vom Vorhandensein eines Index nicht profitieren würden, da die Tabellen keinen oder nur einen Datensatz umfasst.

### 5.12.5. Wartung und Pflege der Logdateien

MySQL Server erstellt eine Reihe verschiedener Logdateien, mit denen Sie ganz einfach feststellen können, was vor sich geht. Siehe auch Abschnitt 5.12, „Die MySQL-Logdateien“. Allerdings müssen Sie diese Dateien regelmäßig bereinigen, damit sichergestellt ist, dass die Logs nicht zu viel Festplattenspeicher belegen.

Wenn Sie MySQL mit aktiviertem Loggen verwenden, dann sollten Sie alte Logdateien von Zeit zu Zeit sichern und entfernen und MySQL anweisen, neue Logdateien zu erstellen. Siehe auch Abschnitt 5.10.1, „Datenbank-Datensicherungen“.

Auf einer Linux-Installation (Red Hat) können Sie hierfür das Skript `mysql-log-rotate` verwenden. Wenn Sie MySQL aus einer RPM-Distribution installiert haben, sollte dieses Skript automatisch installiert worden sein. Allerdings sollten Sie mit dem Skript vorsichtig umgehen, wenn Sie das Binärlog zur Replikation verwenden. Entfernen Sie Binärlogs erst, wenn Sie sicher sind, dass die Inhalte von allen Slaves verarbeitet wurden.

Auf anderen Systemen müssen Sie selbst ein kurzes Skript installieren, welches Sie über cron (oder ein passendes Gegenstück) starten, um Logdateien zu verarbeiten.

Sie können die Einrichtung und Verwendung neuer Logdateien in MySQL mit mysqladmin flush-logs oder der SQL-Anweisung `FLUSH LOGS` erzwingen.

Beim Schreiben einer Logdatei auf die Festplatte geschieht folgendes:

- Wenn das Loggen allgemeiner Abfragen (`--log`) oder langsamer Abfragen (`--log-slow-queries`) verwendet wird, schließt der Server die entsprechende Logdatei und öffnet sie dann neu.

- Beim binären Loggen (`--log-bin`) schließt der Server die aktuelle Logdatei und öffnet eine neue Logdatei mit der nächsthöheren Sequenznummer.

Wenn die Logs auf Festplatte geschrieben werden, erstellt der Server eine neue Binärlogdatei. Die Logs für allgemeine und langsame Abfragen hingegen werden nur geschlossen und dann wieder geöffnet. Wenn Sie unter Unix neue Dateien erstellen wollen, benennen Sie die aktuellen Logs um, bevor Sie sie auf die Festplatte schreiben. Beim Schreiben auf Festplatte öffnet der Server dann neue Logdateien mit den ursprünglichen Namen. Wenn beispielsweise die Logdateien für allgemeine und langsame Abfragen die Namen `mysql.log` bzw. `mysql-slow.log` haben, können Sie folgende Befehlssequenz verwenden:

    shell> cd mysql-data-directory
    shell> mv mysql.log mysql.old
    shell> mv mysql-slow.log mysql-slow.old
    shell> mysqladmin flush-logs

An dieser Stelle können Sie eine Sicherung von `mysql.old` und `mysql-slow.log` erstellen und diese dann von der Festplatte entfernen.

Unter Windows können Sie die Logdateien nicht umbenennen, solange sie vom Server geöffnet sind. Sie müssen zunächst den Server beenden, die Dateien umbenennen und den Server dann neu starten, um neue Logdateien zu erstellen.

## 5.13. Mehrere MySQL-Server auf derselben Maschine laufen lassen

In manchen Fällen kann es wünschenswert oder erforderlich sein, mehrere mysqld-Server auf demselben Computer auszuführen. Dies ist etwa der Fall, wenn Sie einen neuen MySQL-Release testen wollen, ohne die vorhandene Produktionskonfiguration anzurühren, oder wenn Sie verschiedenen Benutzern Zugang zu unterschiedlichen mysqld-Servern gestatten wollen, die dann von diesen Benutzern selbst verwaltet werden. (Ein solcher Fall läge bei einem Internetprovider vor, der separate MySQL-Installationen für verschiedene Kunden bereithält.)

Damit mehrere Server auf demselben Computer ausgeführt werden können, benötigt jeder Server eindeutige Werte für verschiedene Betriebsparameter. Diese können über die Befehlszeile oder in Optionsdateien angegeben werden. Siehe auch Abschnitt 4.3, „Angabe von Programmoptionen“.

Zumindest die folgenden Optionen müssen für jeden Server unterschiedlich sein:

- `--port=`port_num``

  `--port` steuert die Portnummer für TCP/IP-Verbindungen.

- `--socket=`path``

  `--socket` gibt unter Unix den Pfad zur Unix-Socketdatei und unter Windows den Namen der Named Pipe an. Unter Windows müssen separate Pipe-Namen nur für diejenigen Server angegeben werden, die Named-Pipe-Verbindungen unterstützen.

- `--shared-memory-base-name=`name``

  Diese Option wird derzeit nur unter Windows verwendet. Sie bezeichnet den Namen des gemeinsamen Speichers, mit dem ein Windows-Server Clients das Herstellen einer Verbindung über gemeinsamen Speicher gestattet. Die Angabe ist nur für Server erforderlich, die Verbindungen über gemeinsamen Speicher unterstützen.

- `--pid-file=`file_name``

  Diese Option wird nur unter Unix verwendet. Sie gibt den Pfadnamen der Datei an, in die der Server seine Prozesskennung schreibt.

Wenn Sie die folgenden Logdateioptionen verwenden, müssen diese für jeden Server anders sein:

- `--log=`file_name``

- `--log-bin=`file_name``

- `--log-update=`file_name``

- `--log-error=`file_name``

- `--bdb-logdir=`file_name``

Weitere Informationen zu Logdateien finden Sie in Abschnitt 5.12.5, „Wartung und Pflege der Logdateien“.

Zur Leistungsoptimierung können Sie auch die folgenden Optionen für jeden Server individuell angeben, um so die Last auf mehrere physische Festplatten zu verteilen:

- `--tmpdir=`path``

- `--bdb-tmpdir=`path``

Auch die Verwendung verschiedener Temporärverzeichnisse wird empfohlen, um besser bestimmen zu können, welche MySQL-Server welche der vorhandenen Temporärdateien erstellt hat.

Mit sehr wenigen Ausnahmen sollte jeder Server ein eigenes Datenverzeichnis haben, das mit der Option `--datadir=`path`` angegeben wird.

Warnung: Normalerweise sollten Daten in denselben Datenbanken niemals von zwei Servern aktualisiert werden. Dies kann zu unliebsamen Überraschungen führen, wenn Ihr Betriebssystem keine fehlerfreie Systemsperrung unterstützt. Wenn Sie (ungeachtet dieser Warnung) mehrere Server betreiben, die dasselbe Datenverzeichnis verwenden, müssen Sie, wenn das Loggen aktiviert ist, die passenden Optionen zur Angabe der Logdateinamen festlegen, die für jeden Server eindeutig sein müssen. Andernfalls versuchen die Server nämlich, in die gleichen Logdateien zu schreiben. Beachten Sie, dass eine solche Konfiguration nur bei `MyISAM`- und `MERGE`-Tabellen funktioniert, nicht aber bei anderen Speicher-Engines.

Die Warnung vor der gemeinsamen Nutzung eines Datenverzeichnisses durch mehrere Server gilt auch in einer NFS-Umgebung. Mehreren MySQL-Servern den Zugriff auf ein gemeinsames Datenverzeichnis über NFS zu gestatten, ist eine ganz schlechte Idee.

- Das Problem ist hierbei primär, dass NFS in punkto Geschwindigkeit einen Flaschenhals darstellt. NFS ist für einen solchen Einsatz schlichtweg ungeeignet.

- Ein weiteres Risiko besteht bei NFS darin, dass Sie eine Möglichkeit finden müssen, sicherzustellen, dass zwei oder mehr Server einander nicht stören. Normalerweise wird die NFS-Dateisperrung vom Daemon `lockd` verwaltet; es gibt aber derzeit keine Plattform, die die Sperrung in jeder Situation hundertprozentig zuverlässig ausführt.

Machen Sie es sich einfach: Lassen Sie die Freigabe eines Datenverzeichnisses für mehrere Server über NFS einfach bleiben. Eine bessere Lösung besteht in der Verwendung eines Computers, der mehrere Prozessoren enthält und ein Betriebssystem verwendet, das Threads effizient verwaltet.

Wenn Sie mehrere MySQL-Installationen in verschiedenen Verzeichnissen haben, können Sie das Basisinstallationsverzeichnis für jeden Server mit der Option `--basedir=`path`` angeben; in diesem Fall verwendet jeder Server ein anderes Datenverzeichnis, eigene Logdateien und eine eigene Prozesskennungsdatei. (Standardmäßig werden diese Werte relativ zum Basisverzeichnis gesetzt.) In diesem Fall müssen Sie als weitere Optionen nur `--socket` und `--port` angeben. Angenommen, Sie installieren verschiedene MySQL-Versionen aus einer `tar`-Datei mit einer Binärdistribution. Diese Versionen werden an verschiedenen Positionen installiert, d. h. Sie können den Server für jede Installation mit dem Befehl bin/mysqld_safe in seinem jeweiligen Basisverzeichnis starten. mysqld_safe bestimmt die korrekte `--basedir`-Option, die an mysqld übergeben werden muss; Sie müssen dann nur noch die Optionen `--socket` und `--port` für mysqld_safe angeben.

Wie in den vorangegangenen Abschnitten bereits erläutert, können zusätzliche Server durch Einstellen von Umgebungsvariablen oder durch Angabe passender Befehlszeilenoptionen gestartet werden. Wenn Sie allerdings auf Dauer mehrere Server ausführen wollen, ist es praktischer, die Optionswerte, die für jeden Server eindeutig sein müssen, mithilfe von Optionsdateien anzugeben. Die Option `--defaults-file` ist für diese Zwecke praktisch.

### 5.13.1. Mehrere Server unter Windows verwenden

Sie können mehrere Server unter Windows ausführen, indem Sie sie manuell über die Befehlszeile starten und die jeweils passenden Betriebsparameter angeben. Auf Windows NT-basierten Systemen können Sie mehrere Server auch als Windows-Dienste installieren und sie auf diese Weise ausführen. Eine allgemeine Anleitung zur Ausführung von MySQL-Servern über die Befehlszeile oder als Dienste finden Sie in Abschnitt 2.3, „Installation von MySQL unter Windows“. Dieser Abschnitt beschreibt, wie man sicherstellt, dass jeder Server mit unterschiedlichen Werten für diejenigen Optionen gestartet wird, die je Server eindeutig sein müssen (z. B. das Datenverzeichnis). Diese Optionen sind in Abschnitt 5.13, „Mehrere MySQL-Server auf derselben Maschine laufen lassen“, beschrieben.

#### 5.13.1.1. Mehrere Server unter Windows auf der Befehlszeile starten

Um mehrere Server manuell über die Befehlszeile zu starten, können Sie die erforderlichen Optionen ebenfalls über die Befehlszeile oder in einer Optionsdatei angeben. Die Verwendung einer Optionsdatei ist praktischer. Sie müssen aber in jedem Fall sicherstellen, dass jeder Server eigene Optionen zugeordnet bekommt. Zu diesem Zweck erstellen Sie für jeden Server eine Optionsdatei und übergeben dem Server beim Start den Dateinamen mit der Option `--defaults-file`.

Angenommen, Sie wollen mysqld über Port 3307 mit dem Datenverzeichnis `C:\mydata1` und mysqld-max über Port 3308 mit dem Datenverzeichnis `C:\mydata2` ausführen. (Vergewissern Sie sich zu diesem Zweck vor dem Starten der Server, dass die Datenverzeichnisse vorhanden sind und jeweils eine eigene Kopie der `mysql`-Datenbank mit den Grant-Tabellen enthalten.) Erstellen Sie nun zwei Optionsdateien. Legen Sie beispielsweise eine Datei namens `C:\my-opts1.cnf` an, die wie folgt aussieht:

    [mysqld]
    datadir = C:/mydata1
    port = 3307

Legen Sie nun eine zweite Datei namens `C:\my-opts2.cnf` an, die wie folgt aussieht:

    [mysqld]
    datadir = C:/mydata2
    port = 3308

Jetzt starten Sie die Server mit jeweils eigener Optionsdatei:

    C:\> C:\mysql\bin\mysqld --defaults-file=C:\my-opts1.cnf
    C:\> C:\mysql\bin\mysqld-max --defaults-file=C:\my-opts2.cnf

Unter NT starten beide Server in den Vordergrund (d. h. eine Eingabeaufforderung wird erst wieder angezeigt, wenn der Server später beendet wird); Sie müssen deswegen zwei Befehle in separaten Konsolenfenstern ausführen.

Um die Server herunterzufahren, müssen Sie mit jedem Server unter Angabe der entsprechenden Portnummer eine Verbindung herstellen:

    C:\> C:\mysql\bin\mysqladmin --port=3307 shutdown
    C:\> C:\mysql\bin\mysqladmin --port=3308 shutdown

Mit Servern, die auf die beschriebene Weise konfiguriert wurden, können Clients über TCP/IP Verbindungen herstellen. Wenn Ihre Windows-Version Named Pipes unterstützt und Sie Named-Pipe-Verbindungen auch zulassen wollen, dann verwenden Sie die Server mysqld-nt oder mysqld-max-nt und geben Sie Optionen an, die die Named Pipe aktivieren und den zugehörigen Namen definieren. Jeder Server, der Named-Pipe-Verbindungen unterstützt, muss einen eindeutigen Namen für die Pipe verwenden. Beispielsweise könnte die Datei `C:\my-opts1.cnf` wie folgt aussehen:

    [mysqld]
    datadir = C:/mydata1
    port = 3307
    enable-named-pipe
    socket = mypipe1

Starten Sie den Server in diesem Fall wie folgt:

    C:\> C:\mysql\bin\mysqld-nt --defaults-file=C:\my-opts1.cnf

Ändern Sie `C:\my-opts2.cnf` auf ähnliche Weise für die Verwendung durch den zweiten Server ab.

Eine ähnliche Vorgehensweise gilt für Server, die Verbindungen über gemeinsamen Speicher unterstützen sollen. Sie aktivieren solche Verbindungen mit der Option `--shared-memory` und vergeben dann für jeden Server mit der Option `--shared-memory-base-name` einen eindeutigen Namen für den freigegebenen Speicher.

#### 5.13.1.2. Mehrere Server unter Windows als Dienste starten

Unter Windows NT-basierten Systemen kann ein MySQL-Server als Windows-Dienst ausgeführt werden. Die Vorgehensweise zum Installieren, Steuern und Entfernen eines einzelnen MySQL-Dienstes sind in Abschnitt 2.3.12, „Starten von MySQL als Windows-Dienst“, beschrieben.

Sie können auch mehrere MySQL-Server als Dienste installieren. In diesem Fall müssen Sie sicherstellen, dass jeder Server neben allen Parametern, die für jeden Server eindeutig sein müssen, auch einen eigenen Dienstnamen verwendet.

Bei der folgenden Anleitung wird davon ausgegangen, dass Sie den Server mysqld-nt aus zwei verschiedenen MySQL-Versionen ausführen wollen, die in `C:\mysql-5.0.19` bzw. `C:\mysql-5.1.5-alpha` installiert sind. (Dies kann etwa der Fall sein, wenn Sie Version 5.0.19 als Produktionsserver ausführen und gleichzeitig Tests mit Version 5.1.5-alpha durchführen wollen.)

Die folgenden Prinzipien finden Anwendung, wenn Sie einen MySQL-Dienst mit der Option `--install` oder `--install-manual` installieren:

- Wenn Sie keinen Dienstnamen angeben, verwendet der Server den Standarddienstnamen `MySQL` und liest seine Optionen aus dem Abschnitt `[mysqld]` in den Standardoptionsdateien aus.

- Geben Sie hingegen auf die Option `--install` folgend einen Dienstnamen an, dann ignoriert der Server den Abschnitt `[mysqld]` und liest stattdessen die Optionen aus dem Abschnitt aus, der den gleichen Namen wie der Dienst hat. Der Server liest Optionen aus den Standardoptionsdateien aus.

- Wenn Sie eine Option `--defaults-file` auf den Dienstnamen folgend angeben, ignoriert der Server die Standardoptionsdateien und liest seine Optionen aus dem Abschnitt `[mysqld]` der benannten Datei aus.

Hinweis: Vor MySQL 4.0.17 wird der Abschnitt `[mysqld]` in den Standardoptionsdateien nur dann vom Server gelesen, wenn dieser mit dem Standarddienstnamen (`MySQL`) oder dem explizit angegebenen Dienstnamen mysqld installiert wurde. Ab Version 4.0.17 lesen alle Server, falls sie die Standardoptionsdateien auslesen, den Abschnitt `[mysqld]`. Dies gilt auch für Server, die mit einem anderen Dienstnamen installiert wurden. Sie können den Abschnitt `[mysqld]` also für diejenigen Optionen verwenden, die allen MySQL-Diensten gemeinsam sind, und zusätzlich einen Abschnitt mit dem Namen eines bestimmten Dienstes konfigurieren, der dann von dem Server benutzt wird, der mit diesem Dienstnamen installiert wurde.

Basierend auf diesen Informationen stehen Ihnen verschiedene Möglichkeiten zur Verfügung, mehrere Dienste einzurichten. Die folgende Anleitung beschreibt einige Beispiele. Bevor Sie jedoch eines davon ausprobieren, fahren Sie alle vorhandenen MySQL-Dienste herunter und entfernen Sie sie.

- Methode 1: Geben Sie die Optionen für alle Dienste in einer der Standardoptionsdateien an. Verwenden Sie zu diesem Zweck einen anderen Dienstnamen für jeden Server. Angenommen, Sie wollen mysqld-nt aus Version 5.0.19 mit dem Dienstnamen `mysqld1` und mysqld-nt aus Version 5.1.5-alpha mit dem Dienstnamen `mysqld2` ausführen. In diesem Fall können Sie den Abschnitt `[mysqld1]` für Version 5.0.19 und den Abschnitt `[mysqld2]` für Version 5.1.5-alpha verwenden. Sie können `C:\my.cnf` etwa wie folgt konfigurieren:

      # options for mysqld1 service
      [mysqld1]
      basedir = C:/mysql-5.0.19
      port = 3307
      enable-named-pipe
      socket = mypipe1

      # options for mysqld2 service
      [mysqld2]
      basedir = C:/mysql-5.1.5-alpha
      port = 3308
      enable-named-pipe
      socket = mypipe2

  Installieren Sie die Dienste wie folgt und verwenden Sie dabei die vollständigen Serverpfadnamen, um sicherzustellen, dass Windows für jeden Dienst die korrekte ausführbare Datei registriert:

      C:\> C:\mysql-5.0.19\bin\mysqld-nt --install mysqld1
      C:\> C:\mysql-5.1.5-alpha\bin\mysqld-nt --install mysqld2

  Um die Dienste zu starten, verwenden Sie den Dienste-Manager oder NET START mit den entsprechenden Dienstnamen:

      C:\> NET START mysqld1
      C:\> NET START mysqld2

  Um die Dienste zu beenden, verwenden Sie den Dienste-Manager oder NET STOP mit den entsprechenden Dienstnamen:

      C:\> NET STOP mysqld1
      C:\> NET STOP mysqld2

- Methode 2: Sie geben Sie Optionen für jeden Server in einer separaten Datei an und geben bei der Installation `--defaults-file` an, um den Servern die jeweils zu verwendende Datei mitzuteilen. In diesem Fall sollten die Optionen in jeder Datei in einem Abschnitt `[mysqld]` aufgelistet sein.

  Bei dieser Methode erstellen Sie zur Angabe der Optionen für mysqld-nt aus Version 5.0.19 eine Datei `C:\my-opts1.cnf`, die wie folgt aussieht:

      [mysqld]
      basedir = C:/mysql-5.0.19
      port = 3307
      enable-named-pipe
      socket = mypipe1

  Legen Sie nun für mysqld-nt aus Version 5.1.5-alpha eine zweite Datei namens `C:\my-opts2.cnf` an, die wie folgt aussieht:

      [mysqld]
      basedir = C:/mysql-5.1.5-alpha
      port = 3308
      enable-named-pipe
      socket = mypipe2

  Installieren Sie die Dienste wie folgt (geben Sie jeden Befehl in eine eigene Zeile ein):

      C:\> C:\mysql-5.0.19\bin\mysqld-nt --install mysqld1
                 --defaults-file=C:\my-opts1.cnf
      C:\> C:\mysql-5.1.5-alpha\bin\mysqld-nt --install mysqld2
                 --defaults-file=C:\my-opts2.cnf

  Um bei der Installation eines MySQL-Servers als Dienst eine Option `--defaults-file` anzugeben, müssen Sie der Option den Dienstnamen voranstellen.

  Nach der Installation der Dienste starten und beenden Sie sie auf die gleiche Weise wie im vorherigen Beispiel.

Zum Entfernen mehrerer Dienste verwenden Sie für jeden einzelnen Dienst mysqld --remove und geben dabei auf die Option `--remove` folgend einen Dienstnamen an. Wenn der Dienst den Standardnamen (`MySQL`) hat, können Sie die Angabe auch weglassen.

### 5.13.2. Mehrere MySQL-Server unter Unix laufen lassen

Die einfachste Möglichkeit, mehrere Server unter Unix auszuführen, besteht darin, sie mit verschiedenen TCP/IP-Ports und Unix-Socketdateien zu kompilieren, sodass jeder Server auf eine andere Netzwerkschnittstelle horcht. Auch das Einkompilieren verschiedener Basisverzeichnisse für jede Installation hat automatisch ein dediziertes einkompiliertes Verzeichnis zur Folge, in dem Datenverzeichnis, Logdatei und Prozesskennungsdatei des betreffenden Servers abgelegt sind.

Nehmen wir einmal an, dass der vorhandene Server (Version 5.0.19) für den TCP/IP-Standardport (3306) und die Standardsocketdatei (`/tmp/mysql.sock`) konfiguriert ist. Um nun einen neuen Server unter MySQL 5.1.5-alpha mit anderen Betriebsparametern zu konfigurieren, verwenden Sie den Befehl configure wie folgt:

    shell> ./configure --with-tcp-port=port_number \
                 --with-unix-socket-path=file_name \
                 --prefix=/usr/local/mysql-5.1.5-alpha

Hierbei müssen sich `port_number` und `file_name` von der TCP/IP-Standardportnummer bzw. dem Standardpfadnamen der Unix-Socketdatei unterscheiden. Ferner sollte die Option `--prefix` ein anderes Installationsverzeichnis als jenes angeben, in dem sich die vorhandene MySQL-Installation befindet.

Wenn Ihr MySQL-Server auf eine gegebene Portnummer horcht, dann können Sie mit folgendem Befehl herausfinden, welche Betriebsparameter er für verschiedene wichtige konfigurierbare Variablen (einschließlich Basisverzeichnis und Unix-Socketdatei) verwendet:

    shell> mysqladmin --host=host_name --port=port_number variables

Anhand der von diesem Befehl angezeigten Informationen können Sie festlegen, welche Optionswerte Sie nicht verwenden dürfen, wenn Sie einen zusätzlichen Server konfigurieren.

Beachten Sie, dass, wenn Sie `localhost` als Hostnamen angeben, mysqladmin standardmäßig statt TCP/IP eine Verbindung über eine Unix-Socketdatei verwendet. Ab MySQL 4.1 können Sie das zu verwendende Verbindungsprotokoll mit der Option `--protocol={TCP|SOCKET|PIPE|MEMORY}` explizit angeben.

Sie müssen keinen neuen MySQL-Server kompilieren, nur um neu mit einer anderen Unix-Socketdatei und TCP/IP-Portnummer zu starten. Sie können auch dieselbe Serverbinärdatei verwenden und diese mehrfach aufrufen – mit jeweils anderen Parameterwerten zur Laufzeit. Eine Möglichkeit hierzu besteht in der Verwendung von Befehlszeilenoptionen:

    shell> mysqld_safe --socket=file_name --port=port_number

Um einen zweiten Server zu starten, geben Sie andere Optionswerte für `--socket` und `--port` an und übergeben zudem eine Option `--datadir=`path`` an mysqld_safe, damit der Server ein anderes Datenverzeichnis benutzt.

Eine weitere Möglichkeit, mit der sich ein ähnlicher Effekt erzielen lässt, besteht darin, den Namen der Unix-Socketdatei und die TCP/IP-Portnummer mithilfe von Umgebungsvariablen anzugeben:

    shell> MYSQL_UNIX_PORT=/tmp/mysqld-new.sock
    shell> MYSQL_TCP_PORT=3307
    shell> export MYSQL_UNIX_PORT MYSQL_TCP_PORT
    shell> mysql_install_db --user=mysql
    shell> mysqld_safe --datadir=/path/to/datadir &

Dies steht eine schnelle Möglichkeit dar, einen zweiten Server zu Testzwecken zu starten. Das Praktische an dieser Methode ist, dass die Einstellungen der Umgebungsvariablen für alle Clientprogramme gelten, die Sie von derselben Shell aufrufen. Auf diese Weise werden Verbindungen für diese Clients automatisch an den zweiten Server geleitet.

Anhang F, Umgebungsvariablen, enthält eine Liste aller anderen Umgebungsvariablen, die Sie zur Beeinflussung von mysqld verwenden können.

Für die automatische Ausführung des Servers sollte das Startskript, welches beim Systemstart ausgeführt wird, den folgenden Befehl jeweils einmal pro Server ausführen und dabei den jeweils passenden Optionsdateipfad angeben:

    shell> mysqld_safe --defaults-file=file_name

Jede Optionsdatei sollte die Optionswerte für jeweils einen bestimmten Server angeben.

Eine andere Möglichkeit zum Starten mehrerer Server bietet unter Unix das Skript mysqld_multi. Siehe auch Abschnitt 5.4.3, „mysqld_multi — Verwalten mehrerer MySQL-Server“.

### 5.13.3. Verwendung von Client-Programmen in einer Mehrserverumgebung

Um eine Verbindung von einem Clientprogramm mit einem MySQL-Server herzustellen, der auf anderen als den in Ihren Client einkompilierten Netzwerkschnittstellen lauscht, können Sie eine der folgenden Methoden benutzen:

- Starten Sie den Client mit `--host=`host_name` --port=`port_number``, `--host=127.0.0.1 --port=`port_number`` bzw. `--host=localhost --socket=`file_name``, um eine TCP/IP-Verbindung mit einem entfernten Server, eine TCP/IP-Verbindung mit dem lokalen Server oder eine Verbindung mit dem lokalen Server über eine Unix-Socketdatei oder eine Named Pipe unter Windows herzustellen.

- Ab MySQL 4.1 starten Sie den Client mit `--protocol=tcp`, `--protocol=socket`, `--protocol=pipe` bzw. `--protocol=memory`, um eine Verbindung über TCP/IP, eine Unix-Socketdatei, eine Named Pipe oder gemeinsamen Speicher herzustellen. Bei TCP/IP-Verbindungen müssen Sie auch die Optionen `--host` und `--port` angeben. Bei den anderen Verbindungstypen können Sie eine Option `--socket` zur Festlegung einer Unix-Socketdatei bzw. einer Named-Pipe-Datei oder eine Option `--shared-memory-base-name` zur Bezeichnung des Namens des gemeinsamen Speichers angeben. Verbindungen über gemeinsamen Speicher werden nur unter Windows unterstützt.

- Unter Unix stellen Sie, bevor Sie Ihre Clients starten, die Umgebungsvariablen `MYSQL_UNIX_PORT` und `MYSQL_TCP_PORT` so ein, dass sie die Unix-Socketdatei bzw. die TCP/IP-Portnummer angeben. Wenn Sie normalerweise eine bestimmte Socketdatei oder Portnummer verwenden, können Sie die Befehle, die die Werte der Umgebungsvariablen einstellen, in Ihrer Datei `.login` ablegen, damit diese bei jeder Anmeldung automatisch konfiguriert werden. Siehe auch Anhang F, Umgebungsvariablen.

- Geben Sie die Vorgaben für die Unix-Socketdatei und die TCP/IP-Portnummer im Abschnitt `[client]` einer Optionsdatei an. Sie können beispielsweise `C:\my.cnf` unter Windows oder `.my.cnf` in Ihrem Stammverzeichnis unter Unix verwenden. Siehe auch Abschnitt 4.3.2, „my.cnf-Optionsdateien“.

- In einem C-Programm können Sie die Socketdatei- oder Portnummerargumente im Aufruf `mysql_real_connect()` angeben. Sie können das Programm auch die Optionsdateien auslesen lassen, indem Sie `mysql_options()` aufrufen. Siehe auch Abschnitt 24.2.3, „C-API: Funktionsbeschreibungen“.

- Wenn Sie das Perl-Modul `DBD::mysql` verwenden, können Sie ebenfalls Optionen aus MySQL-Optionsdateien auslesen. Zum Beispiel:

      $dsn = "DBI:mysql:test;mysql_read_default_group=client;"
              . "mysql_read_default_file=/usr/local/mysql/data/my.cnf";
      $dbh = DBI->connect($dsn, $user, $password);

  Siehe auch Abschnitt 24.4, „MySQLs Perl-API“.

  Andere Programmierschnittstellen bieten unter Umständen ähnliche Funktionalitäten zum Auslesen von Optionsdateien.

## 5.14. MySQL-Anfragen-Cache

Der Abfrage-Cache speichert den Text einer `SELECT`-Anweisung gemeinsam mit dem zugehörigen Ergebnis, das an den Client gesendet wurde. Wenn später eine identische Anweisung empfangen wird, ruft der Server die Ergebnisse aus dem Abfrage-Cache ab, statt die Anweisung erneut zu verarbeiten und auszuführen.

Der Abfrage-Cache ist extrem nützlich in Umgebungen, in denen sich Tabellen nicht besonders häufig ändern und der Server häufig identische Abfragen empfängt. Dies ist eine typische Situation insbesondere für Webserver, die basierend auf den Datenbankinhalten viele dynamische Seiten erzeugen.

Hinweis: Der Abfrage-Cache gibt keine veralteten Daten zurück. Wenn Tabellen modifiziert werden, werden alle entsprechenden Einträge im Abfrage-Cache synchronisiert.

Hinweis: Der Abfrage-Cache funktioniert nicht in Umgebungen, in denen mehrere mysqld-Server dieselben `MyISAM`-Tabellen aktualisieren.

Hinweis: Der Abfrage-Cache wird nicht bei serverseitig vorbereiteten Anweisungen benutzt. Wenn Sie serverseitig vorbereitete Anweisungen verwenden, müssen Sie berücksichtigen, dass diese Anweisungen nicht vom Abfrage-Cache profitieren. Siehe auch Abschnitt 24.2.4, „C-API: Prepared Statements“.

An dieser Stelle folgen ein paar Leistungsdaten für den Abfrage-Cache. Diese Ergebnisse wurden erzeugt, indem die MySQL-Benchmarks auf einem Linux-Alpha-System mit 2 × 500 MHz, 2 Gbyte RAM und einem Abfrage-Cache von 64 Mbyte ausgeführt wurden.

- Wenn alle von Ihnen durchgeführten Abfragen einfacher Natur sind (z. B. das Auswählen eines Datensatzes aus einer Tabelle mit nur einem Datensatz), aber sich noch voneinander unterscheiden, sodass die Abfragen nicht im Cache abgelegt werden können, dann liegt die Mehrbelastung bei Nutzung eines aktiven Abfrage-Caches bei 13 Prozent. Dies sollte als ungünstigster Fall betrachtet werden. In der Praxis neigen Abfragen dazu, wesentlich komplizierter zu sein, d. h. die Mehrbelastung ist in der Regel deutlich niedriger.

- Suchvorgänge nach einem einzelnen Datensatz in einer Tabelle mit nur einem Datensatz sind mit Abfrage-Cache um 238 Prozent schneller als ohne. Dieser Wert kann annähernd als zu erwartende Mindestbeschleunigung für im Cache abgelegte Abfragen betrachtet werden.

Um den Abfrage-Cache beim Serverstart zu deaktivieren, setzen Sie die Systemvariable `query_cache_size` auf 0. Durch Deaktivierung des Codes für den Abfrage-Cache erhalten Sie keine merkliche Mehrbelastung. Wenn Sie MySQL aus der Quelldistribution erstellen, lässt sich die Abfrage-Cachefunktionalität auf dem Server vollständig abschalten, indem Sie configure mit der Option `--without-query-cache` aufrufen.

### 5.14.1. Wie der Anfragen-Cache funktioniert

Dieser Abschnitt beschreibt, wie der Abfrage-Cache funktioniert, wenn er betriebsbereit ist. Abschnitt 5.14.3, „Konfiguration des Anfragen-Cache“, erläutert, wie Sie ermitteln können, ob die Betriebsbereitschaft gegeben ist.

Eingehende Abfragen werden vor Ihrer Verarbeitung mit denen im Abfrage-Cache verglichen; die folgenden beiden Abfragen werden also aus der Sicht des Abfrage-Caches als unterschiedlich betrachtet:

    SELECT * FROM tbl_name
    Select * from tbl_name

Abfragen müssen absolut (das heißt bytegenau) gleich sein, damit sie als identisch gelten. Außerdem können Abfrage-Strings, die identisch sind, auch aus anderen Gründen wie unterschiedliche Abfragen behandelt werden. Abfragen, die verschiedene Datenbanken, Protokollversionen oder Standardzeichensätze verwenden, gelten als unterschiedliche Abfragen und werden separate im Cache abgelegt.

Bevor ein Abfrageergebnis aus dem Abfrage-Cache abgerufen wird, prüft MySQL, ob der Benutzer die Berechtigung `SELECT` für alle betreffenden Datenbanken und Tabellen hat. Ist dies nicht der Fall, dann wird das Ergebnis im Cache nicht verwendet.

Wird ein Abfrageergebnis aus dem Abfrage-Cache zurückgegeben, dann zählt der Server die Statusvariable `Qcache_hits` hoch, nicht aber `Com_select`. Siehe auch Abschnitt 5.14.4, „Anfragen-Cache-Status und -Wartung“.

Wenn eine Tabelle geändert wird, werden alle Abfragen, die die Tabelle verwenden, ungültig und insofern aus dem Cache entfernt. Dies betrifft auch Abfragen, die `MERGE`-Tabellen verwenden, welche die geänderte Tabelle abbilden. Eine Tabelle kann von vielen Anweisungstypen geändert werden, so etwa `INSERT`, `UPDATE`, `DELETE`, `TRUNCATE`, `ALTER TABLE`, `DROP TABLE` oder `DROP DATABASE`.

Transaktionssichere `InnoDB`-Tabellen, die geändert wurden, werden ungültig, wenn eine `COMMIT`-Anweisung ausgeführt wird.

Der Abfrage-Cache funktioniert auch innerhalb von Transaktionen, wenn Sie `InnoDB`-Tabellen verwenden, denn anhand der Tabellenversionsnummer bestimmt er, ob seine Inhalte nach wie vor gültig sind.

In MySQL 5.1 werden Abfragen, die von Views erstellt werden, im Cache abgelegt.

Der Abfrage-Cache funktioniert bei Abfragen der Typen `SELECT SQL_CALC_FOUND_ROWS ...` und `SELECT FOUND_ROWS()`. `FOUND_ROWS()` gibt den korrekten Wert auch dann zurück, wenn die vorherige Abfragen aus dem Cache geholt wurde, da die Anzahl der gefundenen Datensätze ebenfalls im Cache abgelegt ist.

Eine Abfrage landet nicht im Abfrage-Cache, wenn sie eine der Funktionen enthält, die in der folgenden Tabellen aufgeführt sind.

`BENCHMARK()` | `CONNECTION_ID()` | `CURDATE()`
`CURRENT_DATE()` | `CURRENT_TIME()` | `CURRENT_TIMESTAMP()`
`CURTIME()` | `DATABASE()` | `ENCRYPT()` mit genau einem Parameter
`FOUND_ROWS()` | `GET_LOCK()` | `LAST_INSERT_ID()`
`LOAD_FILE()` | `MASTER_POS_WAIT()` | `NOW()`
`RAND()` | `RELEASE_LOCK()` | `SYSDATE()`
`UNIX_TIMESTAMP()` ohne Parameter | `USER()` |

Auch unter den folgenden Bedingungen wird eine Abfrage nicht im Abfrage-Cache gespeichert:

- Sie verweist auf benutzerdefinierte Funktionen (UDFs).

- Sie verweist auf Benutzervariablen.

- Sie verweist auf Tabellen in der `mysql`-Systemdatenbank.

- Sie hat eine der folgenden Formen:

      SELECT ... IN SHARE MODE
      SELECT ... FOR UPDATE
      SELECT ... INTO OUTFILE ...
      SELECT ... INTO DUMPFILE ...
      SELECT * FROM ... WHERE autoincrement_col IS NULL

  Die letzte Form wird nicht gespeichert, weil Sie als ODBC-Workaround zur Ermittlung des letzten Einfügekennungswertes eingesetzt wird. Siehe auch Abschnitt 25.1.6.1.1, „Abruf von Auto-Increment-Werten“.

- Sie wurde als vorbereitete Anweisung abgesetzt, auch wenn keine Platzhalter verwendet wurden. So wird etwa folgende Abfrage nicht im Cache gespeichert:

      char *my_sql_stmt = "SELECT a, b FROM table_c";
      /* ... */
      mysql_stmt_prepare(stmt, my_sql_stmt, strlen(my_sql_stmt));

  Siehe auch Abschnitt 24.2.4, „C-API: Prepared Statements“.

- Sie verwendet `TEMPORARY`-Tabellen.

- Sie verwendet überhaupt keine Tabellen.

- Der Benutzer hat eine Berechtigung auf Spaltenebene für eine der betreffenden Tabellen.

### 5.14.2. Anfragen-Cache-Optionen in `SELECT`

In `SELECT`-Anweisungen können zwei für den Abfrage-Cache spezifische Optionen angegeben werden:

- `SQL_CACHE`

  Das Abfrageergebnis wird im Abfrage-Cache gespeichert, wenn der Wert der Systemvariable `query_cache_type` `ON` oder `DEMAND` ist.

- `SQL_NO_CACHE`

  Das Abfrageergebnis wird nicht im Cache gespeichert.

Ein paar Beispiele:

    SELECT SQL_CACHE id, name FROM customer;
    SELECT SQL_NO_CACHE id, name FROM customer;

### 5.14.3. Konfiguration des Anfragen-Cache

Die Serversystemvariable `have_query_cache` gibt an, ob der Abfrage-Cache verfügbar ist:

    mysql> SHOW VARIABLES LIKE 'have_query_cache';
    +------------------+-------+
    | Variable_name    | Value |
    +------------------+-------+
    | have_query_cache | YES   |
    +------------------+-------+

Wenn Sie eine MySQL-Standardbinärdatei verwenden, ist der Wert immer `YES` – und zwar auch dann, wenn die Zwischenspeicherung von Abfragen deaktiviert ist.

Mehrere andere Systemvariablen steuern den Betrieb des Abfrage-Caches. Diese können in einer Optionsdatei oder über die Befehlszeile beim Start von mysqld angegeben werden. Die Namen aller Systemvariablen für den Abfrage-Cache beginnen stets mit `query_cache_`. Sie sind in Abschnitt 5.2.2, „Server-Systemvariablen“, kurz beschrieben. An dieser Stelle sollen zusätzliche Konfigurationsinformationen erläutert werden.

Die Größe des Abfrage-Caches stellen Sie mit der Systemvariable `query_cache_size` ein. Die Einstellung 0 deaktiviert den Abfrage-Cache. Standardwert ist 0, d. h. der Abfrage-Cache ist vorgabeseitig deaktiviert.

Wenn Sie `query_cache_size` auf einen Wert ungleich Null setzen, beachten Sie, dass der Abfrage-Cache eine Mindestgröße von ca. 40 Kbyte benötigt, um seine Strukturen zuzuweisen. (Der exakte Wert hängt von der Systemarchitektur ab.) Wenn Sie den Wert zu niedrig ansetzen, erhalten Sie eine Warnung wie im folgenden Beispiel:

    mysql> SET GLOBAL query_cache_size = 40000;
    Query OK, 0 rows affected, 1 warning (0.00 sec)

    mysql> SHOW WARNINGS\G
    *************************** 1. row ***************************
      Level: Warning
       Code: 1282
    Message: Query cache failed to set size 39936; new query cache size is 0

    mysql> SET GLOBAL query_cache_size = 41984;
    Query OK, 0 rows affected (0.00 sec)

    mysql> SHOW VARIABLES LIKE 'query_cache_size';
    +------------------+-------+
    | Variable_name    | Value |
    +------------------+-------+
    | query_cache_size | 41984 |
    +------------------+-------+

Ist die Größe des Abfrage-Caches größer als 0, dann beeinflusst die Variable `query_cache_type` die Wirkungsweise. Die Variable kann auf die folgenden Werte gesetzt werden:

- Der Wert `0` oder `OFF` verhindert das Speichern von Abfragen im und das Abrufen aus dem Cache.

- Der Wert `1` oder `ON` gestattet das Speichern von Abfragen im Cache. Ausgenommen sind Anweisungen, die mit `SELECT SQL_NO_CACHE` beginnen.

- Der Wert `2` oder `DEMAND` speichert nur diejenigen Anweisungen im Cache, die mit `SELECT SQL_CACHE` beginnen.

Die Einstellung des `GLOBAL`-Wertes `query_cache_type` bestimmt das Verhalten des Abfrage-Caches für alle Clients, die nach Durchführung der Änderung eine Verbindung herstellen. Einzelne Clients können das Verhalten des Caches bezüglich ihrer eigenen Verbindung steuern, indem Sie den `SESSION`-Wert `query_cache_type` einstellen. So kann ein Client beispielsweise die Verwendung des Abfrage-Caches für eigene Abfragen wie folgt deaktivieren:

    mysql> SET SESSION query_cache_type = OFF;

Um die maximale Größe einzelner Abfrageergebnisse zu steuern, die im Cache gespeichert werden können, stellen Sie die Systemvariable `query_cache_limit` ein. Der Vorgabewert ist 1 Mbyte.

Wenn eine Abfrage im Cache abgelegt werden soll, wird ihr Ergebnis (d. h. die Daten, die an den Client gesendet werden) während des Abrufens des Ergebnisses im Abfrage-Cache abgelegt. Dies bedeutet, dass die Daten nicht am Stück verwaltet werden. Der Abfrage-Cache reserviert Blöcke zur Speicherung dieser Daten nach Bedarf, d. h. wenn ein Block voll ist, wird der nächste zugewiesen. Da der Speicherreservierungsvorgang (in zeitlicher Hinsicht) aufwändig ist, reserviert der Abfrage-Cache die Blöcke mit einer Mindestgröße, die durch die Systemvariable `query_cache_min_res_unit` festgelegt wird. Wird eine Abfrage ausgeführt, dann wird der letzte Ergebnisblock auf die tatsächliche Datengröße zugeschnitten, sodass unbenutzter Speicher freigegeben wird. Je nach Typ der von Ihrem Server ausgeführten Abfragen kann es für Sie hilfreich sein, den Wert von `query_cache_min_res_unit` zu optimieren:

- Der Vorgabewert von `query_cache_min_res_unit` beträgt 4 Kbyte. Dies sollte für die meisten Fälle ausreichend sein.

- Wenn Sie viele Abfragen mit kleinen Ergebnissen haben, kann die standardmäßige Blockgröße zur Speicherfragmentierung führen, wie durch eine große Anzahl freier Blöcke zu erkennen ist. Die Fragmentierung wiederum kann das Entfernen (Löschen) von Abfragen aus dem Abfragen aufgrund von Speichermangel erforderlich machen. In diesem Fall sollten Sie den Wert von `query_cache_min_res_unit` verringern. Die Anzahl freier Blöcke und entfernter Abfragen wird durch die Werte der Statusvariablen `Qcache_free_blocks` bzw. `Qcache_lowmem_prunes` angegeben.

- Weist die Mehrzahl Ihrer Abfragen hingegen große Ergebnisse auf (dies können Sie mit den Statusvariablen `Qcache_total_blocks` und `Qcache_queries_in_cache` überprüfen), dann können sie die Leistung steigern, indem Sie `query_cache_min_res_unit` erhöhen. Allerdings sollten Sie den Wert nicht zu groß wählen (siehe obige Beschreibung).

### 5.14.4. Anfragen-Cache-Status und -Wartung

Sie können mit der folgenden Anweisung überprüfen, ob der Abfrage-Cache auf Ihrem MySQL-Server vorhanden ist:

    mysql> SHOW VARIABLES LIKE 'have_query_cache';
    +------------------+-------+
    | Variable_name    | Value |
    +------------------+-------+
    | have_query_cache | YES   |
    +------------------+-------+

Um den Abfrage-Cache zu defragmentieren und den vorhandenen Speicher so besser zu nutzen, setzen Sie die Anweisung `FLUSH QUERY CACHE` ab. Diese Anweisung entfernt keine Abfragen aus dem Cache.

Die Anweisung `RESET QUERY CACHE` entfernt alle Abfrageergebnisse aus dem Abfrage-Cache. Auch die Anweisung `FLUSH TABLES` tut dies.

Wenn Sie die Leistung des Abfrage-Caches überwachen wollen, können Sie mit `SHOW STATUS` die Statusvariablen für den Cache anzeigen:

    mysql> SHOW STATUS LIKE 'Qcache%';
    +-------------------------+--------+
    | Variable_name           | Value  |
    +-------------------------+--------+
    | Qcache_free_blocks      | 36     |
    | Qcache_free_memory      | 138488 |
    | Qcache_hits             | 79570  |
    | Qcache_inserts          | 27087  |
    | Qcache_lowmem_prunes    | 3114   |
    | Qcache_not_cached       | 22989  |
    | Qcache_queries_in_cache | 415    |
    | Qcache_total_blocks     | 912    |
    +-------------------------+--------+

Beschreibungen dieser Variablen finden Sie in Abschnitt 5.2.4, „Server-Statusvariablen“. An dieser Stelle wollen wir einige Anwendungsmöglichkeiten für sie beschreiben.

Die Gesamtzahl der `SELECT`-Anweisungen berechnen Sie mit folgender Formel:

      Com_select
    + Qcache_hits
    + queries with errors found by parser

Den Wert `Com_select` erhalten Sie über folgende Formel:

      Qcache_inserts
    + Qcache_not_cached
    + queries with errors found during the column-privileges check

Der Abfrage-Cache verwendet Blöcke variabler Länge, d. h. `Qcache_total_blocks` und `Qcache_free_blocks` lassen Rückschlüsse auf die Speicherfragmentierung des Abfrage-Caches zu. Nach Absetzen von `FLUSH QUERY CACHE` bleibt nur ein einziger freie Block übrig.

Alle im Cache gespeicherten Abfragen benötigen mindestens zwei Blöcke (einen für den Abfragetext und einen weiteren für die Ergebnisse). Ferner benötigt jede Tabelle, die von einer Abfrage verwendet wird, einen Block. Wenn jedoch zwei oder mehr Abfragen dieselbe Tabelle verwenden, muss nur ein Tabellenblock reserviert werden.

Mithilfe der in der Statusvariable `Qcache_lowmem_prunes` gespeicherten Information können Sie die Größe des Abfrage-Cache optimieren. Diese Variable zählt die Anzahl der Abfragen, die aus dem Cache entfernt wurden, um Speicherplatz für die Aufnahme neuer Abfragen zu schaffen. Der Abfrage-Cache entscheidet auf der Basis der zuletzt verwendeten Abfragen, welche Abfragen aus dem Cache entfernt werden können. Hinweise zur Optimierung finden Sie in Abschnitt 5.14.3, „Konfiguration des Anfragen-Cache“.

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.

Zurück |  | Weiter
Kapitel 4. Benutzung von MySQL-Programmen | Zum Anfang | Kapitel 6. Replikation bei MySQL