MySQL 5.1 Reference Manual (Online Help)

Copyright © 1997, 2010, Oracle and/or its affiliates. All rights reserved.

This software and related documentation are provided under a license agreement containing restrictions on use and disclosure and are protected by intellectual property laws. Except as expressly permitted in your license agreement or allowed by law, you may not use, copy, reproduce, translate, broadcast, modify, license, transmit, distribute, exhibit, perform, publish, or display any part, in any form, or by any means. Reverse engineering, disassembly, or decompilation of this software, unless required by law for interoperability, is prohibited.

The information contained herein is subject to change without notice and is not warranted to be error-free. If you find any errors, please report them to us in writing.

Wird diese Software oder zugehörige Dokumentation an die Regierung der Vereinigten Staaten von Amerika bzw. einen Lizenznehmer im Auftrag der Regierung der Vereinigten Staaten von Amerika geliefert, gilt Folgendes:

U.S. GOVERNMENT RIGHTS Programs, software, databases, and related documentation and technical data delivered to U.S. Government customers are "commercial computer software" or "commercial technical data" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations. As such, the use, duplication, disclosure, modification, and adaptation shall be subject to the restrictions and license terms set forth in the applicable Government contract, and, to the extent applicable by the terms of the Government contract, the additional rights set forth in FAR 52.227-19, Commercial Computer Software License (December 2007). Oracle USA, Inc., 500 Oracle Parkway, Redwood City, CA 94065.

This software is developed for general use in a variety of information management applications. It is not developed or intended for use in any inherently dangerous applications, including applications which may create a risk of personal injury. If you use this software in dangerous applications, then you shall be responsible to take all appropriate fail-safe, backup, redundancy, and other measures to ensure the safe use of this software. Oracle Corporation and its affiliates disclaim any liability for any damages caused by use of this software in dangerous applications.

Oracle is a registered trademark of Oracle Corporation and/or its affiliates. MySQL is a trademark of Oracle Corporation and/or its affiliates, and shall not be used without Oracle's express written authorization. Other names may be trademarks of their respective owners.

This software and documentation may provide access to or information on content, products, and services from third parties. Oracle Corporation and its affiliates are not responsible for and expressly disclaim all warranties of any kind with respect to third-party content, products, and services. Oracle Corporation and its affiliates will not be responsible for any loss, costs, or damages incurred due to your access to or use of third-party content, products, or services.

This document in any form, software or printed matter, contains proprietary information that is the exclusive property of Oracle. Your access to and use of this material is subject to the terms and conditions of your Oracle Software License and Service Agreement, which has been executed and with which you agree to comply. This document and information contained herein may not be disclosed, copied, reproduced, or distributed to anyone outside Oracle without prior written consent of Oracle or as specifically provided below. This document is not part of your license agreement nor can it be incorporated into any contractual agreement with Oracle or its subsidiaries or affiliates.

This documentation is NOT distributed under a GPL license. Use of this documentation is subject to the following terms:

You may create a printed copy of this documentation solely for your own personal use. Conversion to other formats is allowed as long as the actual content is not altered or edited in any way. You shall not publish or distribute this documentation in any form or on any media, except if you distribute the documentation in a manner similar to how Oracle disseminates it (that is, electronically for download on a Web site with the software) or on a CD-ROM or similar medium, provided however that the documentation is disseminated together with the software on the same medium. Any other use, such as any dissemination of printed copies or use of this documentation, in whole or in part, in another publication, requires the prior written consent from an authorized representative of Oracle. Oracle and/or its affiliates reserve any and all rights to this documentation not expressly granted above.

For more information on the terms of this license, for details on how the MySQL documentation is built and produced, or if you are interested in doing a translation, please visit MySQL Contact & Questions.

For additional licensing information, including licenses for libraries used by MySQL products, see Preface and Notes.

If you want help with using MySQL, please visit either the MySQL Forums or MySQL Mailing Lists where you can discuss your issues with other MySQL users.

For additional documentation on MySQL products, including translations of the documentation into other languages, and downloadable versions in variety of formats, including HTML and PDF formats, see the MySQL Documentation Library.

Zusammenfassung

This manual describes features that are not included in every edition of MySQL 5.1; such features may not be included in the edition of MySQL 5.1 licensed to you. If you have any questions about the features included in your edition of MySQL 5.1, refer to your MySQL 5.1 license agreement or contact your Oracle sales representative.

Document generated on: 2010-11-12 (revision: 36)


Inhaltsverzeichnis

1. Tutorial
1.1. Herstellen und Trennen einer Verbindung mit dem Server
1.2. Eingeben von Abfragen
1.3. Einrichten und Verwenden einer Datenbank
1.3.1. Einrichten und Auswählen einer Datenbank
1.3.2. Einrichten einer Tabelle
1.3.3. Laden von Daten in eine Tabelle
1.3.4. Abrufen von Informationen aus einer Tabelle
1.4. Abrufen von Informationen über Datenbanken und Tabellen
1.5. Verwenden von mysql im Stapelmodus
1.6. Beispiele für übliche Abfragen
1.6.1. Der Maximalwert für eine Spalte
1.6.2. Die das Maximum einer bestimmten Spalte enthaltende Zeile
1.6.3. Maximum der Spalte pro Gruppe
1.6.4. Die das gruppenbezogene Maximum einer bestimmten Spalte enthaltende Zeile
1.6.5. Verwenden von benutzerdefinierten Variablen
1.6.6. Verwenden von Fremdschlüsseln
1.6.7. Suchen auf zwei Schlüsseln
1.6.8. Berechnen von Besuchen pro Tag
1.6.9. Verwenden von AUTO_INCREMENT
1.7. Abfragen aus dem Twin-Projekt
1.7.1. Ermitteln aller nicht verteilten Zwillinge
1.7.2. Anzeigen einer Tabelle mit dem Zwillingspaar-Status
1.8. Verwenden von MySQL mit Apache
2. Installieren und Aktualisieren von MySQL
2.1. Allgemeines zur Installation
2.1.1. Betriebssysteme, die von MySQL Community Server unterstützt werden
2.1.2. Auswählen der MySQL-Distribution für die Installation
2.1.3. Wo können Sie MySQL beziehen?
2.1.4. Bestätigen der Paketintegrität mittels MD5-Prüfsummen oder GnuPG
2.1.5. Installationslayout
2.2. MySQL-Standardinstallation mithilfe einer Binärdistribution
2.3. Installieren von MySQL unter Windows
2.3.1. Wählen eines Installationspakets
2.3.2. Installieren von MySQL mit dem automatischen Installer
2.3.3. Verwenden des MySQL-Installations-Assistenten
2.3.4. MySQL Server-Konfigurations-Assistent
2.3.5. Installieren von MySQL aus einem Noinstall-Zip-Archiv
2.3.6. Entpacken des Installationsarchivs
2.3.7. Erstellen einer Optionsdatei
2.3.8. Auswählen eines MySQL Server-Typs
2.3.9. Erstmaliges Starten des Servers
2.3.10. Starten von MySQL aus der Windows-Befehlszeile
2.3.11. Starten von MySQL als Windows-Dienst
2.3.12. Testen der MySQL-Installation
2.3.13. Fehlersuche und -behebung in MySQL-Installationen unter Windows
2.3.14. Aktualisieren von MySQL unter Windows
2.3.15. MySQL unter Windows im Vergleich zu MySQL unter Unix
2.4. Installieren von MySQL aus RPM-Paketen unter Linux
2.5. Installieren von MySQL unter Mac OS X
2.6. Installieren von MySQL unter Solaris
2.7. Installieren von MySQL unter i5/OS
2.8. Installieren von MySQL auf NetWare
2.9. Installieren von MySQL aus tar.gz-Paketen auf anderen Unix-ähnlichen Systemen
2.10. MySQL-Installation mittels Quelldistribution
2.10.1. Überblick Quelleninstallation
2.10.2. Typische configure-Optionen
2.10.3. Installation vom Entwicklungs-Source-Tree
2.10.4. Probleme beim Kompilieren von MySQL
2.10.5. Anmerkungen zu MIT-pthreads
2.10.6. Installieren von MySQL unter Windows aus dem Quellcode
2.10.7. Kompilieren von MySQL-Clients unter Windows
2.11. Einstellungen und Tests nach der Installation
2.11.1. Schritte nach der Installation unter Windows
2.11.2. Schritte nach der Installation unter Unix
2.11.3. Kennwortschutz für vorgabeseitige MySQL-Konten
2.12. Aktualisieren von MySQL mittels Upgrade/Downgrade
2.12.1. Upgrade von MySQL
2.12.2. Downgrade von MySQL
2.12.3. Prüfen ob Tabellenindizes neu erstellt werden müssen
2.12.4. Reparieren und Neuerstellen von Tabellen und Indizes
2.12.5. Kopieren von MySQL-Datenbanken auf einen anderen Rechner
2.13. Betriebssystemspezifische Anmerkungen
2.13.1. Anmerkungen zu Linux
2.13.2. Anmerkungen zu Mac OS X
2.13.3. Anmerkungen zu Solaris
2.13.4. Anmerkungen zu BSD
2.13.5. Anmerkungen zu anderen unixartigen Systemen
2.14. Umgebungsvariablen
2.15. Anmerkungen zur Perl-Installation
2.15.1. Installieren von Perl unter Unix
2.15.2. Installieren von ActiveState Perl unter Windows
2.15.3. Probleme bei der Benutzung der DBI/DBD-Schnittstelle von Perl
3. MySQL-Client-Programme
3.1. mysql — Das MySQL Command-Line Tool
3.1.1. mysql Optionen
3.1.2. mysql-Befehle
3.1.3. Serverseitige mysql-Hilfe
3.1.4. Ausführen von SQL-Anweisungen aus einer Textdatei
3.1.5. mysql-Tipps
3.2. mysqladmin — Client zum Verwalten eines MySQL-Servers
3.3. mysqlcheck — ein Tabellenwartungsprogramm
3.4. mysqldump — ein Datenbanksicherungsprogramm
3.5. mysqlcheck — ein Datenimportprogramm
3.6. mysqlshow — Anzeigen von Datenbank-, Tabellen- und Spalteninformationen
3.7. mysqlslap — Lastemulations-Client
4. Optimierung
4.1. Optimierungsübersicht
4.1.1. MySQL-Design-Beschränkungen und Kompromisse
4.1.2. Programme für Portabilität auslegen
4.1.3. Wofür wir MySQL verwendet haben
4.1.4. Die MySQL-Benchmark-Suite
4.1.5. Ihre eigenen Benchmarks verwenden
4.2. SELECT und andere Anweisungen optimieren
4.2.1. Abfragen mit EXPLAIN optimieren
4.2.2. Abschätzen der Abfrageleistung
4.2.3. Geschwindigkeit von SELECT-Abfragen
4.2.4. WHERE-Klausel-Optimierung
4.2.5. Bereichsoptimierung
4.2.6. Index-Merge-Optimierung
4.2.7. Condition Pushdown-Optimierung
4.2.8. IS NULL-Optimierung
4.2.9. LEFT-JOIN- und RIGHT-JOIN-Optimierung
4.2.10. Nested-Loop Join-Algorithmen
4.2.11. Nested Join-Optimierung
4.2.12. Vereinfachung des äußeren Join
4.2.13. ORDER BY-Optimierung
4.2.14. GROUP BY-Optimierung
4.2.15. DISTINCT-Optimierung
4.2.16. Optimieren der IN/=ANY-Unterabfragen
4.2.17. LIMIT-Optimierung
4.2.18. Den Optimierer mit optimizer_switch steuern
4.2.19. So vermeiden Sie Tabellenscans
4.2.20. INFORMATION_SCHEMA-Optimierung
4.2.21. Geschwindigkeit von INSERT-Anweisungen
4.2.22. Geschwindigkeit von UPDATE-Anweisungen
4.2.23. Geschwindigkeit von DELETE-Anweisungen
4.2.24. Weitere Optimierungstipps
4.3. Sperrprobleme
4.3.1. Interne Sperrmethoden
4.3.2. Tabellensperrprobleme
4.3.3. Gleichzeitige Einfügeoperationen
4.3.4. Externe Sperren
4.4. Optimieren der Datenbank-Struktur
4.4.1. Machen Sie Ihre Daten so klein wie möglich
4.4.2. Spaltenindizes
4.4.3. Mehrfachspaltenindizes
4.4.4. So verwendet MySQL Indizes
4.4.5. Der MyISAM-Schlüsselcache
4.4.6. MyISAM-Indexstatistiksammlung
4.4.7. So öffnet und schließt MySQL Tabellen
4.4.8. Nachteile durch das Erstellen vieler Tabellen in der gleichen Datenbank
4.5. Optimieren des MySQL-Servers
4.5.1. So wirken sich Kompilieren und Verknüpfen auf die Geschwindigkeit von MySQL aus
4.5.2. Systemfaktoren und Startup-Parameter-Tuning
4.5.3. Tuning der Server-Parameter
4.5.4. Steuern der Abfrageoptimiererleistung
4.5.5. Der MySQL-Abfragen-Cache
4.5.6. Prüfen der Thread-Informationen
4.5.7. So verwendet MySQL Threads für Clientverbindungen
4.5.8. So verwendet MySQL Speicher
4.5.9. Aktivierung der Unterstützung großer Seiten
4.5.10. So verwendet MySQL interne temporäre Tabellen
4.5.11. So verwendet MySQL DNS
4.6. Festplattenprobleme
4.6.1. Symbolische Verknüpfungen
5. Sprachstruktur
5.1. Literalwerte
5.1.1. Strings
5.1.2. Zahlen
5.1.3. Hexadezimalwerte
5.1.4. Boolesche Werte
5.1.5. Bit-Feldwerte
5.1.6. NULL-Werte
5.2. Schema-Objektnamen
5.2.1. Bezeichner-Kennzeichner
5.2.2. Beachtung der Groß-/Kleinschreibung bei Bezeichnern
5.2.3. Abbilden von Bezeichnern auf Dateinamen
5.2.4. Funktionsnamensanalyse und Auflösung
5.3. Reservierte Wörter
5.4. Benutzerdefinierte Variablen
5.5. Kommentarsyntax
6. Datentypen
6.1. Datentypenübersicht
6.1.1. Übersicht über numerische Typen
6.1.2. Übersicht über Datums- und Zeittypen
6.1.3. Übersicht über String-Typen
6.1.4. Datentyp-Standardwerte
6.2. Numerische Typen
6.3. Datum- und Zeittypen
6.3.1. Die Typen DATETIME, DATE und TIMESTAMP
6.3.2. Der TIME-Typ
6.3.3. Der YEAR-Typ
6.3.4. Jahr-2000-Probleme und Datumstypen
6.4. String-Typen
6.4.1. Die Typen CHAR und VARCHAR
6.4.2. Die Typen BINARY und VARBINARY
6.4.3. Die Typen BLOB und TEXT
6.4.4. Der ENUM-Typ
6.4.5. Der SET-Typ
6.5. Datentyp-Speicheranforderungen
6.6. Auswählen des richtigen Typs für eine Spalte
6.7. Verwenden von Datentypen aus anderen Datenbank-Engines
7. Funktionen und Operatoren
7.1. Operatoren und Funktionen
7.2. Operatoren
7.2.1. Rangfolge von Operatoren
7.2.2. Typumwandlung bei der Auswertung von Ausdrücken
7.2.3. Vergleichsfunktionen und -operatoren
7.2.4. Logische Operatoren
7.3. Ablaufsteuerungsfunktionen
7.4. String-Funktionen
7.4.1. String-Vergleichsfunktionen
7.4.2. Reguläre Ausdrücke
7.5. Numerische Funktionen
7.5.1. Arithmetische Operatoren
7.5.2. Mathematische Funktionen
7.6. Datums- und Zeitfunktionen
7.7. Welchen Kalender benutzt MySQL?
7.8. Volltextsuchfunktionen
7.8.1. Natursprachliche Volltextsuche
7.8.2. Boolesche Volltextsuchen
7.8.3. Volltextsuche mit Abfragenerweiterung
7.8.4. Stoppwörter in der Volltextsuche
7.8.5. Beschränkungen der Volltextsuche
7.8.6. Feineinstellen der MySQL-Volltextsuche
7.9. CAST-Funktionen und Operatoren
7.10. XML-Funktionen
7.11. Weitere Funktionen
7.11.1. Bitfunktionen
7.11.2. Verschlüsselungs- und Komprimierungsfunktionen
7.11.3. Informationsfunktionen
7.11.4. Sonstige Funktionen
7.12. Funktionen und Modifizierer für die Verwendung mit GROUP BY-Klauseln
7.12.1. GROUP BY-Funktionen (Zusammenfassungsfunktionen)
7.12.2. GROUP BY-Modifizierer
7.12.3. GROUP BY und HAVING mit verborgenen Spalten
7.13. Raumbezogene Erweiterungen
7.13.1. Einführung in raumbezogenen Funktionen von MySQL
7.13.2. Das OpenGIS-Geometriemodell
7.13.3. Unterstützte raumbezogene Datenformate
7.13.4. Erzeugen einer MySQL-Datenbank mit raumbezogenen Werten
7.13.5. Analysieren von raumbezogenen Informationen
7.13.6. Optimieren der raumbezogenen Analyse
7.13.7. MySQL-Konformität und Kompatibilität
7.14. Präzisionsberechnungen
7.14.1. Typen numerischer Werte
7.14.2. Änderungen beim Datentyp DECIMAL
7.14.3. Behandlung von Ausdrücken
7.14.4. Rundungsverhalten
7.14.5. Beispiele für Präzisionsberechnungen
8. SQL-Anweisungssyntax
8.1. Datendefinitionsanweisungen
8.1.1. ALTER DATABASE
8.1.2. ALTER EVENT-Syntax
8.1.3. ALTER LOGFILE GROUP-Syntax
8.1.4. ALTER FUNCTION-Syntax
8.1.5. ALTER PROCEDURE-Syntax
8.1.6. ALTER SERVER-Syntax
8.1.7. ALTER TABLE-Syntax
8.1.8. ALTER TABLESPACE-Syntax
8.1.9. ALTER VIEW-Syntax
8.1.10. CREATE DATABASE
8.1.11. CREATE EVENT-Syntax
8.1.12. CREATE FUNCTION-Syntax
8.1.13. CREATE INDEX
8.1.14. CREATE LOGFILE GROUP-Syntax
8.1.15. CREATE PROCEDURE und CREATE FUNCTION
8.1.16. CREATE SERVER-Syntax
8.1.17. CREATE TABLE
8.1.18. CREATE TABLESPACE-Syntax
8.1.19. CREATE TRIGGER-Syntax
8.1.20. CREATE VIEW-Syntax
8.1.21. DROP DATABASE
8.1.22. DROP EVENT-Syntax
8.1.23. DROP FUNCTION-Syntax
8.1.24. DROP INDEX
8.1.25. DROP LOGFILE GROUP-Syntax
8.1.26. DROP PROCEDURE- und DROP FUNCTION-Syntax
8.1.27. DROP SERVER-Syntax
8.1.28. DROP TABLE
8.1.29. DROP TABLESPACE-Syntax
8.1.30. DROP TRIGGER-Syntax
8.1.31. DROP VIEW-Syntax
8.1.32. RENAME DATABASE-Syntax
8.1.33. RENAME TABLE
8.2. Datenbearbeitungsanweisungen
8.2.1. CALL-Syntax
8.2.2. DELETE
8.2.3. DO
8.2.4. HANDLER
8.2.5. INSERT
8.2.6. LOAD DATA INFILE
8.2.7. REPLACE
8.2.8. SELECT
8.2.9. Syntax von Unterabfragen
8.2.10. TRUNCATE-Syntax
8.2.11. UPDATE-Syntax
8.3. Grundlegende Befehle des MySQL-Dienstprogramms für Benutzer
8.3.1. DESCRIBE (Informationen über Spalten abrufen)
8.3.2. EXPLAIN-Syntax
8.3.3. HELP-Syntax
8.3.4. USE
8.4. Transaktionale und Sperrbefehle von MySQL
8.4.1. START TRANSACTION, COMMIT, and ROLLBACK Syntax
8.4.2. Statements, die nicht zurückgerollt werden können
8.4.3. Anweisungen, die implizite Commits verursachen
8.4.4. SAVEPOINT und ROLLBACK TO SAVEPOINT
8.4.5. LOCK TABLES und UNLOCK TABLES
8.4.6. SET TRANSACTION
8.4.7. XA-Transaktionen
8.5. Anweisungen zur Datenbankadministration
8.5.1. Anweisungen zur Benutzerkontenverwaltung
8.5.2. Anweisungen für die Tabellenwartung
8.5.3. Plug-In und benutzerdefinierte Funktionsanweisungen
8.5.4. SET-Syntax
8.5.5. SHOW-Syntax
8.5.6. Weitere Verwaltungsanweisungen
8.6. Replikationsanweisungen
8.6.1. SQL-Anweisungen für die Steuerung von Master-Servern
8.6.2. SQL-Anweisungen für die Steuerung von Slave-Servern
8.7. SQL-Syntax für vorbereitete Anweisungen
8.7.1. PREPARE-Syntax
8.7.2. EXECUTE-Syntax
8.7.3. DEALLOCATE PREPARE-Syntax
8.7.4. Automatische Wiedervorbereitung vorbereiteter Anweisungen
8.8. MySQL-Verbundanweisungssyntax
8.8.1. BEGIN ... END-Verbundanweisungs-Syntax
8.8.2. DECLARE-Syntax
8.8.3. Variablen in gespeicherten Programmen
8.8.4. Bedingungen und Handler
8.8.5. Cursors
8.8.6. Ablaufsteuerungskonstrukte
8.8.7. RETURN-Syntax
9. Die InnoDB-Speicher-Engine
9.1. InnoDB-Kontakt-Informationen
9.2. InnoDB-Konfiguration
9.2.1. Per-Tabelle-Tablespaces
9.2.2. Im raw-Modus betriebene Geräte für den gemeinsamen Tablespace
9.2.3. Einrichten des InnoDB-Tablespaces
9.2.4. Behandeln von InnoDB-Initialisierungs-Problemen
9.3. InnoDB-Startoptionen und Systemvariablen
9.4. Einrichten und Verwenden von InnoDB-Tabellen
9.4.1. Wie verwendet man Transaktionen in InnoDB mit unterschiedlichen APIs
9.4.2. Konvertieren von Tabellen anderer Speicher-Engines in InnoDB
9.4.3. AUTO_INCREMENT-Behandlung in InnoDB
9.4.4. FOREIGN KEY-Constraints
9.4.5. InnoDB und MySQL-Replikation
9.5. Hinzufügen, Entfernen oder Ändern der Größe von InnoDB-Daten und Logdateien
9.6. Sichern und Wiederherstellen einer InnoDB-Datenbank
9.6.1. Der InnoDB-Recovery-Prozess
9.6.2. Erzwingen der InnoDB-Recovery
9.6.3. InnoDB-Checkpoints
9.7. Verschieben einer InnoDB-Datenbank auf eine andere Maschine
9.8. Das InnoDB-Transaktionsmodell und Sperrung
9.8.1. InnoDB-Sperrungsmodi
9.8.2. Konsistente nichtsperrende Leseoperationen
9.8.3. SELECT ... FOR UPDATE und SELECT... LOCK IN SHARE MODE-Sperr-Leseoperationen
9.8.4. InnoDB-Datensatz, Blocklücke und Next-Key-Sperren
9.8.5. Vermeiden des Phantomproblems durch die Verwendung von Next-Key-Sperrungen
9.8.6. Sperrungen durch unterschiedliche SQL-Anweisungen in InnoDB
9.8.7. Implizite Transaktionscommits und Rollbacks
9.8.8. Deadlock-Erkennung und Rollback
9.8.9. Wie wird man mit Deadlocks fertig
9.9. InnoDB-Multiversionierung
9.10. InnoDB-Tabellen- und Index-Strukturen
9.10.1. Cluster- und sekundäre Indizes
9.10.2. Physikalische Struktur eines Indexes
9.10.3. Einfügeoperationspufferung
9.10.4. Adaptive Hash-Indizes
9.10.5. Physikalische Zeilenstruktur
9.11. InnoDB-Festplatten-I/O und Dateiraum-Management
9.11.1. InnoDB-Festplatten-I/O
9.11.2. Dateiraum-Management
9.11.3. Defragmentieren einer Tabelle
9.12. InnoDB-Fehlerbehandlung
9.12.1. InnoDB-Fehlerkennungen
9.12.2. Betriebssystem-Fehlerkennungen
9.13. InnoDB-Leistungs-Tuning und Fehlersuche
9.13.1. Tipps zum InnoDB-Leistungs-Tuning
9.13.2. SHOW ENGINE INNODB STATUS und die InnoDB-Monitore
9.13.3. InnoDB: Allgemeine Fehlersuche
9.13.4. Fehlersuche für InnoDB-Data Dictionary-Operationen
9.14. Beschränkungen auf InnoDB-Tabellen
10. Die MERGE-Speicher-Engine
10.1. MERGE-Tabellen-Probleme
Stichwortverzeichnis

Tabellenverzeichnis

2.1. configure-Optionen
9.1. InnoDB-Funktionen
9.2. Options- und -Variablenreferenz für mysqld InnoDB

Kapitel 1. Tutorial

Dieses Kapitel enthält eine Einführung in MySQL unter Verwendung des Client-Programms mysql. Es wird gezeigt, wie eine einfache Datenbank eingerichtet und verwendet werden kann. mysql (das manchmal auch als „Terminal-Monitor“ oder einfach als „Monitor“ bezeichnet wird) ist ein interaktives Programm, das es Ihnen erlaubt, eine Verbindung zu einem MySQL-Server herzustellen, Abfragen auszuführen und die Ergebnisse anzusehen. mysql kann auch im Stapelmodus verwendet werden: Sie ordnen im Voraus Ihre Abfragen in eine Datei ein und weisen dann mysql an, den Inhalt der Datei auszuführen. Wir werden hier beide Methoden der Verwendung von mysql behandeln.

Um eine Liste der Optionen anzuzeigen, die mysql bietet, rufen Sie es mit der Option --help auf:

shell> mysql --help

Dieses Kapitel setzt voraus, dass mysql auf Ihrem Computer installiert ist und dass ein MySQL Server verfügbar ist, mit dem Sie eine Verbindung herstellen können. Sollte dies nicht der Fall sein, dann wenden Sie sich an Ihren MySQL-Administrator. (Wenn Sie selbst der Administrator sind, lesen Sie die erforderlichen Abschnitte dieses Handbuchs, z. B. MySQL Server Administration.)

Dieses Kapitel beschreibt den gesamten Vorgang der Einrichtung und Verwendung einer Datenbank. Wenn Sie nur am Zugriff auf eine vorhandene Datenbank interessiert sind, können Sie die Abschnitte überspringen, die beschreiben, wie Datenbanken und die darin enthaltenen Tabellen erstellt werden.

Da dieses Kapitel lediglich ein Tutorial ist, werden natürlich viele Detailangaben weggelassen. Um mehr zu den hier behandelten Themen zu erfahren, lesen Sie die einschlägigen Abschnitte dieses Handbuchs.

1.1. Herstellen und Trennen einer Verbindung mit dem Server

Um eine Verbindung mit dem Server herzustellen, müssen Sie beim Aufruf von mysql normalerweise einen MySQL-Benutzernamen und in aller Regel auch ein Passwort angeben. Wird der Server auf einem anderen System als demjenigen ausgeführt, an dem Sie sich anmelden, dann müssen Sie auch einen Hostnamen angeben. Wenden Sie sich an Ihrem Administrator, um zu erfahren, welche Parameter (Host- und Benutzernamen sowie Passwort) Sie für die Verbindung angeben müssen. Wenn Sie die korrekten Anmeldeinformationen kennen, sollten Sie wie folgt eine Verbindung herstellen können:

shell> mysql -h host -u user -p
Enter password: ********

host und user stehen für den Namen des Hosts, auf dem Ihr MySQL Server ausgeführt wird, bzw. den Benutzernamen Ihres MySQL-Kontos. Ersetzen Sie die Werte wie für Ihre Konfiguration erforderlich. Hierbei steht ******** für Ihr Passwort; geben Sie dieses ein, wenn mysql die Aufforderung Enter password: anzeigt.

Funktioniert alles wie erwartet, dann werden ein paar einleitende Informationen gefolgt von der Eingabeaufforderung mysql> angezeigt:

shell> mysql -h host -u user -p
Enter password: ********
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 25338 to server version: 5.1.54-standard
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql>

Die Eingabeaufforderung mysql> zeigt an, dass mysql nun zur Entgegennahme von Befehlen bereit ist.

Wenn Sie sich an dem Computer angemeldet haben, auf dem auch MySQL ausgeführt wird, dann können Sie den Hostnamen weglassen und einfach Folgendes eingeben:

shell> mysql -u user -p

Wenn Sie beim Anmeldeversuch eine Fehlermeldung wie etwa ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)erhalten, bedeutet dies, dass der MySQL Server-Daemon (unter Unix) bzw. der MySQL Server-Dienst (unter Windows) nicht ausgeführt wird. Wenden Sie sich an den Administrator oder lesen Sie den für Ihr Betriebssystem vorgesehenen Abschnitt in Kapitel 2, Installieren und Aktualisieren von MySQL.

Hilfe bei anderen Problemen, die beim Anmelden häufig auftreten, finden Sie in Common Errors When Using MySQL Programs.

Einige MySQL-Installationen gestatten Benutzern die Herstellung einer Verbindung zum auf dem lokalen Host laufenden Server als anonymer (d. h. nicht benannter) Benutzer. Sollte dies bei Ihrem System der Fall sein, dann sollten Sie eine Verbindung herstellen können, indem Sie mysql einfach ohne weitere Optionen aufrufen:

shell> mysql

Wenn Sie erfolgreich eine Verbindung hergestellt haben, können Sie diese jederzeit trennen, indem Sie QUIT (oder einfach \q) an der Eingabeaufforderung mysql> eingeben:

mysql> QUIT
Bye

Unter Unix können Sie die Trennung auch mit der Tastenkombination Strg D durchführen.

Die meisten Beispiele in den nachfolgenden Abschnitten setzen voraus, dass Sie mit dem Server verbunden sind. Dieses wird durch die Eingabeaufforderung mysql> angezeigt.

1.2. Eingeben von Abfragen

Stellen Sie zunächst wie im vorhergehenden Abschnitt beschrieben eine Verbindung zum Server her. Durch diesen Vorgang wird noch keine Datenbank ausgewählt, was aber noch nicht problematisch ist. Wir wollen erst einmal sehen, wie man Abfragen absetzt, statt gleich mit den eigentlichen Datenbankfunktionen – dem Erstellen von Tabellen und dem Einladen von Daten in bzw. Abrufen dieser Daten aus den Tabellen – anzufangen. Dieser Abschnitt erläutert die Grundprinzipien der Befehlseingabe mithilfe verschiedener Abfragen, die Sie ausprobieren können, um sich mit der Funktionsweise von mysql vertraut zu machen.

Hier zunächst ein einfacher Befehl, der den Server bittet, seine Versionsnummer und das aktuelle Datum anzugeben. Geben Sie den Befehl wie hier gezeigt an der Eingabeaufforderung mysql> ein und betätigen Sie dann die Eingabetaste:

mysql> SELECT VERSION(), CURRENT_DATE;
+-----------------+--------------+
| VERSION()       | CURRENT_DATE |
+-----------------+--------------+
| 5.1.2-alpha-log | 2005-10-11   |
+-----------------+--------------+
1 row in set (0.01 sec)
mysql>

Diese Abfrage veranschaulicht mehrere Aspekte von mysql:

  • Ein Befehl besteht normalerweise aus einer SQL-Anweisung gefolgt von einem Semikolon. (Es gibt eine Reihe von Ausnahmen, bei denen das Semikolon weggelassen werden kann. QUIT, wie bereits erwähnt, ist eine von ihnen. Wir werden später zu anderen gelangen.)

  • Wenn Sie einen Befehl absetzen, sendet mysql ihn zur Ausführung an den Server und zeigt die Ergebnisse an. Darauf folgt wieder eine neue Eingabeaufforderung mysql>, mit der angezeigt wird, dass nun ein neuer Befehl eingegeben werden kann.

  • mysql zeigt die Abfrageausgabe in Tabellenform (d. h. als Zeilen und Spalten) an. Die erste Zeile enthält die Spaltenüberschriften. Alle nachfolgenden Zeilen sind Abfrageergebnisse. Normalerweise sind Spaltenüberschriften die Namen der Spalten, die aus den Datenbanktabellen abgerufen werden. Wenn Sie den Wert eines Ausdrucks statt einer Tabellenspalte (wie im obigen Beispiel) abrufen, beschriftet mysql die Spalte mit dem Ausdruck selbst.

  • mysql zeigt an, wie viele Datensätze (Zeilen) zurückgegeben wurden und wie lange die Ausführung der Abfrage dauerte; hierdurch können Sie grob auf die Serverleistung schließen. Die Werte sind allerdings nicht sehr genau, denn sie geben nur eine normale Zeit statt der Prozessor- oder Systemzeit an, die zudem durch Faktoren wie der Serverauslastung und der Netzwerklatenz beeinflusst wird. (Aus Gründen der Übersichtlichkeit haben wir die Zeile „rows in set“ in einigen der in diesem Kapitel aufgeführten Beispiele weggelassen.)

Schlüsselwörter können in beliebiger Groß-/Kleinschreibung angegeben werden. Die folgenden Abfragen sind gleichwertig:

mysql> SELECT VERSION(), CURRENT_DATE;
mysql> select version(), current_date;
mysql> SeLeCt vErSiOn(), current_DATE;

Es folgt eine weitere Abfrage. Sie veranschaulicht, wie man mysql als einfachen Taschenrechner verwenden kann:

mysql> SELECT SIN(PI()/4), (4+1)*5;
+------------------+---------+
| SIN(PI()/4)      | (4+1)*5 |
+------------------+---------+
| 0.70710678118655 |      25 |
+------------------+---------+
1 row in set (0.02 sec)

Die bislang gezeigten Abfragen waren vergleichsweise kurze, einzeilige Anweisungen. Sie können aber auch mehrere Anweisungen in eine Zeile schreiben. Schließen Sie sie jeweils mit einem Semikolon ab:

mysql> SELECT VERSION(); SELECT NOW();
+-----------------+
| VERSION()       |
+-----------------+
| 5.1.2-alpha-log |
+-----------------+
1 row in set (0.00 sec)
+---------------------+
| NOW()               |
+---------------------+
| 2005-10-11 15:15:00 |
+---------------------+
1 row in set (0.00 sec)

Ein Befehl muss nicht komplett auf keiner einzigen Zeile gegeben werden, deshalb sind lange Befehle, die mehrere Zeilen benötigen, kein Problem. mysql entscheidet, wo Ihre Anweisung endet, indem es nach dem beendenden Semikolon sucht, und nicht, indem es nach dem Ende der Eingabezeile sucht. (Mit anderen Worten akzeptiert mysql eine Freiformateingabe: es stellt Eingabezeilen zusammen, aber führt sie nicht aus, solange es kein Semikolon findet.)

Hier sehen Sie eine einfache mehrzeilige Anweisung:

mysql> SELECT
    -> USER()
    -> ,
    -> CURRENT_DATE;
+---------------+--------------+
| USER()        | CURRENT_DATE |
+---------------+--------------+
| jon@localhost | 2005-10-11   |
+---------------+--------------+

Beachten Sie in diesem Beispiel, wie die Eingabeaufforderung von mysql> auf -> umschaltet, nachdem Sie die erste Zeile einer mehrzeiligen Abfrage eingegeben haben. Auf diese Weise zeigt mysql an, dass noch keine vollständige Anweisung erkannt wurde und weitere Eingaben erwartet werden. Diese Form der Eingabeaufforderung ist sehr praktisch, denn sie erlaubt Rückschlüsse auf erforderliche Eingaben. Sie wissen also immer, worauf mysql gerade wartet.

Wenn Sie einen Befehl, den Sie gerade eingeben, doch nicht ausführen wollen, können Sie ihn durch Eingabe von \c abbrechen:

mysql> SELECT
    -> USER()
    -> \c
mysql>

Beachten Sie auch hier die Eingabeaufforderung. Sie schaltet zurück auf mysql>, nachdem Sie \c eingegeben haben. So wird angezeigt, dass mysql auf einen neuen Befehl wartet.

Die folgende Tabelle zeigt alle Eingabeaufforderungen, auf die Sie treffen können, und fasst ferner zusammen, welche Rückschlüsse sie jeweils bezüglich des Zustandes von mysql erlauben.

EingabeaufforderungBedeutung
mysql>Bereit für einen neuen Befehl.
->Erwartet die nächste Zeile einer mehrzeiligen Befehlseingabe.
'>Erwartet die nächste Zeile und die Vervollständigung eines Strings, der mit einem einfachen Anführungszeichen („'“) begonnen wurde.
">Erwartet die nächste Zeile und die Vervollständigung eines Strings, der mit einem doppelten Anführungszeichen („"“) begonnen wurde.
`>Erwartet die nächste Zeile und die Vervollständigung eines Bezeichners, der mit einem Backtick („`“) begonnen wurde.
/*>Erwartet die nächste Zeile und die Vervollständigung eines Kommentars, der mit /* begonnen wurde.

Mehrzeilige Anweisungen treten häufig ungewollt auf, wenn Sie eigentlich nur einen einzeiligen Befehl absetzen wollen, aber das abschließende Semikolon vergessen. In diesem Fall erwartet mysql eine weitere Eingabe:

mysql> SELECT USER()
    ->

Wenn das geschieht (d. h., wenn Sie glauben, dass Sie einen vollständigen Befehl eingegeben haben, aber die Eingabeaufforderung -> erscheint), dann wartet mysql in aller Regel auf das Semikolon. Wenn Sie nicht wissen, was Ihnen die Eingabeaufforderung sagt, könnten Sie eine Zeit lang am Rechner sitzen, bevor Ihnen klar wird, was Sie ausführen müssen. Geben Sie ein Semikolon ein, um die Anweisung abzuschließen, damit mysql sie dann ausführt:

mysql> SELECT USER()
    -> ;
+---------------+
| USER()        |
+---------------+
| jon@localhost |
+---------------+

Die Eingabeaufforderungen '> und "> erscheinen bei der Erfassung von Strings (MySQL erwartet also die Vervollständigung eines Strings). In MySQL können Sie Strings entweder in „'“ oder „"“ setzen (z. B. 'hello' oder "goodbye"). mysql erlaubt die Eingabe von Strings, die sich über mehrere Zeilen erstrecken. Wenn Sie die Eingabeaufforderung '> oder "> sehen, bedeutet dies, dass Sie eine Zeile mit einem String eingegeben haben, der mit dem Anführungszeichen „'“ oder „"“ beginnt, diesen String aber noch nicht mit dem zugehörigen schließenden Anführungszeichen beendet haben. Hierdurch ist häufig erkennbar, dass Sie ein Anführungszeichen einzugeben vergessen haben. Ein Beispiel:

mysql> SELECT * FROM my_table WHERE name = 'Smith AND age < 30;
    '>

Wenn Sie diese SELECT-Anweisung eingeben und dann die Eingabetaste betätigen, werden Sie eine Zeit lang warten, ohne dass etwas passiert. Wenn Sie sich wundern, warum die Verarbeitung der Abfrage so lange dauert, werden Sie bald feststellen, dass die Eingabeaufforderung '> angezeigt wird. Sie besagt, dass mysql den Rest eines nicht abgeschlossenen Strings erwartet. (Erkennen Sie den Fehler in der Anweisung? Beim String 'Smith fehlt das zweite einzelne Anführungszeichen.)

Was können Sie nun tun? Die einfachste Möglichkeit besteht darin, den Befehl abzubrechen. Sie können in diesem Fall aber nicht einfach \c eingeben, da mysql dies als Teil des Strings interpretieren würde, den Sie vermeintlich eingeben. Geben Sie stattdessen zuerst das schließende Anführungszeichen (damit mysql weiß, dass der String abgeschlossen ist) und erst dann \c ein:

mysql> SELECT * FROM my_table WHERE name = 'Smith AND age < 30;
    '> '\c
mysql>

Die Eingabeaufforderung schaltet nun auf mysql> zurück und zeigt so an, dass mysql für einen neuen Befehl bereit ist.

Die Eingabeaufforderung `> ähnelt '> und ">, gibt aber an, dass Sie mit einem Backtick einen Bezeichner begonnen, aber noch nicht beendet haben.

Zu wissen, was die Eingabeaufforderungen '>, "> und `> bedeuten, ist wichtig, denn wenn Sie versehentlich einen nicht abgeschlossenen String eingeben, werden alle nachfolgend eingegebenen Zeilen von mysql ignoriert, einschließlich der Zeile mit dem Befehl QUIT. Dies kann insbesondere dann recht verwirrend sein, wenn Sie nicht wissen, dass Sie ein schließendes Anführungszeichen eingeben müssen, bevor Sie den aktuellen Befehl abbrechen können.

1.3. Einrichten und Verwenden einer Datenbank

Nachdem Sie nun wissen, wie Sie Befehle eingeben, sind Sie so weit, dass Sie auf eine Datenbank zugreifen können.

Angenommen, Sie halten bei sich zu Hause mehrere Haustiere (Ihre kleine Menagerie) und wollen nun verschiedene Informationen zu diesen Tieren verwalten. Dies können Sie tun, indem Sie Tabellen erstellen, die die gewünschten Informationen aufnehmen sollen, und diese Tabellen dann mit den erforderlichen Daten bestücken. Danach können Sie zu Ihren Tieren verschiedene Arten von Fragen beantworten, indem Sie Daten aus den Tabellen abrufen. Dieser Abschnitt zeigt Ihnen, wie Sie die folgenden Operationen ausführen sollten:

  • eine Datenbank erstellt,

  • eine Tabelle erstellt,

  • Daten in eine Tabelle lädt,

  • Daten auf verschiedene Weisen aus der Tabelle abruft,

  • mehrere Tabellen verwendet.

Die Menageriedatenbank ist (bewusst) einfach gehalten, aber es ist auch nicht schwierig, sich Situationen aus dem täglichen Leben vorzustellen, in denen eine ähnliche Art von Datenbank zum Einsatz kommen könnte. Eine solche Datenbank könnte etwa von einem Landwirt, der seinen Tierbestand organisieren möchte, oder von einem Tierarzt zur Patientenverwaltung verwendet werden. Eine Menageriedistribution mit einigen der in den folgenden Abschnitten verwendeten Abfragen und Beispieldaten finden Sie auf der MySQL-Website. Sie ist sowohl als komprimierte tar-Datei als auch in Zip-Formaten unter http://dev.mysql.com/doc/ verfügbar.

Verwenden Sie die SHOW-Anweisung, um zu ermitteln, welche Datenbanken derzeit auf dem Server vorhanden sind:

mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| mysql    |
| test     |
| tmp      |
+----------+

Die mysql-Datenbank beschreibt Benutzerzugriffsberechtigungen. Die Datenbank test hingegen ist als Spielplatz für Benutzer verfügbar, die Dinge ausprobieren möchten.

Die Liste der Datenbanken, die von der Anweisung angezeigt wird, kann auf Ihrem Rechner anders sein; SHOW DATABASES zeigt keine Datenbanken an, für die Sie keine Berechtigungen haben, wenn Sie nicht über die SHOW DATABASES-Berechtigung verfügen. Siehe auch Abschnitt 8.5.5.15, „SHOW DATABASES.

Wenn die Datenbank test vorhanden ist, versuchen Sie sie aufzurufen:

mysql> USE test
Database changed

USE braucht ebenso wie QUIT kein Semikolon. (Sie können solche Anweisungen aber nichtsdestoweniger mit einem Semikolon abschließen – hierdurch wird kein Schaden angerichtet.) Die USE-Anweisung ist auch anderweitig besonders: Sie muss auf einer einzelnen Zeile gegeben werden.

Sie können die Datenbank test für die folgenden Beispiele verwenden (vorausgesetzt, Sie haben Zugriff darauf); beachten Sie aber, dass alles, was Sie in dieser Datenbank erstellen, von allen anderen Benutzern, die darauf zugreifen dürfen, entfernt werden kann. Aus diesem Grund sollten Sie Ihren MySQL-Administrator besser bitten, eine eigene Datenbank verwenden zu dürfen. Angenommen, Sie möchten Ihre Datenbank Menagerie nennen. Der Administrator muss einen Befehl ausführen, der in etwa so aussieht:

mysql> GRANT ALL ON menagerie.* TO 'your_mysql_name'@'your_client_host';

Hierbei ist your_mysql_name der Ihnen zugewiesene MySQL-Benutzername und your_client_host der Name des Hosts, von dem aus Sie die Verbindung zum Server herstellen.

1.3.1. Einrichten und Auswählen einer Datenbank

Wenn Ihr Administrator beim Konfigurieren der Berechtigungen eine Datenbank für Sie erstellt hat, können Sie diese sofort nutzen. Andernfalls müssen Sie sie selbst einrichten:

mysql> CREATE DATABASE menagerie;

Unter Unix wird bei Datenbanknamen – anders als bei SQL-Schlüsselwörtern – die Groß-/Kleinschreibung unterschieden. Deswegen muss der Datenbankname immer als menagerie und nicht als Menagerie, MENAGERIE oder in einer anderen Variante angegeben werden. Gleiches gilt für Tabellennamen. (Unter Windows gilt diese Einschränkung nicht; allerdings müssen Sie innerhalb einer Abfrage eine Datenbank oder Tabelle konsistent mit derselben Schreibung bezeichnen. Wir empfehlen jedoch aus verschiedenen Gründen, immer dieselbe Schreibweise zu nutzen, die beim Einrichten der Datenbank verwendet wurde.)

Anmerkung

Wenn Sie beim Erstellen einer Datenbank eine Fehlermeldung wie etwa ERROR 1044 (42000): Access denied for user 'monty'@'localhost' to database 'menagerie' erhalten, bedeutet dies, dass Ihr Benutzerkonto nicht die zur Datenbankerstellung erforderlichen Berechtigungen hat. Besprechen Sie dies mit Ihrem Administrator oder lesen Sie The MySQL Access Privilege System.

Wenn Sie eine Datenbank erstellen, wird diese nicht automatisch für die Verwendung ausgewählt; Sie müssen dies ausdrücklich tun. Um menagerie also zur aktuellen Datenbank zu machen, verwenden Sie folgenden Befehl:

mysql> USE menagerie
Database changed

Ihre Datenbank muss nur einmal erstellt werden, sie muss aber jedes Mal, wenn Sie eine mysql-Sitzung beginnen, zur Verwendung ausgewählt werden. Dies tun Sie durch Absetzen einer USE-Anweisung wie im Beispiel gezeigt. Alternativ können Sie die Datenbank auch auf der Befehlszeile auswählen, wenn Sie mysql aufrufen. Geben Sie auf alle ggf. erforderlichen Verbindungsparameter folgend einfach den Datenbanknamen ein. Ein Beispiel:

shell> mysql -h host -u user -p menagerie
Enter password: ********
Wichtig

menagerie im gerade gezeigten Befehl ist nicht Ihr Passwort. Wenn Sie Ihr Passwort auf der Befehlszeile nach der Option -p angeben wollen, müssen Sie dies ohne zwischengeschaltetes Leerzeichen tun (z. B. als -pmypassword, nicht jedoch als -p mypassword). Allerdings wird von der Übermittlung des Passworts auf der Befehlszeile ohnehin abgeraten, weil es so anderen Benutzern offenbart werden könnte, die an Ihrem Computer angemeldet sind.

Anmerkung

Sie können jederzeit sehen, welche Datenbank gegenwärtig bei der Verwendung von SELECT DATABASE() ausgewählt wird.

1.3.2. Einrichten einer Tabelle

Das Erstellen einer Datenbank ist ganz einfach. Noch aber ist die Datenbank leer, wie Sie mit SHOW TABLES nachprüfen können:

mysql> SHOW TABLES;
Empty set (0.00 sec)

Der schwierigere Teil besteht darin zu entscheiden, wie die Struktur Ihrer Datenbank sein sollte: welche Tabellen Sie benötigen und welche Spalten in jeder Tabelle sein sollten.

Sie brauchen eine Tabelle, die einen Datensatz für jedes Ihrer Haustiere enthält. Diese Tabelle könnte man haustier nennen; sie sollte zumindest den Namen jedes Tieres enthalten. Da der Name an sich aber nicht besonders interessant ist, sollte die Tabelle auch weitere Informationen enthalten. Wenn beispielsweise mehrere Personen in Ihrer Familie Haustiere halten, würde es sich anbieten, die Besitzer der einzelnen Tiere aufzuführen. Ferner könnten einige grundlegende Beschreibungen eingetragen werden, z. B. die Tierart und das Geschlecht.

Und das Alter der Tiere? Das könnte zwar interessant sein, die Speicherung in einer Datenbank ist jedoch problematisch. Da sich das Alter im Laufe der Zeit ändert, müssten Sie Ihre Datensätze regelmäßig aktualisieren. Stattdessen ist es besser, einen festen Wert wie etwa das Geburtsdatum zu speichern. Wann immer Sie dann das Alter eines Tieres in Erfahrung bringen wollten, müssten Sie nur die Differenz zwischen dem aktuellen Datum und dem Geburtsdatum errechnen. MySQL bietet Funktionen, die derartige Rechenaufgaben erledigen können, sodass dies nicht weiter schwierig ist. Das Speichern des Geburtsdatums statt des Alters hat aber auch weitere Vorteile:

  • Sie können die Datenbank für Aufgaben wie das automatische Erinnern an anstehende Tiergeburtstage verwenden. (Wenn Sie der Ansicht sind, dass eine solche Abfrage etwas albern ist, dann beachten Sie, dass Sie dieselbe Frage im Kontext einer Unternehmensdatenbank verwenden könnten, um Kunden zu ermitteln, denen Sie demnächst Geburtstagsgrüße senden wollen – die persönliche Note mit freundlicher Unterstützung Ihrer Datenbank.)

  • Sie können das Alter auch in Relation zu anderen als dem aktuellen Datum berechnen. Wenn Sie etwa das Sterbedatum eines Tieres in der Datenbank ablegen, können Sie ganz leicht berechnen, wie alt es bei seinem Tod war.

Sie können sich wahrscheinlich eine Reihe andere Informationstypen vorstellen, die in der Tabelle haustier von Nutzen sein könnten, aber die bisher genannten sollen fürs Erste ausreichen: name, besitzer, gattung, geschlecht, geburtstag und todestag.

Das Layout Ihrer Tabelle legen Sie mit einer CREATE TABLE-Anweisung fest:

mysql> CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20),
    -> species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);

VARCHAR ist eine geeignete Wahl für die Spalten name, besitzer und gattung, denn die Werte dieser Spalten können in der Länge variieren. Die Längen in diesen Spaltendefinitionen müssen weder identisch sein noch alle den Wert 20 haben. Sie können eine beliebige Länge zwischen 1 und 65535 eingeben – je nachdem, was Ihnen am sinnvollsten erscheint. Haben Sie jedoch eine falsche Entscheidung getroffen und es stellt sich später heraus, dass Sie ein längeres Feld benötigen, dann bietet MySQL hierfür die ALTER TABLE-Anweisung an.

Zur Auswahl des Geschlechts Ihrer Tiere bieten sich mehrere Wertetypen an, z. B. 'm' und 'w' oder auch 'männlich' und 'weiblich'. Am einfachsten ist die Verwendung der Einzelzeichen 'm' und 'w'.

Der Datentyp DATE ist offensichtlich am geeignetsten für die Spalten geburtstag und todestag.

Wenn Sie eine Tabelle erstellt haben, sollte die Anweisung SHOW TABLES eine entsprechende Ausgabe erzeugen:

mysql> SHOW TABLES;
+---------------------+
| Tables in menagerie |
+---------------------+
| pet                 |
+---------------------+

Um zu überprüfen, dass Ihre Tabelle wie gewünscht erstellt worden ist, verwenden Sie eine DESCRIBE-Anweisung:

mysql> DESCRIBE pet;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| name    | varchar(20) | YES  |     | NULL    |       |
| owner   | varchar(20) | YES  |     | NULL    |       |
| species | varchar(20) | YES  |     | NULL    |       |
| sex     | char(1)     | YES  |     | NULL    |       |
| birth   | date        | YES  |     | NULL    |       |
| death   | date        | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+

Sie können DESCRIBE auch jederzeit aufrufen, wenn Sie die Spaltennamen Ihrer Tabelle oder die verwendeten Datentypen vergessen haben.

Weitere Informationen zu MySQL-Datentypen finden Sie in Kapitel 6, Datentypen.

1.3.3. Laden von Daten in eine Tabelle

Nachdem Sie Ihre Tabelle erstellt haben, müssen Sie sie mit Daten füllen. Zu diesem Zweck sind die Anweisungen LOAD DATA und INSERT vorhanden.

Angenommen, Ihre Haustierdatensätze können wie hier gezeigt bezeichnet werden. (Beachten Sie, dass MySQL Daten im 'YYYY-MM-DD'-Format erwartet; dies kann sich von dem unterscheiden, was Sie kennen.)

namebesitzergattunggeschlechtgeburtstagtodestag
FluffyHaroldKatzew1993-02-04 
ClawsGwenKatzem1994-03-17 
BuffyHaroldHundw1989-05-13 
FangBennyHundm1990-08-27 
BowserDianeHundm1979-08-311995-07-29
ChirpyGwenVogelw1998-09-11 
WhistlerGwenVogel 1997-12-09 
SlimBennySchlangem1996-04-29 

Da wir anfangs eine leere Tabelle haben, können Sie diese zunächst ganz einfach ausfüllen, indem Sie eine Textdatei erstellen, die jeweils eine Zeile pro Tier enthält. Die Inhalte der Datei können Sie dann mit einer einzigen Anweisung in die Tabelle einladen.

Erstellen Sie also eine Textdatei namens pet.txt mit einem Datensatz pro Zeile, bei dem die einzelnen Werte durch Tabulatorzeichen voneinander getrennt sind; die Werte müssen dabei in der Reihenfolge eingegeben werden, in der Sie in der CREATE TABLE-Anweisung aufgeführt wurden. Bei fehlenden Werten (z. B. wenn das Geschlecht nicht bekannt oder das Ableben des Tieres noch nicht erfolgt ist) können Sie NULL-Werte eingeben. Diese geben Sie als \N (Backslash, großes N) in Ihre Textdatei ein. So würde der Datensatz für Whistler, den Vogel, wie folgt aussehen (der Whitespace zwischen den Werten ist ein Tabulatorzeichen):

Whistler        Gwen    bird    \N      1997-12-09      \N

Um die Textdatei pet.txt in die Tabelle haustier zu laden, genügt die folgende Anweisung:

mysql> LOAD DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet;

Wenn Sie die Datei unter Windows mit einem Editor erstellt haben, der \r\n als Zeilenbegrenzer verwendet, sollten Sie stattdessen diese Anweisung verwenden:

mysql> LOAD DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet
    -> LINES TERMINATED BY '\r\n';

(Auf einem Apple Macintosh unter Mac OS X würden Sie hingegen eher LINES TERMINATED BY '\r' benutzen.)

Sie können das Trennzeichen für Spaltenwerte und den Zeilenbegrenzer bei Bedarf auch ausdrücklich in der LOAD DATA-Anweisung angeben, die Standardeinstellungen sind jedoch das Tabulator- bzw. das Zeilenvorschubzeichen. Diese Einstellungen sind zum Einlesen unserer Datei pet.txt geeignet.

Schlägt die Anweisung fehl, dann liegt das wahrscheinlich daran, dass bei der MySQL-Installation standardmäßig nicht die Funktionalität für lokale Dateien aktiviert ist. Wie Sie dies ändern, erfahren Sie in Security Issues with LOAD DATA LOCAL.

Zum sukzessiven Einfügen neuer Datensätze ist die INSERT-Anweisung am praktischsten. In ihrer einfachsten Form geben Sie Werte für jede Spalte in der Reihenfolge an, in der die Spalten in der CREATE TABLE-Anweisung aufgeführt waren. Angenommen, Diane bekommt einen neuen Hamster namens „Puffball“. Sie könnten über eine INSERT-Anweisung wie diese einen neuen Datensatz hinzufügen:

mysql> INSERT INTO pet
    -> VALUES ('Puffball','Diane','hamster','f','1999-03-30',NULL);

String- und Datenwerte werden hier in Anführungszeichen gesetzt. Mit der INSERT-Anweisung können Sie NULL auch direkt eingeben, um einen fehlenden Wert darzustellen. \N würden Sie hier – anders als bei LOAD DATA – nicht verwenden.

Aus diesem Beispiel sollte klar werden, dass die Erstellung der Basisdatensätze mithilfe einzelner INSERT-Anweisungen erheblich mehr Tipparbeit bedeuten würde als die Verwendung einer einzelnen LOAD DATA-Anweisung.

1.3.4. Abrufen von Informationen aus einer Tabelle

Mit der SELECT-Anweisung können Sie Daten aus einer Tabelle abrufen. Die allgemeine Form dieser Anweisung sieht wie folgt aus:

SELECT what_to_select
FROM which_table
WHERE conditions_to_satisfy;

what_to_select gibt hierbei an, was Sie sehen wollen. Dies kann eine Liste mit Spalten oder alternativ * sein, wenn Sie alle Spalten anzeigen wollen. which_table gibt die Tabelle an, aus der Sie Daten abrufen wollen.„“ Die WHERE-Klausel ist optional. Ist sie vorhanden, dann gibt conditions_to_satisfy eine oder mehrere Bedingungen an, die Datensätze erfüllen müssen, um abgerufen zu werden.

1.3.4.1. Auswählen aller Daten

Die einfachste Form von SELECT ruft alle in der Tabelle vorhandenen Daten ab:

mysql> SELECT * FROM pet;
+----------+--------+---------+------+------------+------------+
| name     | owner  | species | sex  | birth      | death      |
+----------+--------+---------+------+------------+------------+
| Fluffy   | Harold | cat     | f    | 1993-02-04 | NULL       |
| Claws    | Gwen   | cat     | m    | 1994-03-17 | NULL       |
| Buffy    | Harold | dog     | f    | 1989-05-13 | NULL       |
| Fang     | Benny  | dog     | m    | 1990-08-27 | NULL       |
| Bowser   | Diane  | dog     | m    | 1979-08-31 | 1995-07-29 |
| Chirpy   | Gwen   | bird    | f    | 1998-09-11 | NULL       |
| Whistler | Gwen   | bird    | NULL | 1997-12-09 | NULL       |
| Slim     | Benny  | snake   | m    | 1996-04-29 | NULL       |
| Puffball | Diane  | hamster | f    | 1999-03-30 | NULL       |
+----------+--------+---------+------+------------+------------+

Diese Verwendung von SELECT ist nützlich, wenn Sie beispielsweise Ihre Tabelle überprüfen wollen, nachdem Sie gerade die ersten Daten eingeladen haben. Nehmen wir etwa an, dass Sie nicht ganz sicher sind, ob Sie für Bowser das richtige Geburtsdatum eingegeben haben. Dem Stammbaum entnehmen Sie, dass das korrekte Geburtsjahr nicht 1979, sondern 1989 lautet.

Nun gibt es zwei Möglichkeiten, den Fehler zu beheben:

  • Sie korrigieren den Datensatz in der Datei pet.txt, leeren die Tabelle mit DELETE und laden die Daten dann mit LOAD DATA neu ein:

    mysql> DELETE FROM pet;
    mysql> LOAD DATA LOCAL INFILE 'pet.txt' INTO TABLE pet;
    

    Allerdings müssen Sie bei dieser Vorgehensweise auch die Daten für Puffball neu eingeben.

  • Sie ändern nur den fehlerhaften Datensatz. Hierzu verwenden Sie eine UPDATE-Anweisung:

    mysql> UPDATE pet SET birth = '1989-08-31' WHERE name = 'Bowser';
    

    Mit UPDATE ändern Sie nur den fraglichen Datensatz – Sie müssen die Tabellendaten in diesem Fall nicht neu laden.

1.3.4.2. Auswählen besonderer Zeilen

Wie im vorherigen Abschnitt gezeigt, ist das Abrufen der Daten einer ganzen Tabelle recht einfach. Sie lassen einfach die WHERE-Klausel in der SELECT-Anweisung weg. In der Regel wollen Sie aber nicht die gesamte Tabelle anzeigen – insbesondere dann nicht, wenn diese sehr groß ist. Stattdessen werden Sie meist an der Beantwortung einer bestimmten Frage interessiert sein. In diesem Fall müssen Sie Beschränkungen für die gewünschten Daten definieren. Betrachten wir einmal einige Auswahlabfragen dahingehend, welche Fragen diese zu Ihren Haustieren beantworten.

Sie können die Auswahl in Ihrer Tabelle auch auf bestimmte Datensätze beschränken. Wollen Sie z. B. die Änderungen am Geburtsdatum von Bowser überprüfen, dann wählen Sie den entsprechenden Datensatz wie folgt aus:

mysql> SELECT * FROM pet WHERE name = 'Bowser';
+--------+-------+---------+------+------------+------------+
| name   | owner | species | sex  | birth      | death      |
+--------+-------+---------+------+------------+------------+
| Bowser | Diane | dog     | m    | 1989-08-31 | 1995-07-29 |
+--------+-------+---------+------+------------+------------+

Die Ausgabe bestätigt die korrekte Änderung der Jahresangabe von 1979 auf 1989.

Bei String-Vergleichen wird die Groß-/Kleinschreibung normalerweise ignoriert, weswegen Sie den Namen als 'bowser', 'BOWSER' usw. angeben können. Das Abfrageergebnis ist stets gleich.

Sie können Bedingungen aber nicht nur für name, sondern für jede beliebige Spalte angeben. Wenn Sie beispielsweise wissen wollen, welche Tiere im Jahre 1998 oder danach geboren wurden, testen Sie die Spalte geburtstag:

mysql> SELECT * FROM pet WHERE birth >= '1998-1-1';
+----------+-------+---------+------+------------+-------+
| name     | owner | species | sex  | birth      | death |
+----------+-------+---------+------+------------+-------+
| Chirpy   | Gwen  | bird    | f    | 1998-09-11 | NULL  |
| Puffball | Diane | hamster | f    | 1999-03-30 | NULL  |
+----------+-------+---------+------+------------+-------+

Sie können auch Bedingungen kombinieren, um etwa nach weiblichen Hunden zu suchen:

mysql> SELECT * FROM pet WHERE species = 'dog' AND sex = 'f';
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+

Obige Abfrage verwendet den Operator AND (logisches Und). Es gibt analog auch einen Operator OR (logisches Oder):

mysql> SELECT * FROM pet WHERE species = 'snake' OR species = 'bird';
+----------+-------+---------+------+------------+-------+
| name     | owner | species | sex  | birth      | death |
+----------+-------+---------+------+------------+-------+
| Chirpy   | Gwen  | bird    | f    | 1998-09-11 | NULL  |
| Whistler | Gwen  | bird    | NULL | 1997-12-09 | NULL  |
| Slim     | Benny | snake   | m    | 1996-04-29 | NULL  |
+----------+-------+---------+------+------------+-------+

AND und OR können auch gemischt verwendet werden, wobei AND jedoch Vorrang vor OR hat. Wenn Sie beide Operatoren verwenden, bietet sich die Verwendung von Klammern an, um exakt anzugeben, wie die Bedingungen gruppiert werden sollen:

mysql> SELECT * FROM pet WHERE (species = 'cat' AND sex = 'm')
    -> OR (species = 'dog' AND sex = 'f');
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+

1.3.4.3. Auswählen besonderer Spalten

Wenn Sie nicht die gesamten Datensätze aus Ihrer Tabelle sehen wollen, dann führen Sie in der jeweiligen Abfrage die gewünschten Spalten durch Kommata getrennt auf. Wollen Sie also etwa wissen, wann Ihre Tiere geboren wurden, dann wählen Sie die Spalten name und geburtstag:

mysql> SELECT name, birth FROM pet;
+----------+------------+
| name     | birth      |
+----------+------------+
| Fluffy   | 1993-02-04 |
| Claws    | 1994-03-17 |
| Buffy    | 1989-05-13 |
| Fang     | 1990-08-27 |
| Bowser   | 1989-08-31 |
| Chirpy   | 1998-09-11 |
| Whistler | 1997-12-09 |
| Slim     | 1996-04-29 |
| Puffball | 1999-03-30 |
+----------+------------+

Um herauszufinden, wem welches Tier gehört, setzen Sie folgende Abfrage ab:

mysql> SELECT owner FROM pet;
+--------+
| owner  |
+--------+
| Harold |
| Gwen   |
| Harold |
| Benny  |
| Diane  |
| Gwen   |
| Gwen   |
| Benny  |
| Diane  |
+--------+

Beachten Sie, dass diese einfache Abfrage die Spalte besitzer jedes Datensatzes abruft; einige davon tauchen mehrfach auf. Um die Ausgabe zu optimieren, können Sie jeden eindeutigen Ergebnisdatensatz genau einmal ausgeben, indem Sie einfach das Schlüsselwort DISTINCT hinzufügen:

mysql> SELECT DISTINCT owner FROM pet;
+--------+
| owner  |
+--------+
| Benny  |
| Diane  |
| Gwen   |
| Harold |
+--------+

Mithilfe einer WHERE-Klausel können Sie Datensatz- und Spaltenauswahl kombinieren. Um z. B. die Geburtsdaten von Hunden und Katzen anzuzeigen, verwenden Sie folgende Abfrage:

mysql> SELECT name, species, birth FROM pet
    -> WHERE species = 'dog' OR species = 'cat';
+--------+---------+------------+
| name   | species | birth      |
+--------+---------+------------+
| Fluffy | cat     | 1993-02-04 |
| Claws  | cat     | 1994-03-17 |
| Buffy  | dog     | 1989-05-13 |
| Fang   | dog     | 1990-08-27 |
| Bowser | dog     | 1989-08-31 |
+--------+---------+------------+

1.3.4.4. Sortieren von Datensätzen

Sie haben in den vorangegangenen Beispielen vielleicht bereits festgestellt, dass die Ergebnisdatensätze nicht in einer bestimmten Reihenfolge angezeigt werden. Häufig ist es jedoch einfacher, das Abfrageergebnis zu durchsuchen, wenn die Datensätze sinnvoll sortiert werden. Um ein Ergebnis zu sortieren, verwenden Sie die ORDER BY-Klausel.

Nachfolgend sind die Geburtstage der Tiere nach Datum sortiert aufgelistet:

mysql> SELECT name, birth FROM pet ORDER BY birth;
+----------+------------+
| name     | birth      |
+----------+------------+
| Buffy    | 1989-05-13 |
| Bowser   | 1989-08-31 |
| Fang     | 1990-08-27 |
| Fluffy   | 1993-02-04 |
| Claws    | 1994-03-17 |
| Slim     | 1996-04-29 |
| Whistler | 1997-12-09 |
| Chirpy   | 1998-09-11 |
| Puffball | 1999-03-30 |
+----------+------------+

Bei zeichenbasierten Spalten erfolgt die Sortierung – wie bei allen anderen Vergleichsoperationen auch – normalerweise ohne Berücksichtigung der Groß-/Kleinschreibung. Das bedeutet, dass die Reihenfolge bei Spalten, die bis auf die Groß-/Kleinschreibung identisch sind, nicht definiert ist. Sie können ein schreibweisenabhängiges Sortieren für eine Spalte erzwingen, indem Sie BINARY so verwenden: ORDER BY BINARY col_name.

Die Standardreihenfolge bei der Sortierung ist aufsteigend, d. h., die kleinsten Werte werden zuerst aufgeführt. Um in umgekehrter (absteigender) Reihenfolge zu sortieren, fügen Sie das Schlüsselwort DESC zum Namen der Spalte zu, nach der die Sortierung erfolgt:

mysql> SELECT name, birth FROM pet ORDER BY birth DESC;
+----------+------------+
| name     | birth      |
+----------+------------+
| Puffball | 1999-03-30 |
| Chirpy   | 1998-09-11 |
| Whistler | 1997-12-09 |
| Slim     | 1996-04-29 |
| Claws    | 1994-03-17 |
| Fluffy   | 1993-02-04 |
| Fang     | 1990-08-27 |
| Bowser   | 1989-08-31 |
| Buffy    | 1989-05-13 |
+----------+------------+

Sie können auch nach mehreren Spalten und diese jeweils mit eigener Reihenfolge sortieren. Um beispielsweise nach der Tierart in aufsteigender, dann dem Geburtsdatum innerhalb der Tierart in absteigender Reihenfolge (d. h. das jüngste Tier zuerst nennend) zu sortieren, verwenden Sie die folgende Abfrage:

mysql> SELECT name, species, birth FROM pet
    -> ORDER BY species, birth DESC;
+----------+---------+------------+
| name     | species | birth      |
+----------+---------+------------+
| Chirpy   | bird    | 1998-09-11 |
| Whistler | bird    | 1997-12-09 |
| Claws    | cat     | 1994-03-17 |
| Fluffy   | cat     | 1993-02-04 |
| Fang     | dog     | 1990-08-27 |
| Bowser   | dog     | 1989-08-31 |
| Buffy    | dog     | 1989-05-13 |
| Puffball | hamster | 1999-03-30 |
| Slim     | snake   | 1996-04-29 |
+----------+---------+------------+

Das Schlüsselwort DESC gilt nur für den Spaltennamen, dem es direkt vorangestellt ist (geburtstag); die Sortierreihenfolge der Spalte gattung wird hiervon nicht berührt.

1.3.4.5. Datumsberechnungen

MySQL bietet eine Anzahl von Funktionen, mit denen Sie datumsbezogene Berechnungen durchführen können, um etwa Altersangaben zu ermitteln oder Teile aus Datumsangaben zu extrahieren.

Um zu bestimmen, wie alt Ihre Haustiere jeweils sind, berechnen Sie die Differenz im Jahresbestandteil des aktuellen und des Geburtsdatums und ziehen den Wert 1 ab, sofern das aktuelle Datum im Kalenderjahr vor dem Geburtsdatum liegt. Die folgende Abfrage zeigt für jedes Haustier das Geburtsdatum, das aktuelle Datum und das Alter in Jahren an.

mysql> SELECT name, birth, CURDATE(),
    -> (YEAR(CURDATE())-YEAR(birth))
    -> - (RIGHT(CURDATE(),5)<RIGHT(birth,5))
    -> AS age
    -> FROM pet;
+----------+------------+------------+------+
| name     | birth      | CURDATE()  | age  |
+----------+------------+------------+------+
| Fluffy   | 1993-02-04 | 2003-08-19 |   10 |
| Claws    | 1994-03-17 | 2003-08-19 |    9 |
| Buffy    | 1989-05-13 | 2003-08-19 |   14 |
| Fang     | 1990-08-27 | 2003-08-19 |   12 |
| Bowser   | 1989-08-31 | 2003-08-19 |   13 |
| Chirpy   | 1998-09-11 | 2003-08-19 |    4 |
| Whistler | 1997-12-09 | 2003-08-19 |    5 |
| Slim     | 1996-04-29 | 2003-08-19 |    7 |
| Puffball | 1999-03-30 | 2003-08-19 |    4 |
+----------+------------+------------+------+

Hierbei extrahiert YEAR() die Jahreszahl aus dem Datum, während mit RIGHT() die fünf Zeichen ganz rechts im Datum (MM-DD, also der Monat und der Tag) ermittelt werden. Der Teil des Ausdrucks, der die Werte MM-DD vergleicht, ist entweder 1 oder 0. Hiermit wird von der Jahresdifferenz ggf. ein Jahr abgezogen, sofern CURDATE() (das aktuelle Datum) im Kalenderjahr vor geburtstag liegt. Der gesamte Ausdruck wirkt ein wenig unübersichtlich, weswegen ein Alias (tieralter) verwendet wird, um die Beschriftung der Ausgabespalte sinnvoller zu gestalten.

Die Abfrage funktioniert zwar, aber das Ergebnis ließe sich einfacher erfassen, wenn die Datensätze in einer bestimmten Reihenfolge angezeigt würden. Dies ist durch Ergänzen der Klausel ORDER BY name möglich, die die Ausgaben dem Namen nach sortiert:

mysql> SELECT name, birth, CURDATE(),
    -> (YEAR(CURDATE())-YEAR(birth))
    -> - (RIGHT(CURDATE(),5)<RIGHT(birth,5))
    -> AS age
    -> FROM pet ORDER BY name;
+----------+------------+------------+------+
| name     | birth      | CURDATE()  | age  |
+----------+------------+------------+------+
| Bowser   | 1989-08-31 | 2003-08-19 |   13 |
| Buffy    | 1989-05-13 | 2003-08-19 |   14 |
| Chirpy   | 1998-09-11 | 2003-08-19 |    4 |
| Claws    | 1994-03-17 | 2003-08-19 |    9 |
| Fang     | 1990-08-27 | 2003-08-19 |   12 |
| Fluffy   | 1993-02-04 | 2003-08-19 |   10 |
| Puffball | 1999-03-30 | 2003-08-19 |    4 |
| Slim     | 1996-04-29 | 2003-08-19 |    7 |
| Whistler | 1997-12-09 | 2003-08-19 |    5 |
+----------+------------+------------+------+

Um die Ausgabe nach dem Alter statt dem Namen zu sortieren, verwenden Sie einfach eine andere ORDER BY-Klausel:

mysql> SELECT name, birth, CURDATE(),
    -> (YEAR(CURDATE())-YEAR(birth))
    -> - (RIGHT(CURDATE(),5)<RIGHT(birth,5))
    -> AS age
    -> FROM pet ORDER BY age;
+----------+------------+------------+------+
| name     | birth      | CURDATE()  | age  |
+----------+------------+------------+------+
| Chirpy   | 1998-09-11 | 2003-08-19 |    4 |
| Puffball | 1999-03-30 | 2003-08-19 |    4 |
| Whistler | 1997-12-09 | 2003-08-19 |    5 |
| Slim     | 1996-04-29 | 2003-08-19 |    7 |
| Claws    | 1994-03-17 | 2003-08-19 |    9 |
| Fluffy   | 1993-02-04 | 2003-08-19 |   10 |
| Fang     | 1990-08-27 | 2003-08-19 |   12 |
| Bowser   | 1989-08-31 | 2003-08-19 |   13 |
| Buffy    | 1989-05-13 | 2003-08-19 |   14 |
+----------+------------+------------+------+

Eine ähnliche Abfrage kann verwendet werden, um das erreichte Alter bereits verstorbener Tiere zu bestimmen. Welche Tiere dies sind, ermitteln Sie durch die Überprüfung, ob für todestag der Wert NULL lautet. Bei denjenigen Datensätzen, bei denen der Wert nicht NULL ist, berechnen Sie die Differenz zwischen den Werten todestag und geburtstag:

mysql> SELECT name, birth, death,
    -> (YEAR(death)-YEAR(birth)) - (RIGHT(death,5)<RIGHT(birth,5))
    -> AS age
    -> FROM pet WHERE death IS NOT NULL ORDER BY age;
+--------+------------+------------+------+
| name   | birth      | death      | age  |
+--------+------------+------------+------+
| Bowser | 1989-08-31 | 1995-07-29 |    5 |
+--------+------------+------------+------+

Die Abfrage verwendet todestag IS NOT NULL statt todestag <> NULL, da NULL ein Sonderwert ist, der nicht mithilfe der üblichen Vergleichsoperatoren verglichen werden kann. Wir werden später noch darauf eingehen. Siehe auch Abschnitt 1.3.4.6, „Arbeiten mit NULL-Werten“.

Was aber, wenn Sie nun wissen wollen, welche Tiere im nächsten Monat Geburtstag haben? Für diese Art der Berechnung sind Jahr und Tag irrelevant: Sie müssen lediglich den Monat aus der Spalte geburtstag extrahieren. MySQL bietet mehrere Funktionen zur Extraktion von Datumsbestandteilen, z. B. YEAR(), MONTH() und DAYOFMONTH(). MONTH() ist für unsere Belange die passende Funktion. Um zu sehen, wie sie funktioniert, führen Sie eine einfache Abfrage aus, die den Wert von geburtstag und MONTH(geburtstag) anzeigt:

mysql> SELECT name, birth, MONTH(birth) FROM pet;
+----------+------------+--------------+
| name     | birth      | MONTH(birth) |
+----------+------------+--------------+
| Fluffy   | 1993-02-04 |            2 |
| Claws    | 1994-03-17 |            3 |
| Buffy    | 1989-05-13 |            5 |
| Fang     | 1990-08-27 |            8 |
| Bowser   | 1989-08-31 |            8 |
| Chirpy   | 1998-09-11 |            9 |
| Whistler | 1997-12-09 |           12 |
| Slim     | 1996-04-29 |            4 |
| Puffball | 1999-03-30 |            3 |
+----------+------------+--------------+

Das Suchen von Tieren, die nächsten Monat Geburtstag haben, ist ebenfalls ganz einfach. Nehmen wir einmal an, es wäre April. In diesem Fall ist der Monatswert 4 – Sie suchen also nach Tieren, die im Mai (d. h. im Monat 5) geboren sind. Das geht wie folgt:

mysql> SELECT name, birth FROM pet WHERE MONTH(birth) = 5;
+-------+------------+
| name  | birth      |
+-------+------------+
| Buffy | 1989-05-13 |
+-------+------------+

Wenn der aktuelle Monat Dezember ist, gibt es eine kleine Komplikation. Sie können nämlich nicht einfach die Monatsnummer (12) um den Wert 1 erhöhen – die Suche nach im Monat 13 geborenen Tieren brächte kein Ergebnis, weil es diesen Monat nicht gibt. Schließlich suchen Sie nach Tieren, die im Januar (Monat 1) geboren sind.

Sie können die Abfrage so verfassen, dass sie unabhängig vom aktuellen Monat funktioniert, sodass Sie die Nummer eines bestimmten Monats gar nicht verwenden müssen. DATE_ADD() erlaubt Ihnen das Addieren eines bestimmten Zeitintervalls für ein gegebenes Datum. Wenn Sie einen Monat zum aktuellen Wert von CURDATE() hinzuaddieren wollen, extrahieren Sie den Monatsbestandteil mit MONTH(). Das Ergebnis ist der Monat, in dem Sie nach Geburtstagen suchen müssen:

mysql> SELECT name, birth FROM pet
    -> WHERE MONTH(birth) = MONTH(DATE_ADD(CURDATE(),INTERVAL 1 MONTH));

Eine andere Möglichkeit, diese Aufgabe zu lösen, besteht darin, 1 hinzuzuaddieren und dann den auf den aktuellen Monat folgenden Monat zu ermitteln, wobei mithilfe der Modulofunktion (MOD) der Monatswert auf 0 gesetzt wird, wenn er derzeit 12 beträgt:

mysql> SELECT name, birth FROM pet
    -> WHERE MONTH(birth) = MOD(MONTH(CURDATE()), 12) + 1;

MONTH() gibt eine Zahl zwischen 1 und 12 zurück. Ferner gibt MOD(something,12) eine Zahl zwischen 0 und 11 zurück. Insofern muss die Addition nach MOD() erfolgen, andernfalls würden wir von November (11) direkt zu Januar (1) springen.

1.3.4.6. Arbeiten mit NULL-Werten

Wenn Sie mit dem Wert NULL noch keine Erfahrung haben, kann Ihnen manche Überraschung bevorstehen. Vom Konzept her bezeichnet NULL einen „fehlenden unbekannten Wert“ und wird etwas anders behandelt als andere Werte. Um auf NULL zu prüfen, können Sie arithmetische Vergleichsoperatoren wie =, < oder <> nicht verwenden. Um dies zu demonstrieren, geben Sie einmal Folgendes ein:

mysql> SELECT 1 = NULL, 1 <> NULL, 1 < NULL, 1 > NULL;
+----------+-----------+----------+----------+
| 1 = NULL | 1 <> NULL | 1 < NULL | 1 > NULL |
+----------+-----------+----------+----------+
|     NULL |      NULL |     NULL |     NULL |
+----------+-----------+----------+----------+

Offensichtlich lassen sich aus diesen Vergleichen keine sinngebenden Ergebnisse ziehen. Verwenden Sie stattdessen die Operatoren IS NULL und IS NOT NULL:

mysql> SELECT 1 IS NULL, 1 IS NOT NULL;
+-----------+---------------+
| 1 IS NULL | 1 IS NOT NULL |
+-----------+---------------+
|         0 |             1 |
+-----------+---------------+

In MySQL entspricht 0 oder NULL falsch, während alles andere wahr ist. Der standardmäßig wahr entsprechende Wert aus einer booleschen Operation ist 1.

Die Sonderbehandlung für NULL ist der Grund dafür, warum im vorherigen Abschnitt die Frage, welche Tiere nicht mehr leben, mit todestag IS NOT NULL statt mit todestag <> NULL ermittelt werden musste.

Zwei NULL in einer GROUP BY-Klausel werden als gleichberechtigt betrachtet.

Wenn Sie ein ORDER BY ausführen, werden NULL-Werte zuerst präsentiert, wenn Sie ORDER BY ... ASCausführen, und zuletzt, wenn Sie ORDER BY ... DESC ausführen.

Ein häufiger Fehler beim Umgang mit NULL besteht in der Annahme, dass es nicht möglich ist, eine Null oder einen Leer-String in eine Spalte einzufügen, die als NOT NULL definiert ist. Das stimmt nicht. Dies sind in der Tat Werte, wohingegen NULL bedeutet, dass es „keinen Wert gibt“. Sie können dies sehr leicht unter Verwendung von IS [NOT] NULL, wie hier gezeigt, testen:

mysql> SELECT 0 IS NULL, 0 IS NOT NULL, '' IS NULL, '' IS NOT NULL;
+-----------+---------------+------------+----------------+
| 0 IS NULL | 0 IS NOT NULL | '' IS NULL | '' IS NOT NULL |
+-----------+---------------+------------+----------------+
|         0 |             1 |          0 |              1 |
+-----------+---------------+------------+----------------+

Es ist also durchaus möglich, eine Null oder einen Leer-String in eine NOT NULL-Spalte einzusetzen, denn diese Werte sind in der Tat NOT NULL. Siehe auch Problems with NULL Values.

1.3.4.7. Mustervergleich

MySQL ermöglicht einen Mustervergleich sowohl nach SQL-Standard als auch basierend auf erweiterten regulären Ausdrücken, wie man es von Unix-Hilfsprogrammen wie vi, grep und sed her kennt.

Beim SQL-Mustervergleich können Sie „_“ für eine Übereinstimmung mit einzelnen Zeichen sowie „%“ für eine Übereinstimmung mit einer beliebigen Anzahl von Zeichen (einschließlich 0 Zeichen) verwenden. In MySQL wird bei SQL-Mustern standardmäßig keine Unterscheidung der Groß-/Kleinschreibung vorgenommen. Einige Beispiele sind hier aufgeführt. In Verbindung mit SQL-Mustern verwenden Sie nicht = oder <>, sondern die Vergleichsoperatoren LIKE bzw. NOT LIKE.

Namen, die mit „b beginnen, finden Sie so“:

mysql> SELECT * FROM pet WHERE name LIKE 'b%';
+--------+--------+---------+------+------------+------------+
| name   | owner  | species | sex  | birth      | death      |
+--------+--------+---------+------+------------+------------+
| Buffy  | Harold | dog     | f    | 1989-05-13 | NULL       |
| Bowser | Diane  | dog     | m    | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+

Namen, die auf „fy enden, finden Sie so“:

mysql> SELECT * FROM pet WHERE name LIKE '%fy';
+--------+--------+---------+------+------------+-------+
| name   | owner  | species | sex  | birth      | death |
+--------+--------+---------+------+------------+-------+
| Fluffy | Harold | cat     | f    | 1993-02-04 | NULL  |
| Buffy  | Harold | dog     | f    | 1989-05-13 | NULL  |
+--------+--------+---------+------+------------+-------+

Und Namen, die „w enthalten, finden Sie so“:

mysql> SELECT * FROM pet WHERE name LIKE '%w%';
+----------+-------+---------+------+------------+------------+
| name     | owner | species | sex  | birth      | death      |
+----------+-------+---------+------+------------+------------+
| Claws    | Gwen  | cat     | m    | 1994-03-17 | NULL       |
| Bowser   | Diane | dog     | m    | 1989-08-31 | 1995-07-29 |
| Whistler | Gwen  | bird    | NULL | 1997-12-09 | NULL       |
+----------+-------+---------+------+------------+------------+

Um Namen zu ermitteln, die aus genau fünf Zeichen bestehen, verwenden Sie fünf Instanzen des Musterzeichens „_“:

mysql> SELECT * FROM pet WHERE name LIKE '_____';
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+

Der andere von MySQL unterstützte Mustervergleichstyp nutzt erweiterte reguläre Ausdrücke. Wenn Sie bei diesem Mustertyp auf Übereinstimmung testen, verwenden Sie die Operatoren REGEXP und NOT REGEXP (bzw. deren Synonyme RLIKE und NOT RLIKE).

Die folgende Liste beschreibt einige Merkmale von erweiterten regulären Ausdrücken:

  • .“ stimmt mit genau einem beliebigen Zeichen überein.

  • Eine Zeichenklasse „[...]“ führt zur Übereinstimmung bei jedem Zeichen in den Klammern. Beispielsweise liegt bei „[abc]“ eine Übereinstimmung mit „a“, „b“ oder „c“ vor. Um einen Zeichenbereich anzugeben, verwenden Sie einen Bindestrich. „[a-z]“ führt zur Übereinstimmung mit einem beliebigen Buchstaben, wohingegen „[0-9] einer Übereinstimmung mit jeder Ziffer entspricht.

  • *“ stimmt mit null oder mehr Instanzen des Elements überein, das ihm vorangeht. Beispielsweise liegt bei „x*“ eine Übereinstimmung mit einer beliebigen Anzahl von „x“-Zeichen vor. Gleiches gilt bei „[0-9]*“ für eine beliebige Anzahl von Ziffern und bei „.*“ für eine beliebige Anzahl eines beliebigen Elements.

  • Ein REGEXP-Mustervergleich ist erfolgreich, wenn eine Übereinstimmung des Musters an beliebiger Stelle im getesteten Wert vorliegt. (Hier liegt ein Unterschied zum LIKE-Mustervergleich, der nur erfolgreich ist, wenn das Muster mit dem gesamten Wert übereinstimmt.)

  • Um einen Anker im Muster zu setzen, sodass es mit dem Anfang oder Ende des getesteten Wertes übereinstimmen muss, verwenden Sie „^“ am Anfang bzw. „$“ am Ende des Musters.

Um zu demonstrieren, wie erweiterte reguläre Ausdrücke funktionieren, haben wir die oben gezeigten LIKE-Abfragen so umgeschrieben, dass sie REGEXP verwenden.

Um Namen zu finden, die mit „b“ beginnen, verwenden Sie „^“ für eine Übereinstimmung mit dem Namensanfang:

mysql> SELECT * FROM pet WHERE name REGEXP '^b';
+--------+--------+---------+------+------------+------------+
| name   | owner  | species | sex  | birth      | death      |
+--------+--------+---------+------+------------+------------+
| Buffy  | Harold | dog     | f    | 1989-05-13 | NULL       |
| Bowser | Diane  | dog     | m    | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+

Wenn Sie einen REGEXP-Vergleich mit Unterscheidung der Groß-/Kleinschreibung wirklich erzwingen wollen, verwenden Sie das Schlüsselwort BINARY, um aus einem der Strings einen Binär-String zu machen. Bei folgender Abfrage liegt eine Übereinstimmung nur bei einem kleinen „b am Anfang des Namens vor:

mysql> SELECT * FROM pet WHERE name REGEXP BINARY '^b';

Um Namen zu finden, die auf „fy“ enden, verwenden Sie „$“ für eine Übereinstimmung mit dem Namensende:

mysql> SELECT * FROM pet WHERE name REGEXP 'fy$';
+--------+--------+---------+------+------------+-------+
| name   | owner  | species | sex  | birth      | death |
+--------+--------+---------+------+------------+-------+
| Fluffy | Harold | cat     | f    | 1993-02-04 | NULL  |
| Buffy  | Harold | dog     | f    | 1989-05-13 | NULL  |
+--------+--------+---------+------+------------+-------+

Namen schließlich, die „w“ enthalten, finden Sie mit folgender Abfrage:

mysql> SELECT * FROM pet WHERE name REGEXP 'w';
+----------+-------+---------+------+------------+------------+
| name     | owner | species | sex  | birth      | death      |
+----------+-------+---------+------+------------+------------+
| Claws    | Gwen  | cat     | m    | 1994-03-17 | NULL       |
| Bowser   | Diane | dog     | m    | 1989-08-31 | 1995-07-29 |
| Whistler | Gwen  | bird    | NULL | 1997-12-09 | NULL       |
+----------+-------+---------+------+------------+------------+

Da ein auf einem regulären Ausdruck basierendes Muster eine Übereinstimmung liefert, wenn es an beliebiger Stelle im Wert auftaucht, ist es in dieser Abfrage nicht notwendig, ein Jokerzeichen an den beiden Seiten des Musters zu setzen (bei einem SQL-Muster wäre dies hingegen erforderlich, um eine Übereinstimmung zu erzielen).

Um Namen zu ermitteln, die aus genau fünf Zeichen bestehen, verwenden Sie „^“ und „$“ für Übereinstimmungen für Anfang und Ende des Namens und fünf Instanzen von „.“ dazwischen:

mysql> SELECT * FROM pet WHERE name REGEXP '^.....$';
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+

Sie könnten diese Abfrage auch mithilfe des Operators {n} („n-mal wiederholen“) schreiben:

mysql> SELECT * FROM pet WHERE name REGEXP '^.{5}$';
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+

In Abschnitt 7.4.2, „Reguläre Ausdrücke“, finden Sie weitere Informationen zur Syntax regulärer Ausdrücke.

1.3.4.8. Zählen von Datensätzen

Datenbanken werden oft verwendet, um die Frage zu beantworten, „wie oft eine gewisse Art von Daten in einer Tabelle auftritt“.Sie könnten zum Beispiel wissen wollen, wieviele Haustiere Sie haben oder wieviele Haustiere jeder Besitzer hat, oder Sie könnten verschiedene Arten von statistischen Daten zu Ihren Tieren erheben wollen.

Das Zählen aller vorhandenen Tiere entspricht der Frage „Wie viele Datensätze sind in der Tabelle haustier vorhanden?“, denn es gibt genau einen Datensatz pro Tier. COUNT(*) zählt die Anzahl der Datensätze, d. h., die Abfrage zur Zählung Ihrer Tiere sieht wie folgt aus:

mysql> SELECT COUNT(*) FROM pet;
+----------+
| COUNT(*) |
+----------+
|        9 |
+----------+

Weiter oben haben Sie die Namen der Leute abgerufen, die Tiere besitzen. Mit COUNT() können Sie etwa ermitteln, wie viele Tiere jeder Besitzer hat:

mysql> SELECT owner, COUNT(*) FROM pet GROUP BY owner;
+--------+----------+
| owner  | COUNT(*) |
+--------+----------+
| Benny  |        2 |
| Diane  |        2 |
| Gwen   |        3 |
| Harold |        2 |
+--------+----------+

Die vorangehende Abfrage nutzt GROUP BY, um alle Datensätze für jeden Besitzer zu gruppieren. Die Kombination von COUNT() mit GROUP BY ist nützlich für die Charakterisierung Ihrer Daten in verschiedenen Einteilungen. Die folgenden Beispiele zeigen verschiedene Wege, statistische Daten zu den Tieren zu erheben.

Anzahl der Exemplare je Tierart:

mysql> SELECT species, COUNT(*) FROM pet GROUP BY species;
+---------+----------+
| species | COUNT(*) |
+---------+----------+
| bird    |        2 |
| cat     |        2 |
| dog     |        3 |
| hamster |        1 |
| snake   |        1 |
+---------+----------+

Anzahl der Tiere je Geschlecht:

mysql> SELECT sex, COUNT(*) FROM pet GROUP BY sex;
+------+----------+
| sex  | COUNT(*) |
+------+----------+
| NULL |        1 |
| f    |        4 |
| m    |        4 |
+------+----------+

(In dieser Ausgabe gibt NULL an, dass das Geschlecht unbekannt ist.)

Anzahl der Tiere je Kombination von Tierart und Geschlecht:

mysql> SELECT species, sex, COUNT(*) FROM pet GROUP BY species, sex;
+---------+------+----------+
| species | sex  | COUNT(*) |
+---------+------+----------+
| bird    | NULL |        1 |
| bird    | f    |        1 |
| cat     | f    |        1 |
| cat     | m    |        1 |
| dog     | f    |        1 |
| dog     | m    |        2 |
| hamster | f    |        1 |
| snake   | m    |        1 |
+---------+------+----------+

Wenn Sie COUNT() verwenden, müssen Sie nicht die gesamte Tabelle abrufen. Die obige Abfrage beispielsweise sieht wie folgt aus, wenn Sie nur für Hunde und Katzen durchgeführt wird:

mysql> SELECT species, sex, COUNT(*) FROM pet
    -> WHERE species = 'dog' OR species = 'cat'
    -> GROUP BY species, sex;
+---------+------+----------+
| species | sex  | COUNT(*) |
+---------+------+----------+
| cat     | f    |        1 |
| cat     | m    |        1 |
| dog     | f    |        1 |
| dog     | m    |        2 |
+---------+------+----------+

Oder, wenn Sie die Anzahl der Tiere je Geschlecht nur für diejenigen Tiere anzeigen wollen, deren Geschlecht auch bekannt ist:

mysql> SELECT species, sex, COUNT(*) FROM pet
    -> WHERE sex IS NOT NULL
    -> GROUP BY species, sex;
+---------+------+----------+
| species | sex  | COUNT(*) |
+---------+------+----------+
| bird    | f    |        1 |
| cat     | f    |        1 |
| cat     | m    |        1 |
| dog     | f    |        1 |
| dog     | m    |        2 |
| hamster | f    |        1 |
| snake   | m    |        1 |
+---------+------+----------+

Wenn Sie Spalten zusätzlich zum COUNT()-Wert, zur Auswahl benennen, sollte eine GROUP BY-Klausel vorhanden sein, die diese gleichen Spalten benennt. Ansonsten tritt das folgende Verhalten auf:

  • Wenn der ONLY_FULL_GROUP_BY-SQL-Modus aktiviert ist, tritt ein Fehler auf:

    mysql> SET sql_mode = 'ONLY_FULL_GROUP_BY';
    Query OK, 0 rows affected (0.00 sec)
    mysql> SELECT owner, COUNT(*) FROM pet;
    ERROR 1140 (42000): Mixing of GROUP columns (MIN(),MAX(),COUNT()...)
    with no GROUP columns is illegal if there is no GROUP BY clause
    
  • Wenn ONLY_FULL_GROUP_BY nicht aktiviert ist, wird die Abfrage verarbeitet, indem alle Zeilen als eine einzelne Gruppe betrachtet werden, aber der ausgewählte Wert für jede benannte Spalte ergebnislos ist. Der Server kann den Wert frei aus jedem beliebigen Datensatz auswählen:

    mysql> SET sql_mode = '';
    Query OK, 0 rows affected (0.00 sec)
    mysql> SELECT owner, COUNT(*) FROM pet;
    +--------+----------+
    | owner  | COUNT(*) |
    +--------+----------+
    | Harold |        8 | 
    +--------+----------+
    1 row in set (0.00 sec)
    

Siehe auch Abschnitt 7.12.3, „GROUP BY und HAVING mit verborgenen Spalten“.

1.3.4.9. Verwenden mehrerer Tabellen

Die Tabelle haustier enthält Daten zu den Tieren, die Sie besitzen. Wollen Sie andere Informationen zu diesen aufzeichnen – z. B. Ereignisse wie Tierarztbesuche oder die Ankunft von Nachwuchs –, dann benötigen Sie eine zweite Tabelle. Wie sollte diese Tabelle aussehen? Sie muss die folgenden Informationen enthalten:

  • Der Name des Tieres, damit Sie wissen, welches Ereignis zu welchem Tier gehört.

  • Das Ereignisdatum.

  • Ein Feld, welches das Ereignis beschreibt.

  • Ein Ereignistypfeld, das Sie zum Kategorisieren der Ereignisse benötigen.

Unter Berücksichtigung dieser Aspekte könnte die CREATE TABLE-Anweisung für die Tabelle ereignis wie folgt aussehen:

mysql> CREATE TABLE event (name VARCHAR(20), date DATE,
    -> type VARCHAR(15), remark VARCHAR(255));

Wie bei der Tabelle haustier ist es auch hier am einfachsten, die bereits bekannten Daten über eine tabulatorgetrennte Textdatei in die Tabelle einzuladen. Diese Datei soll die folgenden Informationen enthalten.

namedatumtypbemerkung
Fluffy1995-05-15Nachwuchs4 Kätzchen, 3 weiblich, 1 männlich
Buffy1993-06-23Nachwuchs5 Welpen, 2 weiblich, 3 männlich
Buffy1994-06-19Nachwuchs3 Welpen, 3 weiblich
Chirpy1999-03-21TierarztSchnabel begradigt
Slim1997-08-03Tierarztgebrochene Rippe
Bowser1991-10-12Hundepension 
Fang1991-10-12Hundepension 
Fang1998-08-28Geburtstagneues Kauspielzeug
Claws1998-03-17Geburtstagneues Flohhalsband
Whistler1998-12-09Geburtstagerster Geburtstag

Laden Sie die Datensätze wie folgt:

mysql> LOAD DATA LOCAL INFILE 'event.txt' INTO TABLE event;

Mit dem, was Sie bereits aus den Abfragen erlernt haben, die Sie zur Tabelle haustier abgesetzt haben, sollten Sie auch Daten aus der Tabelle ereignis abrufen können; die Prinzipien sind dieselben. Was aber, wenn Sie die Fragen, die Sie stellen, mit der Tabelle ereignis allein nicht beantworten können?

Nehmen wir an, Sie wollen herausfinden, in welchem Alter die jeweiligen Tiere Nachwuchs bekommen haben. Wir haben bereits weiter oben gesehen, wie Sie das Alter auf der Grundlage zweiter Datumsangaben berechnen. Das Datum, an dem die Mutter ihren Nachwuchs auf die Welt gebracht hat, ist in der Tabelle ereignis gespeichert, aber um das Alter der Mutter am Tag der Niederkunft zu ermitteln, benötigen Sie das Geburtsdatum, welches wiederum in der Tabelle haustier abgelegt ist. Das bedeutet, dass wir zwei Tabellen benötigen:

mysql> SELECT pet.name,
    -> (YEAR(date)-YEAR(birth)) - (RIGHT(date,5)<RIGHT(birth,5)) AS age,
    -> remark
    -> FROM pet INNER JOIN event
    ->   ON pet.name = event.name
    -> WHERE event.type = 'litter';
+--------+------+-----------------------------+
| name   | age  | remark                      |
+--------+------+-----------------------------+
| Fluffy |    2 | 4 kittens, 3 female, 1 male |
| Buffy  |    4 | 5 puppies, 2 female, 3 male |
| Buffy  |    5 | 3 puppies, 3 female         |
+--------+------+-----------------------------+

Bei dieser Abfrage fällt Verschiedenes auf:

  • Die FROM-Klausel verknüpft zwei Tabellen, da die Abfrage Informationen aus beiden Tabellen abrufen muss.

  • Wenn Sie Daten aus mehreren Tabellen kombinieren (verknüpfen), dann müssen Sie angeben, wie die Datensätze der einen Tabelle denen der anderen Tabelle zugeordnet werden können. Dies ist recht einfach, da beide Tabellen eine Spalte name haben. Die Abfrage verwendet eine ON-Klausel zur Zuordnung von Datensätzen der beiden Tabellen basierend auf den Werten in der Spalte name.

    Die Abfrage nutzt ein INNER JOIN, um die Tabellen zu verbinden. Ein INNER JOIN ermöglicht, dass Zeilen aus einer der Tabellen im Ergebnis erscheinen, wenn – und nur wenn – beide Tabellen den Bedingungen in der ON-Klausel entsprechen. In diesem Beispiel gibt die ON-Klausel an, dass die Spalte name in der Tabelle haustier zur Spalte name in der Tabelle ereignis passen muss. Wenn ein Name in einer Tabelle, aber nicht in der anderen erscheint, erscheint die Zeile nicht im Ergebnis, weil die Bedingung in der ON-Klausel fehlschlägt.

  • Da die Spalte name in beiden Tabellen auftritt, müssen Sie bei Bezugnahme auf diese Spalte angeben, welche der beiden Tabellen Sie meinen. Dies erfolgt durch Voranstellung des Tabellennamens vor den Spaltennamen.

Um eine solche Verknüpfung – einen Join – durchzuführen, brauchen Sie keine zwei Tabellen. Manchmal ist es nützlich, eine Tabelle mit sich selbst zu verknüpfen, wenn man etwa Datensätze in einer Tabelle mit anderen Datensätzen in derselben Tabelle vergleichen will. Um beispielsweise Zuchtmöglichkeiten unter Ihren Tieren auszuloten, kann eine Verknüpfung der Tabelle haustier mit sich selbst praktisch sein, um passende Männchen und Weibchen einer Tierart zu ermitteln:

mysql> SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species
    -> FROM pet AS p1 INNER JOIN pet AS p2
    ->   ON p1.species = p2.species AND p1.sex = 'f' AND p2.sex = 'm';
+--------+------+--------+------+---------+
| name   | sex  | name   | sex  | species |
+--------+------+--------+------+---------+
| Fluffy | f    | Claws  | m    | cat     |
| Buffy  | f    | Fang   | m    | dog     |
| Buffy  | f    | Bowser | m    | dog     |
+--------+------+--------+------+---------+

In dieser Abfrage geben Sie Aliase für den Tabellennamen an, um auf die Spalten Bezug zu nehmen und klar zu machen, welcher Tabelleninstanz die Bezugnahme auf eine Spalte zuzuordnen ist.

1.4. Abrufen von Informationen über Datenbanken und Tabellen

Was können Sie tun, wenn Sie den Namen einer Datenbank oder Tabelle vergessen haben oder nicht mehr wissen, wie die Struktur einer gegebenen Tabelle aussieht (d. h., wie beispielsweise die Spalten heißen)? MySQL bietet zur Lösung dieses Problems eine Reihe von Anweisungen an, die Informationen zu unterstützten Datenbanken und Tabellen vermitteln.

Die Anweisung SHOW DATABASES, die die vom Server verwalteten Datenbanken auflistet, haben Sie bereits gesehen. Um herauszufinden, welche Datenbank gerade gewählt ist, verwenden Sie die Funktion DATABASE():

mysql> SELECT DATABASE();
+------------+
| DATABASE() |
+------------+
| menagerie  |
+------------+

Haben Sie noch keine Datenbank ausgewählt, dann lautet das Ergebnis NULL.

Um herauszufinden, welche Tabellen die Standarddatenbank enthält (wenn Sie etwa den Namen einer Tabelle nicht mehr genau wissen), verwenden Sie diesen Befehl:

mysql> SHOW TABLES;
+---------------------+
| Tables_in_menagerie |
+---------------------+
| event               |
| pet                 |
+---------------------+

Der Name der Spalte in der von dieser Anweisung erzeugten Ausgabe ist immer Tables_in_db_name, wobei db_name der Name der Datenbank ist. Weitere Informationen finden Sie in Abschnitt 8.5.5.39, „SHOW TABLES.

Wollen Sie die Struktur einer Tabelle ermitteln, dann ist der Befehl DESCRIBE praktisch, denn er zeigt Informationen zu allen Spalten einer Tabelle an:

mysql> DESCRIBE pet;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| name    | varchar(20) | YES  |     | NULL    |       |
| owner   | varchar(20) | YES  |     | NULL    |       |
| species | varchar(20) | YES  |     | NULL    |       |
| sex     | char(1)     | YES  |     | NULL    |       |
| birth   | date        | YES  |     | NULL    |       |
| death   | date        | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+

Field ist dabei der Spaltenname, Type der Datentyp der Spalte, NULL zeigt an, ob die Spalte NULL-Werte enthalten kann, Key, ob die Spalte indiziert ist, und Default bezeichnet den Standardwert der Spalte. Extra zeigt besondere Informationen über Spalten an: Wenn eine Spalte mit der AUTO_INCREMENT-Option eingerichtet wurde, wird der Wert eher auto_increment anstatt leer sein.

DESC ist eine Kurzform von DESCRIBE. Weitere Informationen finden Sie in Abschnitt 8.3.1, „DESCRIBE (Informationen über Spalten abrufen)“.

Sie können die CREATE TABLE-Anweisung, die zum Einrichten einer existierenden Tabelle erforderlich ist, über die SHOW CREATE TABLE-Anweisung abrufen. Siehe auch Abschnitt 8.5.5.12, „SHOW CREATE TABLE.

Wenn Sie Indizes in einer Tabelle verwenden, generiert SHOW INDEX FROM tbl_name Informationen zu diesen. Weitere Informationen über diese Anweisung finden Sie unter Abschnitt 8.5.5.23, „SHOW INDEX.

1.5. Verwenden von mysql im Stapelmodus

In obigen Abschnitten haben Sie mysql interaktiv zur Eingabe von Abfragen und zur Anzeige der Ergebnisse verwendet. Sie können mysql aber auch im Stapelbetrieb (Batch-Modus) ausführen. Zu diesem Zweck legen Sie die gewünschten Befehle in einer Datei ab und weisen mysql dann an, diese Datei auszulesen und die Befehle zu verarbeiten:

shell> mysql < batch-file

Wenn Sie mysql unter Windows ausführen und gewisse Sonderzeichen in der Datei Probleme verursachen, dann können Sie Folgendes tun:

C:\> mysql -e "source batch-file"

Müssen Sie die Verbindungsparameter auf der Befehlszeile angeben, dann könnte der Befehl so aussehen:

shell> mysql -h host -u user -p < batch-file
Enter password: ********

Wenn Sie mysql auf diese Weise verwenden, erstellen Sie eine Skriptdatei und führen das Skript dann aus.

Soll das Skript auch dann vollständig abgearbeitet werden, wenn enthaltene Anweisungen Fehler erzeugen, dann sollten Sie die Befehlszeilenoption --force verwenden.

Warum sollte man Skripten verwenden? Dafür gibt es ein paar gute Gründe:

  • Führen Sie eine Abfrage häufiger aus (beispielsweise einmal in der Woche), dann können Sie ein Skript erstellen und sich so die Tipparbeit sparen, die bei jeder Neueingabe der Abfrage anfallen würde.

  • Sie können neue Abfragen aus bereits vorhandenen ähnlichen erstellen, indem Sie Skriptdateien kopieren und bearbeiten.

  • Der Stapelbetrieb kann auch nützlich sein, wenn Sie eine Abfrage entwickeln; dies gilt insbesondere für mehrzeilige Befehle oder aus mehreren Anweisungen bestehende Befehlsabfolgen. Wenn Sie einen Fehler machen, brauchen Sie nicht alles neu einzugeben. Beheben Sie den Fehler einfach in Ihrem Skript und weisen Sie mysql dann an, es erneut auszuführen.

  • Wenn Ihre Abfrage eine umfangreiche Ausgabe erzeugt, dann können Sie diese seitenweise anzeigen lassen, statt sie am oberen Bildschirmrand verschwinden zu sehen:

    shell> mysql < batch-file | more
    
  • Zur weiteren Verarbeitung können Sie die Ausgabe auch in eine Datei leiten:

    shell> mysql < batch-file > mysql.out
    
  • Sie können Ihr Skript auch an andere Benutzer weitergeben, damit diese ebenfalls die entsprechenden Befehle ausführen können.

  • Manche Situationen erlauben keine interaktive Vorgehensweise. Dies ist etwa der Fall, wenn eine Abfrage aus einem cron-Job heraus erfolgt. In diesem Fall müssen Sie den Stapelbetrieb verwenden.

Wenn Sie mysql im Stapelbetrieb verwenden, ist das Standardausgabeformat anders (genauer gesagt, knapper) als im interaktiven Modus. Die Ausgabe von SELECT DISTINCT gattung FROM haustier etwa sieht wie folgt aus, wenn mysql interaktiv läuft:

+---------+
| species |
+---------+
| bird    |
| cat     |
| dog     |
| hamster |
| snake   |
+---------+

Im Stapelbetrieb hingegen sieht die Ausgabe so aus:

species
bird
cat
dog
hamster
snake

Wenn Sie das interaktive Ausgabeformat auch im Stapelbetrieb wünschen, verwenden Sie zum Aufruf mysql -t. Damit die Ausgabe der ausgeführten Befehle angezeigt wird, verwenden Sie mysql -vvv.

Sie können auch Skripten an der mysql-Eingabeaufforderung verwenden. Hierzu dient der Befehl source bzw. \.:

mysql> source filename;
mysql> \. filename

Weitere Informationen finden Sie in Abschnitt 3.1.4, „Ausführen von SQL-Anweisungen aus einer Textdatei“.

1.6. Beispiele für übliche Abfragen

Es folgen einige Beispiele dafür, wie man häufige Probleme mit MySQL löst.

Einige dieser Beispiele verwenden die Tabelle shop, in der die Preise jedes Artikels (bzw. Artikelnummer) für bestimmte Händler aufgeführt sind. Wenn man davon ausgeht, dass jeder Händler genau einen bestimmten Festpreis für einen Artikel hat, dann ist (artikel, haendler) ein Primärschlüssel für die Datensätze.

Starten Sie das Befehlszeilen-Tool mysql und wählen Sie eine Datenbank aus:

shell> mysql your-database-name

(Bei den meisten MySQL-Installationen können Sie die Datenbank test verwenden.)

Erstellung der Beispieltabelle und Ausfüllen mit Daten erfolgen mit den folgenden Anweisungen:

CREATE TABLE shop (
    article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
    dealer  CHAR(20)                 DEFAULT ''     NOT NULL,
    price   DOUBLE(16,2)             DEFAULT '0.00' NOT NULL,
    PRIMARY KEY(article, dealer));
INSERT INTO shop VALUES
    (1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),
    (3,'C',1.69),(3,'D',1.25),(4,'D',19.95);

Nachdem Sie die Anweisungen abgesetzt haben, weist die Tabelle den folgenden Inhalt auf:

SELECT * FROM shop;
+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
|    0001 | A      |  3.45 |
|    0001 | B      |  3.99 |
|    0002 | A      | 10.99 |
|    0003 | B      |  1.45 |
|    0003 | C      |  1.69 |
|    0003 | D      |  1.25 |
|    0004 | D      | 19.95 |
+---------+--------+-------+

1.6.1. Der Maximalwert für eine Spalte

Was ist die höchste Artikelnummer?

SELECT MAX(article) AS article FROM shop;
+---------+
| article |
+---------+
|       4 |
+---------+

1.6.2. Die das Maximum einer bestimmten Spalte enthaltende Zeile

Aufgabe: Ermitteln Sie Nummer, Händler und Preis des teuersten Artikels.

Dies lässt sich recht einfach mit einer Unterabfrage bewerkstelligen:

SELECT article, dealer, price
FROM   shop
WHERE  price=(SELECT MAX(price) FROM shop);
+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
|    0004 | D      | 19.95 |
+---------+--------+-------+

Andere Lösungen sind, ein LEFT JOIN zu verwenden oder alle Zeilen absteigend nach Preis zu sortieren und nur die erste Zeile abzurufen, indem Sie die MySQL-spezifische LIMIT-Klausel verwenden:

SELECT s1.article, s1.dealer, s1.price
FROM shop s1
LEFT JOIN shop s2 ON s1.price < s2.price
WHERE s2.article IS NULL;
SELECT article, dealer, price
FROM shop
ORDER BY price DESC
LIMIT 1;
Anmerkung

Wenn mehrere teuerste Artikel zum gleichen Preis vorhanden sind, dann zeigt die LIMIT-Lösung nur einen davon an.

1.6.3. Maximum der Spalte pro Gruppe

Aufgabe: Ermitteln Sie den höchsten Preis je Artikel.

SELECT article, MAX(price) AS price
FROM   shop
GROUP BY article;
+---------+-------+
| article | price |
+---------+-------+
|    0001 |  3.99 |
|    0002 | 10.99 |
|    0003 |  1.69 |
|    0004 | 19.95 |
+---------+-------+

1.6.4. Die das gruppenbezogene Maximum einer bestimmten Spalte enthaltende Zeile

Aufgabe: Ermitteln Sie für jeden Artikel den oder die Händler mit dem höchsten Preis.

Dieses Problem lässt sich mit einer Unterabfrage wie der folgenden lösen:

SELECT article, dealer, price
FROM   shop s1
WHERE  price=(SELECT MAX(s2.price)
              FROM shop s2
              WHERE s1.article = s2.article);
+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
|    0001 | B      |  3.99 |
|    0002 | A      | 10.99 |
|    0003 | C      |  1.69 |
|    0004 | D      | 19.95 |
+---------+--------+-------+

Das vorangehende Beispiel verwendet eine korrelierte Unterabfrage, die ineffizient sein kann (siehe Abschnitt 8.2.9.7, „Korrelierte Unterabfragen“). Eine andere Möglichkeit zur Lösung des Problems ist, eine unkorrelierte Unterabfrage in der FROM-Klausel oder ein LEFT JOIN zu verwenden:

SELECT s1.article, dealer, s1.price
FROM shop s1
JOIN (
  SELECT article, MAX(price) AS price
  FROM shop
  GROUP BY article) AS s2
  ON s1.article = s2.article AND s1.price = s2.price;
SELECT s1.article, s1.dealer, s1.price
FROM shop s1
LEFT JOIN shop s2 ON s1.article = s2.article AND s1.price < s2.price
WHERE s2.article IS NULL;

Das LEFT JOIN funktioniert so, dass es, wenn s1.price seinen Maximalwert hat, kein s2.price mit einem größeren Wert gibt, und die s2-Zeilenwerte NULL sein werden. Siehe auch Abschnitt 8.2.8.1, „JOIN.

1.6.5. Verwenden von benutzerdefinierten Variablen

Sie können MySQL-Benutzervariablen verwenden, um die Ergebnisse zu vermerken, ohne sie in Temporärvariablen auf dem Client speichern zu müssen. (Siehe auch Abschnitt 5.4, „Benutzerdefinierte Variablen“.)

Um beispielsweise die Artikel mit dem höchsten und dem niedrigsten Preis zu ermitteln, können Sie Folgendes tun:

mysql> SELECT @min_price:=MIN(price),@max_price:=MAX(price) FROM shop;
mysql> SELECT * FROM shop WHERE price=@min_price OR price=@max_price;
+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
|    0003 | D      |  1.25 |
|    0004 | D      | 19.95 |
+---------+--------+-------+
Anmerkung

Es ist auch möglich, den Namen eines Datenbankobjekts wie einer Tabelle oder einer Spalte in einer Benutzervariablen zu speichern und dann diese Variable in einer SQL-Anweisung zu verwenden; allerdings benötigen Sie dazu eine vorbereitete Anweisung. Weitere Informationen finden Sie in Abschnitt 8.7, „SQL-Syntax für vorbereitete Anweisungen“.

1.6.6. Verwenden von Fremdschlüsseln

Bei MySQL unterstützen InnoDB-Tabellen die Überprüfung von Fremdschlüsselbeschränkungen. Siehe auch Kapitel 9, Die InnoDB-Speicher-Engine, und Foreign Keys.

Eine Fremdschlüsselbeschränkung ist nicht erforderlich, wenn Sie lediglich zwei Tabellen miteinander verknüpfen wollen. Bei anderen Speicher-Engines als InnoDB ist dies möglich, indem eine Spalte zur Verwendung einer REFERENCES tbl_name(col_name)-Klausel definiert wird; diese hat keine eigentliche Wirkung und dient Ihnen lediglich als Erinnerung oder Anmerkung, damit Sie daran denken, dass die derzeit definierte Spalte auf eine Spalte in einer anderen Tabelle verweisen soll. Es ist bei Verwendung dieser Syntax extrem wichtig, sich zu vergegenwärtigen, dass

  • MySQL keinerlei Überprüfung durchführt, um sicherzustellen, dass col_name tatsächlich in tbl_name vorhanden ist (bzw. dass tbl_name selbst existiert),

  • MySQL führt keinerlei Aktion für tbl_name wie das Löschen von Zeilen als Antwort auf Zeilenaktionen in der Tabelle aus; mit anderen Worten induziert diese Syntax überhaupt kein ON DELETE- oder ON UPDATE-Verhalten. (Obwohl Sie eine ON DELETE- oder ON UPDATE-Klausel als Teil der REFERENCES-Klausel schreiben können, wird sie ebenfalls ignoriert.)

  • diese Syntax eine Spalte erstellt (und keinerlei Index oder Schlüssel),

Sie können eine Spalte, die als Join-Spalte erstellt wurde, wie nachfolgend gezeigt verwenden:

CREATE TABLE person (
    id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
    name CHAR(60) NOT NULL,
    PRIMARY KEY (id)
);
CREATE TABLE shirt (
    id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
    style ENUM('t-shirt', 'polo', 'dress') NOT NULL,
    color ENUM('red', 'blue', 'orange', 'white', 'black') NOT NULL,
    owner SMALLINT UNSIGNED NOT NULL REFERENCES person(id),
    PRIMARY KEY (id)
);
INSERT INTO person VALUES (NULL, 'Antonio Paz');
SELECT @last := LAST_INSERT_ID();
INSERT INTO shirt VALUES
(NULL, 'polo', 'blue', @last),
(NULL, 'dress', 'white', @last),
(NULL, 't-shirt', 'blue', @last);
INSERT INTO person VALUES (NULL, 'Lilliana Angelovska');
SELECT @last := LAST_INSERT_ID();
INSERT INTO shirt VALUES
(NULL, 'dress', 'orange', @last),
(NULL, 'polo', 'red', @last),
(NULL, 'dress', 'blue', @last),
(NULL, 't-shirt', 'white', @last);
SELECT * FROM person;
+----+---------------------+
| id | name                |
+----+---------------------+
|  1 | Antonio Paz         |
|  2 | Lilliana Angelovska |
+----+---------------------+
SELECT * FROM shirt;
+----+---------+--------+-------+
| id | style   | color  | owner |
+----+---------+--------+-------+
|  1 | polo    | blue   |     1 |
|  2 | dress   | white  |     1 |
|  3 | t-shirt | blue   |     1 |
|  4 | dress   | orange |     2 |
|  5 | polo    | red    |     2 |
|  6 | dress   | blue   |     2 |
|  7 | t-shirt | white  |     2 |
+----+---------+--------+-------+
SELECT s.* FROM person p INNER JOIN shirt s
   ON s.owner = p.id
 WHERE p.name LIKE 'Lilliana%'
   AND s.color <> 'white';
+----+-------+--------+-------+
| id | style | color  | owner |
+----+-------+--------+-------+
|  4 | dress | orange |     2 |
|  5 | polo  | red    |     2 |
|  6 | dress | blue   |     2 |
+----+-------+--------+-------+

Wenn sie auf diese Weise eingesetzt wird, wird die REFERENCES-Klausel in der Ausgabe von SHOW CREATE TABLE oder DESCRIBE nicht angezeigt:

SHOW CREATE TABLE shirt\G
*************************** 1. row ***************************
Table: shirt
Create Table: CREATE TABLE `shirt` (
`id` smallint(5) unsigned NOT NULL auto_increment,
`style` enum('t-shirt','polo','dress') NOT NULL,
`color` enum('red','blue','orange','white','black') NOT NULL,
`owner` smallint(5) unsigned NOT NULL,
PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

Die Verwendung von REFERENCES als derartigen Kommentar oder „Erinnerung“ in einer Spaltendefinition funktioniert mit MyISAM-Tabellen.

1.6.7. Suchen auf zwei Schlüsseln

Eine Suche mit OR über einen Schlüssel ist in MySQL ebenso optimal gelöst wie die Verwendung von AND.

Der einzige etwas heikle Fall ist die Suche über zwei verschiedene Schlüssel, die durch OR kombiniert sind:

SELECT field1_index, field2_index FROM test_table
WHERE field1_index = '1' OR  field2_index = '1'

Dieser Fall ist optimiert. Siehe auch Abschnitt 4.2.6, „Index-Merge-Optimierung“.

Sie können das Problem auch effizient mithilfe einer Union lösen, die die Ausgabe zweier getrennter SELECT-Anweisungen zusammenfasst. Siehe auch Abschnitt 8.2.8.3, „UNION.

Jede SELECT-Anweisung sucht nur über einen Schlüssel und kann optimiert werden:

SELECT field1_index, field2_index
    FROM test_table WHERE field1_index = '1'
UNION
SELECT field1_index, field2_index
    FROM test_table WHERE field2_index = '1';

1.6.8. Berechnen von Besuchen pro Tag

Das folgende Beispiel zeigt, wie Sie die Bitgruppenfunktionen zur Berechnung der Anzahl von Tagen im Monat verwenden können, an denen ein Benutzer eine bestimmte Webseite besucht hat.

CREATE TABLE t1 (year YEAR(4), month INT(2) UNSIGNED ZEROFILL,
             day INT(2) UNSIGNED ZEROFILL);
INSERT INTO t1 VALUES(2000,1,1),(2000,1,20),(2000,1,30),(2000,2,2),
            (2000,2,23),(2000,2,23);

Die Beispieltabelle enthält Jahr/Monat/Tag-Werte, die die Besuche von Benutzern auf der Seite repräsentieren. Um zu ermitteln, an wie vielen verschiedenen Tagen in den einzelnen Monaten diese Besuche stattfanden, verwenden Sie folgende Abfrage:

SELECT year,month,BIT_COUNT(BIT_OR(1<<day)) AS days FROM t1
       GROUP BY year,month;

Das Ergebnis sieht wie folgt aus:

+------+-------+------+
| year | month | days |
+------+-------+------+
| 2000 |    01 |    3 |
| 2000 |    02 |    2 |
+------+-------+------+

Die Abfrage berechnet, wie viele verschiedene Tage in der Tabelle für jede Jahr/Monat/Tag-Kombination erscheinen, und entfernt doppelte Einträge dabei automatisch.

1.6.9. Verwenden von AUTO_INCREMENT

Das Attribut AUTO_INCREMENT kann zur Erzeugung einer eindeutigen Kennung für neue Datensätze verwendet werden:

CREATE TABLE animals (
     id MEDIUMINT NOT NULL AUTO_INCREMENT,
     name CHAR(30) NOT NULL,
     PRIMARY KEY (id)
 );
INSERT INTO animals (name) VALUES
    ('dog'),('cat'),('penguin'),
    ('lax'),('whale'),('ostrich');
SELECT * FROM animals;

Das Ergebnis sieht wie folgt aus:

+----+---------+
| id | name    |
+----+---------+
|  1 | dog     |
|  2 | cat     |
|  3 | penguin |
|  4 | lax     |
|  5 | whale   |
|  6 | ostrich |
+----+---------+

Sie können den aktuellen AUTO_INCREMENT-Wert mit der SQL-Funktion LAST_INSERT_ID() oder der C-API-Funktion mysql_insert_id() abrufen. Diese Funktionen sind verbindungsspezifisch, d. h., ihre Rückgabewerte werden nicht durch eine andere Verbindung beeinträchtigt, die ebenfalls Einfügeoperationen durchführt.

Anmerkung

Bei mehrzeiligen Einfügeoperationen geben LAST_INSERT_ID() und mysql_insert_id() den AUTO_INCREMENT-Schlüssel des ersten eingefügten Datensatzes zurück. Auf diese Weise lassen sich mehrzeilige Einfügeoperationen auch von anderen Servern in einer Replikationskonfiguration korrekt nachvollziehen.

Bei MyISAM-Tabellen können Sie AUTO_INCREMENT in einer Sekundärspalte eines mehrspaltigen Indexes angeben. In diesem Fall wird der erzeugte Wert der AUTO_INCREMENT-Spalte als MAX(auto_increment_column) + 1 WHERE prefix=given-prefix berechnet. Dies ist praktisch, wenn Sie Daten in sortierte Gruppen eingeben wollen.

CREATE TABLE animals (
    grp ENUM('fish','mammal','bird') NOT NULL,
    id MEDIUMINT NOT NULL AUTO_INCREMENT,
    name CHAR(30) NOT NULL,
    PRIMARY KEY (grp,id)
) ENGINE=MyISAM;
INSERT INTO animals (grp,name) VALUES
    ('mammal','dog'),('mammal','cat'),
    ('bird','penguin'),('fish','lax'),('mammal','whale'),
    ('bird','ostrich');
SELECT * FROM animals ORDER BY grp,id;

Das Ergebnis sieht wie folgt aus:

+--------+----+---------+
| grp    | id | name    |
+--------+----+---------+
| fish   |  1 | lax     |
| mammal |  1 | dog     |
| mammal |  2 | cat     |
| mammal |  3 | whale   |
| bird   |  1 | penguin |
| bird   |  2 | ostrich |
+--------+----+---------+

In diesem Fall (wenn die AUTO_INCREMENT-Spalte Teil eines mehrspaltigen Index ist) werden AUTO_INCREMENT-Werte neu verwendet, wenn Sie den Datensatz mit dem höchsten AUTO_INCREMENT-Wert in einer beliebigen Gruppe löschen. Dies gilt auch für MyISAM-Tabellen, bei denen AUTO_INCREMENT-Werte normalerweise nicht wiederverwendet werden.

Wenn die AUTO_INCREMENT-Spalte Bestandteil mehrerer Indizes ist, erzeugt MySQL Folgewerte auf der Basis des Indexes, der mit der AUTO_INCREMENT-Spalte beginnt (sofern er vorhanden ist). Wenn also die Tabelle animals die Indizes PRIMARY KEY (grp, id) und INDEX (id) enthielte, würde MySQL den Index PRIMARY KEY bei der Erstellung von Folgewerten ignorieren. Das Ergebnis wäre eine Tabelle, die eine einzelne Folge (und nicht eine Folge pro grp-Wert) enthalten würde.

Wenn Sie bei einem anderen AUTO_INCREMENT-Wert als 1 beginnen wollen, können Sie diesen Wert mit CREATE TABLE oder ALTER TABLE wie folgt festlegen:

mysql> ALTER TABLE tbl AUTO_INCREMENT = 100;

Weitere Informationen zu AUTO_INCREMENT finden Sie hier:

1.7. Abfragen aus dem Twin-Projekt

An den Orten, wo das frühe MySQL entwickelt wurde (Analytikerna und Lentus), führten die Gründer System- und Vor-Ort-Arbeiten für ein großes Forschungsprojekt aus. Dieses Projekt war eine Zusammenarbeit zwischen dem Institut für Umweltmedizin am Karolinska Institutet in Stockholm und der Abteilung für klinische Forschung bei Altersprozessen und Psychologie an der University of Southern California.

Für das Projekt wurden viele Daten von allen Zwillingen in Schweden erfasst, die älter als 65 Jahre waren (http://ki.se/ki/jsp/polopoly.jsp?d=9610&l=en ).

Für große Teile des Projekts kam zu Verwaltungszwecken eine Weboberfläche zum Einsatz, die in Perl und MySQL geschrieben war.

1.7.1. Ermitteln aller nicht verteilten Zwillinge

Die folgende Abfrage wurde verwendet, um zu entscheiden, welche Zwillinge nach einem Anfangsscreening weiter untersucht werden sollten. Sie wurde ca. 1997 mit MySQL 3.19 geschrieben.

SELECT
    CONCAT(p1.id, p1.tvab) + 0 AS tvid,
    CONCAT(p1.christian_name, ' ', p1.surname) AS Name,
    p1.postal_code AS Code,
    p1.city AS City,
    pg.abrev AS Area,
    IF(td.participation = 'Aborted', 'A', ' ') AS A,
    p1.dead AS dead1,
    l.event AS event1,
    td.suspect AS tsuspect1,
    id.suspect AS isuspect1,
    td.severe AS tsevere1,
    id.severe AS isevere1,
    p2.dead AS dead2,
    l2.event AS event2,
    h2.nurse AS nurse2,
    h2.doctor AS doctor2,
    td2.suspect AS tsuspect2,
    id2.suspect AS isuspect2,
    td2.severe AS tsevere2,
    id2.severe AS isevere2,
    l.finish_date
FROM
    twin_project AS tp
    /* For Twin 1 */
    LEFT JOIN twin_data AS td ON tp.id = td.id
              AND tp.tvab = td.tvab
    LEFT JOIN informant_data AS id ON tp.id = id.id
              AND tp.tvab = id.tvab
    LEFT JOIN harmony AS h ON tp.id = h.id
              AND tp.tvab = h.tvab
    LEFT JOIN lentus AS l ON tp.id = l.id
              AND tp.tvab = l.tvab
    /* For Twin 2 */
    LEFT JOIN twin_data AS td2 ON p2.id = td2.id
              AND p2.tvab = td2.tvab
    LEFT JOIN informant_data AS id2 ON p2.id = id2.id
              AND p2.tvab = id2.tvab
    LEFT JOIN harmony AS h2 ON p2.id = h2.id
              AND p2.tvab = h2.tvab
    LEFT JOIN lentus AS l2 ON p2.id = l2.id
              AND p2.tvab = l2.tvab,
    person_data AS p1,
    person_data AS p2,
    postal_groups AS pg
WHERE
    /* p1 gets main twin and p2 gets his/her twin. */
    /* ptvab is a field inverted from tvab */
    p1.id = tp.id AND p1.tvab = tp.tvab AND
    p2.id = p1.id AND p2.ptvab = p1.tvab AND
    /* Just the screening survey */
    tp.survey_no = 5 AND
    /* Skip if partner died before 65 but allow emigration (dead=9) */
    (p2.dead = 0 OR p2.dead = 9 OR
     (p2.dead = 1 AND
      (p2.death_date = 0 OR
       (((TO_DAYS(p2.death_date) - TO_DAYS(p2.birthday)) / 365)
        >= 65))))
    AND
    (
    /* Twin is suspect */
    (td.future_contact = 'Yes' AND td.suspect = 2) OR
    /* Twin is suspect - Informant is Blessed */
    (td.future_contact = 'Yes' AND td.suspect = 1
                               AND id.suspect = 1) OR
    /* No twin - Informant is Blessed */
    (ISNULL(td.suspect) AND id.suspect = 1
                        AND id.future_contact = 'Yes') OR
    /* Twin broken off - Informant is Blessed */
    (td.participation = 'Aborted'
     AND id.suspect = 1 AND id.future_contact = 'Yes') OR
    /* Twin broken off - No inform - Have partner */
    (td.participation = 'Aborted' AND ISNULL(id.suspect)
                                  AND p2.dead = 0))
    AND
    l.event = 'Finished'
    /* Get at area code */
    AND SUBSTRING(p1.postal_code, 1, 2) = pg.code
    /* Not already distributed */
    AND (h.nurse IS NULL OR h.nurse=00 OR h.doctor=00)
    /* Has not refused or been aborted */
    AND NOT (h.status = 'Refused' OR h.status = 'Aborted'
    OR h.status = 'Died' OR h.status = 'Other')
ORDER BY
    tvid;

Hierzu ein paar Anmerkungen:

  • CONCAT(p1.id, p1.tvab) + 0 AS tvid

    Die verketteten Werte id und tvab sollen in numerischer Reihenfolge sortiert werden. Durch Hinzufügen von 0 zum Ergebnis wird MySQL dazu veranlasst, dieses Ergebnis als Zahl zu betrachten.

  • Spalte id

    Bezeichnet ein Zwillingspaar. Ist ein Index in allen Tabellen.

  • Spalte tvab

    Bezeichnet einen Zwilling in einem Paar. Der Wert ist entweder 1 oder 2.

  • Spalte ptvab

    Dies ist das Gegenstück zu tvab. Wenn tvab 1 ist, dann ist dieser Wert 2 und umgekehrt. Zweck ist die Einsparung von Tipparbeit und eine vereinfachte Optimierung der Abfrage durch MySQL.

Diese Abfrage veranschaulicht unter anderem, wie man Daten in einer Tabelle mithilfe eines Joins von derselben Tabelle aus durchführt (p1 und p2). Im Beispiel wird dieser Join verwendet, um zu überprüfen, ob der Partner eines Zwillings vor dem Erreichen des Alters 65 Jahre starb. Wenn ja, wird der Datensatz nicht zurückgegeben.

Alle genannten Elemente sind in allen Tabellen mit Informationen zu den Zwillingen vorhanden. Um Abfragen zu beschleunigen, wurde ein Index sowohl auf id, tvab (alle Tabellen) als auch auf id, ptvab (person_data) erstellt.

Als wir diese Arbeit machten, war unser Produktionsrechner eine 200-MHz-UltraSPARC, und auf dieser alten Hardware gab diese Abfrage ca. 150 bis 200 Datensätze in weniger als einer Sekunde zurück. Die Haupttabelle hatte 70.000 Datensätze.

1.7.2. Anzeigen einer Tabelle mit dem Zwillingspaar-Status

Jeder Zwilling hat einen Statuscode, das sog. event. Die nachfolgend gezeigte Abfrage wird zur Auswahl aller Zwillingspaare mit zugeordnetem Statuscode verwendet. Sie zeigt an, bei wie vielen Paaren beide Zwillinge zugelassen wurden, bei wie vielen Paaren nur ein Zwilling zugelassen (und der andere abgelehnt) wurde usw.

SELECT
        t1.event,
        t2.event,
        COUNT(*)
FROM
        lentus AS t1,
        lentus AS t2,
        twin_project AS tp
WHERE
        /* We are looking at one pair at a time */
        t1.id = tp.id
        AND t1.tvab=tp.tvab
        AND t1.id = t2.id
        /* Just the screening survey */
        AND tp.survey_no = 5
        /* This makes each pair only appear once */
        AND t1.tvab='1' AND t2.tvab='2'
GROUP BY
        t1.event, t2.event;

1.8. Verwenden von MySQL mit Apache

Es gibt Programme, die Ihnen die Authentifizierung Ihrer Benutzer aus einer MySQL-Datenbank gestatten und gleichzeitig das Schreiben der Logdateien in eine MySQL-Tabelle ermöglichen.

Sie können das Apache-Logformat so ändern, dass es leichter von MySQL gelesen werden kann. Hierzu fügen Sie Folgendes in Ihre Apache-Konfigurationsdatei ein:

LogFormat \
        "\"%h\",%{%Y%m%d%H%M%S}t,%>s,\"%b\",\"%{Content-Type}o\",  \
        \"%U\",\"%{Referer}i\",\"%{User-Agent}i\""

Um eine Logdatei in diesem Format in MySQL einzuladen, können Sie etwa folgende Anweisung verwenden:

LOAD DATA INFILE '/local/access_log' INTO TABLE tbl_name
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\'

Die benannte Tabelle sollte so erstellt sein, dass sie Spalten aufweist, die denen entsprechen, welche die Zeile LogFormat in die Logdatei schreibt.

Kapitel 2. Installieren und Aktualisieren von MySQL

Inhaltsverzeichnis

2.1. Allgemeines zur Installation
2.1.1. Betriebssysteme, die von MySQL Community Server unterstützt werden
2.1.2. Auswählen der MySQL-Distribution für die Installation
2.1.3. Wo können Sie MySQL beziehen?
2.1.4. Bestätigen der Paketintegrität mittels MD5-Prüfsummen oder GnuPG
2.1.5. Installationslayout
2.2. MySQL-Standardinstallation mithilfe einer Binärdistribution
2.3. Installieren von MySQL unter Windows
2.3.1. Wählen eines Installationspakets
2.3.2. Installieren von MySQL mit dem automatischen Installer
2.3.3. Verwenden des MySQL-Installations-Assistenten
2.3.4. MySQL Server-Konfigurations-Assistent
2.3.5. Installieren von MySQL aus einem Noinstall-Zip-Archiv
2.3.6. Entpacken des Installationsarchivs
2.3.7. Erstellen einer Optionsdatei
2.3.8. Auswählen eines MySQL Server-Typs
2.3.9. Erstmaliges Starten des Servers
2.3.10. Starten von MySQL aus der Windows-Befehlszeile
2.3.11. Starten von MySQL als Windows-Dienst
2.3.12. Testen der MySQL-Installation
2.3.13. Fehlersuche und -behebung in MySQL-Installationen unter Windows
2.3.14. Aktualisieren von MySQL unter Windows
2.3.15. MySQL unter Windows im Vergleich zu MySQL unter Unix
2.4. Installieren von MySQL aus RPM-Paketen unter Linux
2.5. Installieren von MySQL unter Mac OS X
2.6. Installieren von MySQL unter Solaris
2.7. Installieren von MySQL unter i5/OS
2.8. Installieren von MySQL auf NetWare
2.9. Installieren von MySQL aus tar.gz-Paketen auf anderen Unix-ähnlichen Systemen
2.10. MySQL-Installation mittels Quelldistribution
2.10.1. Überblick Quelleninstallation
2.10.2. Typische configure-Optionen
2.10.3. Installation vom Entwicklungs-Source-Tree
2.10.4. Probleme beim Kompilieren von MySQL
2.10.5. Anmerkungen zu MIT-pthreads
2.10.6. Installieren von MySQL unter Windows aus dem Quellcode
2.10.7. Kompilieren von MySQL-Clients unter Windows
2.11. Einstellungen und Tests nach der Installation
2.11.1. Schritte nach der Installation unter Windows
2.11.2. Schritte nach der Installation unter Unix
2.11.3. Kennwortschutz für vorgabeseitige MySQL-Konten
2.12. Aktualisieren von MySQL mittels Upgrade/Downgrade
2.12.1. Upgrade von MySQL
2.12.2. Downgrade von MySQL
2.12.3. Prüfen ob Tabellenindizes neu erstellt werden müssen
2.12.4. Reparieren und Neuerstellen von Tabellen und Indizes
2.12.5. Kopieren von MySQL-Datenbanken auf einen anderen Rechner
2.13. Betriebssystemspezifische Anmerkungen
2.13.1. Anmerkungen zu Linux
2.13.2. Anmerkungen zu Mac OS X
2.13.3. Anmerkungen zu Solaris
2.13.4. Anmerkungen zu BSD
2.13.5. Anmerkungen zu anderen unixartigen Systemen
2.14. Umgebungsvariablen
2.15. Anmerkungen zur Perl-Installation
2.15.1. Installieren von Perl unter Unix
2.15.2. Installieren von ActiveState Perl unter Windows
2.15.3. Probleme bei der Benutzung der DBI/DBD-Schnittstelle von Perl

Dieses Kapitel beschreibt, wie Sie sich MySQL beschaffen und installieren. Zunächst folgt eine Zusammenfassung der Vorgehensweise; die Details werden dann im weiteren Verlauf beschrieben. Wenn Sie MySQL nicht zum ersten Mal installieren, sondern eine vorhandene MySQL-Version auf eine neuere Version aktualisieren wollen, dann finden Sie weitere Informationen zur Vorgehensweise und zu Gesichtspunkten, die vor dem Upgrade beachtet werden müssen, in Abschnitt 2.12.1, „Upgrade von MySQL“.

Wenn Sie an einer Migration von einem anderen Datenbanksystem auf MySQL interessiert sind, lesen Sie bitte zunächst MySQL 5.1 FAQ: Migration. Hier werden einige häufige Fragen zu Problemen bei der Migration beantwortet.

  1. Ermitteln Sie, ob Ihre Plattform unterstützt wird. Bitte beachten Sie, dass nicht alle Plattformen gleichermaßen zur Ausführung von MySQL geeignet sind und nicht alle Plattformen, auf denen MySQL ausgeführt werden kann, offiziell von Sun Microsystems, Inc. unterstützt werden:

  2. Wählen Sie die zu installierende Distribution. Es sind verschiedene MySQL-Versionen verfügbar, die meisten davon in unterschiedlichen Distributionsformaten. Sie können zwischen fertig gepackten Distributionen mit binären (vorkompilierten) Programmen und dem Quellcode wählen. Entscheiden Sie sich im Zweifelsfall für eine binäre Distribution. Für Benutzer, die unsere aktuellsten Entwicklungen sehen und uns beim Testen des neuesten Codes helfen wollen, bieten wir auch einen öffentlichen Zugang zum aktuellen Source-Tree. Wie Sie bestimmen, welche Version und welchen Distributionstyp Sie verwenden sollten, erfahren Sie in Abschnitt 2.1.2, „Auswählen der MySQL-Distribution für die Installation“.

  3. Laden Sie die Distribution herunter, die Sie installieren wollen. Informationen zur Vorgehensweise finden Sie in Abschnitt 2.1.3, „Wo können Sie MySQL beziehen?“. Um die Integrität der Distribution zu überprüfen, gehen Sie vor wie in Abschnitt 2.1.4, „Bestätigen der Paketintegrität mittels MD5-Prüfsummen oder GnuPG, beschrieben.

  4. Installieren Sie die Distribution. Um MySQL aus einer binären Distribution zu installieren, gehen Sie vor wie in Abschnitt 2.2, „MySQL-Standardinstallation mithilfe einer Binärdistribution“ beschrieben. Wenn Sie MySQL hingegen aus einer Quelldistribution oder aus dem aktuellen Entwicklungs-Source-Tree installieren, gehen Sie vor wie in Abschnitt 2.10, „MySQL-Installation mittels Quelldistribution“, beschrieben.

    Wenn Sie bei der Installation Probleme haben, finden Sie plattformspezifische Hinweise zu deren Beseitigung in Abschnitt 2.13, „Betriebssystemspezifische Anmerkungen“.

  5. Führen Sie die nach der Installation erforderlichen Konfigurationsschritte durch.? Lesen Sie nach der Installation von MySQL Abschnitt 2.11, „Einstellungen und Tests nach der Installation“. Dieser Abschnitt enthält wichtige Informationen dazu, wie Sie den einwandfreien Betrieb des MySQL Servers sicherstellen. Ferner ist dort beschrieben, wie Sie die bei der Installation erstellten MySQL-Benutzerkonten, die anfangs keine Passwörter aufweisen, bis zur Konfiguration von Passwörtern sichern. Die in diesem Abschnitt enthaltenen Informationen gelten unabhängig davon, ob Sie MySQL mithilfe einer Binär- oder einer Quelldistribution installieren.

  6. Wenn Sie die MySQL-Benchmark-Skripten ausführen wollen, muss der Perl-Support für MySQL eingerichtet sein. Siehe auch Abschnitt 2.15, „Anmerkungen zur Perl-Installation“.

2.1. Allgemeines zur Installation

Die Vorgehensweise bei der Installation von MySQL hängt davon ab, ob Sie MySQL Enterprise Server oder MySQL Community Server installieren wollen. Die möglichen Plattformen sind davon abhängig, welche Distribution Sie installieren:

Für MySQL Enterprise Server installieren Sie die Hauptdistribution sowie etwaig gewünschte Service Packs oder Hotfixes mit dem Enterprise Installer. Für Plattformen, auf denen sich noch kein Enterprise Installer befindet, gehen Sie nach den Anweisungen für den Community Server vor.

Für MySQL Community Server installieren Sie die Hauptdistribution sowie etwaige Hotfixes und Updates:

  • Laden Sie ein binäres Release oder ein Quell-Release herunter und erstellen Sie MySQL selbst anhand des Quellcodes.

  • Rufen Sie MySQL aus dem Bazaar-Baum ab und erstellen Sie es mit dem Quellcode. Der Bazaar-Baum enthält den aktuellen Entwicklercode.

Die folgenden Abschnitte enthalten die Informationen, die Sie zur Auswahl, zum Herunterladen und zum Bestätigen Ihrer Distribution benötigen. Die Anweisungen in späteren Abschnitten des Kapitels beschreiben, wie Sie Ihre gewählte Distribution installieren. Die Anweisungen für binäre Distributionen finden Sie unter Abschnitt 2.2, „MySQL-Standardinstallation mithilfe einer Binärdistribution“. Zum Erstellen von MySQL aus dem Quellcode gehen Sie entsprechend der Beschreibung unter Abschnitt 2.10, „MySQL-Installation mittels Quelldistribution“ vor.

2.1.1. Betriebssysteme, die von MySQL Community Server unterstützt werden

Dieser Abschnitt listet die Betriebssysteme auf, auf denen die Ausführung von MySQL Community Server möglich ist.

Wichtig

Sun Microsystems, Inc. bietet nicht unbedingt für alle in diesem Abschnitt auflisteten Plattformen offizielle Unterstützung. Informationen zu den offiziell unterstützten Plattformen finden Sie unter MySQL Server Supported Platforms auf der MySQL-Website.

Wir verwenden GNU Autoconf, weswegen eine Portierung von MySQL auf alle modernen Systeme möglich ist, die einen C++-Compiler und eine funktionsfähige Implementierung von POSIX-Threads enthalten. (Die Thread-Unterstützung wird für den Server benötigt. Wenn Sie nur den Clientcode kompilieren wollen, benötigen Sie lediglich den C++-Compiler.)

Berichten zufolge lässt sich MySQL erfolgreich auf den nachfolgend aufgeführten Kombinationen aus Betriebssystem und Thread-Paket kompilieren.

MySQL wurde bekanntermaßen in der Vergangenheit auch auf anderen Systemen ausgeführt. Siehe auch Abschnitt 2.13, „Betriebssystemspezifische Anmerkungen“. Gegebenenfalls sind auf diesen Systemen einzelne Portierungsmaßnahmen für aktuelle MySQL-Versionen notwendig.

Nicht alle Plattformen sind für die Ausführung von MySQL gleichermaßen geeignet. Die Eignung einer Plattform für einen unternehmenskritischen, stark beanspruchten MySQL Server wird von den folgenden Faktoren bestimmt:

  • Allgemeine Stabilität der Thread-Bibliothek. Auch auf Plattformen, die ansonsten einen exzellenten Ruf genießen, ist MySQL nur so stabil wie die aufgerufene Thread-Bibliothek – und zwar auch dann, wenn alles andere perfekt ist.

  • Die Funktionalität des Kernels und der Thread-Bibliothek bezüglich der optimalen Nutzung von SMP-Systemen (symmetrischen Multiprozessorsystemen). Mit anderen Worten: Wenn ein Prozess einen Thread erstellt, sollte dieser auf einem anderen Prozessor laufen können als der ursprüngliche Prozess.

  • Die Fähigkeit von Kernel und Thread-Bibliothek, mehrere Threads auszuführen, die häufig ein Mutex für einen kurzen kritischen Bereich ohne umfassende Kontextschalter setzen, und aufzuheben. Wenn die Implementierung von pthread_mutex_lock() zu zurückhaltend bei der Bereitstellung von Prozessorzeit ist, wird MySQL hierdurch empfindlich gestört. Wird dieser Aspekt nicht berücksichtigt, dann macht das Ergänzen zusätzlicher Prozessoren MySQL tatsächlich langsamer.

  • Allgemeine Stabilität und Leistungsfähigkeit des Dateisystems.

  • Tabellengröße. Wenn Ihre Tabellen sehr groß werden, steht und fällt die Leistung mit der Fähigkeit des Dateisystems, mit großen Dateien nicht nur überhaupt, sondern sogar effizient umgehen zu können.

  • Unser eigenes Fachwissen hier bei Sun Microsystems, Inc. bezüglich der Plattform. Kennen wir eine Plattform gut, dann können wir plattformspezifische Optimierungen und Fehlerbehebungen bei der Kompilierung aktivieren. Außerdem können wir Informationen zur optimalen Konfiguration Ihres Systems für MySQL vermitteln.

  • Der Umfang der Tests, die wir intern für ähnliche Konfigurationen durchgeführt haben.

  • Die Anzahl der Benutzer, die MySQL erfolgreich auf Plattformen mit ähnlichen Konfigurationen verwenden. Ist diese Zahl groß, dann ist die Wahrscheinlichkeit plattformspezifischer Überraschungen eher gering.

2.1.2. Auswählen der MySQL-Distribution für die Installation

Wenn Sie die Installation von MySQL vorbereiten, sollten Sie entscheiden, welche Version Sie benutzen. Die Entwicklung von MySQL erfolgt in mehreren Release-Serien, von denen Sie sich die für Ihre Zwecke geeignetste auswählen können. Wenn Sie sich für eine Version entschieden haben, können Sie ein Distributionsformat auswählen. Releases sind im Binär- und im Quellformat verfügbar.

2.1.2.1. Auswählen der MySQL-Version für die Installation

Die erste zu treffende Entscheidung ist die, ob Sie einen (stabilen) Produktions-Release oder aber einen Entwicklungs-Release verwenden wollen. Im MySQL-Entwicklungsprozess koexistieren mehrere Release-Serien miteinander, die sich alle durch ihren Grad der Ausgereiftheit voneinander unterscheiden:

  • MySQL 5.4 und 6.0 sind die aktuellen Entwicklungs-Release-Serien.

  • MySQL 5.1 ist die aktuelle General-Availability-Release-Serie (Produktion). Neue Releases erscheinen nur bei Vorhandensein von Bugfixes; neue Funktionalitäten werden nicht ergänzt, da sie die Stabilität beeinträchtigen könnten.

  • MySQL 5.0 ist die vorherige stabile Release-Serie für Produktionsumgebungen.

  • MySQL 4.1, 4.0 und 3.23 sind die alten stabilen Release-Serien für Produktionsumgebungen. MySQL 4.1 befindet sich jetzt am Ende der Produktlebensdauer. Die aktive Entwicklung und der Support für diese Versionen wurden eingestellt.

    Der erweiterte Support für MySQL 4.1 ist weiter verfügbar. Gemäß der MySQL Lifecycle Policy werden für MySQL 4.1 nur noch Sicherheitsprobleme und Probleme der Sicherheitsstufe 1 behoben.

Wir halten ein endgültiges Einfrieren von Codes nicht für machbar, da dies Bugfixes und andere Fehlerbereinigungen, die erforderlich sind, unmöglich machen würde. Das von uns bevorzugte „Teileinfrieren“ erlaubt uns das Ergänzen von Kleinigkeiten, die sich nicht auf die Einsatzfähigkeit eines Produktions-Releases auswirken sollten. Natürlich pflanzen sich wesentliche Bugfixes in früheren Serien auch auf ihre jeweiligen Nachfolger fort.

Wenn Sie MySQL zum ersten Mal verwenden oder es auf ein System portieren wollen, für das keine binäre Distribution verfügbar ist, verwenden Sie die General-Availability-Release-Serie. Gegenwärtig ist das MySQL 5.1. Alle MySQL-Releases – auch die der Entwicklungsserie – werden vor der Veröffentlichung mit den MySQL-Benchmarks und der umfangreichen Testsuite überprüft.

Wenn Sie ein älteres System verwenden und ein Upgrade durchführen möchten, gleichzeitig aber Probleme bei der Aktualisierung vermeiden möchten, sollten Sie auf die aktuelle Version derselben Release-Serie aktualisieren, die Sie bereits verwenden (hierbei ist nur der letzte Teil der Versionsnummer höher als bei der von Ihnen verwendeten Version). Wir haben lediglich versucht, kritische Bugs zu beheben und kleine, relativ „sichere“ Änderungen an dieser Version vorzunehmen.

Wenn Sie neue Funktionen verwenden wollen, die nicht in der Produktions-Release-Serie vorhanden sind, können Sie sich auch für eine Version aus der Entwicklungsserie entscheiden. Beachten Sie, dass die Entwicklungs-Releases nicht so stabil sind wie die Produktions-Releases.

Wollen Sie die allerneuesten Quellcodes mit allen aktuellen Patches und Bugfixes einsetzen, dann können Sie eines unserer Bazaar-Repositorys verwenden. Dies sind nicht „Releases“ im eigentlichen Sinne, sondern Vorabversionen des Codes, auf dem zukünftige Releases basieren werden.

Das MySQL-Benennungsschema verwendet Release-Namen, die aus drei Zahlen und einem Suffix bestehen. Dies kann etwa so aussehen: mysql-5.0.12-beta. Die Zahlen im Release-Namen sind wie folgt zu interpretieren:

  • Die erste Zahl (5) ist die Hauptversion und beschreibt das Dateiformat. Alle MySQL 5-Releases haben das gleiche Dateiformat.

  • Die zweite Zahl (0) ist der Release-Level. Zusammengefasst bilden Hauptversion und Release-Level die Nummer der Release-Serie.

  • Die dritte Zahl (12) ist die Versionsnummer innerhalb der Release-Serie. Diese wird bei jedem neuen Release um den Wert 1 erhöht. In der Regel sollten Sie immer die neueste Version in der von Ihnen gewählten Serie verwenden.

Bei kleineren Updates wird jeweils die letzte Zahl im Versions-String hochgezählt. Liegen wesentliche Neuerungen bei den Merkmalen oder kleinere Inkompatibilitäten mit vorherigen Versionen vor, dann wird die zweite Zahl im Versions-String hochgezählt. Ändert sich schließlich das Dateiformat, dann wird die erste Zahl erhöht.

Release-Namen enthalten auch ein Suffix, welches die Stabilitätsstufe für den Release angibt. Releases innerhalb einer Serie durchschritten eine bestimmte Abfolge von Suffixen, die jeweils anzeigen, wie sich die Stabilität erhöht. Mögliche Suffixe sind die folgenden:

  • Alpha zeigt an, dass das Release nur für die Vorschau vorgesehen ist. Bekannte Bugs sollten im Abschnitt ?News“ dokumentiert sein (siehe auch MySQL Change History). Die meisten Alpha-Releases implementieren neue Befehle und Erweiterungen. Die aktive Entwicklung, die auch umfassende Änderungen am Code beinhalten kann, erfolgt in der Alphaphase. Allerdings werden vor der Veröffentlichung eines Releases Tests durchgeführt.

  • Beta zeigt an, dass das Release mit Neuentwicklungen zur Verwendung geeignet ist. In Beta-Releases sollten die Funktionen und die Kompatibilität unverändert bleiben. Allerdings können Beta-Releases zahlreiche und größere, nicht behobene Bugs enthalten.

    Bei zukünftigen Beta-, Release-Candidate- oder Produktions-Releases erfolgen keine Änderungen mehr an APIs, extern sichtbaren Strukturen und Spalten für SQL-Anweisungen.

  • rc ist ein Release-Candidate. Bei Release-Candidates wird davon ausgegangen, dass sie stabil sind. Sie haben alle internen MySQL-Tests durchlaufen, alle kritischen Laufzeit-Bugs wurden behoben. Das Release ist jedoch noch nicht lange genug verbreitet verwendet worden, um mit Sicherheit sagen zu können, dass alle Bugs gefunden worden sind. Es werden nur noch kleinere Fehlerkorrekturen vorgenommen. (Ein Release-Candidate entspricht dem, was man früher als Gamma-Release bezeichnete.)

  • Ist kein Suffix vorhanden, dann bedeutet dies, dass es sich um ein GA-Release (General Availability, allgemeine Verfügbarkeit) oder Produktions-Release handelt. GA-Releases sind stabil, haben alle vorhergehenden Release-Stadien erfolgreich absolviert und gelten als zuverlässig, frei von ernsten Bugs und für die Verwendung in Produktionssystemen geeignet. Bei solchen Releases werden nur kritische Bugfixes implementiert.

MySQL verwendet ein Benennungsschema, welches sich geringfügig von dem anderer Produkte unterscheidet. In der Regel können Sie problemlos jede Version einsetzen, die bereits seit ein paar Wochen verfügbar ist, ohne durch eine neue Version innerhalb derselben Release-Serie ersetzt worden zu sein.

Alle MySQL-Releases werden mit unseren Standardtests und Benchmarks überprüft, damit gewährleistet ist, dass ihr Einsatz relativ sicher ist. Da die Standardtests im Laufe der Zeit so erweitert werden, dass alle zuvor gefundenen Bugs berücksichtigt werden, wird unsere Testsuite immer besser.

Alle Releases wurden zumindest mit den folgenden Tools getestet:

  • Einer internen Testsuite.

    Das Verzeichnis mysql-test enthält ein umfangreiches Set mit Testfällen. Wir führen diese Tests an jeder Server-Binärdistribution durch. Weitere Informationen zur Testsuite finden Sie in MySQL Test Suite.

  • MySQL-Benchmarks.

    Diese Reihe führt eine Anzahl gängiger Abfragen aus. Ferner ermöglicht sie zu bestimmen, ob der letzte Optimierungsstapel den Code tatsächlich beschleunigt hat. Siehe auch Abschnitt 4.1.4, „Die MySQL-Benchmark-Suite“.

  • Crash-Me-Test.

    Dieser Test versucht zu ermitteln, welche Funktionen die Datenbank unterstützt und welche Fähigkeiten und Einschränkungen vorhanden sind. Siehe auch Abschnitt 4.1.4, „Die MySQL-Benchmark-Suite“.

Wir testen außerdem die neueste MySQL-Version immer auf zumindest einem System in unserer internen Produktionsumgebung. Dabei stehen uns mehr als 100 Gbyte Daten zum Arbeiten zur Verfügung.

2.1.2.2. Auswählen eines Distributionsformats

Nachdem Sie die zu installierende MySQL-Version gewählt haben, müssen Sie noch festlegen, ob eine binäre oder eine Quelldistribution für die Installation verwendet werden soll. In den meisten Fällen werden Sie sich wahrscheinlich für die Binärdistribution entscheiden, sofern es für Ihre Plattform eine solche gibt. Binärdistributionen sind für viele Plattformen im nativen Format verfügbar, z. B. RPM-Dateien für Linux oder PKG-Paket-Installer für Mac OS X oder Solaris. Distributionen sind außerdem als Zip-Archive oder komprimierte tar-Dateien erhältlich.

Die folgenden Gründe sprechen für die Verwendung einer Binärdistribution:

  • Binärdistributionen sind in der Regel einfacher zu installieren als Quelldistributionen.

  • Um unterschiedliche Benutzeranforderungen zu erfüllen, bieten wir verschiedene Server als Binärdistribution. mysqld ist ein optimierter Server, und zwar eine kleinere, schnellere Binärdatei. mysqld-Debug ist mit Debug-Support kompiliert.

    Jeder dieser Server wird von der gleichen Quelldistribution, jedoch mit unterschiedlichen Konfigurationsoptionen, kompiliert. Alle nativen MySQL-Clients können mit Servern aus beiden MySQL-Versionen Verbindungen herstellen.

Unter bestimmten Umständen kann es auch von Vorteil sein, MySQL aus einer Quelldistribution heraus zu installieren:

  • Sie wollen MySQL an einer expliziten Position installieren. Die Standardbinärdistributionen lassen sich an jeder Installationsposition ausführen, aber unter Umständen benötigen Sie noch mehr Flexibilität, um MySQL-Komponenten an jeder beliebigen Stelle abzulegen.

  • Sie wollen mysqld konfigurieren, um sicherzustellen, dass Funktionen, die unter Umständen nicht in den Standardbinärdistributionen enthalten sind, in jedem Fall vorhanden sind. Es folgt eine Liste der meistbenötigten Zusatzoptionen, die Sie verwenden können, um die Verfügbarkeit von Funktionen zu gewährleisten:

    • --with-libwrap

    • --with-named-z-libs (erfolgt für einige der Binärdistributionen)

    • --with-debug[=full]

  • Sie wollen mysqld ohne bestimmte Funktionen konfigurieren, die in den Standardbinärdistributionen enthalten sind. So werden Distributionen beispielsweise mit der Unterstützung für alle Zeichensätze kompiliert. Wenn Sie einen kleineren MySQL Server wünschen, können Sie diesen so kompilieren, dass nur die erforderlichen Zeichensätze unterstützt werden.

  • Sie haben einen speziellen Compiler (z. B. pgcc) oder wollen Compiler-Optionen nutzen, die für Ihren Prozessor besser optimiert sind. Binärdistributionen werden mit Optionen kompiliert, die auf einer Vielzahl von Prozessoren derselben Prozessorfamilie funktionieren sollten.

  • Sie wollen die aktuellsten Quelltexte aus einem der Bazaar-Repositorys verwenden, um Zugang zu allen aktuellen Bugfixes zu haben. Wenn Sie beispielsweise einen Bug gefunden und diesen dem MySQL-Entwicklerteam gemeldet haben, dann wird der Bugfix in das Quellcode-Repository geschrieben, und Sie können dann dort darauf zugreifen. Der Bugfix erscheint in einem Release erst, wenn dieser tatsächlich veröffentlicht wird.

  • Sie wollen den C- oder C++-Code lesen (oder ändern), aus dem MySQL besteht. Zu diesem Zweck sollten Sie sich eine Quelldistribution besorgen, denn der Quellcode ist immer das ultimative Handbuch.

  • Quelldistributionen enthalten mehr Tests und Beispiele als Binärdistributionen. Wann und wie Updates veröffentlicht werden

2.1.2.3. Wann und wie Updates veröffentlicht werden

MySQL entwickelt sich ziemlich schnell, und neue Entwicklungen wollen wir anderen MySQL-Benutzern möglichst umgehend bereitstellen. Deswegen erstellen wir immer dann einen neuen Release, wenn wir neue und nützliche Funktionen integriert haben, die auch für andere Benutzer nützlich oder notwendig sein könnten.

Außerdem versuchen wir Benutzern zu helfen, die nach Funktionen fragen, welche leicht zu implementieren sind. Wir achten darauf, was unsere lizenzierten Benutzer – und insbesondere die Kunden, die unseren Support nutzen – wünschen, und versuchen, ihnen in dieser Hinsicht zu helfen.

Niemand ist gezwungen, einen neuen Release herunterzuladen. Der Abschnitt ?News“ soll Ihnen dabei helfen zu ermitteln, ob im neuen Release etwas dabei ist, was Sie wirklich brauchen. Siehe auch MySQL Change History.

Bei der Aktualisierung von MySQL halten wir uns an die folgenden Richtlinien:

  • Enterprise Server-Releases sollen alle 18 Monate erscheinen und werden durch vierteljährliche Service Packs und monatliche Schnell-Updates ergänzt. Community Server-Releases sollen zwei- bis dreimal jährlich erscheinen.

  • Releases werden innerhalb jeder Serie veröffentlicht. Bei jedem Release ist die letzte Zahl in der Versionsnummer um 1 höher als beim vorherigen Release in der Serie.

  • Binärdistributionen für bestimmte Plattformen werden von uns für Haupt-Releases erstellt. Binärdistributionen für andere Systeme werden von Dritten angefertigt, dies aber wahrscheinlich weniger häufig.

  • Bugfixes werden bereitgestellt, sobald kleine oder unkritische, aber ärgerliche Bugs erkannt und korrigiert wurden. Diese Fixes sind im Quellcode sofort in den Bazaar-Repositorys verfügbar und außerdem Bestandteil des nächsten Releases.

  • Wird durch Zufall eine Sicherheitsschwachstelle oder ein kritischer Bug in einem Release gefunden, dann ist es unser Grundsatz, diese in einem neuen Release schnellstmöglich zu beheben. (Wir wünschten uns, andere Unternehmen würden das auch so handhaben!)

2.1.2.4. Von Sun Microsystems Inc. kompilierte MySQL-Binärdistributionen

Sun Microsystems, Inc. bietet verschiedene MySQL-Binärdistributionen. Neben den Binärdateien in den plattformspezifischen Paketformaten bieten wir für eine Anzahl von Plattformen auch Binärdistributionen in Form komprimierter tar-Dateien (.tar.gz-Dateien) an. Siehe auch Abschnitt 2.2, „MySQL-Standardinstallation mithilfe einer Binärdistribution“. Informationen zu Windows-Distributionen finden Sie in Abschnitt 2.3, „Installieren von MySQL unter Windows“.

Wollen Sie eine Debug-Version von MySQL aus einer Quelldistribution kompilieren, dann sollten Sie die Option --with-debug bzw. --with-debug=full an den für die Distribution verwendeten configure-Befehl anfügen und ggf. vorhandene -fomit-frame-pointer-Optionen entfernen.

2.1.3. Wo können Sie MySQL beziehen?

Informationen zur aktuellen MySQL-Version und Hinweise zum Download finden Sie auf unserer Downloadseite unter http://dev.mysql.com/downloads/. Eine vollständige und aktuelle Liste der Spiegelserver für den MySQL-Download finden Sie unter http://dev.mysql.com/downloads/mirrors.html. Dort erhalten Sie auch Hinweise dazu, wie Sie selbst einen MySQL-Spiegelserver anbieten können und wie Sie ausgefallene oder veraltete Spiegelserver melden.

Unser Hauptspiegelserver befindet sich unter http://mirrors.sunsite.dk/mysql/.

2.1.4. Bestätigen der Paketintegrität mittels MD5-Prüfsummen oder GnuPG

Wenn Sie das für Ihre Zwecke geeignete MySQL-Paket heruntergeladen haben, sollten Sie, bevor Sie die Installation starten, sicherstellen, dass es intakt ist und nicht verändert wurde. Für die Überprüfung der Integrität gibt es drei Methoden:

  • MD5-Prüfsummen

  • Kryptografiesignaturen unter Verwendung von GnuPG (GNU Privacy Guard)

  • die eingebaute RPM-Integritätsprüfmethode für RPM-Pakete

Die folgenden Abschnitte beschreiben, wie diese Methoden verwendet werden.

Wenn Sie feststellen, dass MD5-Prüfsumme oder GPG-Signaturen nicht übereinstimmen, probieren Sie zunächst, das betreffende Paket noch einmal von einem anderen Spiegelserver herunterzuladen. Wenn Sie die Integrität des Pakets mehrfach nicht erfolgreich verifizieren können, teilen Sie uns dies unter Angabe des vollständigen Paketnamens und des verwendeten Downloadservers via E-Mail an die Adresse oder mit. Bitte melden Sie Probleme mit dem Download nicht über das Bugmeldesystem.

2.1.4.1. Verifizieren der MD5-Prüfsumme

Wenn Sie ein MySQL-Paket heruntergeladen haben, sollten Sie sicherstellen, dass die zugehörige MD5-Prüfsumme mit der auf den MySQL-Downloadseiten angegebenen Prüfsumme übereinstimmt. Jedes Paket weist eine individuelle Prüfsumme auf, die Sie mithilfe des folgenden Befehls abfragen können (hierbei ist package_name der Name des heruntergeladenen Pakets):

shell> md5sum package_name

Beispiel:

shell> md5sum mysql-standard-5.1.54-linux-i686.tar.gz
aaab65abbec64d5e907dcd41b8699945  mysql-standard-5.1.54-linux-i686.tar.gz

Vergewissern Sie sich, dass die resultierende Prüfsumme (der angezeigte Hexadezimal-String) mit der Angabe übereinstimmt, die auf der Downloadseite unmittelbar unter dem betreffenden Paket angegeben ist.

Anmerkung

Sie müssen die Prüfsumme der Archivdatei (d. h. der .zip- oder .tar.gz-Datei) verifizieren, nicht die Prüfsumme der Dateien, die im Archiv gespeichert sind.

Beachten Sie, dass nicht alle Betriebssysteme den Befehl md5sum unterstützen. Bei manchen heißt er einfach md5, bei anderen ist er überhaupt nicht enthalten. Bei Linux ist er Teil des Pakets GNU Text Utilities, das für eine Vielzahl von Plattformen verfügbar ist. Sie können den Quellcode auch unter http://www.gnu.org/software/textutils/ herunterladen. Wenn Sie OpenSSL installiert haben, können Sie stattdessen den Befehl openssl md5 package_name verwenden. Eine Windows-Implementierung des Befehls md5 ist unter http://www.fourmilab.ch/md5/ verfügbar. winMd5Sum ist ein grafisches MD5-Prüfwerkzeug, das Sie sich unter http://www.nullriver.com/index/products/winmd5sum beschaffen können.

2.1.4.2. Signaturüberprüfung mit GnuPG

Eine andere Methode zur Überprüfung der Integrität und Authentizität eines Pakets besteht in der Verwendung kryptografischer Signaturen. Diese sind zuverlässiger, aber arbeitsaufwändiger als MD5-Prüfsummen.

Wir signieren die von MySQL herunterladbaren Pakete mit GnuPG (GNU Privacy Guard). GnuPG ist eine Open-Source-Alternative zum bekannten Pretty Good Privacy (PGP) von Phil Zimmermann. Weitere Informationen zu GnuPG sowie zu dessen Download und Installation auf Ihrem System finden Sie unter http://www.gnupg.org/. Die meisten Linux-Distributionen werden mit standardmäßig installiertem GnuPG ausgeliefert. Weitere Informationen zu GnuPG finden Sie unter http://www.openpgp.org/.

Um die Signatur für ein bestimmtes Paket zu überprüfen, müssen Sie sich zunächst eine Kopie unseres GPG-Build-Schlüssels beschaffen. Diese können Sie unter http://keyserver.pgp.com/ herunterladen. Der erforderliche Schlüssel heißt build@mysql.com. Alternativ können Sie den Schlüssel aus dem folgenden Text kopieren und direkt einfügen:

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org
mQGiBD4+owwRBAC14GIfUfCyEDSIePvEW3SAFUdJBtoQHH/nJKZyQT7h9bPlUWC3
RODjQReyCITRrdwyrKUGku2FmeVGwn2u2WmDMNABLnpprWPkBdCk96+OmSLN9brZ
fw2vOUgCmYv2hW0hyDHuvYlQA/BThQoADgj8AW6/0Lo7V1W9/8VuHP0gQwCgvzV3
BqOxRznNCRCRxAuAuVztHRcEAJooQK1+iSiunZMYD1WufeXfshc57S/+yeJkegNW
hxwR9pRWVArNYJdDRT+rf2RUe3vpquKNQU/hnEIUHJRQqYHo8gTxvxXNQc7fJYLV
K2HtkrPbP72vwsEKMYhhr0eKCbtLGfls9krjJ6sBgACyP/Vb7hiPwxh6rDZ7ITnE
kYpXBACmWpP8NJTkamEnPCia2ZoOHODANwpUkP43I7jsDmgtobZX9qnrAXw+uNDI
QJEXM6FSbi0LLtZciNlYsafwAPEOMDKpMqAK6IyisNtPvaLd8lH0bPAnWqcyefep
rv0sxxqUEMcM3o7wwgfN83POkDasDbs3pjwPhxvhz6//62zQJ7Q7TXlTUUwgUGFj
a2FnZSBzaWduaW5nIGtleSAod3d3Lm15c3FsLmNvbSkgPGJ1aWxkQG15c3FsLmNv
bT6IXQQTEQIAHQUCR6yUtAUJDTBYqAULBwoDBAMVAwIDFgIBAheAAAoJEIxxjTtQ
cuH1rpIAn38+BlBI815Dou9VXMIAsQEk4G3tAJ9+Cz69Y/Xwm611lzteJrCAA32+
aYhMBBMRAgAMBQI+PqPRBYMJZgC7AAoJEElQ4SqycpHyJOEAn1mxHijft00bKXvu
cSo/pECUmppiAJ41M9MRVj5VcdH/KN/KjRtW6tHFPYhMBBMRAgAMBQI+QoIDBYMJ
YiKJAAoJELb1zU3GuiQ/lpEAoIhpp6BozKI8p6eaabzF5MlJH58pAKCu/ROofK8J
Eg2aLos+5zEYrB/LsohGBBARAgAGBQI/rOOvAAoJEK/FI0h4g3QP9pYAoNtSISDD
AAU2HafyAYlLD/yUC4hKAJ0czMsBLbo0M/xPaJ6Ox9Q5Hmw2uIhGBBARAgAGBQI/
tEN3AAoJEIWWr6swc05mxsMAnRag9X61Ygu1kbfBiqDku4czTd9pAJ4q5W8KZ0+2
ujTrEPN55NdWtnXj4YhGBBARAgAGBQJDW7PqAAoJEIvYLm8wuUtcf3QAnRCyqF0C
pMCTdIGc7bDO5I7CIMhTAJ0UTGx0O1d/VwvdDiKWj45N2tNbYIhGBBMRAgAGBQJE
8TMmAAoJEPZJxPRgk1MMCnEAoIm2pP0sIcVh9Yo0YYGAqORrTOL3AJwIbcy+e8HM
NSoNV5u51RnrVKie34hMBBARAgAMBQJBgcsBBYMGItmLAAoJEBhZ0B9ne6HsQo0A
nA/LCTQ3P5kvJvDhg1DsfVTFnJxpAJ49WFjg/kIcaN5iP1JfaBAITZI3H4hMBBAR
AgAMBQJBgcs0BYMGItlYAAoJEIHC9+viE7aSIiMAnRVTVVAfMXvJhV6D5uHfWeeD
046TAJ4kjwP2bHyd6DjCymq+BdEDz63axohMBBARAgAMBQJBgctiBYMGItkqAAoJ
EGtw7Nldw/RzCaoAmwWM6+Rj1zl4D/PIys5nW48Hql3hAJ0bLOBthv96g+7oUy9U
j09Uh41lF4hMBBARAgAMBQJB0JMkBYMF1BFoAAoJEH0lygrBKafCYlUAoIb1r5D6
qMLMPMO1krHk3MNbX5b5AJ4vryx5fw6iJctC5GWJ+Y8ytXab34hMBBARAgAMBQJC
K1u6BYMFeUjSAAoJEOYbpIkV67mr8xMAoJMy+UJC0sqXMPSxh3BUsdcmtFS+AJ9+
Z15LpoOnAidTT/K9iODXGViK6ohMBBIRAgAMBQJAKlk6BYMHektSAAoJEDyhHzSU
+vhhJlwAnA/gOdwOThjO8O+dFtdbpKuImfXJAJ0TL53QKp92EzscZSz49lD2YkoE
qohMBBIRAgAMBQJAPfq6BYMHZqnSAAoJEPLXXGPjnGWcst8AoLQ3MJWqttMNHDbl
xSyzXhFGhRU8AJ4ukRzfNJqElQHQ00ZM2WnCVNzOUIhMBBIRAgAMBQJBDgqEBYMG
lpoIAAoJEDnKK/Q9aopf/N0AniE2fcCKO1wDIwusuGVlC+JvnnWbAKDDoUSEYuNn
5qzRbrzWW5zBno/Nb4hMBBIRAgAMBQJCgKU0BYMFI/9YAAoJEAQNwIV8g5+o4yQA
nA9QOFLV5POCddyUMqB/fnctuO9eAJ4sJbLKP/Z3SAiTpKrNo+XZRxauqIhMBBMR
AgAMBQI+TU2EBYMJV1cIAAoJEC27dr+t1MkzBQwAoJU+RuTVSn+TI+uWxUpT82/d
s5NkAJ9bnNodffyMMK7GyMiv/TzifiTD+4hMBBMRAgAMBQJB14B2BYMFzSQWAAoJ
EGbv28jNgv0+P7wAn13uu8YkhwfNMJJhWdpK2/qM/4AQAJ40drnKW2qJ5EEIJwtx
pwapgrzWiYhMBBMRAgAMBQJCGIEOBYMFjCN+AAoJEHbBAxyiMW6hoO4An0Ith3Kx
5/sixbjZR9aEjoePGTNKAJ94SldLiESaYaJx2lGIlD9bbVoHQYhdBBMRAgAdBQJH
rJTPBQkNMFioBQsHCgMEAxUDAgMWAgECF4AACgkQjHGNO1By4fV0KgCgsLpG2wP0
rc3s07Fync9g7MfairMAoIUefSNKrGTsTxvLeyH4DLzJW/QFiHsEMBECADsFAkJ3
NfU0HQBPb3BzLi4uIHNob3VsZCBoYXZlIGJlZW4gbG9jYWwhIEknbSAqc28qIHN0
dXBpZC4uLgAKCRA5yiv0PWqKX+9HAJ0WjTx/rqgouK4QCrOV/2IOU+jMQQCfYSC8
JgsIIeN8aiyuStTdYrk0VWCIjwQwEQIATwUCRW8Av0gdAFNob3VsZCBoYXZlIGJl
ZW4gYSBsb2NhbCBzaWduYXR1cmUsIG9yIHNvbWV0aGluZyAtIFdURiB3YXMgSSB0
aGlua2luZz8ACgkQOcor9D1qil+g+wCfcFWoo5qUl4XTE9K8tH3Q+xGWeYYAnjii
KxjtOXc0ls+BlqXxbfZ9uqBsiQIiBBABAgAMBQJBgcuFBYMGItkHAAoJEKrj5s5m
oURoqC8QAIISudocbJRhrTAROOPoMsReyp46Jdp3iL1oFDGcPfkZSBwWh8L+cJjh
dycIwwSeZ1D2h9S5Tc4EnoE0khsS6wBpuAuih5s//coRqIIiLKEdhTmNqulkCH5m
imCzc5zXWZDW0hpLr2InGsZMuh2QCwAkB4RTBM+r18cUXMLV4YHKyjIVaDhsiPP/
MKUj6rJNsUDmDq1GiJdOjySjtCFjYADlQYSD7zcd1vpqQLThnZBESvEoCqumEfOP
xemNU6xAB0CL+pUpB40pE6Un6Krr5h6yZxYZ/N5vzt0Y3B5UUMkgYDSpjbulNvaU
TFiOxEU3gJvXc1+h0BsxM7FwBZnuMA8LEA+UdQb76YcyuFBcROhmcEUTiducLu84
E2BZ2NSBdymRQKSinhvXsEWlH6Txm1gtJLynYsvPi4B4JxKbb+awnFPusL8W+gfz
jbygeKdyqzYgKj3M79R3geaY7Q75Kxl1UogiOKcbI5VZvg47OQCWeeERnejqEAdx
EQiwGA/ARhVOP/1l0LQA7jg2P1xTtrBqqC2ufDB+v+jhXaCXxstKSW1lTbv/b0d6
454UaOUV7RisN39pE2zFvJvY7bwfiwbUJVmYLm4rWJAEOJLIDtDRtt2h8JahDObm
3CWkpadjw57S5v1c/mn+xV9yTgVx5YUfC/788L1HNKXfeVDq8zbAiQIiBBMBAgAM
BQJCnwocBYMFBZpwAAoJENjCCglaJFfPIT4P/25zvPp8ixqV85igs3rRqMBtBsj+
5EoEW6DJnlGhoi26yf1nasC2frVasWG7i4JIm0U3WfLZERGDjR/nqlOCEqsP5gS3
43N7r4UpDkBsYh0WxH/ZtST5llFK3zd7XgtxvqKL98l/OSgijH2W2SJ9DGpjtO+T
iegq7igtJzw7Vax9z/LQH2xhRQKZR9yernwMSYaJ72i9SyWbK3k0+e95fGnlR5pF
zlGq320rYHgD7v9yoQ2t1klsAxK6e3b7Z+RiJG6cAU8o8F0kGxjWzF4v8D1op7S+
IoRdB0Bap01ko0KLyt3+g4/33/2UxsW50BtfqcvYNJvU4bZns1YSqAgDOOanBhg8
Ip5XPlDxH6J/3997n5JNj/nk5ojfd8nYfe/5TjflWNiput6tZ7frEki1wl6pTNbv
V9C1eLUJMSXfDZyHtUXmiP9DKNpsucCUeBKWRKLqnsHLkLYydsIeUJ8+ciKc+EWh
FxEY+Ml72cXAaz5BuW9L8KHNzZZfez/ZJabiARQpFfjOwAnmhzJ9r++TEKRLEr96
taUI9/8nVPvT6LnBpcM38Td6dJ639YvuH3ilAqmPPw50YvglIEe4BUYD5r52Seqc
8XQowouGOuBX4vs7zgWFuYA/s9ebfGaIw+uJd/56Xl9ll6q5CghqB/yt1EceFEnF
CAjQc2SeRo6qzx22uQINBD4+ox0QCADv4Yl/Fsx1jjCyU+eMf2sXg3ap9awQ3+XF
pmglhzdrozTZYKceXpqFPb+0ErbDVAjhgW15HjuAK+2Bvo7Ukd986jYd8uZENGJG
N3UNMIep7JfsIeFyCGP901GVbZnSXlAURyZX1TRWGndoV9YLhSN+zctT6GQBbMTv
NoPlwf0nvK//rG5lXDjXXHSHhSqxNxYy7SIzUHMQupfUNjsvCg8Rv871GRt/h+Yt
7XUTMhoJrg+oBFdBlzh2FKKcy3ordfgGtGwpN+jMG7vgXjsPwiVt/m9Jgdu4Tmn/
WggPOeSD+nyRb7cXG5avJxyKoVNw3PbXnLJff0tcWeUvMpRv8XkbAAMFB/4vCqpr
wIatF+w4AnGKbrcId+3LmZRzmtRKdOyUZgQg4JHUF5Bq7I9ls8OwMP0xnVlpJp9q
cW/AUbouXH3GRTu3Or68ouhaSbi7nF/e+fnlWOdJ3VpD15CdRxeIvhycEahNs5Yj
f0RzLOCyXMF0L74w+NxBNwDunolRWw/qgAHcVBaDni25SjQRzxuwzxvcS/jYua5B
Pk10ocbAexdM+2XSSWThtCTg5qMeyLLUExqGlPbuNaMmUyIlz4hYnSaCGQoe33bq
z/KZ91/keR1DVzK+zPm2vJUjcXHvxd5Jh9C+67CqnYfXf2lcYSSDSfop1Q5611la
F7vRgY0/DXKNYlPUiEwEGBECAAwFAkeslPwFCQ0wWN8ACgkQjHGNO1By4fWlzgCf
Qj3rkfcljYZOuLOn50J7PFuF7FoAnjwWGhwVi9+Fm2B5RZvpo++BBkdP
=Xquv
-----END PGP PUBLIC KEY BLOCK-----

Um den Schlüssel in Ihren eigenen öffentlichen GPG-Schlüsselbund zu importieren, verwenden Sie gpg --import. Haben Sie den Schlüssel beispielsweise unter dem Dateinamen mysql_pubkey.asc gespeichert, dann sieht der Importbefehl wie folgt aus:

shell> gpg --import mysql_pubkey.asc
gpg: key 5072E1F5: public key "MySQL Package signing key (www.mysql.com) <build@mysql.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1
gpg: no ultimately trusted keys found

Alternativ können Sie den Schlüssel vom öffentlichen Schlüsselserver mit der öffentlichen Schlüsselkennung 5072E1F5 herunterladen:

shell> gpg --recv-keys 5072E1F5
gpg: requesting key 5072E1F5 from hkp server subkeys.pgp.net
gpg: key 5072E1F5: "MySQL Package signing key (www.mysql.com) <build@mysql.com>" 2 new signatures
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg:         new signatures: 2

Wenn Sie den Schlüssel zur Bestätigung von RPM-Installationspaketen in Ihre RPM-Konfiguration importieren wollen, sollten Sie den Schlüssel direkt importieren können:

shell> rpm --import mysql_pubkey.asc

Bei Problemen versuchen Sie, den Schlüssel von gpg zu exportieren und zu importieren:

shell> gpg --export -a 5072e1f5 > 5072e1f5.asc
shell> rpm --import 5072e1f5.asc

Alternativ unterstützt rpm auch das direkte Laden des Schlüssels von einer URL. Dafür können Sie diese Handbuchseite verwenden:

shell> rpm --import http://dev.mysql.com/doc/refman/5.1/en/checking-gpg-signature.html

Nachdem Sie den öffentlichen Schlüssel heruntergeladen und importiert haben, laden Sie das gewünschte MySQL-Paket und die entsprechende Signatur herunter (diese steht ebenfalls auf der Downloadseite zur Verfügung). Die Signaturdatei hat den gleichen Namen wie die Distributionsdatei und trägt die Erweiterung .asc (siehe Beispiele in der folgenden Tabelle).

Distributionsdateimysql-standard-5.1.54-linux-i686.tar.gz
Signaturdateimysql-standard-5.1.54-linux-i686.tar.gz.asc

Stellen Sie sicher, dass beide Dateien im gleichen Verzeichnis gespeichert sind, und führen Sie dann den folgenden Befehl aus, um die Signatur der Distributionsdatei zu verifizieren:

shell> gpg --verify package_name.asc

Beispiel:

shell> gpg --verify mysql-standard-5.1.54-linux-i686.tar.gz.asc
gpg: Signature made Tue 12 Jul 2005 23:35:41 EST using DSA key ID 5072E1F5
gpg: Good signature from "MySQL Package signing key (www.mysql.com) <build@mysql.com>"

Die Meldung Good signature (Signatur korrekt) zeigt an, dass alles in Ordnung ist. Sie können alle Warnungen vom Typ insecure memory ignorieren, die unter Umständen angezeigt werden.

Weitere Informationen zum Umgang mit öffentlichen Schlüsseln finden Sie in der GPG-Dokumentation.

2.1.4.3. Signaturüberprüfung mit RPM

Bei RPM-Paketen ist keine separate Signatur vorhanden. RPM-Pakete enthalten vielmehr eine integrierte GPG-Signatur und eine MD5-Prüfsumme. Sie können ein Paket durch Ausführen des folgenden Befehls verifizieren:

shell> rpm --checksig package_name.rpm

Beispiel:

shell> rpm --checksig MySQL-server-5.1.54-0.glibc23.i386.rpm
MySQL-server-5.1.54-0.glibc23.i386.rpm: md5 gpg OK
Anmerkung

Wenn Sie RPM 4.1 verwenden und die Meldung (GPG) NOT OK (MISSING KEYS: GPG#5072e1f5) erhalten, obwohl Sie den öffentlichen MySQL-Build-Schlüssel in Ihren GPG-Schlüsselbund importiert haben, dann müssen Sie den Schlüssel zuerst in den RPM-Schlüsselbund importieren. RPM 4.1 verwendet nicht länger den GPG-Schlüsselbund (oder GPG selbst). Stattdessen arbeitet es mit einem eigenen Schlüsselbund, da es eine systemweite Anwendung ist, während der öffentliche GPG-Schlüsselbund eine benutzerspezifische Datei ist. Um den öffentlichen MySQL-Schlüssel in den RPM-Schlüsselbund zu importieren, besorgen Sie sich den Schlüssel zunächst wie in Abschnitt 2.1.4.2, „Signaturüberprüfung mit GnuPG, beschrieben. Nachfolgend verwenden Sie den Befehl rpm --import für den Schlüsselimport. Haben Sie den öffentlichen Schlüssel beispielsweise unter dem Dateinamen mysql_pubkey.asc gespeichert, dann sieht der Importbefehl wie folgt aus:

shell> rpm --import mysql_pubkey.asc

Wie Sie sich den öffentlichen MySQL-Schlüssel beschaffen, lesen Sie in Abschnitt 2.1.4.2, „Signaturüberprüfung mit GnuPG.

2.1.5. Installationslayout

Dieser Abschnitt beschreibt das Standardlayout der Verzeichnisse, die bei der Installation der von Sun Microsystems, Inc. bereitgestellten Binär- oder Quelldistributionen erstellt werden. Distributionen anderer Anbieter verwenden unter Umständen ein anderes Layout als das hier beschriebene.

Bei MySQL 5.1 unter Windows heißt das Standardinstallationsverzeichnis C:\Program Files\MySQL\MySQL Server 5.1. (Manche Windows-Benutzer ziehen eine Installation in C:\mysql vor, da dieses Verzeichnis früher einmal der Standardpfad war. Allerdings bleibt auch in diesem Fall die Struktur der Unterverzeichnisse dieselbe.) Das Installationsverzeichnis hat die folgenden Unterverzeichnisse:

VerzeichnisVerzeichnisinhalt
binClientprogramme und der mysqld-Server
dataLogdateien, Datenbanken
DocsHandbuch im CHM-Format
examplesBeispielprogramme und -skripten
includeInclude-Dateien (Header-Dateien)
libBibliotheken
scriptsHilfsprogrammskripten
shareFehlermeldungsdateien

Installationen, die mit unseren Linux-RPM-Distributionen erstellt werden, erzeugen Dateien in den folgenden Systemverzeichnissen:

VerzeichnisVerzeichnisinhalt
/usr/binClientprogramme und -skripten
/usr/sbinDer mysqld-Server
/var/lib/mysqlLogdateien, Datenbanken
/usr/share/infoHandbuch im Info-Format
/usr/share/manUnix-Handbuchseiten
/usr/include/mysqlInclude-Dateien (Header-Dateien)
/usr/lib/mysqlBibliotheken
/usr/share/mysqlFehlermeldungs- und Zeichensatzdateien
/usr/share/sql-benchBenchmarks

Unter Unix wird eine tar-Binärdistributionsdatei installiert, indem sie am gewählten Speicherort für die Installation (meist /usr/local/mysql) entpackt wird. Dabei werden die folgenden Verzeichnisse erstellt:

VerzeichnisVerzeichnisinhalt
binClientprogramme und der mysqld-Server
dataLogdateien, Datenbanken
docsHandbuch im Info-Format
manUnix-Handbuchseiten
includeInclude-Dateien (Header-Dateien)
libBibliotheken
scriptsmysql_install_db
share/mysqlFehlermeldungsdateien
sql-benchBenchmarks

Eine Quelldistribution wird installiert, nachdem Sie sie konfiguriert und kompiliert haben. Standardmäßig werden bei der Installation Dateien in den folgenden Unterverzeichnissen von /usr/local erstellt:

VerzeichnisVerzeichnisinhalt
binClientprogramme und -skripten
include/mysqlInclude-Dateien (Header-Dateien)
DocsHandbuch im Info- und CHM-Format
manUnix-Handbuchseiten
lib/mysqlBibliotheken
libexecDer mysqld-Server
share/mysqlFehlermeldungsdateien
sql-benchBenchmarks und der Crash-Me-Test
varDatenbanken und Logdateien

Innerhalb des Installationsverzeichnisses unterscheidet sich die Struktur einer Quelldistribution wie folgt von der einer Binärdistribution:

  • Der mysqld-Server wird im Verzeichnis libexec statt im Verzeichnis bin installiert.

  • Das Datenverzeichnis ist var und nicht data.

  • mysql_install_db wird im Verzeichnis bin installiert, nicht im Verzeichnis scripts.

  • Die Header-Datei- und Bibliotheksverzeichnisse sind include/mysql und lib/mysql statt include und lib.

Sie können Ihre eigene Binärdistribution aus einer kompilierten Quelldistribution erstellen, indem Sie das Skript scripts/make_binary_distribution aus dem Stammverzeichnis der Quelldistribution ausführen.

2.2. MySQL-Standardinstallation mithilfe einer Binärdistribution

Die nachfolgenden Abschnitte behandeln die Installation von MySQL auf Plattformen, für die wir Pakete im nativen Paketformat der jeweiligen Plattform anbieten. (Dies wird auch als Durchführung einer „Binärinstallation“ bezeichnet.) Binärdistributionen von MySQL sind allerdings auch für viele andere Plattformen verfügbar. In Abschnitt 2.9, „Installieren von MySQL aus tar.gz-Paketen auf anderen Unix-ähnlichen Systemen“, finden Sie allgemeine Installationsanweisungen für diese Pakete, die für alle Plattformen gelten.

In Abschnitt 2.1, „Allgemeines zur Installation“, finden Sie weitere Informationen dazu, welche anderen Binärdistributionen verfügbar sind und wie Sie diese erhalten.

2.3. Installieren von MySQL unter Windows

Eine native Windows-Distribution von MySQL wird seit Version 3.21 angeboten. Der Anteil dieser Distributionen an den täglichen MySQL-Downloads ist beträchtlich. In diesem Abschnitt beschreiben wir die Vorgehensweise bei der MySQL-Installation unter Windows.

Anmerkung

Wenn Sie eine vorhandene Installation von MySQL aktualisieren, die älter als MySQL 4.1.5 ist, dann müssen Sie zunächst die in Abschnitt 2.3.14, „Aktualisieren von MySQL unter Windows“ beschriebenen Schritte ausführen.

Um MySQL unter Windows auszuführen, benötigen Sie Folgendes:

  • Ein Windows-Betriebssystem wie Windows 2000, Windows XP, Windows Vista, Windows Server 2003 oder Windows Server 2008. Es werden sowohl 32- als auch 64-Bit-Versionen unterstützt.

    Windows-Betriebssysteme gestatten Ihnen die Ausführung des MySQL Servers als Dienst. Siehe auch Abschnitt 2.3.11, „Starten von MySQL als Windows-Dienst“.

    Sie sollten MySQL unter Windows generell mithilfe eines Kontos erstellen, das über Administratorrechte verfügt. Andernfalls kann es bei bestimmten Operationen wie der Bearbeitung der Umgebungsvariablen PATH oder dem Zugriff auf den Service Control Manager zu Problemen kommen. Nach der Installation muss MySQL nicht unter Verwendung eines Benutzers mit Administrator-Berechtigungen ausgeführt werden.

  • TCP/IP-Protokollunterstützung.

  • Ausreichend viel Speicherplatz auf Ihrer Festplatte, um MySQL entpacken und installieren und die Datenbanken entsprechend Ihren Anforderungen erstellen zu können (mindestens 200 Mbyte empfohlen).

Eine Aufstellung der Beschränkungen der Windows-Version von MySQL finden Sie unter Windows Platform Limitations.

Je nachdem, wie Sie MySQL einsetzen wollen, können auch weitere Anforderungen vorliegen:

  • Wenn Sie die Verbindung zum MySQL Server via ODBC herstellen wollen, benötigen Sie einen Connector/ODBC-Treiber. Siehe auch MySQL Connector/ODBC.

  • Wenn Sie MySQL Server mit ADO.NET-Anwendungen nutzen wollen, brauchen Sie den Connector/NET-Treiber. Siehe auch MySQL Connector/NET.

  • Wenn Sie Tabellen benötigen, die größer als 4 GByte sind, installieren Sie MySQL auf NTFS oder einem neueren Dateisystem. Vergessen Sie nicht, bei der Erstellung von Tabellen MAX_ROWS und AVG_ROW_LENGTH zu verwenden. Siehe auch Abschnitt 8.1.17, „CREATE TABLE.

MySQL für Windows ist in verschiedenen Distributionsformaten erhältlich:

  • Es sind Binärdistributionen verfügbar, die ein Setup-Programm enthalten, das alles Erforderliche installiert, sodass Sie den Server sofort starten können. Ein anderes Binärdistributionsformat enthält ein Archiv, das Sie einfach an der Installationsposition entpacken und dann selbst konfigurieren. Detaillierte Informationen finden Sie in Abschnitt 2.3.1, „Wählen eines Installationspakets“.

  • Die Quelldistribution enthält den gesamten Code und alle Supportdateien zur Erstellung der ausführbaren Dateien mithilfe des Compiler-Systems Visual Studio.

Allgemein sollten Sie eine Binärdistribution wählen, die ein Installationsprogramm einschließt. Sie ist einfacher zu verwenden als die übrigen, und Sie benötigen keine zusätzlichen Tools, um MySQL zum Laufen zu bringen. Das Installationsprogramm der Windows-Version von MySQL installiert in Verbindung mit einem grafischen Konfigurations-Assistenten automatisch MySQL, erstellt eine Optionsdatei, startet den Server und sichert die voreingestellten Benutzerkonten ab.

Achtung

Die Verwendung von Antivirensoftware wie Norton/Symantec AntiVirus auf Dateiverzeichnissen, die MySQL-Daten und temporäre Tabellen enthalten, kann Probleme verursachen, die einerseits die Leistung von MySQL betreffen und andererseits dazu führen können, dass die Antivirensoftware den Inhalt der Dateien fälschlicherweise als Spam erkennt. Dies ist auf den Fingerabdruckmechanismus der Antivirensoftware und die Art und Weise zurückzuführen, in der MySQL verschiedene Dateien schnell aktualisiert, was als potenzielles Sicherheitsrisiko identifiziert werden kann.

Nach der Installation von MySQL Server sollten Sie die Virensuche im Hauptverzeichnis (datadir) deaktivieren, das zum Speichern Ihrer MySQL-Tabellendaten verwendet wird. In der Regel verfügt Antivirensoftware über ein integriertes System, mit dem bestimmte Dateiverzeichnisse während der Virensuche speziell ignoriert werden können.

Außerdem legt MySQL im temporären Windows-Verzeichnis standardmäßig Temporärdateien an. Um zu verhindern, dass die Temporärdateien ebenfalls durchsucht werden, sollten Sie ein gesondertes Dateiverzeichnis für temporäre MySQL-Dateien konfigurieren und zur Ausschlussliste für die Virensuche hinzufügen. Ergänzen Sie dafür Ihre my.ini-Konfigurationsdatei um eine Konfigurationsoption für den tmpdir-Parameter. Weitere Informationen siehe Abschnitt 2.3.7, „Erstellen einer Optionsdatei“.

Im folgenden Abschnitt wird beschrieben, wie MySQL unter Windows mithilfe einer Binärdistribution installiert wird. Bei der Verwendung eines Installationspakets, das kein Installationsprogramm beinhaltet, gehen Sie entsprechend der Beschreibung in Abschnitt 2.3.5, „Installieren von MySQL aus einem Noinstall-Zip-Archiv“ vor. Informationen zur Installation einer Quelldistribution finden Sie in Abschnitt 2.10.6, „Installieren von MySQL unter Windows aus dem Quellcode“.

MySQL-Distributionen für Windows können Sie unter http://dev.mysql.com/downloads/ herunterladen. Siehe auch Abschnitt 2.1.3, „Wo können Sie MySQL beziehen?“.

2.3.1. Wählen eines Installationspakets

Bei MySQL 5.1 können Sie zwischen drei Installationspaketen für MySQL unter Windows wählen:

  • Das Essentials-Paket: Dieses Paket erkennen Sie am Dateinamen mit dem Aufbau mysql-essential-5.1.54-win32.msi. Es enthält die für die Installation von MySQL unter Windows mindestens erforderlichen Dateien einschließlich des Konfigurations-Assistenten. Nicht enthalten sind optionale Komponenten wie der eingebettete Server und die Benchmark-Reihe.

  • Das Complete-Paket: Dieses Paket erkennen Sie am Dateinamen mit dem Aufbau mysql-5.1.54-win32.zip. Es enthält alle Dateien, die für eine vollständige Windows-Installation erforderlich sind, einschließlich des Konfigurations-Assistenten. Ferner enthalten sind optionale Komponenten wie der eingebettete Server und die Benchmark-Reihe.

  • Das Noinstall-Archiv: Dieses Paket erkennen Sie am Dateinamen mit dem Aufbau mysql-noinstall-5.1.54-win32.zip. Es enthält alle im Complete-Paket enthaltenen Dateien mit Ausnahme des Konfigurations-Assistenten. Das Paket umfasst kein automatisiertes Installationsprogramm, muss also manuell installiert und konfiguriert werden.

Für die meisten Benutzer wird das Essentials-Paket empfohlen. Die Essentials- und die Complete-Distribution werden als .msi-Datei zur Verwendung mit Windows Installer bereitgestellt. Die Noinstall-Distribution ist in Zip-Archiven verpackt. Für die Verwendung von Zip-Archiven benötigen Sie ein Werkzeug, das .zip-Dateien entpacken kann.

Welches Paket Sie auswählen, wirkt sich auf den nachfolgenden Installationsvorgang aus. Entscheiden Sie sich für das Essentials- oder Complete-Paket, dann finden Sie weitere Informationen in Abschnitt 2.3.2, „Installieren von MySQL mit dem automatischen Installer“. Wollen Sie MySQL hingegen aus dem Noinstall-Archiv installieren, dann fahren Sie fort mit Abschnitt 2.3.5, „Installieren von MySQL aus einem Noinstall-Zip-Archiv“.

2.3.2. Installieren von MySQL mit dem automatischen Installer

Neue MySQL-Benutzer können den MySQL-Installations-Assistenten und den MySQL-Konfigurations-Assistenten zur Installation von MySQL unter Windows verwenden. Diese Assistenten sind so aufgebaut, dass die MySQL-Installation und -Konfiguration neuen Benutzern den sofortigen Einsatz von MySQL ermöglicht.

Die MySQL-Installations- und MySQL-Konfigurations-Assistenten sind Bestandteil des Essentials- und des Complete-Pakets von MySQL. Sie werden für die meisten MySQL-Standardinstallationen empfohlen. Ausnahmen betreffen Benutzer, die mehrere MySQL-Instanzen auf demselben Serverhost installieren wollen, und fortgeschrittene Benutzer, die volle Kontrolle über die Serverkonfiguration wünschen.

2.3.3. Verwenden des MySQL-Installations-Assistenten

Der MySQL-Installations-Assistent ist ein Installationsprogramm für den MySQL Server, das die aktuellen Installer-Technologien von Microsoft Windows nutzt. In Verbindung mit dem MySQL-Konfigurations-Assistenten ermöglicht der MySQL-Installations-Assistent einem Benutzer die Installation und Konfiguration eines MySQL Servers, der direkt nach der Installation einsatzbereit ist.

Der MySQL-Installations-Assistent ist das Standardinstallationsprogramm für alle MySQL Server-Distributionen, Version 4.1.5 und höher. Benutzer vorheriger MySQL-Versionen müssen ihre vorhandenen MySQL-Installationen manuell herunterfahren und entfernen, bevor sie MySQL mit dem MySQL-Installations-Assistenten installieren. In Abschnitt 2.3.3.6, „Aktualisieren von MySQL mit dem Installations-Assistenten“, finden Sie weitere Informationen zur Aktualisierung einer früheren Version.

In den aktuellen Windows-Versionen hat Microsoft eine verbesserte Version von MSI (Microsoft Windows Installer) implementiert. In Windows 2000, Windows XP und Windows Server 2003 ist MSI der De-Facto-Standard für Anwendungsinstallationen. Der MySQL-Installations-Assistent nutzt diese Technologie, um den Installationsprozess reibungsloser und flexibler zu gestalten.

Die Microsoft Windows Installer-Engine wurde mit der Veröffentlichung von Windows XP aktualisiert. Wenn Sie eine frühere Windows-Version einsetzen, finden Sie in dem Microsoft Knowledge Base-Artikel Informationen zum Upgrade auf die aktuelle Version der Windows Installer-Engine.

Ferner hat Microsoft kürzlich das WiX-Toolkit (Windows Installer XML) vorgestellt. Hierbei handelt es sich um das erste offizielle Open-Source-Projekt von Microsoft. Wir verwenden WiX nun auch, denn erstens ist es ein Open-Source-Projekt, und zweitens gestattet es die Handhabung des gesamten Windows-Installationsvorgangs auf flexible Weise unter Verwendung von Skripten.

Die Optimierung des MySQL-Installations-Assistenten steht und fällt mit der Unterstützung und dem Feedback solcher Benutzer wie Ihnen. Wenn Sie feststellen, dass im MySQL-Installations-Assistenten etwas fehlt, das für Sie sehr wichtig wäre, oder einen Bug entdecken, melden Sie dies bitte in unserer Bugdatenbank. Hinweise hierzu finden Sie in How to Report Bugs or Problems.

2.3.3.1. Herunterladen und Starten des MySQL-Installations-Assistenten

Die MySQL-Installationspakete können unter http://dev.mysql.com/downloads/ heruntergeladen werden. Wenn das von Ihnen heruntergeladene Paket in einem ZIP-Archiv gespeichert ist, müssen Sie dieses zunächst entpacken.

Anmerkung

Wenn Sie unter Windows Vista installieren, ist es am besten, vor der Installation einen Netzwerkport zu öffnen. Stellen Sie hierzu zunächst sicher, dass Sie als Administrator angemeldet sind. Doppelklicken Sie dann in der Systemsteuerung auf das Windows-Firewall-Symbol. Wählen Sie die Option Programm durch die Windows-Firewall kommunizieren lassen und klicken Sie auf die Schaltfläche Port hinzufügen. Tragen Sie in das Textfeld Name MySQL und in das Textfeld Portnummer 3306 (bzw. den Port Ihrer Wahl) ein. Stellen Sie auch sicher, dass die Optionsschaltfläche TCP-Protokoll ausgewählt ist. Wenn Sie wünschen, können Sie auch den Zugang zum MySQL Server beschränken, indem Sie die Schaltfläche Bereich ändern auswählen. Bestätigen Sie Ihre Auswahl durch Klicken auf OK. Wenn Sie vor der Installation keinen Port öffnen, können Sie den MySQL Server nicht unmittelbar nach der Installation konfigurieren. Wenn Sie den MySQL-Installations-Assistenten unter Windows Vista ausführen, müssen Sie außerdem sicherstellen, dass Sie als Benutzer mit Administratorrechten angemeldet sind.

Der Vorgang zum Starten des Assistenten hängt vom Inhalt des heruntergeladenen Installationspakets ab. Enthält dieses eine Datei namens setup.exe, dann doppelklicken Sie darauf, um den Installationsvorgang zu starten. Enthält das Paket eine .msi-Datei, dann doppelklicken Sie darauf, um den Installationsvorgang zu starten.

2.3.3.2. Auswählen eines Installationstyps

Es gibt drei verfügbare Installationstypen: Typical (Standard), Complete (Vollständig) und Custom (Benutzerdefiniert).

Bei der Installationsmethode Typical werden der MySQL Server, der Befehlszeilenclient mysql und die befehlszeilenbasierten Hilfsprogramme installiert. Zu den Befehlszeilenclients und Hilfsprogrammen gehören mysqldump, myisamchk und verschiedene weitere Programme zur Verwaltung des MySQL Servers.

Die Installationsmethode Complete installiert alle Komponenten, die im Installationspaket enthalten sind. Das vollständige Installationspaket umfasst Komponenten wie die eingebettete Serverbibliothek, die Benchmark-Reihe, Support-Skripten und die Dokumentation.

Bei der Installationsmethode Custom haben Sie vollständige Kontrolle darüber, welche Pakete installiert werden und wie der Installationspfad aussieht. Weitere Informationen zur benutzerdefinierten Installation finden Sie unter Abschnitt 2.3.3.3, „Der Dialog zur benutzerspezifischen Installation“.

Wenn Sie sich für die Installationsmethode Typical oder Complete entschieden haben und auf die Schaltfläche Next klicken, wird ein Fenster angezeigt, in dem Sie die gewählten Optionen überprüfen und die Installation dann starten können. Wenn Sie hingegen die Methode Custom auswählen und dann auf die Schaltfläche Next klicken, wird nachfolgend das Dialogfeld für die benutzerdefinierte Installation aufgerufen, welches in Abschnitt 2.3.3.3, „Der Dialog zur benutzerspezifischen Installation“, beschrieben wird.

2.3.3.3. Der Dialog zur benutzerspezifischen Installation

Wenn Sie den Installationspfad oder bestimmte Komponenten ändern wollen, die vom MySQL-Installations-Assistenten installiert werden, wählen Sie die Installationsmethode Custom.

Alle verfügbaren Komponenten werden dann in einer Baumstruktur links im Installationsdialog angezeigt. Komponenten, die nicht installiert werden, sind durch ein rotes X gekennzeichnet, während für die Installation gewählten Komponenten ein graues Symbol aufweisen. Um den Installationsstatus einer Komponente umzuschalten, klicken Sie auf das Symbol der betreffenden Komponente und wählen die gewünschte Option aus der erscheinenden Dropdown-Liste.

Sie können den vorgegebenen Installationspfad ändern, indem Sie auf die Schaltfläche Change... rechts neben dem angezeigten Installationspfad klicken.

Wenn Sie die zu installierenden Komponenten und den Pfad gewählt haben, klicken Sie auf die Schaltfläche Next, um den Bestätigungsdialog anzuzeigen.

2.3.3.4. Der Bestätigungsdialog

Wenn Sie eine Installationsmethode und ggf. die zu installierenden Komponenten gewählt haben, schreiten Sie fort zum Bestätigungsdialog. Installationsmethode und Pfad werden nun zur Bestätigung angezeigt.

Wenn die angezeigten Einstellungen korrekt sind, klicken Sie auf die Schaltfläche Install, um MySQL zu installieren. Wenn Sie Ihre Einstellungen noch einmal ändern wollen, klicken Sie auf die Schaltfläche Back. Um den MySQL-Installations-Assistenten zu verlassen, ohne MySQL zu installieren, klicken Sie auf die Schaltfläche Cancel.

Wenn die Installation abgeschlossen ist, können Sie sich auf der MySQL-Website registrieren. Wenn Sie registriert sind, können Sie Mitteilungen an die MySQL-Foren unter forums.mysql.com schicken, Bugs unter bugs.mysql.com melden und unseren Newsletter abonnieren. Der Abschlussbildschirm des Installationsprogramms zeigt eine Zusammenfassung der Installation und erlaubt Ihnen den Aufruf des MySQL-Konfigurations-Assistenten, mit dem Sie eine Konfigurationsdatei erstellen, den MySQL-Dienst installieren und die Sicherheitseinstellungen konfigurieren können.

2.3.3.5. Änderungen, die der MySQL-Installations-Assistent durchführt

Wenn Sie auf die Schaltfläche Install klicken, startet der MySQL-Installations-Assistent den Installationsvorgang und nimmt bestimmte Änderungen an Ihrem System vor, die in den nachfolgenden Abschnitten beschrieben sind.

Änderungen in der Registrierung

Der MySQL-Installations-Assistent erstellt bei Auswahl der Standardinstallation einen Schlüssel in der Windows-Registrierung. Dieser befindet sich unter HKEY_LOCAL_MACHINE\SOFTWARE\MySQL AB.

Der MySQL-Installations-Assistent richtet einen Schlüssel ein, der nach der Hauptversion des installierten Servers benannt ist (z. B. MySQL Server 5.1). Dieser enthält zwei Zeichenfolgenwerte namens Location und Version. Die Zeichenfolge Location enthält den Pfad zum Installationsverzeichnis. Bei einer Standardinstallation heißt der Wert C:\Program Files\MySQL\MySQL Server 5.1\. Die Zeichenfolge Version enthält die Release-Nummer. Wird etwa MySQL Server 5.1.54 installiert, dann erhält der Schlüssel den Wert 5.1.54.

Diese Registrierungsschlüssel ermöglichen es externen Programmen, das Installationsverzeichnis des MySQL Servers zu ermitteln; hierdurch wird eine zeitaufwändige vollständige Durchsuchung der Festplatte zur Ermittlung des Installationspfads des MySQL Servers unnötig. Die Registrierungsschlüssel sind für die Ausführung des Servers nicht erforderlich und werden, wenn Sie MySQL aus dem Noinstall-Archiv installieren, auch nicht erstellt.

Änderungen im Startmenü

Der MySQL-Installations-Assistent erstellt im Windows-Menü Start einen neuen Eintrag in einem MySQL-Menü, welches nach der installierten MySQL-Hauptversion benannt ist. Installieren Sie beispielsweise MySQL 5.1, dann erstellt der Installations-Assistent einen Abschnitt namens MySQL Server 5.1 im Menü Start.

In diesem neuen Abschnitt im Menü Start werden die folgenden Einträge eingerichtet:

  • MySQL Command Line Client: Dies ist eine Verknüpfung mit dem Befehlszeilenclient mysql, die so konfiguriert ist, dass eine Verbindung als Benutzer root hergestellt wird. Beim Aufruf fordert die Verknüpfung die Eingabe eines root-Benutzerpassworts an, wenn Sie eine Verbindung herstellen.

  • MySQL Server Instance Config Wizard: Dies ist eine Verknüpfung zum MySQL Server-Konfigurations-Assistenten. Verwenden Sie diese Verknüpfung zur Konfiguration eines neu installierten oder zur Neukonfiguration eines vorhandenen Servers.

  • MySQL Documentation: Dies ist eine Verknüpfung zur Dokumentation zum MySQL Server, die lokal im Installationsverzeichnis des MySQL Servers gespeichert ist. Die Option ist nicht verfügbar, wenn der MySQL Server aus dem Essentials-Paket installiert wurde.

Änderungen am Dateisystem

Der MySQL-Installations-Assistent installiert den MySQL 5.1 Server standardmäßig im Verzeichnis C:\Program Files\MySQL\MySQL Server 5.1. Hierbei ist Program Files das Standardverzeichnis für Anwendungen auf Ihrem System und 5.1 die Hauptversion Ihres MySQL Servers. Dies ist das empfohlene Verzeichnis für den MySQL Server. Es ersetzt die vormalige Standardposition C:\mysql.

Standardmäßig werden alle MySQL-Anwendungen in einem gemeinsamen Verzeichnis in C:\Program Files\MySQL gespeichert. Hierbei ist Program Files in Ihrer Windows-Installation das Standardverzeichnis für Anwendungen. Bei einer typischen MySQL-Installation auf einem Entwicklersystem könnte dies wie folgt aussehen:

C:\Program Files\MySQL\MySQL Server 5.1
C:\Program Files\MySQL\MySQL Workbench 5.1 OSS

Dieser Ansatz erleichtert Verwaltung und Pflege aller auf einem System installierten MySQL-Anwendungen.

In MySQL 5.1.23 und früher befindet sich der Standard-Speicherort für die von MySQL verwendeten Datendateien im entsprechenden MySQL Server-Installationsverzeichnis. In MySQL 5.1.24 und später ist der Standard-Speicherort des Datenverzeichnisses das Verzeichnis AppData, das für den Benutzer konfiguriert wird, der die MySQL-Anwendung installiert hat.

2.3.3.6. Aktualisieren von MySQL mit dem Installations-Assistenten

Der MySQL-Installations-Assistent kann Server-Upgrades automatisch mithilfe der MSI-Aktualisierungsfunktionen durchführen. Das bedeutet, dass Sie eine vorhandene Installation nicht mehr manuell entfernen müssen, bevor Sie einen neuen Release installieren. Das Installationsprogramm beendet und entfernt den vorhandenen MySQL-Dienst selbsttätig, bevor die neue Version installiert wird.

Automatische Upgrades sind nur dann verfügbar, wenn Sie Aktualisierungen zwischen Installationen durchführen, die die gleiche Haupt- und Unterversionsnummern aufweisen. So kann etwa ein automatisches Upgrade von MySQL 4.1.5 auf MySQL 4.1.6 erfolgen, nicht jedoch von MySQL 5.0 auf MySQL 5.1.

Siehe auch Abschnitt 2.3.14, „Aktualisieren von MySQL unter Windows“.

2.3.4. MySQL Server-Konfigurations-Assistent

Der MySQL Server-Konfigurations-Assistent hilft Ihnen bei der Automatisierung der Serverkonfiguration. Er erstellt eine benutzerdefinierte MySQL-Konfigurationsdatei (my.ini oder my.cnf). Hierzu stellt er Ihnen eine Reihe von Fragen und verknüpft Ihre Antworten dann mit einer Vorlage, um die für Ihre Installation maßgeschneiderte Konfigurationsdatei zu erzeugen.

Der MySQL Server-Konfigurations-Assistent ist Bestandteil des MySQL 5.1 Servers. Er ist nur für Windows verfügbar.

2.3.4.1. Starten des MySQL Server-Konfigurations-Assistenten

Der MySQL Server-Konfigurations-Assistent wird normalerweise im Rahmen des Installationsprozesses gestartet. Sie sollten den MySQL Server-Konfigurations-Assistenten nur dann erneut ausführen müssen, wenn Sie die Konfigurationsparameter Ihres Servers verändern müssen.

Wenn Sie vor der Installation von MySQL unter Windows Vista keinen Port geöffnet haben, können Sie den MySQL Server-Konfigurations-Assistenten nach der Installation verwenden. Allerdings müssen Sie einen Port in der Windows-Firewall öffnen. Die Anweisungen dazu finden Sie in Abschnitt 2.3.3.1, „Herunterladen und Starten des MySQL-Installations-Assistenten“. Anstatt einen Port zu öffnen, können Sie auch MySQL als Programm hinzufügen, das den Windows Firewall umgeht. Eine der beiden Optionen ist ausreichend – Sie müssen nicht beide ausführen. Wenn Sie den MySQL Server-Konfigurations-Assistenten unter Windows Vista ausführen, müssen Sie außerdem sicherstellen, dass Sie als Benutzer mit Administratorrechten angemeldet sind.

MySQL Server-Konfigurations-Assistent

Sie können den MySQL Server-Konfigurations-Assistenten durch Auswahl des Eintrags MySQL Server Instance Config Wizard im Abschnitt MySQL des Windows-Menüs Start aufrufen.

Alternativ navigieren Sie zum Verzeichnis bin Ihrer MySQL-Installation und rufen die Datei MySQLInstanceConfig.exe direkt auf.

Der MySQL Server-Konfigurations-Assistent legt die Datei my.ini im Installationsverzeichnis des MySQL Servers ab. Dies erleichtert die Zuordnung von Konfigurationsdateien zu bestimmten Serverinstanzen.

Um sicherzustellen, dass der MySQL Server weiß, wo er nach der Datei my.ini suchen muss, wird im Zuge der Dienstinstallation ein Argument ähnlich dem folgenden an den MySQL Server übergeben:

--defaults-file="C:\Program Files\MySQL\MySQL Server 5.1\my.ini"

Hierbei wird C:\Program Files\MySQL\MySQL Server 5.1 durch den Installationspfad des MySQL Servers ersetzt. Die Option --defaults-file weist den MySQL Server an, beim Start die Konfigurationsoptionen aus der angegebenen Datei auszulesen.

Neben Änderungen, die Sie an der Datei my.ini durch nochmaliges Ausführen des MySQL Server-Konfigurations-Assistenten vornehmen, können Sie sie auch ändern, indem Sie sie mit einem Texteditor öffnen und notwendige Änderungen vornehmen. Sie können die Serverkonfiguration auch mit dem Hilfsprogramm MySQL Administrator bearbeiten. Weitere Informationen zur Serverkonfiguration finden Sie in Server Command Options.

MySQL-Clients und Hilfsprogramme wie die Befehlszeilenclients mysql und mysqldump können die Datei my.ini im Serverinstallationsverzeichnis nicht lokalisieren. Um Client- und Hilfsprogrammanwendungen zu konfigurieren, erstellen Sie eine neue my.ini-Datei im Windows-Installationsverzeichnis (zum Beispiel C:\WINDOWS).

Unter Windows Server 2003, Windows Server 2000, Windows XP und Windows Vista konfiguriert der MySQL Server-Konfigurations-Assistent MySQL als Windows-Dienst. Zum Starten und Beenden von MySQL verwenden Sie die Anwendung Services, die Bestandteil der Windows-Verwaltung ist.

2.3.4.2. Auswählen einer Wartungsoption

Wenn der MySQL Server-Konfigurations-Assistent eine vorhandene Konfigurationsdatei erkennt, können Sie wahlweise den vorhandenen Server umkonfigurieren oder die Serverinstanz durch Löschen der Konfigurationsdatei entfernen und den MySQL-Dienst beenden und entfernen.

Wenn Sie den vorhandenen Server umkonfigurieren wollen, wählen Sie die Option Re-configure Instance und klicken dann auf die Schaltfläche Next. Vorhandene Konfigurationsdateien werden nicht überschrieben, aber (innerhalb desselben Dateiverzeichnisses) mithilfe eines Zeitstempels (Windows) oder einer laufenden Nummer (Linux) umbenannt. Wenn Sie die vorhandene Serverinstanz entfernen wollen, wählen Sie die Option Remove Instance und klicken dann auf die Schaltfläche Next.

Wählen Sie die Option Remove Instance, dann wird ein Bestätigungsfenster aufgerufen. Klicken Sie auf die Schaltfläche Execute. Der MySQL Server-Konfigurations-Assistent beendet und entfernt nun den MySQL-Dienst. Anschließend löscht er die Konfigurationsdatei. Die Serverinstallation und ihr Ordner data werden nicht entfernt.

Wenn Sie die Option Re-configure Instance auswählen, wird das Dialogfeld Configuration Type angezeigt. Hier können Sie den Installationstyp auswählen, den Sie konfigurieren wollen.

2.3.4.3. Auswählen eines Konfigurationstyps

Wenn Sie den MySQL Server-Konfigurations-Assistenten für eine neue MySQL-Installation aufrufen oder die Option Re-configure Instance für eine vorhandene Installation auswählen, wird das Dialogfeld Configuration Type aufgerufen.

MySQL Server-Konfigurations-Assistent:
            Konfigurationstyp

Es stehen zwei Konfigurationsmethoden zur Verfügung: Detailed Configuration und Standard Configuration. Die Option Standard Configuration ist für Neubenutzer vorgesehen, die direkt mit MySQL arbeiten wollen, ohne sich vorher Gedanken zur Serverkonfiguration machen zu müssen. Die Option Detailed Configuration ist hingegen für fortgeschrittene Benutzer gedacht, die eine exaktere Kontrolle über die Serverkonfiguration wünschen.

Wenn Sie noch nicht mit MySQL gearbeitet haben und einen Server benötigen, der als Entwicklersystem für genau einen Benutzer vorgesehen ist, dann ist Standard Configuration die richtige Wahl für Ihre Bedürfnisse. Wenn Sie die Option Standard Configuration wählen, stellt der MySQL Server-Konfigurations-Assistent alle Konfigurationsoptionen mit Ausnahme von Service Options (Dienstoptionen) und Security Options (Sicherheitsoptionen) automatisch ein.

Unter Umständen werden bei Auswahl von Standard Configuration Optionseinstellungen vorgenommen, die mit Systemen, auf denen bereits MySQL-Installationen vorhanden sind, nicht kompatibel sind. Ist auf dem System, auf dem Sie eine MySQL-Installation konfigurieren wollen, bereits eine andere MySQL-Installation vorhanden, dann wird die Auswahl Detailed Configuration empfohlen.

Um die Auswahl Standard Configuration fertig zu stellen, lesen Sie bitte die Abschnitte zu Service Options und Security Options in Abschnitt 2.3.4.10, „Der Dialog zu Dienstoptionen“ bzw. Abschnitt 2.3.4.11, „Der Dialog zu Sicherheitsoptionen“.

2.3.4.4. Der Dialog zum Servertyp

Sie können zwischen drei verschiedenen Servertypen wählen. Welchen Servertyp Sie wählen, wirkt sich auf die Entscheidungen aus, die der MySQL Server-Konfigurations-Assistent in den Bereichen Speicher-, Festplatten- und Prozessornutzung trifft.

MySQL Server-Konfigurations-Assistent:
            Servertyp
  • Developer Machine: Diese Option ist die beste Wahl für eine normale Desktop-Workstation, auf der MySQL nur für den privaten Einsatz vorgesehen ist. Es wird vorausgesetzt, dass viele andere Desktopanwendungen ausgeführt werden. Der MySQL Server wird deswegen für eine minimale Nutzung der Systemressourcen konfiguriert.

  • Server Machine: Wählen Sie diese Option für ein Serversystem, bei dem der MySQL Server gemeinsam mit anderen Serveranwendungen wie FTP-, Mail- oder Webservern ausgeführt wird. Der MySQL Server wird in diesem Fall für eine moderate Nutzung der Systemressourcen konfiguriert.

  • Dedicated MySQL Server Machine: Die Option wählen Sie bei einem Serversystem, auf dem ausschließlich der MySQL Server läuft. Es wird vorausgesetzt, dass keine anderen Anwendungen ausgeführt werden. Der MySQL Server wird deswegen für die Nutzung aller Systemressourcen konfiguriert.

Anmerkung

Durch die Auswahl einer der vorkonfigurierten Konfigurationen ändern sich die einzelnen Optionen in den Dateien my.cnf oder my.ini entsprechend. Die im Handbuch beschriebenen Standardwerte und Optionen können deshalb von den Optionen und Werten abweichen, die während der Ausführung des Konfigurations-Assistenten eingerichtet wurden.

2.3.4.5. Die Dialog zur Datenbankverwendung

Das Dialogfeld Database Usage erlaubt Ihnen die Angabe von Speicher-Engines, die Sie bei der Erstellung von MySQL-Tabellen voraussichtlich verwenden werden. Die hier gewählte Option bestimmt, ob die InnoDB-Speicher-Engine verfügbar ist und welcher Anteil der Serverressourcen für InnoDB bereitgestellt wird.

MySQL Server-Konfigurations-Assistent:
            Verwendungsdialog
  • Multifunctional Database: Diese Option aktiviert sowohl die InnoDB- als auch die MyISAM-Speicher-Engine und teilt die verfügbaren Ressourcen gleichmäßig zwischen diesen beiden auf. Die Option ist für Benutzer empfehlenswert, die beide Speicher-Engines regelmäßig verwenden.

  • Transactional Database Only: Diese Option aktiviert sowohl die InnoDB- als auch die MyISAM-Speicher-Engine, reserviert den überwiegenden Teil der Serverressourcen jedoch für die InnoDB-Engine. Diese Option ist für Benutzer gedacht, die InnoDB fast ausschließlich verwenden und MyISAM nur in sehr seltenen Fällen einsetzen.

  • Non-Transactional Database Only: Diese Option deaktiviert die InnoDB-Speicher-Engine vollständig und weist die gesamten Serverressourcen der MyISAM-Engine zu. Sie wird Benutzern empfohlen, die InnoDB überhaupt nicht verwenden.

Der Konfigurations-Assistent verwendet eine Vorlage für die Generierung der Serverkonfigurationsdatei. Mit dem Dialogfeld Database Usage wird einer der folgenden Optionsstrings festgelegt:

Multifunctional Database:        MIXED
Transactional Database Only:     INNODB
Non-Transactional Database Only: MYISAM

Wenn diese Optionen durch die Standardvorlage bearbeitet werden (my-template.ini), ergibt sich folgendes Ergebnis:

Multifunctional Database:
default-storage-engine=InnoDB
_myisam_pct=50
Transactional Database Only:
default-storage-engine=InnoDB
_myisam_pct=5
Non-Transactional Database Only:
default-storage-engine=MyISAM
_myisam_pct=100
skip-innodb

Der Wert _myisam_pct wird verwendet, um den Prozentsatz der für MyISAM reservierten Ressourcen zu berechnen. Die übrigen Ressourcen werden InnoDB zugewiesen.

2.3.4.6. Der InnoDB-Tablespace-Dialog

Manche Benutzer wollen die InnoDB-Tablespace-Dateien an einer anderen Position als im MySQL Serverdatenverzeichnis speichern. Dies kann wünschenswert sein, wenn Ihr System über ein Speichergerät mit höherer Kapazität oder mehr Leistung verfügt (z. B. ein RAID-Speichersystem).

MySQL Server-Konfigurations-Assistent:
            InnoDB-Tablespace-Dialog

Um die Standardposition der InnoDB-Tablespace-Dateien zu ändern, wählen Sie ein anderes Laufwerk aus der Dropdown-Liste mit den Laufwerksbuchstaben aus und stellen dann in der Dropdown-Liste mit den Pfaden einen anderen Pfad ein. Um einen benutzerdefinierten Pfad zu erstellen, klicken Sie auf die Schaltfläche ....

Wenn Sie die Konfiguration eines vorhandenen Servers modifizieren, müssen Sie auf die Schaltfläche Modify klicken, bevor Sie den Pfad ändern. In dieser Situation müssen Sie die vorhandenen Tablespace-Dateien manuell an die neue Position verschieben, bevor Sie den Server starten.

2.3.4.7. Der Dialog zu gleichzeitigen Verbindungen

Um zu verhindern, dass der Server keine Ressourcen mehr zugewiesen bekommt, ist es wichtig, die Anzahl gleichzeitiger Verbindungen zum MySQL Server zu begrenzen. Das Dialogfeld Concurrent Connections ermöglicht Ihnen die Angabe der erwarteten Auslastung Ihres Servers und stellt die Anzahl gleichzeitiger Verbindungen entsprechend ein. Es ist ferner möglich, die Anzahl gleichzeitiger Verbindungen manuell zu ändern.

MySQL Server-Konfigurations-Assistent:
            Verbindungen
  • Decision Support (DSS)/OLAP: Wählen Sie diese Option, wenn Ihr Server keine hohe Anzahl gleichzeitiger Verbindungen unterstützen muss. Die maximale Anzahl von Verbindungen wird in diesem Fall auf 100 gesetzt, wobei ein Durchschnitt von 20 Verbindungen erwartet wird.

  • Online Transaction Processing (OLTP): Wählen Sie diese Option, wenn Ihr Server eine große Zahl gleichzeitiger Verbindungen unterstützen muss. Die maximale Anzahl der Verbindungen wird hier auf 500 festgelegt.

  • Manual Setting: Wählen Sie diese Option, wenn Sie die maximale Anzahl gleichzeitiger Verbindungen zum Server manuell einstellen wollen. Wählen Sie die Anzahl gleichzeitiger Verbindungen über die Dropdown-Liste aus oder geben Sie den gewünschten Wert direkt in das Dropdown-Feld ein, sofern er nicht in der Liste enthalten ist.

2.3.4.8. Der Dialog zu Netzwerk- und Strict-Modus-Optionen

Im Dialogfeld Networking Options aktivieren oder deaktivieren Sie die TCP/IP-Netzwerkunterstützung und konfigurieren die Portnummer, die zur Verbindung mit dem MySQL Server verwendet wird.

MySQL Server-Konfigurations-Assistent:
            Netzwerkkonfiguration

Standardmäßig ist die TCP/IP-Netzwerkunterstützung aktiviert. Um sie zu deaktivieren, entfernen Sie die Markierung des Kontrollkästchen Enable TCP/IP Networking.

Standardmäßig ist Port 3306 gewählt. Um den für den MySQL-Zugriff verwendeten Port zu ändern, wählen Sie im Dropdown-Feld eine neue Portnummer aus und geben die gewünschte Nummer direkt in das Dropdown-Feld ein. Wird die eingetragene Portnummer bereits verwendet, dann werden Sie aufgefordert, Ihre Eingabe zu bestätigen.

Über Server SQL Mode können Sie den strikten SQL-Servermodus aktivieren oder deaktivieren. Bei aktiviertem striktem Modus (Standard) verhält sich MySQL ähnlich wie andere Datenbankmanagementsysteme. Wenn Sie Anwendungen ausführen, die auf das vorherige „nachsichtige“ Verhalten von MySQL angewiesen sind, müssen Sie diese Anwendungen entweder anpassen oder den strikten Modus deaktivieren. Weitere Informationen zum strikten Modus finden Sie in Server SQL Modes.

2.3.4.9. Der Zeichensatzdialog

Der MySQL Server unterstützt mehrere Zeichensätze. In diesem Zusammenhang ist es möglich, einen Standardzeichensatz einzustellen, der für alle Tabellen, Spalten und Datenbanken verwendet wird, soweit nichts anderes explizit festgelegt ist. Im Dialogfeld Character Set können Sie den Standardzeichensatz des MySQL Servers ändern.

MySQL Server-Konfigurations-Assistent:
            Zeichensatz
  • Standard Character Set: Wählen Sie diese Option, wenn Sie utf1 als Standardzeichensatz verwenden wollen. latin1 wird für Englisch und viele westeuropäische Sprachen verwendet.

  • Best Support For Multilingualism: Wählen Sie diese Option, wenn Sie utf8 als Standardzeichensatz verwenden wollen. Dies ist ein Unicode-Zeichensatz, der Zeichen vieler verschiedener Sprachen enthält.

  • Manual Selected Default Character Set/Collation: Wählen Sie diese Option, wenn Sie den Standardzeichensatz des Servers manuell auswählen wollen. Wählen Sie den gewünschten Zeichensatz aus der angezeigten Dropdown-Liste.

2.3.4.10. Der Dialog zu Dienstoptionen

Auf Windows-Plattformen kann der MySQL Server als Windows-Dienst installiert werden. Wenn der Server auf diese Weise installiert wird, kann er beim Systemstart automatisch gestartet werden. Zudem ist auch ein automatischer Neustart des Dienstes durch Windows nach einem Ausfall möglich.

Der MySQL Server-Konfigurations-Assistent installiert den MySQL Server standardmäßig als Dienst mit dem Dienstnamen MySQL. Wollen Sie den Dienst nicht installieren, dann deaktivieren Sie das Kontrollkästchen Install As Windows Service. Sie können den Namen des Dienstes ändern, indem Sie einen anderen Namen im vorhandenen Dropdown-Feld auswählen oder einen neuen Dienstnamen direkt in das Feld eintragen.

Anmerkung

Dienstnamen können bis auf Schrägstrich (/) und Backslash (\) jedes zulässige Zeichen enthalten und müssen kürzer als 256 Zeichen sein.

Warnung

Wenn Sie mehrere MySQL-Versionen auf demselben Computer installieren, müssen Sie für jede installierte Version einen anderen Dienstnamen verwenden. Erhält nicht jede einzelne Version einen individuellen Dienstnamen, führt dies zu inkonsistenten Dienstmanagerinformationen. Das wird dann problematisch, wenn Sie versuchen, Vorgängerversionen zu deinstallieren.

Wenn Sie bereits mehrere Versionen unter demselben Dienstnamen installiert haben, müssen Sie den Inhalt des Parameters HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services in der Windows-Registrierung manuell editieren und dort die Verbindung zwischen Dienstname und korrekter Server-Version aktualisieren.

In der Regel erstellen Sie bei der Installation mehrerer Versionen den Dienstnamen basierend auf den Versionsangaben. So könnten Sie beispielsweise MySQL 5.x als mysql5 oder spezielle Versionen wie MySQL 5.1.30 als mysql50130 installieren.

Um den MySQL Server als Dienst zu installieren, der aber beim Systemstart nicht automatisch gestartet wird, deaktivieren Sie das Kontrollkästchen Launch the MySQL Server Automatically.

2.3.4.11. Der Dialog zu Sicherheitsoptionen

Es wird dringend empfohlen, ein root-Kennwort für Ihren MySQL Server einzurichten. Der MySQL Server-Konfigurations-Assistent fordert Sie standardmäßig dazu auf. Wollen Sie kein root-Kennwort erstellen, dann deaktivieren Sie das Kontrollkästchen Modify Security Settings.

MySQL Server-Konfigurations-Assistent:
            Sicherheit

Um das root-Kennwort einzurichten, geben Sie das gewünschte Kennwort in die Felder New root password und Confirm ein. Wenn Sie einen vorhandenen Server umkonfigurieren, müssen Sie das vorhandene root-Passwort in das Feld Current root password eingeben.

Um root-Anmeldungen über das Netzwerk zuzulassen, aktivieren Sie das Kontrollkästchen Enable root access from remote machines. Dies vermindert die Sicherheit Ihres root-Kontos.

Um ein anonymes Benutzerkonto einzurichten, markieren Sie das Kontrollkästchen Create An Anonymous Account . Die Erstellung eines solchen Kontos kann die Serversicherheit verringern und Probleme mit der Anmeldung und mit Berechtigungen verursachen. Aus diesem Grund wird davon abgeraten.

2.3.4.12. Der Bestätigungsdialog

Das letzte Dialogfeld im MySQL Server-Konfigurations-Assistenten ist Confirmation Dialog. Um den Konfigurationsvorgang zu starten, klicken Sie auf die Schaltfläche Execute. Wenn Sie zu einem der vorherigen Dialogfelder zurückkehren wollen, klicken Sie auf die Schaltfläche Back. Um den MySQL Server-Konfigurations-Assistenten zu verlassen, ohne MySQL zu konfigurieren, klicken Sie auf die Schaltfläche Cancel.

MySQL Server-Konfigurations-Assistent:
            Bestätigung

Wenn Sie auf die Schaltfläche Execute geklickt haben, führt der MySQL Server-Konfigurations-Assistent eine Reihe von Aufgaben aus und zeigt deren Fortschritt auf dem Bildschirm an.

Der MySQL Server-Konfigurations-Assistent ermittelt zunächst die Konfigurationsdateioptionen basierend auf Ihren Einstellungen. Hierzu verwendet er eine Vorlage, die von Entwicklern und Technikern bei MySQL erstellt wurde. Diese Vorlage heißt my-template.ini und befindet sich in Ihrem Serverinstallationsverzeichnis.

Der MySQL Server-Konfigurations-Assistent schreibt diese Optionen dann in die entsprechende Konfigurationsdatei.

Wenn Sie angegeben haben, dass ein Dienst für den MySQL Server eingerichtet werden soll, erstellt und startet der MySQL Server-Konfigurations-Assistent diesen Dienst. Konfigurieren Sie einen vorhandenen Dienst um, dann startet der MySQL Server-Konfigurations-Assistent den Dienst neu, um Ihre Konfigurationsänderungen anzuwenden.

Haben Sie angegeben, dass ein root-Kennwort eingerichtet werden soll, dann stellt der MySQL Server-Konfigurations-Assistent eine Verbindung mit dem Server her, richtet Ihr neues root-Kennwort ein und übernimmt ggf. weitere von Ihnen gewählte Sicherheitseinstellungen.

Wenn der MySQL Server-Konfigurations-Assistent seine Aufgaben abgeschlossen hat, wird eine Zusammenfassung angezeigt. Klicken Sie auf die Schaltfläche Finish, um den MySQL Server-Konfigurations-Assistenten zu beenden.

2.3.5. Installieren von MySQL aus einem Noinstall-Zip-Archiv

Benutzer, die eine Installation aus dem Noinstall-Paket vornehmen, können die Anweisungen in diesem Abschnitt zur manuellen Installation von MySQL verwenden. Die Installation von MySQL aus einem ZIP-Archiv erfolgt mit den nachfolgenden Schritten:

  1. Extrahieren Sie das Archiv in das gewünschte Installationsverzeichnis

  2. Erstellen Sie die Optionsdatei

  3. Wählen Sie den MySQL Server-Typ aus

  4. Starten Sie den MySQL Server

  5. Schützen Sie die standardmäßig eingerichteten Benutzerkonten

Die Abläufe werden in den nachfolgenden Abschnitten beschrieben.

2.3.6. Entpacken des Installationsarchivs

So installieren Sie MySQL manuell:

  1. Wenn Sie ein Upgrade von einer vorherigen Version durchführen wollen, lesen Sie bitte Abschnitt 2.3.14, „Aktualisieren von MySQL unter Windows“, bevor Sie den Upgradevorgang beginnen.

  2. Stellen Sie sicher, dass Sie als Benutzer mit Administratorrechten angemeldet sind.

  3. Wählen Sie ein Installationsverzeichnis aus. Traditionell wird der MySQL Server im Verzeichnis C:\mysql installiert. Der MySQL-Installations-Assistent installiert MySQL hingegen in C:\Program Files\MySQL. Wenn Sie MySQL nicht in C:\mysql installieren, müssen Sie den Pfad zum Installationsverzeichnis während des Systemstarts oder in einer Optionsdatei angeben. Siehe auch Abschnitt 2.3.7, „Erstellen einer Optionsdatei“.

  4. Verwenden Sie ein ZIP-kompatibles Programm, um das Installationsarchiv in das gewählte Verzeichnis zu extrahieren. Bei Verwendung bestimmter Programme wird das Archiv in einen Ordner im Installationsverzeichnis extrahiert. Sollte dies bei Ihrem Programm der Fall sein, dann verschieben Sie den gesamten Inhalt des Unterordners in das gewählte Installationsverzeichnis.

2.3.7. Erstellen einer Optionsdatei

Wenn Sie für die Ausführung des Servers bestimmte Startoptionen angeben wollen, können Sie dies über die Befehlszeile tun oder sie in einer Optionsdatei ablegen. Sollen die Optionen bei jedem Serverstart verwendet werden, dann ist die Verwendung einer Optionsdatei zur Angabe Ihrer MySQL-Konfiguration praktischer. Dies gilt insbesondere unter den folgenden Umständen:

  • Die Speicherorte von Installations- und Datenverzeichnis unterscheiden sich von den Standardvorgaben (C:\Program Files\MySQL\MySQL Server 5.1 und C:\Program Files\MySQL\MySQL Server 5.1\data).

  • Sie müssen die Servereinstellungen, wie Speicher, Zwischenspeicher oder InnoDB-Konfigurationsinformationen, optimieren.

Wenn der MySQL Server unter Windows gestartet wird, sucht er in zwei Dateien nach Optionseinstellungen: in der Datei my.ini im Windows-Verzeichnis und der Datei C:\my.cnf. Das Windows-Verzeichnis heißt normalerweise C:\WINDOWS o. ä. Sie können die exakte Position der Umgebungsvariablen WINDIR entnehmen. Hierzu geben Sie den folgenden Befehl ein:

C:\> echo %WINDIR%

MySQL sucht zunächst in der Datei my.ini und nachfolgend in my.cnf nach Optionseinstellungen. Allerdings sollten Sie, um Verwirrung zu vermeiden, am besten nur eine Datei verwenden. Verwendet Ihr PC einen Boot-Loader, bei dem C: nicht das Startlaufwerk ist, dann können Sie ohnehin nur die Datei my.ini benutzen. Unabhängig von der gewählten Option muss es sich in jedem Fall um eine unverschlüsselte Textdatei handeln.

Sie können auch die Beispieloptionsdateien verwenden, die zum Umfang Ihrer MySQL-Distribution gehören, siehe Preconfigured Option Files.

Eine Optionsdatei kann mit jedem Texteditor (z. B. Notepad) erstellt und bearbeitet werden. Ist MySQL beispielsweise in E:\mysql installiert und befindet sich das Datenverzeichnis in E:\mydata\data, dann können Sie eine Optionsdatei erstellen, die einen Abschnitt [mysqld] enthält. In diesem geben Sie die Werte für die Parameter basedir und datadir an:

[mysqld]
# set basedir to your installation path
basedir=E:/mysql
# set datadir to the location of your data directory
datadir=E:/mydata/data

Beachten Sie, dass Windows-Pfadnamen in Optionsdateien nicht mit Backslashs, sondern mit normalen Schrägstrichen angegeben werden. Wenn Sie Backslashs (umgekehrte Schrägstriche) verwenden, müssen Sie sie doppelt angeben:

[mysqld]
# set basedir to your installation path
basedir=E:\\mysql
# set datadir to the location of your data directory
datadir=E:\\mydata\\data

In MySQL 5.1.23 und früher legt das MySQL-Installationsprogramm das Datenverzeichnis direkt im Installationsverzeichnis von MySQL ab. In MySQL 5.1.24 und später befindet sich das Datenverzeichnis im Verzeichnis AppData des Benutzers, der MySQL ausführt.

Wenn Sie das Datenverzeichnis an eine andere Position verschieben wollen, sollten Sie den gesamten Inhalt des Verzeichnisses data an die neue Position kopieren. Wollen Sie stattdessen E:\mydata als Datenverzeichnis verwenden, dann müssen Sie zweierlei tun:

  1. Sie verschieben das gesamte Verzeichnis data und alle darin enthaltenen Daten vom Standardspeicherort (z. B. C:\Program Files\MySQL\MySQL Server 5.1\data) nach E:\mydata.

  2. Sie verwenden die Option --datadir, um die neue Position des Datenverzeichnisses bei jedem Serverstart anzugeben. Auswahl des MySQL Server-Typs

2.3.8. Auswählen eines MySQL Server-Typs

Die folgende Tabelle zeigt die in MySQL 5.1.20 und früher für Windows verfügbaren Server:

BinärdateiBeschreibung
mysqld-ntOptimierte Binärdatei mit Unterstützung von Named Pipes
mysqldOptimierte Binärdatei ohne Unterstützung von Named Pipes
mysqld-debugWie mysqld-nt, jedoch mit allen Debugging-Funktionen und automatischer Überprüfung der Speicherzuordnung kompiliert

Die folgende Tabelle zeigt die ab MySQL 5.1.21 für Windows verfügbaren Server:

BinärdateiBeschreibung
mysqldOptimierte Binärdatei mit Unterstützung von Named Pipes
mysqld-debugWie mysqld, jedoch mit allen Debugging-Funktionen und automatischer Überprüfung der Speicherzuordnung kompiliert

Alle genannten Binärdateien sind für moderne Intel-Prozessoren optimiert, sollten aber auf allen Intel i386-Prozessoren oder höher funktionieren.

Jeder Server einer Distribution unterstützt die gleichen Speicher-Engines. Die Anweisung SHOW ENGINES zeigt, welche Engines der jeweilige Server unterstützt.

Alle Windows-MySQL 5.1 Server unterstützen symbolische Verknüpfungen von Datenbankverzeichnissen.

MySQL unterstützt TCP/IP auf allen Windows-Plattformen. Unter Windows unterstützen MySQL Server Named Pipes (siehe folgende Aufstellung). Allerdings wird TCP/IP standardmäßig unabhängig von der Plattform verwendet. (Named Pipes sind in vielen Windows-Konfigurationen langsamer als TCP/IP.)

Die Verwendung von Named Pipes hängt von folgenden Bedingungen ab:

  • Named Pipes werden nur aktiviert, wenn Sie den Server mit der Option --enable-named-pipe starten. Diese Option muss explizit angegeben werden, da einige Benutzer Schwierigkeiten mit dem Herunterfahren des MySQL Servers hatten, wenn Named Pipes verwendet wurden.

  • Bei MySQL 5.1.20 und früher sind Named-Pipe-Verbindungen nur bei den Servern mysqld-nt und mysqld-debug zulässig. Ab MySQL 5.1.21 enthalten die Server mysqld und mysqld-debug die Unterstützung für Named-Pipe-Verbindungen.

Anmerkung

Die meisten Beispiele in diesem Handbuch verwenden mysqld als Servername. Wenn Sie einen anderen Server (z. B. mysqld-nt oder mysqld-debug) auswählen, nehmen Sie bei den in den Beispielen gezeigten Befehlen die erforderlichen Änderungen vor.

2.3.9. Erstmaliges Starten des Servers

In diesem Abschnitt finden Sie einen allgemeinen Überblick zum Start des MySQL Servers. Die nachfolgenden Abschnitte enthalten spezielle Informationen zum Starten des MySQL Servers von der Befehlszeile oder als Windows-Dienst.

Die hier enthaltenen Informationen gelten in erster Linie, wenn Sie MySQL aus dem Noinstall-Paket heraus installiert haben oder MySQL manuell (statt unter Verwendung der grafischen Oberflächen) konfigurieren und testen wollen.

Die Beispiele in diesem und den folgenden Abschnitten setzen voraus, dass MySQL im Standardverzeichnis C:\Program Files\MySQL\MySQL Server 5.1 installiert wurde. Haben Sie MySQL an anderer Stelle installiert, dann müssen Sie die in den Beispielen gezeigten Pfadnamen entsprechend abändern.

Für Clients gibt es zwei Optionen. Sie können entweder TCP/IP verwenden oder eine Named Pipe nutzen, sofern der Server Named-Pipe-Verbindungen unterstützt.

MySQL für Windows unterstützt auch Verbindungen mit gemeinsam genutztem Speicher, sofern beim Start des Servers die Option --shared-memory angegeben wurde. Clients können sich über Shared Memory mit der Option --protocol=memory verbinden.

Informationen zur zu startenden Serverbinärdatei finden Sie in Abschnitt 2.3.8, „Auswählen eines MySQL Server-Typs“.

Tests führen Sie am besten über die Eingabeaufforderung in einem Konsolenfenster (oder „DOS-Fenster“) aus. So kann der Server Statusmeldungen im Fenster anzeigen, wo sie leicht zu sehen sind. Funktioniert bei der Konfiguration etwas nicht einwandfrei, dann können Sie Probleme mithilfe dieser Meldungen erkennen und beheben.

Um den Server zu starten, geben Sie folgenden Befehl ein:

C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld" --console

Bei Servern, die die InnoDB-Unterstützung enthalten, sollten Sie folgende Mitteilungen beim Serverstart sehen (die Pfadnamen und Größen können abweichen):

InnoDB: The first specified datafile c:\ibdata\ibdata1 did not exist:
InnoDB: a new database to be created!
InnoDB: Setting file c:\ibdata\ibdata1 size to 209715200
InnoDB: Database physically writes the file full: wait...
InnoDB: Log file c:\iblogs\ib_logfile0 did not exist: new to be created
InnoDB: Setting log file c:\iblogs\ib_logfile0 size to 31457280
InnoDB: Log file c:\iblogs\ib_logfile1 did not exist: new to be created
InnoDB: Setting log file c:\iblogs\ib_logfile1 size to 31457280
InnoDB: Log file c:\iblogs\ib_logfile2 did not exist: new to be created
InnoDB: Setting log file c:\iblogs\ib_logfile2 size to 31457280
InnoDB: Doublewrite buffer not found: creating new
InnoDB: Doublewrite buffer created
InnoDB: creating foreign key constraint system tables
InnoDB: foreign key constraint system tables created
011024 10:58:25  InnoDB: Started

Wenn der Server seine Startsequenz beendet, sollten Sie eine Meldung in der Art der folgenden sehen (hierdurch wird angezeigt, dass der Server nun zur Annahme von Clientverbindungen bereit ist):

mysqld: ready for connections
Version: '5.1.54'  socket: ''  port: 3306

Nachfolgend schreibt der Server weiterhin alle erzeugten Diagnoseausgaben in die Konsole. Sie können ein neues Konsolenfenster öffnen, in dem Clientprogramme ausgeführt werden.

Wenn Sie die Option --console weglassen, schreibt der Server die gesamte Diagnoseausgabe in das Fehlerlog im Datenverzeichnis (standardmäßig C:\Program Files\MySQL\MySQL Server 5.1\data). Das Fehlerlog ist die Datei mit der Erweiterung .err.

Anmerkung

Für die in den MySQL-Grant-Tabellen aufgeführten Konten gibt es zunächst noch keine Passwörter. Wenn Sie den Server gestartet haben, sollten Sie entsprechend der in Abschnitt 2.11, „Einstellungen und Tests nach der Installation“, beschriebenen Verfahrensweise Passwörter für diese Konten einrichten.

2.3.10. Starten von MySQL aus der Windows-Befehlszeile

Der MySQL Server kann manuell über die Befehlszeile gestartet werden. Dies ist bei jeder Windows-Version möglich.

Um dem Server mysqld von der Befehlszeile zu starten, öffnen Sie ein Konsolenfenster („Eingabeaufforderung“) und geben folgenden Befehl ein:

C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld"

Der Pfad für mysqld kann je nach dem Installationsort von MySQL auf Ihrem System variieren.

Sie können den MySQL Server mit folgendem Befehl beenden:

C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqladmin" -u root shutdown
Anmerkung

Wenn das MySQL-Benutzerkonto root ein Passwort aufweist, müssen Sie mysqladmin mit der Option -p aufrufen und das Passwort auf Aufforderung angeben.

Mit diesem Befehl rufen Sie das MySQL-Administrationshilfsprogramm mysqladmin auf, welches eine Verbindung zum Server herstellt und das Herunterfahren auslöst. Der Befehl stellt die Verbindung als MySQL-Benutzer root her. Dies ist das standardmäßige Administratorenkonto im MySQL-Grant-System. Beachten Sie, dass Benutzer im MySQL-Grant-System nichts mit den Benutzerkonten zu tun haben, über die man sich am Windows-System anmeldet.

Wenn mysqld nicht startet, kontrollieren Sie, ob der Server im Fehlerlog Meldungen eingetragen hat, die auf die Ursache des Problems schließen lassen. Das Fehlerlog befindet sich im Verzeichnis C:\Program Files\MySQL\MySQL Server 5.1\data. Es handelt sich um die Datei mit der Erweiterung .err. Sie können auch versuchen, den Server als mysqld --console zu starten; in diesem Fall erhalten Sie unter Umständen über den Bildschirm einige nützliche Informationen, die bei der Beseitigung des Problems helfen können.

Die letzte Option ist der Start von mysqld mit den Optionen --standalone und --debug. In diesem Fall schreibt mysqld eine Logdatei namens C:\mysqld.trace, die die Ursache dafür angeben sollte, dass mysqld nicht gestartet wird. Siehe auch MySQL Internals: Porting.

Verwenden Sie mysqld --verbose --help, um alle Optionen anzuzeigen, die mysqld unterstützt.

2.3.11. Starten von MySQL als Windows-Dienst

Unter Windows besteht die empfohlene Methode zur Ausführung von MySQL in der Installation als Dienst, wobei MySQL automatisch mit Windows gestartet und beendet wird. Ein MySQL Server, der als Dienst installiert ist, lässt sich mithilfe von NET über die Befehlszeile oder über das grafische Hilfsprogramm Dienste steuern. Bei der Installation von MySQL als Windows-Dienst sollten Sie generell als Benutzer eines Kontos mit Administratorrechten angemeldet sein.

Das Hilfsprogramm Dienste (der Service Control Manager von Windows) lässt sich über die Windows-Systemsteuerung aufrufen (Abschnitt Verwaltung bei Windows 2000, XP, Vista und Server 2003). Um Konflikte zu vermeiden, ist es ratsam, das Hilfsprogramm Dienste während der Serverinstallation oder Löschaktionen über die Befehlszeile zu schließen.

Bevor Sie MySQL als Windows-Dienst installieren, sollten Sie zunächst mit dem folgenden Befehl den aktuellen Server beenden, sofern dieser ausgeführt wird:

C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqladmin"
          -u root shutdown
Anmerkung

Wenn das MySQL-Benutzerkonto root ein Passwort aufweist, müssen Sie mysqladmin mit der Option -p aufrufen und das Passwort auf Aufforderung angeben.

Mit diesem Befehl rufen Sie das MySQL-Administrationshilfsprogramm mysqladmin auf, welches eine Verbindung zum Server herstellt und das Herunterfahren auslöst. Der Befehl stellt die Verbindung als MySQL-Benutzer root her. Dies ist das standardmäßige Administratorenkonto im MySQL-Grant-System. Beachten Sie, dass Benutzer im MySQL-Grant-System nichts mit den Benutzerkonten zu tun haben, über die man sich am Windows-System anmeldet.

Installieren Sie den Server mit dem folgenden Befehl als Dienst:

C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld" --install

Mit dem Befehl zur Dienstinstallation wird der Server nicht gestartet. Hinweise zum Start finden Sie in einem späteren Abschnitt.

Um den Aufruf von MySQL-Programmen zu erleichtern, können Sie den Pfadnamen des MySQL-Verzeichnisses bin zur Umgebungsvariable PATH Ihres Windows-Systems hinzufügen:

  • Klicken Sie auf dem Windows-Desktop mit der rechten Maustaste auf das Symbol Arbeitsplatz und wählen Sie Eigenschaften.

  • Wählen Sie nun im angezeigten Fenster Systemeigenschaften die Registerkarte Erweitert und klicken Sie auf die Schaltfläche Umgebungsvariablen.

  • Unter Systemvariablen wählen Sie Path und klicken dann auf die Schaltfläche Bearbeiten. Das Dialogfeld Systemvariable bearbeiten erscheint.

  • Setzen Sie den Cursor an das Ende des im Feld Wert der Variablen gezeigten Texts (betätigen Sie die Taste Ende, um sicherzustellen, dass der Cursor tatsächlich ans Ende des Textes in diesem Textfeld gesetzt wird). Geben Sie nun den vollständigen Pfadnamen Ihres MySQL-Verzeichnisses bin ein (beispielsweise C:\Program Files\MySQL\MySQL Server 5.1\bin). Achten Sie dabei darauf, dass dieser Pfad durch ein Semikolon von den übrigen Werten in diesem Feld abgetrennt ist. Bestätigen Sie nun alle angezeigten Dialogfelder nacheinander durch Anklicken der jeweiligen Schaltflächen OK, bis keine offenen Dialogfelder mehr angezeigt werden. Sie sollten jetzt aus jedem beliebigen Verzeichnis heraus jedes ausführbare MySQL-Programm durch Eingabe seines Namens an der DOS-Eingabeaufforderung starten können, ohne den vollständigen Pfad angeben zu müssen. Dies betrifft die Server, den mysql-Client und alle befehlszeilenbasierten MySQL-Hilfsprogramme wie mysqladmin und mysqldump.

    Wenn Sie mehrere MySQL Server auf Ihrem System betreiben, sollten Sie das MySQL-Verzeichnis bin nicht der Windows-Umgebungsvariablen PATH hinzufügen.

Warnung

Bei der manuellen Editierung der Umgebungsvariablen PATH müssen Sie größte Vorsicht walten lassen: Wenn Sie einen Teil des Werts von PATH versehentlich löschen oder ändern, kann das System instabil oder sogar unbrauchbar werden.

Bei der Installation des Dienstes können die folgenden zusätzlichen Argumente in MySQL 5.1 verwendet werden:

  • Sie können unmittelbar auf die Option --install einen Dienstnamen angeben. Der Standardname für den Dienst lautet MySQL.

  • Wird ein Name für den Dienst angegeben, so kann genau eine weitere Option folgen. Konventionsgemäß ist dies --defaults-file=file_name; hierdurch wird der Name einer Optionsdatei angegeben, die der Server beim Start auslesen soll.

    Die Verwendung einer anderen einzelnen Option als --defaults-file ist zwar möglich, wird aber nicht empfohlen. --defaults-file ist flexibler, da es Ihnen die Festlegung einer Vielzahl von Startoptionen für den Server gestattet, die einfach in der spezifizierten Optionsdatei abgelegt werden.

  • Sie können auch eine Option --local-service gefolgt vom Dienstnamen angeben. In diesem Fall wird der Server über das Windows-Konto LocalService ausgeführt, welches über eingeschränkte Systemberechtigungen verfügt. Dieses Konto ist nur unter Windows XP oder höher vorhanden. Werden beide Optionen --defaults-file und --local-service auf den Dienstnamen folgend angegeben, dann ist die Reihenfolge unerheblich.

Bei einem MySQL Server, der als Windows-Dienst installiert ist, bestimmen die folgenden Grundsätze den Dienstnamen und die vom Server verwendeten Optionsdateien:

  • Wenn der Dienstinstallationsbefehl keinen Dienstnamen oder den Vorgabenamen (MySQL) gefolgt von der Option --install angibt, dann verwendet der Server den Dienstnamen MySQL und liest seine Optionen aus dem Abschnitt [mysqld] der Standardoptionsdateien aus.

  • Wurde im Dienstinstallationsbefehl ein anderer Dienstname als MySQL gefolgt von der Option --install angegeben, dann verwendet der Server diesen anderen Namen. Die Optionen werden dann aus dem Abschnitt [mysqld] und dem Abschnitt ausgelesen, der den gleichen Namen hat wie der Dienst in den Standardoptionsdateien. 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.

  • Wenn im Dienstinstallationsbefehl die Option --defaults-file auf den Dienstnamen folgend angegeben wird, liest der Server nur die Optionen im Abschnitt [mysqld] der angegebenen Datei aus und ignoriert die Standardoptionsdateien.

Nehmen wir einmal den folgenden Befehl als ein etwas komplexeres Beispiel:

C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld"
          --install MySQL --defaults-file=C:\my-opts.cnf

Hier wird der Standarddienstname (MySQL) auf die Option --install folgend angegeben. Wäre keine Option --defaults-file vorhanden, dann würde dieser Befehl dafür sorgen, dass der Server den Abschnitt [mysqld] in den Standardoptionsdateien ausliest. Da allerdings die Option --defaults-file angegeben ist, liest der Server die Optionen im Abschnitt [mysqld] der spezifizierten Datei.

Sie können Optionen auch als Startparameter im Windows-Hilfsprogramm Dienste festlegen, bevor Sie den MySQL-Dienst starten.

Wurde ein MySQL Server als Dienst installiert, dann startet Windows den Dienst automatisch beim Systemstart. Der Dienst lässt sich auch direkt aus dem Hilfsprogramm Dienste oder mithilfe des Befehls NET START MySQL starten. Der NET-Befehl unterscheidet hierbei keine Groß-/Kleinschreibung.

Wenn mysqld als Dienst ausgeführt wird, hat es keinen Zugriff auf ein Konsolenfenster; insofern werden keine Meldungen angezeigt. Wenn mysqld nicht startet, kontrollieren Sie, ob der Server im Fehlerlog Meldungen eingetragen hat, die auf die Ursache des Problems schließen lassen. Das Fehlerlog befindet sich im MySQL-Datenverzeichnis (z. B. C:\Program Files\MySQL\MySQL Server 5.1\data). Es handelt sich um die Datei mit der Erweiterung .err.

Wenn ein MySQL Server als Dienst installiert wurde und dieser Dienst ausgeführt wird, beendet Windows ihn automatisch beim Herunterfahren. Der Server kann auch manuell im Hilfsprogramm Dienste, mit dem Befehl NET STOP MySQL oder dem Befehl mysqladmin shutdown beendet werden.

Außerdem haben Sie die Möglichkeit, den Server als manuellen Dienst zu installieren, wenn Sie nicht wollen, dass der Dienst beim Hochfahren automatisch gestartet wird. Verwenden Sie zu diesem Zweck die Option --install-manual statt --install:

C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld" --install-manual

Um einen Server zu entfernen, der als Dienst installiert ist, beenden Sie ihn zunächst, sofern er noch ausgeführt wird; hierzu verwenden Sie den Befehl NET STOP MYSQL. Danach entfernen Sie ihn mit der Option --remove:

C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld" --remove

Wenn mysqld nicht als Dienst ausgeführt wird, können Sie ihn über die Befehlszeile starten. Informationen zur Vorgehensweise finden Sie in Abschnitt 2.3.10, „Starten von MySQL aus der Windows-Befehlszeile“.

Bitte schlagen Sie in Abschnitt 2.3.13, „Fehlersuche und -behebung in MySQL-Installationen unter Windows“, nach, wenn Sie bei der Installation Probleme haben sollten.

2.3.12. Testen der MySQL-Installation

Ob der MySQL Server funktioniert, können Sie durch Ausführen eines der folgenden Befehle leicht überprüfen:

C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqlshow"
C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqlshow" -u root mysql
C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqladmin" version status proc
C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysql" test

Wenn mysqld nur langsam auf TCP/IP-Verbindungen von Clientprogrammen reagiert, liegt wahrscheinlich ein DNS-Problem vor. Starten Sie in einem solchen Fall mysqld mit der Option --skip-name-resolve und verwenden Sie nur localhost und IP-Nummern in der Spalte Host der MySQL-Berechtigungstabellen.

Sie können die Verwendung einer Named-Pipe-Verbindung (statt einer TCP/IP-Verbindung) erzwingen, indem Sie die Optionen --pipe oder --protocol=PIPE verwenden oder den Punkt . als Hostnamen angeben. Verwenden Sie die Option --socket, um den Namen der Pipe anzugeben, sofern Sie nicht den Namen der Standard-Pipe verwenden wollen. Troubleshooting einer MySQL-Installation unter Windows

Wenn Sie ein Kennwort für das root-Konto eingerichtet, das anonyme Konto gelöscht oder ein neues Benutzerkonto angelegt haben, beachten Sie bitte, dass Sie die entsprechenden -u- und -p-Optionen mit den obigen Befehlen verwenden müssen, um eine Verbindung mit dem MySQL Server herzustellen. Siehe auch Connecting to the MySQL Server.

Weitere Informationen zu mysqlshow finden Sie unter Abschnitt 3.6, „mysqlshow — Anzeigen von Datenbank-, Tabellen- und Spalteninformationen“.

2.3.13. Fehlersuche und -behebung in MySQL-Installationen unter Windows

Wenn Sie MySQL zum ersten Mal installieren und ausführen, können bestimmte Fehler auftreten, die verhindern, dass der MySQL Server gestartet wird. Dieser Abschnitt soll Ihnen dabei helfen, einige dieser Fehler zu diagnostizieren und zu beheben.

Ihre erste Ressource bei der Fehlersuche ist das Fehlerlog. Der MySQL Server verwendet das Fehlerlog zur Aufzeichnung von Daten zu dem Fehler, der verhindert, dass der Server gestartet werden kann. Das Fehlerlog befindet sich im Datenverzeichnis, das in Ihrer Datei my.ini angegeben ist. Die Standardposition des Datenverzeichnisses ist C:\Program Files\MySQL\MySQL Server 5.1\data. Siehe auch The Error Log.

Eine andere Informationsquelle zu möglichen Fehlern sind die Konsolenmeldungen, die beim Starten des MySQL-Dienstes angezeigt werden. Verwenden Sie den Befehl NET START mysql aus der Befehlszeile, nachdem Sie mysqld als Dienst installiert haben, um Fehlermeldungen anzuzeigen, die beim Start des MySQL Servers als Dienst erzeugt werden. Siehe auch Abschnitt 2.3.11, „Starten von MySQL als Windows-Dienst“.

Die folgenden Beispiele zeigen weitere häufig auftretende Fehlermeldungen, die bei der Installation von MySQL und dem ersten Start des Servers angezeigt werden können:

  • Wenn der MySQL Server die mysql-Berechtigungsdatenbank oder andere kritische Dateien nicht finden kann, erscheinen Meldungen folgenden Typs:

    System error 1067 has occurred.
    Fatal error: Can't open privilege tables: Table 'mysql.host' doesn't exist
    

    Solche Meldungen treten häufig auf, wenn das MySQL-Datenbank- oder das MySQL-Datenverzeichnis nicht an der Standardposition (C:\Program Files\MySQL\MySQL Server 5.1 bzw. C:\Program Files\MySQL\MySQL Server 5.1\data) installiert wurde.

    Die Situation entsteht, wenn MySQL aktualisiert und in einem neuen Verzeichnis installiert, aber die Konfigurationsdatei nicht an die geänderte Umgebung angepasst wurde. Außerdem kann es zu Konflikten zwischen alten und neuen Konfigurationsdateien kommen. Benennen Sie alte Konfigurationsdateien in jedem Fall um oder löschen Sie sie, bevor Sie MySQL aktualisieren.

    Wenn Sie MySQL in ein anderes Verzeichnis als C:\Program Files\MySQL\MySQL Server 5.1 installiert haben, müssen Sie sicherstellen, dass dies dem MySQL Server bekannt ist. Hierzu verwenden Sie die Konfigurationsdatei my.ini. Die Datei mit dem Namen my.ini muss in Ihrem Windows-Verzeichnis gespeichert sein (normalerweise C:\WINDOWS). Sie können die exakte Position der Umgebungsvariable WINDIR entnehmen. Hierzu geben Sie den folgenden Befehl an der Befehlszeile ein:

    C:\> echo %WINDIR%
    

    Eine Optionsdatei kann mit jedem Texteditor (z. B. Notepad) erstellt und bearbeitet werden. Ist MySQL beispielsweise in E:\mysql installiert und befindet sich das Datenverzeichnis in D:\MySQLdata, dann können Sie eine Optionsdatei erstellen, die einen Abschnitt [mysqld] enthält. In diesem geben Sie die Werte für die Parameter basedir und datadir an:

    [mysqld]
    # set basedir to your installation path
    basedir=E:/mysql
    # set datadir to the location of your data directory
    datadir=D:/MySQLdata
    

    Beachten Sie, dass Windows-Pfadnamen in Optionsdateien nicht mit Backslashs, sondern mit normalen Schrägstrichen angegeben werden. Wenn Sie Backslashs (umgekehrte Schrägstriche) verwenden, müssen Sie sie doppelt angeben:

    [mysqld]
    # set basedir to your installation path
    basedir=C:\\Program Files\\MySQL\\MySQL Server 5.1
    # set datadir to the location of your data directory
    datadir=D:\\MySQLdata
    

    Wenn Sie den Wert datadir in Ihrer MySQL-Konfigurationsdatei ändern, müssen Sie den Inhalt des vorhandenen MySQL-Datenverzeichnisses verschieben, bevor Sie den MySQL Server neu starten.

    Siehe auch Abschnitt 2.3.7, „Erstellen einer Optionsdatei“.

  • Wenn Sie MySQL neu installieren oder aktualisieren, ohne den vorhandenen MySQL-Dienst zu beenden und zu entfernen, und zur Installation den MySQL-Konfigurations-Assistenten verwenden, dann wird unter Umständen folgende Fehlermeldung angezeigt:

    Error: Cannot create Windows service for MySql. Error: 0
    

    Dies passiert, wenn der Konfigurations-Assistent einen Dienst zu installieren versucht und einen anderen Dienst gleichen Namens vorfindet.

    Eine Lösung dieses Problems besteht darin, bei Verwendung des Konfigurations-Assistenten einen anderen Dienstnamen als mysql auszuwählen. Hierdurch wird der neue Dienst korrekt installiert. Allerdings bleibt dann ein veralteter Dienst zurück. Dies ist an sich zwar unproblematisch, aber trotzdem sollten alte Dienste, die nicht mehr erforderlich sind, korrekt entfernt werden.

    Um den alten mysql-Dienst permanent zu entfernen, führen Sie den folgenden Befehl als Benutzer mit Administratorrechten an der Befehlszeile aus:

    C:\> sc delete mysql
    [SC] DeleteService SUCCESS
    

    Wenn das Hilfsprogramm sc bei Ihrer Windows-Version nicht vorhanden ist, laden Sie das Hilfsprogramm delsrv unter http://www.microsoft.com/windows2000/techinfo/reskit/tools/existing/delsrv-o.asp herunter und verwenden Sie die Syntax delsrv mysql.

2.3.14. Aktualisieren von MySQL unter Windows

Dieser Abschnitt listet einige der Schritte auf, die bei der Aktualisierung von MySQL unter Windows erforderlich sind.

  1. Lesen Sie Abschnitt 2.12.1, „Upgrade von MySQL“. Sie finden dort weitere, nicht Windows-spezifische Informationen zum Upgrade von MySQL.

  2. Fertigen Sie immer eine Sicherung Ihrer aktuellen MySQL-Installation an, bevor Sie ein Upgrade durchführen. Siehe auch Database Backup Methods.

  3. Laden Sie die aktuelle Windows-Distribution von MySQL unter http://dev.mysql.com/downloads/ herunter.

  4. Vor Durchführung des Upgrades müssen Sie den Server beenden. Ist der Server als Dienst installiert, dann beenden Sie ihn durch Eingabe des folgenden Befehls an der Befehlszeile:

    C:\> NET STOP MySQL
    

    Wird der MySQL Server nicht als Dienst ausgeführt, dann beenden Sie ihn mit dem folgenden Befehl:

    C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqladmin" -u root shutdown
    
    Anmerkung

    Wenn das MySQL-Benutzerkonto root ein Passwort aufweist, müssen Sie mysqladmin mit der Option -p aufrufen und das Passwort auf Aufforderung angeben.

  5. Wenn Sie von einer MySQL-Version vor 4.1.5 auf MySQL 5.1 aktualisieren oder ein Upgrade von einer MySQL-Version, die aus einem ZIP-Archiv installiert wurde, auf eine mit dem MySQL-Installations-Assistenten zu installierende Version durchführen, dann müssen Sie die vorherige Installation und den MySQL-Dienst (sofern der Server als Dienst installiert ist) manuell entfernen.

    Verwenden Sie den folgenden Befehl, um den MySQL-Dienst zu entfernen:

    C:\> C:\mysql\bin\mysqld --remove
    

    Wenn Sie den vorhandenen Dienst nicht entfernen, kann der MySQL-Installations-Assistent den neuen MySQL-Dienst unter Umständen nicht korrekt installieren.

  6. Wenn Sie von MySQL 5.1.23 auf MySQL 5.1.24 aktualisieren, müssen Sie aufgrund der Änderung des Standardspeicherorts für das Datenverzeichnis von einem Verzeichnis in der MySQL-Installation zum Ordner AppData die Datendateien von Ihrer alten Installation manuell an den neuen Speicherort kopieren.

  7. Wenn Sie den MySQL-Installations-Assistenten verwenden, starten Sie den Assistenten wie in Abschnitt 2.3.3, „Verwenden des MySQL-Installations-Assistenten“, beschrieben.

  8. Wenn Sie MySQL aus einem ZIP-Archiv installieren, extrahieren Sie das Archiv. Sie können die vorhandene MySQL-Installation entweder überschreiben (diese befindet sich normalerweise im Verzeichnis C:\mysql) oder es in ein anderes Verzeichnis (z. B. C:\mysql5) installieren. Wir empfehlen das Überschreiben der vorhandenen Installation.

  9. Wenn Sie MySQL als Windows-Dienst ausführen und Sie den Dienst zu einem früheren Zeitpunkt dieses Vorgangs deinstallieren mussten, installieren Sie ihn jetzt neu. (Siehe auch Abschnitt 2.3.11, „Starten von MySQL als Windows-Dienst“.)

  10. Starten Sie den Server neu. Verwenden Sie beispielsweise NET START MySQL, wenn Sie MySQL als Dienst ausführen, oder rufen Sie mysqld auf andere Weise direkt auf.

  11. Wenn Fehler auftreten, finden Sie weitere Informationen in Abschnitt 2.3.13, „Fehlersuche und -behebung in MySQL-Installationen unter Windows“.

2.3.15. MySQL unter Windows im Vergleich zu MySQL unter Unix

MySQL für Windows hat sich als sehr stabil erwiesen. Die Windows-Version von MySQL hat dieselben Merkmale wie die entsprechende Unix-Version. Es gibt jedoch folgende Ausnahmen:

  • Eingeschränkte Anzahl von Ports

    Windows-Systeme stellen für Clientverbindungen etwa 4000 Ports bereit. Wird eine Verbindung über einen Port beendet, dann dauert es zwei bis vier Minuten, bis der Port wieder verwendet werden kann. In Situationen, in denen Clients sehr schnell Verbindungen mit dem Server herstellen und diese wieder trennen, ist es unter Umständen möglich, dass alle verfügbaren Ports verbraucht sind, bevor bereits geschlossene Ports wieder verfügbar werden. In diesem Fall scheint der MySQL Server stehen geblieben zu sein, obwohl er tatsächlich nach wie vor ausgeführt wird. Beachten Sie, dass unter Umständen auch andere auf dem System laufenden Anwendungen Ports beanspruchen; in diesem Fall ist die Anzahl der für MySQL verfügbaren Ports noch geringer.

    Weitere Informationen zu diesem Problem finden Sie unter http://support.microsoft.com/default.aspx?scid=kb;en-us;196271.

  • Gleichzeitige Leseoperationen

    MySQL ist auf die Systemaufrufe pread() und pwrite() angewiesen, um INSERT und SELECT miteinander kombinieren zu können. Zurzeit verwenden wir Mutexe zur Emulation von pread() und pwrite(). Wir beabsichtigen, diese Schnittstelle auf Dateiebene in der Zukunft durch eine virtuelle Schnittstelle zu ersetzen, damit wir die Schnittstelle readfile()/writefile() verwenden und so eine höhere Geschwindigkeit erzielen können. Die aktuelle Implementierung beschränkt die Anzahl der von MySQL &current-series verwendbaren offenen Dateien auf 2048, d. h., Sie können unter Windows nicht so viele gleichzeitige Threads ausführen wie unter Unix.

  • Sperrleseoperationen

    MySQL verwendet für jede Verbindung eine Sperrleseoperation. Dies hat die folgenden Auswirkungen, wenn Named-Pipe-Verbindungen aktiviert sind:

    • Eine Verbindung wird – anders als bei MySQL für Unix – nicht automatisch nach acht Stunden getrennt.

    • Hängt eine Verbindung, dann ist es nicht möglich, diese zu unterbrechen, ohne MySQL zu terminieren.

    • mysqladmin kill funktioniert bei hängenden Verbindungen nicht.

    • mysqladmin shutdown kann MySQL nicht herunterfahren, solange eine Verbindung hängt.

    Wir beabsichtigen, dieses Problem in der Zukunft zu lösen.

  • ALTER TABLE

    Während Sie eine ALTER TABLE-Anweisung ausführen, ist die betreffende Tabelle für die Benutzung durch andere Threads gesperrt. Dies hängt mit der Tatsache zusammen, dass Sie eine Datei unter Windows nicht löschen können, solange sie von einem anderen Thread verwendet wird. Wir hoffen, für dieses Problem in der Zukunft einen Workaround zu finden.

  • DROP TABLE

    Die Ausführung von DROP TABLE für eine Tabelle, die von einer MERGE-Tabelle verwendet wird, funktioniert unter Windows nicht, da der MERGE-Handler die Tabellenzuordnung vor der übergeordneten Schicht von MySQL verborgen vornimmt. Da Windows das Löschen geöffneter Dateien nicht gestattet, müssen Sie zunächst alle MERGE-Tabellen (mit FLUSH TABLES) neu laden oder die MERGE-Tabelle löschen, bevor Sie die gewünschte Tabelle tatsächlich löschen können.

  • DATA DIRECTORY und INDEX DIRECTORY

    Die Optionen DATA DIRECTORY und INDEX DIRECTORY für CREATE TABLE werden unter Windows ignoriert, da Windows keine symbolischen Verknüpfungen unterstützt. Außerdem werden diese Optionen auf Systemen ignoriert, bei denen der Aufruf realpath() nicht funktioniert.

  • DROP DATABASE

    Sie können eine Datenbank, die gerade von einem Thread verwendet wird, nicht löschen.

  • Irrelevante Groß-/Kleinschreibung bei Namen

    Da die Groß-/Kleinschreibung bei Dateinamen unter Windows nicht unterschieden wird, ist auch die Schreibweise der Namen von MySQL-Datenbanken und -Tabellen unter Windows irrelevant. Die einzige Einschränkung besteht darin, dass die Datenbank- und Tabellennamen unter Verwendung derselben Schreibweise (Groß- oder Kleinschreibung) in einer gegebenen Anweisung festgelegt werden müssen. Siehe auch Abschnitt 5.2.2, „Beachtung der Groß-/Kleinschreibung bei Bezeichnern“.

  • Dateiverzeichnis- und Dateinamen

    Unter Windows unterstützt der MySQL Server nur Dateiverzeichnis- und Dateinamen, die mit den aktuellen ANSI-Codeseiten kompatibel sind. Zum Beispiel funktioniert der folgende japanische Verzeichnisname bei westlichen Einstellungen (Codeseite 1252) nicht:

    datadir="C:/????????????????????????????????????????????????????????????????????????"
    

    Dieselbe Begrenzung gilt für Dateiverzeichnis- und Dateinamen, die in SQL-Anweisungen referenziert werden, wie der Datendateipfadname in LOAD DATA INFILE.

  • Das Pfadtrennzeichen „\

    Unter Windows werden die Bestandteile von Pfaden durch das Zeichen „\“ voneinander getrennt, welches gleichzeitig das Escape-Zeichen von MySQL ist. Wenn Sie LOAD DATA INFILE oder SELECT ... INTO OUTFILE verwenden, verwenden Sie Dateinamen im Unix-Stil mit „/“-Zeichen:

    mysql> LOAD DATA INFILE 'C:/tmp/skr.txt' INTO TABLE skr;
    mysql> SELECT * INTO OUTFILE 'C:/tmp/skr.txt' FROM skr;
    

    Alternativ müssen Sie das Zeichen „\“ doppelt verwenden:

    mysql> LOAD DATA INFILE 'C:\\tmp\\skr.txt' INTO TABLE skr;
    mysql> SELECT * INTO OUTFILE 'C:\\tmp\\skr.txt' FROM skr;
    
  • Probleme mit Pipes

    An der Windows-Eingabeaufforderung funktionieren Pipes nicht zuverlässig. Wenn eine Pipe das Zeichen ^Z/CHAR(24) enthält, meint Windows ein Dateiende zu erkennen und bricht das Programm ab.

    Dies ist in erster Linie ein Problem, wenn Sie wie folgt eine binäre Logdatei anzuwenden versuchen:

    C:\> mysqlbinlog binary_log_file | mysql --user=root
    

    Wenn Sie bei der Anwendung des Logs Probleme haben und das Zeichen ^Z/CHAR(24) für die Ursache halten, dann können Sie den folgenden Workaround verwenden:

    C:\> mysqlbinlog binary_log_file --result-file=/tmp/bin.sql
    C:\> mysql --user=root --execute "source /tmp/bin.sql"
    

    Der untere Befehl kann auch verwendet werden, um zuverlässig in einer beliebigen SQL-Datei zu lesen, die unter Umständen Binärdateien enthält.

  • Fehler Access denied for user

    Wenn MySQL Ihren Hostnamen nicht korrekt auflösen kann, erhalten Sie unter Umständen folgende Fehlermeldung, sobald Sie versuchen, ein MySQL-Clientprogramm auszuführen, um eine Verbindung mit dem auf dem gleichen Computer laufenden Server herzustellen:

    Access denied for user 'some_user'@'unknown'
    to database 'mysql'
    

    Um dieses Problem zu beheben, sollten Sie eine Datei namens \windows\hosts erstellen, die die folgenden Informationen enthält:

    127.0.0.1       localhost
    

Es folgen einige offene Punkte für alle, die uns helfen wollen, MySQL unter Windows zu verbessern:

  • Hinzufügen von Makros für die Verwendung der von Windows bereitgestellten, schnelleren threadsicheren Increment-/Decrement-Methode.

2.4. Installieren von MySQL aus RPM-Paketen unter Linux

Die empfohlene Vorgehensweise zur Installation von MySQL unter RPM-basierten Linux-Distributionen besteht in der Verwendung von RPM-Paketen. Die von uns gelieferten RPMs sollten unter allen Linux-Versionen funktionieren, die RPM-Pakete unterstützen und glibc 2.3 verwenden. Wie Sie sich die RPM-Pakete beschaffen, lesen Sie in Abschnitt 2.1.3, „Wo können Sie MySQL beziehen?“.

Für Linux-Distributionen, die nicht auf RPM basieren, können Sie MySQL mithilfe eines .tar.gz-Pakets installieren. Siehe auch Abschnitt 2.9, „Installieren von MySQL aus tar.gz-Paketen auf anderen Unix-ähnlichen Systemen“.

Wir bieten eine Reihe plattformspezifischer RPMs an. Der Unterschied zwischen einem plattformspezifischen und einem generischen RPM besteht darin, dass ein plattformspezifisches RPM auf der Zielplattform erstellt und dynamisch verknüpft wurde, wohingegen ein generisches RPM statisch mit LinuxThreads verknüpft ist.

Anmerkung

RPM-Distributionen von MySQL werden häufig von anderen Anbietern bereitgestellt. Beachten Sie, dass Merkmale und Funktionsumfang sich von den Versionen unterscheiden können, die von uns angeboten werden, und dass die Angaben in diesem Handbuch nicht unbedingt für deren Installation gelten. Ziehen Sie im Zweifelsfall die Dokumentation des Anbieters zu Rate.

Wenn Sie Probleme mit einer RPM-Datei haben (also etwa, wenn die Fehlermeldung Sorry, the host 'xxxx' could not be looked up angezeigt wird), finden Sie weitere Informationen in Abschnitt 2.13.1.2, „Anmerkungen zur Linux-Binärdistribution“.

In den meisten Fällen müssen Sie nur die Pakete MySQL-server und MySQL-client installieren, um eine lauffähige MySQL-Installation zu erhalten. Die übrigen Pakete sind für eine Standardinstallation nicht erforderlich.

RPMs für MySQL Cluster.  Ab MySQL 5.1.24 bieten von MySQL erstellte Standard-RPMs für MySQL Server keine Unterstützung der Speicher-Engine NDBCLUSTER mehr. Benutzer von MySQL Cluster, die MySQL 5.1.23 oder frühere Installationen von durch MySQL erstellten RPMs aktualisieren wollen, sollten auf MySQL Cluster NDB 6.2 oder MySQL Cluster NDB 6.3 aktualisieren. Für beide Release-Reihen sind RPMs verfügbar, die auf den meisten Linux-Distributionen funktionieren sollten.

Wichtig

Beim Aktualisieren einer RPM-Installation von MySQL Cluster müssen Sie alle installierten RPMs aktualisieren, auch die Server und Client-RPMs.

Weitere Informationen zur Installation von MySQL Cluster von RPMs finden Sie in MySQL Cluster Multi-Computer Installation.

Wenn Ihre Installation ursprünglich durch die Installation mehrerer RPM-Pakete erzeugt wurde, ist es bei Aktualisierungen am besten, nicht nur einige, sondern alle Pakete zu aktualisieren. Haben Sie also beispielsweise bereits die Server- und Client-RPMs installiert, aktualisieren Sie nicht nur das Server-RPM.

Wenn Sie bei dem Versuch, MySQL-Pakete zu installieren, einen Abhängigkeitsfehler erhalten (z. B. error: removing these packages would break dependencies: libmysqlclient.so.10 is needed by ...), dann sollten Sie auch das Paket MySQL-shared-compat installieren, denn dieses enthält die beiden gemeinsamen Bibliotheken für die Abwärtskompatibilität (libmysqlclient.so.12 für MySQL 4.0 und libmysqlclient.so.10 für MySQL 3.23).

Einige Linux-Distributionen werden immer noch mit MySQL 3.23 ausgeliefert und verknüpfen Anwendungen gewöhnlich dynamisch, um Festplattenkapazität zu sparen. Befinden sich diese gemeinsamen Bibliotheken in einem separaten Paket (z. B. MySQL-shared), dann reicht es aus, dieses Paket einfach installiert zu lassen und nur die MySQL Server- und -Clientpakete zu aktualisieren (diese sind statisch verknüpft und hängen nicht von den gemeinsamen Bibliotheken ab). Bei Distributionen, in denen die gemeinsamen Bibliotheken im selben Paket enthalten sind wie der MySQL Server (z. B. Red Hat Linux), können Sie entweder unser MySQL-shared-RPM für Version 3.23 installieren oder stattdessen das Paket MySQL-shared-compat verwenden. (Installieren Sie nicht beide.)

Die in der folgenden Liste genannten RPM-Pakete sind verfügbar. Die hier aufgeführten Namen verwenden das Suffix .glibc23.i386.rpm. Einzelne Pakete können jedoch abweichende Suffixe haben (siehe Beschreibung unten).

  • MySQL-server-VERSION.glibc23.i386.rpm

    Das ist der MySQL Server. Sie benötigen ihn in jedem Fall, sofern Sie nicht lediglich eine Verbindung mit einem MySQL Server herstellen wollen, der auf einem anderen Computer ausgeführt wird.

  • MySQL-client-VERSION.glibc23.i386.rpm

    Die MySQL-Standardclientprogramme. Dieses Paket sollten Sie immer installieren.

  • MySQL-devel-VERSION.glibc23.i386.rpm

    Die Bibliotheken und Include-Dateien, die erforderlich sind, wenn Sie andere MySQL-Clients (z. B. die Perl-Module) kompilieren wollen.

  • MySQL-debuginfo-VERSION.glibc23.i386.rpm

    Dieses Paket enthält Debug-Informationen. debuginfo-RPMs sind für die Verwendung von MySQL-Software nie notwendig; das gilt sowohl für Server- als auch für Client-Programme. Allerdings enthalten sie Zusatzinformationen, die von einem Debugger benötigt werden könnten, um einen Absturz zu analysieren.

  • MySQL-shared-VERSION.glibc23.i386.rpm

    Dieses Paket enthält die gemeinsamen Bibliotheken (libmysqlclient.so*), die bestimmte Sprachen und Anwendungen benötigen, um MySQL dynamisch laden und verwenden zu können. Es enthält threadsichere und Singlethread-Bibliotheken. Wenn Sie dieses Paket installieren, installieren Sie das Paket MySQL-shared-compat nicht.

  • MySQL-shared-compat-VERSION.glibc23.i386.rpm

    Dieses Paket enthält die gemeinsamen Bibliotheken für MySQL 3.23, 4.0 usw. bis zum aktuellen Release. Es enthält threadsichere und Singlethread-Bibliotheken. Installieren Sie dieses Paket statt MySQL-shared, wenn Sie Anwendungen haben, die dynamisch mit älteren MySQL-Versionen verknüpft sind, Sie aber auf die aktuelle Version aktualisieren wollen, ohne die Bibliotheksabhängigkeiten zu durchbrechen.

  • MySQL-shared-compat-advanced-gpl-VERSION.glibc23.i386.rpm, MySQL-shared-compat-advanced-VERSION.glibc23.i386.rpm

    Diese Pakete entsprechen dem Paket MySQL-shared-compat, allerdings für die Produkte von „MySQL Enterprise Server – Advanced Edition“. Installieren Sie diese Pakete anstelle des normalen Pakets MySQL-shared-compat, wenn Sie gemeinsame Clientbibliotheken für ältere MySQL-Versionen aufnehmen wollen.

  • MySQL-embedded-VERSION.glibc23.i386.rpm

    Die eingebettete MySQL Server-Bibliothek.

  • MySQL-ndb-management-VERSION.glibc23.i386.rpm, MySQL-ndb-storage-VERSION.glibc23.i386.rpm, MySQL-ndb-tools-VERSION.glibc23.i386.rpm, MySQL-ndb-extra-VERSION.glibc23.i386.rpm

    Pakete, die zusätzliche Dateien für MySQL Cluster-Installationen enthalten.

    Anmerkung

    Das MySQL-ndb-tools-RPM verlangt eine Perl-Installation. Vor MySQL 5.1.18 waren auch die Pakete DBI und HTML::Template erforderlich. Weitere Informationen finden Sie in Abschnitt 2.15, „Anmerkungen zur Perl-Installation“, und ndb_size.pl.

  • MySQL-test-VERSION.glibc23.i386.rpm

    Dieses Paket beinhaltet die MySQL-Testsuite.

  • MySQL-VERSION.src.rpm

    Dieses Paket enthält den Quellcode aller zuvor aufgeführten Pakete. Es kann auch zur Neuerstellung der RPMs auf anderen Architekturen (z. B. Alpha oder SPARC) verwendet werden.

Das Suffix von RPM-Paketnamen (nach dem Wert VERSION) hat die folgende Syntax:

.PLATFORM.CPU.rpm

Die Werte PLATFORM und CPU zeigen die Art des Systems an, für das das Paket erstellt wurde. PLATFORM steht für die Plattform und CPU für Prozessortyp oder -familie.

Alle Pakete sind dynamisch mit glibc 2.3 verknüpft. Der Wert PLATFORM zeigt, ob das Paket plattformunabhängig oder an eine spezielle Plattform gebunden ist (siehe folgende Tabelle).

glibc23Plattformunabhängig, sollte auf jeder Linux-Distribution laufen, die glibc 2.3 unterstützt
rhel3, rhel4Red Hat Enterprise Linux 3 oder 4
sles9, sles10SuSE Linux Enterprise Server 9 oder 10

In MySQL-5.1 sind derzeit nur glibc23-Pakete verfügbar.

Der Wert CPU zeigt den Prozessortyp oder die Prozessorfamilie an, für die das Paket erstellt wurde.

i386x86-Prozessor, ab 386
i586x86-Prozessor, ab Pentium
x86_6464-Bit-x86-Prozessor
ia64Itanium-Prozessor (IA-64)

Um alle in einem RPM-Paket (z. B. einem MySQL-server-RPM) enthaltenen Dateien anzuzeigen, führen Sie den folgenden Befehl aus:

shell> rpm -qpl MySQL-server-VERSION.glibc23.i386.rpm

Wollen Sie eine minimale Standardinstallation durchführen, dann installieren Sie die Server- und Client-RPMs:

shell> rpm -i MySQL-server-VERSION.glibc23.i386.rpm
shell> rpm -i MySQL-client-VERSION.glibc23.i386.rpm

Wenn Sie nur die Clientprogramme benötigen, dann installieren Sie lediglich das Client-RPM:

shell> rpm -i MySQL-client-VERSION.glibc23.i386.rpm

Das RPM-Format bietet eine Funktion zur Überprüfung der Integrität und Authentifizierung von Paketen vor der Installation. Wenn Sie mehr zu dieser Funktion erfahren wollen, lesen Sie Abschnitt 2.1.4, „Bestätigen der Paketintegrität mittels MD5-Prüfsummen oder GnuPG.

Das Server-RPM legt Daten im Verzeichnis /var/lib/mysql ab. Außerdem richtet das RPM ein Anmeldekonto für einen Benutzer namens mysql (sofern nicht bereits vorhanden) ein, über das der MySQL Server ausgeführt wird, und erstellt die entsprechenden Einträge in /etc/init.d/, um den Server automatisch mit dem System zu starten. (Dies bedeutet, dass Sie, wenn Sie zuvor bereits eine Installation durchgeführt und Änderungen an deren Startskript vorgenommen haben, eine Kopie des Skripts erstellen sollten, damit es bei der Installation eines neueren RPM nicht verloren geht.) Weitere Informationen dazu, wie MySQL automatisch mit dem System gestartet werden kann, finden Sie in Abschnitt 2.11.2.2, „Automatisches Starten und Beenden von MySQL“.

Wenn Sie das MySQL-RPM auf älteren Linux-Distributionen installieren wollen, die Initialisierungsskripten in /etc/init.d noch nicht (direkt oder über eine symbolische Verknüpfung) unterstützen, dann sollten Sie eine symbolische Verknüpfung erstellen, die auf die Position verweist, an der Ihre Initialisierungsskripten tatsächlich installiert sind. Heißt die Position etwa /etc/rc.d/init.d, dann geben Sie vor der Installation des RPM die folgenden Befehle ein, um /etc/init.d als symbolische Verknüpfung zu erstellen, die darauf verweist:

shell> cd /etc
shell> ln -s rc.d/init.d .

Allerdings sollten die aktuellen Versionen aller wichtigen Linux-Distributionen das neue Verzeichnislayout unterstützen, das /etc/init.d verwendet, da es für die LSB-Kompatibilität (Linux Standard Base) erforderlich ist.

Wenn zu den RPM-Dateien, die Sie installieren, MySQL-server gehört, dann sollte der Server mysqld nach der Installation einwandfrei funktionieren. Sie sollten ihn mithilfe von MySQL starten können.

Klappt etwas nicht, dann erhalten Sie weitere Informationen im Abschnitt zur Installation von Binärdistributionen. Siehe auch Abschnitt 2.9, „Installieren von MySQL aus tar.gz-Paketen auf anderen Unix-ähnlichen Systemen“.

Anmerkung

Für die in den MySQL-Grant-Tabellen aufgeführten Konten gibt es zunächst noch keine Passwörter. Wenn Sie den Server gestartet haben, sollten Sie entsprechend der in Abschnitt 2.11, „Einstellungen und Tests nach der Installation“, beschriebenen Verfahrensweise Passwörter für diese Konten einrichten.

Während der RPM-Installation werden ein Benutzer mit der Bezeichnung mysql und eine Gruppe mit der Bezeichnung mysql im System eingerichtet. Das erfolgt mithilfe der Befehle useradd, groupadd und usermod. Für diese Befehle sind entsprechende Administratorrechte erforderlich, die für lokal verwaltete Benutzer und Gruppen (entsprechend den Angaben in den Dateien /etc/passwd und /etc/group) durch den RPM-Installationsprozess, der von root gestartet wird, gewährleistet sind.

Bei einer nicht lokalen Benutzerverwaltung (LDAP, NIS usw.) können die Verwaltungswerkzeuge eine zusätzliche Authentifizierung fordern (z. B. ein Kennwort) und schlagen fehl, wenn der installierende Benutzer diese nicht liefert. Auch wenn sie fehlschlagen, wird die RPM-Installation nicht abgebrochen, sondern erfolgreich beendet; und das ist Absicht. Bei einem Fehlschlagen wurden gegebenenfalls einzelne erwartete Besitzrechte nicht übertragen. In diesem Fall sollte der Systemadministrator manuell sicherstellen, dass geeignete Benutzer und Gruppen vorhanden sind, und die Besitzrechte entsprechend den Schritten aus der RPM-Spec-Datei übertragen.

2.5. Installieren von MySQL unter Mac OS X

Sie können MySQL unter Mac OS X 10.3.x („Panther“) oder höher mithilfe eines Mac OS X-Binärpakets im PKG-Format anstelle der binären tar-Distribution installieren. Bitte beachten Sie, dass ältere Mac OS X-Versionen (z. B. 10.1.x oder 10.2.x) nicht durch dieses Paket unterstützt werden.

Das Paket befindet sich in einer Festplattenimagedatei (.dmg), die Sie zunächst einbinden müssen. Doppelklicken Sie im Finder auf das zugehörige Symbol. Danach binden Sie das Image ein und zeigen seinen Inhalt an.

Bei der Installation von der Paketversion sollten Sie auch MySQL Preference Pane installieren, womit Sie das Starten und Ausführen Ihres MySQL Servers über System Preferences steuern können.

Wie Sie sich MySQL beschaffen, lesen Sie in Abschnitt 2.1.3, „Wo können Sie MySQL beziehen?“.

Anmerkung

Bevor Sie mit der Installation fortfahren, müssen Sie alle laufenden MySQL Server-Instanzen herunterfahren. Dies tun Sie entweder mit der MySQL-Manager-Anwendung (unter Mac OS X Server) oder mithilfe von mysqladmin shutdown an der Befehlszeile.

Um nun die MySQL-PGK-Datei zu installieren, doppelklicken Sie auf das Paketsymbol. Nun wird das Installationsprogramm für das Mac OS X-Paket gestartet. Dieses Programm geleitet Sie durch die Installation von MySQL.

Aufgrund eines Bugs im Mac OS X-Paketinstallationsprogramm wird bei Anzeige des Dialogfelds zur Auswahl des Ziellaufwerks unter Umständen die folgende Fehlermeldung angezeigt:

You cannot install this software on this disk. (null)

Klicken Sie in diesem Fall einmal auf die Schaltfläche Go Back, um zum vorherigen Bildschirm zurückzukehren. Klicken Sie dann auf Continue, um das Dialogfeld zur Auswahl des Ziellaufwerks erneut aufzurufen. Nun sollten Sie das Ziellaufwerk problemlos auswählen können. Wir haben diesen Bug Apple bereits gemeldet. Das Problem wird dort untersucht.

Das Mac OS X-PKG von MySQL installiert sich im Verzeichnis /usr/local/mysql-VERSION. Ferner wird eine symbolische Verknüpfung /usr/local/mysql eingerichtet, die ebenfalls auf die neue Position verweist. Ist ein Verzeichnis namens /usr/local/mysql bereits vorhanden, dann wird dieses zunächst in /usr/local/mysql.bak umbenannt. Außerdem erstellt das Installationsprogramm die Grant-Tabellen in der mysql-Datenbank. Hierzu führt es den Befehl mysql_install_db aus.

Das Installationslayout ähnelt dem einer tar-Binärdistribution: Alle MySQL-Binärdateien befinden sich im Verzeichnis /usr/local/mysql/bin. Die MySQL-Socketdatei wird standardmäßig als /tmp/mysql.sock erstellt. Siehe auch Abschnitt 2.1.5, „Installationslayout“.

Für die MySQL-Installation ist ein Mac OS X-Benutzerkonto mit dem Namen mysql erforderlich. Unter Mac OS X 10.2 und höher sollte ein solches Konto standardmäßig vorhanden sein.

Wenn Sie Mac OS X Server ausführen, sollte eine MySQL-Version bereits installiert sein. Die folgende Tabelle zeigt die MySQL-Versionen, die mit den verschiedenen Versionen von Mac OS X Server ausgeliefert werden.

Mac OS X Server-VersionMySQL-Version
10.2-10.2.23.23.51
10.2.3-10.2.63.23.53
10.34.0.14
10.3.24.0.16
10.4.04.1.10a

Dieser Handbuchabschnitt behandelt nur die Installation des offiziellen MySQL-PKG für Mac OS X. Lesen Sie in jedem Fall die Hilfeinformationen von Apple zur Installation von MySQL: Starten Sie die Anwendung „Hilfeanzeige“ und wählen Sie die Hilfe für „Mac OS X-Server“. Suchen Sie dann nach dem Begriff „MySQL“ und lesen Sie das Thema „MySQL installieren“.

Haben Sie zuvor MySQL-Pakete für Mac OS X von Marc Liyanage verwendet (http://www.entropy.ch), dann können Sie einfach die auf den dortigen Seiten beschriebenen Aktualisierungsanweisungen für Pakete unter Verwendung der dort bezeichneten Installationsstruktur für Binärdistributionen befolgen.

Aktualisieren Sie von Marcs Versionen 3.23.x oder von der Mac OS X Server-Version von MySQL auf das offizielle MySQL-PKG, dann müssen Sie die vorhandenen MySQL-Berechtigungstabellen ebenfalls in das aktuelle Format konvertieren, da einige neue Sicherheitsberechtigungen hinzugefügt worden sind. Siehe auch mysql_upgrade.

Wenn Sie wollen, dass MySQL während des Systemstarts automatisch gestartet wird, müssen Sie auch das MySQL-Startobjekt installieren. Es ist auf dem Mac OS X-Installationsmedium als separates Installationspaket enthalten. Doppelklicken Sie einfach auf das Symbol MySQLStartupItem.pkg und folgen Sie dann den Anweisungen am Bildschirm. Das Startobjekt muss nur einmal installiert werden. Es ist nicht notwendig, das Startobjekt bei jeder späteren Aktualisierung des MySQL-Pakets vorzunehmen.

Das Startobjekt für MySQL wird in /Library/Startobjekte/MySQLCOM installiert. (Vor MySQL 4.1.2 hieß das Verzeichnis /Library/StartupItems/MySQL, aber dies führt zu einem Konflikt mit dem MySQL-Startobjekt, das von Mac OS X Server installiert wurde.) Bei der Startobjektinstallation wird eine Variable MYSQLCOM=-YES- in der Systemkonfigurationsdatei /etc/hostconfig ergänzt. Wenn Sie den automatischen Start von MySQL deaktivieren wollen, ändern Sie einfach den Wert der Variablen wie folgt: MYSQLCOM=-NO-.

Unter Mac OS X Server verwendet die MySQL-Standardinstallation die Variable MYSQL in der Datei /etc/hostconfig. Das Startobjekt-Installationsprogramm von MySQL deaktiviert diese Variable (MYSQL=-NO-). Hierdurch werden beim Systemstart Konflikte mit der Variablen MYSQLCOM vermieden, die vom MySQL-Startobjekt verwendet wird. Allerdings wird dabei ein laufender MySQL Server nicht heruntergefahren. Dies müssen Sie selbst erledigen.

Nach der Installation können Sie MySQL mithilfe der folgenden Befehle in einem Terminal-Fenster ausführen. Um diesen Vorgang durchzuführen, benötigen Sie Administratorrechte.

Wenn Sie das Startobjekt installiert haben, verwenden Sie folgenden Befehl:

shell> sudo /Library/StartupItems/MySQLCOM/MySQLCOM start
(Enter your password, if necessary)
(Press Control-D or enter "exit" to exit the shell)

Wenn Sie das Startobjekt hingegen nicht installiert haben, geben Sie diese Befehlsfolge ein:

shell> cd /usr/local/mysql
shell> sudo ./bin/mysqld_safe
(Enter your password, if necessary)
(Press Control-Z)
shell> bg
(Press Control-D or enter "exit" to exit the shell)

Sie sollten nun in der Lage sein, eine Verbindung zum MySQL Server herzustellen. Hierzu können Sie etwa /usr/local/mysql/bin/mysql ausführen.

Anmerkung

Für die in den MySQL-Grant-Tabellen aufgeführten Konten gibt es zunächst noch keine Passwörter. Wenn Sie den Server gestartet haben, sollten Sie entsprechend der in Abschnitt 2.11, „Einstellungen und Tests nach der Installation“, beschriebenen Verfahrensweise Passwörter für diese Konten einrichten.

Sie sollten in der Ressourcendatei Ihrer Shell Aliasse ergänzen, um den Zugriff auf häufig verwendete Programme wie mysql und mysqladmin über die Befehlszeile zu erleichtern. Die Syntax für bash lautet:

alias mysql=/usr/local/mysql/bin/mysql
alias mysqladmin=/usr/local/mysql/bin/mysqladmin

Für tcsh verwenden Sie Folgendes:

alias mysql /usr/local/mysql/bin/mysql
alias mysqladmin /usr/local/mysql/bin/mysqladmin

Noch vorteilhafter ist es, /usr/local/mysql/bin zur Umgebungsvariablen PATH hinzuzufügen. Das erreichen Sie durch Ändern der entsprechenden Startdatei für Ihre Shell. Weitere Informationen siehe Invoking MySQL Programs.

Aktualisieren Sie eine vorhandene Installation, dann beachten Sie, dass, wenn Sie ein neues MySQL-PKG installieren, das Verzeichnis der alten Installation nicht entfernt wird. Leider bietet das Mac OS X-Installationsprogramm noch nicht die Funktionalität, die zur korrekten Aktualisierung zuvor installierter Pakete erforderlich ist.

Um Ihre vorhandenen Datenbanken mit der neuen Installation verwenden zu können, müssen Sie den Inhalt des alten Datenverzeichnisses in das neue Datenverzeichnis kopieren. Stellen Sie sicher, dass weder der alte noch der neue Server laufen, während Sie diesen Kopiervorgang durchführen. Haben Sie die MySQL-Datenbankdateien der alten Installation kopiert und den neuen Server erfolgreich gestartet, dann können Sie die alten Installationsdateien entfernen, um Festplattenspeicher zu sparen. Ebenfalls entfernen sollten Sie ältere Versionen der Package-Receipt-Verzeichnisse in /Library/Receipts/mysql-VERSION.pkg. Installation von MySQL unter NetWare

2.6. Installieren von MySQL unter Solaris

Eine MySQL-Binärdistribution für Solaris im tar- oder PKG-Format erhalten Sie unter http://dev.mysql.com/downloads/mysql/5.1.html.

Bei der Installation einer tar-Binärdistribution unter Solaris haben Sie möglicherweise schon die ersten Probleme, bevor Sie die MySQL-Distribution überhaupt entpacken können, denn tar kann unter Solaris nicht mit langen Dateinamen umgehen. Dies bedeutet, dass Ihnen unter Umständen Fehler angezeigt werden, wenn Sie MySQL entpacken.

In diesem Fall müssen Sie GNU tar (gtar) zum Entpacken der Distribution verwenden.

Sie können MySQL auf Solaris mithilfe eines Binärpakets im PKG-Format anstelle der tar-Binärdistribution installieren. Vor der Installation mit dem PKG-Binärpaket müssen Sie den Benutzer und die Gruppe mysql anlegen, z. B.:

groupadd mysql
useradd -g mysql mysql

Einige grundlegende Befehle für den Umgang mit PKG-Paketen sind:

  • Hinzufügen eines Pakets:

    pkgadd -d package_name.pkg
    
  • Entfernen eines Pakets:

    pkgrm package_name
    
  • Abrufen einer Gesamtliste installierter Pakete:

    pkginfo
    
  • Abrufen detaillierter Informationen über ein Paket:

    pkginfo -l package_name
    
  • Auflisten der zu einem Paket gehörenden Dateien:

    pkgchk -v package_name
    
  • Abrufen von Paketierungsinformationen zu einer beliebigen Datei:

    pkgchk -l -p file_name
    

Weitere Informationen zur Installation von MySQL unter Solaris finden Sie in Abschnitt 2.13.3, „Anmerkungen zu Solaris“.

2.7. Installieren von MySQL unter i5/OS

Das MySQL-Paket für i5/OS POWER wurde in Zusammenarbeit mit IBM erstellt. MySQL funktioniert in der Portablen Application Solution Environment (PASE) im Hardware-System iSeries und bietet außerdem Datenbankdienste für Zend Core for i5/OS.

MySQL für i5/OS wird als Sicherungsdateipaket (.savf) bereitgestellt, das heruntergeladen und direkt ohne zusätzlich erforderliche Installationsschritte installiert werden kann.

MySQL wird nur unter i5/OS V5R4 oder späteren Releases unterstützt. Damit MySQL funktioniert, muss i5/OS PASE installiert sein. Sie müssen sich als Benutzer in der *SECOFR-Klasse anmelden können.

Machen Sie sich vor Beginn der Installation mit den Hinweisen und Tipps für i5/OS bekannt. Siehe Installationshinweise für i5/OS.

Anmerkung

Das Installationspaket verwendet eine existierende Konfiguration, wenn Sie MySQL bereits installiert haben (um diese zu erkennen, wird nach der Datei /etc/my.cnf gesucht). Die während der Installation angegebenen Werte für das Datenverzeichnis (DATADIR) und den Besitzer der MySQL-Dateien (USRPRF) werden ignoriert. Stattdessen werden die Werte aus der Datei /etc/my.cnf verwendet.

Wenn Sie diese Parameter im Rahmen einer Neuinstallation ändern wollen, benennen Sie /etc/my.cnf vorläufig um, installieren MySQL mit Ihren neuen Parametern und führen dann Ihre früheren /etc/my.cnf-Konfigurationseinstellungen mit der neuen /etc/my.cnf-Datei zusammen, die während Installation eingerichtet wird.

Für die Installation von MySQL unter i5/OS gehen Sie wie folgt vor:

  1. Richten Sie ein Benutzerprofil MYSQL ein. Das Benutzerprofil MYSQL ist der Besitzer aller MySQL-Dateien und -Datenbanken und der aktive Benutzer, wenn der MySQL Server läuft. Das Profil sollte deaktiviert werden, so dass Sie sich nicht als MySQL-Benutzer anmelden können. Zum Einrichten eines Benutzerprofils verwenden Sie CRTUSRPRF:

    CRTUSRPRF USRPRF(MYSQL) STATUS(*DISABLED) TEXT('MySQL user id')
  2. Richten Sie auf dem System i-Rechner eine Sicherungsdatei ein, die zum Speichern der heruntergeladenen Installationssicherungsdatei dient. Die Datei sollte sich in der General Purpose Library (QGPL) befinden:

    CRTSAVF FILE(QGPL/MYSQLINST)
  3. Laden Sie die MySQL-Installationssicherungsdatei in 32 Bit (mysql-5.0.42-i5os-power-32bit.savf) oder 64 bit (mysql-5.0.42-i5os-power-64bit.savf) von MySQL Downloads herunter.

  4. Die heruntergeladene .savf-Datei müssen Sie über FTP direkt in die QGPL/MYSQLINST-Datei auf dem System i-Server übertragen. Das können Sie über FTP wie folgt ausführen, nachdem Sie sich am System i-Rechner angemeldet haben:

    ftp> bin
    ftp> cd qgpl
    ftp> put mysql-5.0.42-i5os-power.savf mysqlinst
  5. Melden Sie sich am System i-Server mit einem Benutzer in der *SECOFR-Klasse an (z. B. Benutzerkennung QSECOFR).

  6. Sie müssen die in der .savf-Sicherungsdatei gespeicherte Installationsbibliothek aktualisieren:

    RSTLIB MYSQLINST DEV(*SAVF) SAVF(QGPL/MYSQLINST)
  7. Sie müssen den Installationsbefehl MYSQLINST/INSMYSQL ausführen. Während der Installation können Sie drei Parametereinstellungen angeben:

    • DIR('/opt/mysql') legt den Installationsort für die MySQL-Dateien fest. Das Dateiverzeichnis wird eingerichtet, wenn es noch nicht vorhanden ist.

    • DATADIR('/QOpenSys/mysal/data') legt den Speicherort des Verzeichnisses fest, das zum Speichern der Datenbankdateien und Binär-Logs verwendet wird. Die Standardeinstellung ist /QOpenSys/mysql/data. Beachten Sie, wenn das Installationsprogramm eine vorhandene Installation feststellt (aufgrund des Vorhandenseins von /etc/my.cnf), wird dieser Parameter ignoriert.

    • USRPRF(MYSQL) legt das Benutzerprofil fest, das der Besitzer der installierten Dateien sein wird. Das Profil wird eingerichtet, wenn es noch nicht vorhanden ist.

    MySQL kann an einem beliebigen Ort installiert werden. Für dieses Beispiel nehmen wir an, dass MySQL unter /opt/mysql installiert wurde. Für das Profil ist das MYSQL-Benutzerprofil zu verwenden, das im Rahmen dieses Verfahrens bereits erstellt wurde:

    MYSQLINST/INSMYSQL DIR('/opt/mysql') DATADIR('/opt/mysqldata') USRPRF(MYSQL)

    Wenn Sie eine existierende MySQL-Installation mit einer Installation aktualisieren, sollten Sie die gleichen Parameterwerte verwenden, die verwendet wurden, als MySQL ursprünglich installiert wurde.

    Die Installation kopiert alle notwendigen Dateien in ein Dateiverzeichnis, das der Paketversion entspricht (zum Beispiel mysql-5.0.42-i5os-power-32bit), legt die Besitzrechte für diese Dateien fest, richtet die MySQL-Umgebung ein und erstellt die MySQL-Konfigurationsdatei (in /etc/my.cnf). Alle diese Schritte laufen in einem typischen binären Installationsprozess automatisch ab. Wenn es sich um eine Neuinstallation von MySQL handelt oder das Installationsprogramm feststellt, dass es sich um eine neue Version handelt (da die Datei /etc/my.cnf nicht existiert), dann werden die MySQL-Ausgangsdatenbanken ebenfalls während der Installation eingerichtet.

  8. Nach dem Abschluss der Installation können Sie die Installationsdatei löschen:

    DLTLIB LIB(MYSQLINST)

So starten Sie MySQL:

  1. Melden Sie sich am System i-Server mit einem Benutzer in der *SECOFR-Klasse an (z. B. Benutzerkennung QSECOFR).

    Anmerkung

    Starten Sie mysqld_safe mit einem Benutzer, der in der PASE-Umgebung die Kennung 0 hat (Äquivalent des root-Standardbenutzers in Unix). Wenn Sie keinen Benutzer mit dieser Kennung verwenden, kann das System den Benutzer beim Ausführen von mysqld entsprechend der Einstellung mittels der Option --user nicht ändern. Ist das der Fall, ist mysqld gegebenenfalls nicht in der Lage, die Dateien im MySQL-Datenverzeichnis zu lesen, sodass die Ausführung fehlschlägt.

  2. Rufen Sie die PASE-Umgebung mittels call qp2term auf.

  3. Starten Sie den MySQL Server, indem Sie in das Installationsverzeichnis wechseln und mysqld_safe ausführen. Geben Sie dabei den Benutzernamen an, der für die Serverinstallation verwendet wurde. Das Installationsprogramm installiert nun eine symbolische Verknüpfung zum Installationsverzeichnis (mysql-5.0.42-i5os-power-32bit) als /opt/mysql/mysql:

    > cd /opt/mysql/mysql
    > bin/mysqld_safe --user=mysql &

    Sie sollten die folgende Mitteilung (o. ä.) sehen:

    Starting mysqld daemon with databases »
         from /opt/mysql/mysql-enterprise-5.0.42-i5os-power-32bit/data

Bei Problemen mit dem Starten des MySQL Servers siehe Abschnitt 2.11.2.3, „Starten des MySQL Servers und Fehlersuche“.

So beenden Sie MySQL:

  1. Melden Sie sich am System i-Server mit der *SECOFR-Klasse an (z. B. Benutzerkennung QSECOFR).

  2. Rufen Sie die PASE-Umgebung mittels call qp2term auf.

  3. Beenden Sie den MySQL Server, indem Sie in das Installationsverzeichnis wechseln und mysqladmin ausführen. Geben Sie dabei den Benutzernamen an, der für die Serverinstallation verwendet wurde:

    > cd /opt/mysql/mysql
    > bin/mysqladmin -u root shutdown

    Wenn die Sitzungen, mit denen Sie MySQL gestartet und beendet haben, übereinstimmen, erhalten Sie ggf. die Log-Ausgabe mysqld:

       STOPPING server from pid file »
         /opt/mysql/mysql-enterprise-5.0.42-i5os-power-32bit/data/I5DBX.RCHLAND.IBM.COM.pid
       070718 10:34:20  mysqld ended

    Wenn die Sitzungen zum Starten und Beenden von MySQL voneinander abweichen, erhalten Sie keine Bestätigung über die Abschaltung.

Hinweis und Tipps

  • Es ist ein Problem mit dem Installationsprozess auf DBCS-Systemen festgestellt worden. Wenn Sie Probleme bei der Installation von MySQL auf einem DBCS-System haben, müssen Sie den codierten Zeichensatzbezeichner Ihres Auftrags (CSSID) in 37 (EBCDIC) ändern, ehe Sie den Installationsbefehl INSMYSQL ausführen. Ermitteln Sie dafür Ihren vorhandenen CSSID (mittels DSPJOB und Auswahl von Option 2), führen Sie CHGJOB CSSID(37) aus, starten Sie INSMYSQL, um MySQL zu installieren und führen Sie anschließend CHGJOB erneut mit Ihrem Original-CSSID aus.

  • Wenn Sie die Perl-Skripten verwenden wollen, die in MySQL enthalten sind, müssen Sie die iSeries-Tools for Developers (5799-PTL) herunterladen. Siehe http://www-03.ibm.com/servers/enable/site/porting/tools/.

2.8. Installieren von MySQL auf NetWare

Die Portierung von MySQL auf NetWare wurde von Novell gezielt unterstützt. Kunden von Novell werden erfreut sein zu erfahren, dass NetWare 6.5 im Bündel mit MySQL-Binärdateien ausgeliefert wird – komplett mit einer automatischen Lizenz zur kommerziellen Nutzung, gültig für alle Server, auf denen diese NetWare-Version läuft.

MySQL für NetWare wird mithilfe einer Kombination aus Metrowerks CodeWarrior for NetWare und speziellen Versionen der GNU-Autotools zur Cross-Kompilierung kompiliert.

Die aktuellen Binärpakete für NetWare erhalten Sie unter http://dev.mysql.com/downloads/. Siehe auch Abschnitt 2.1.3, „Wo können Sie MySQL beziehen?“.

Ein NetWare-Server, auf dem MySQL laufen soll, muss die folgenden Anforderungen erfüllen:

  • Der aktuelle Support Pack von NetWare 6.5 muss installiert sein.

  • Das System muss die Mindestanforderungen erfüllen, die Novell für die Ausführung der betreffenden NetWare-Version stellt.

  • MySQL-Daten und die Programmbinärdateien müssen auf einem NSS-Volume installiert sein (traditionelle Volumes werden nicht unterstützt).

Gehen Sie wie folgt vor, um MySQL für NetWare zu installieren:

  1. Wenn Sie eine vorhandene Installation aktualisieren, beenden Sie den MySQL Server. Hierzu geben Sie den folgenden Befehl an der Serverkonsole ein:

    SERVER:  mysqladmin -u root shutdown
    
    Anmerkung

    Wenn das MySQL-Benutzerkonto root ein Passwort aufweist, müssen Sie mysqladmin mit der Option -p aufrufen und das Passwort auf Aufforderung angeben.

  2. Melden Sie sich am Zielserver über einen Clientcomputer an, der Zugriff auf das Verzeichnis hat, in dem Sie MySQL installieren wollen.

  3. Extrahieren Sie die ZIP-Datei mit dem Binärpaket auf den Server. Stellen Sie dabei sicher, dass die in der ZIP-Datei gespeicherten Pfade verwendet werden. Am sichersten ist das einfache Entpacken nach SYS:\.

    Wenn Sie eine vorhandene Installation aktualisieren, müssen Sie unter Umständen das Datenverzeichnis (beispielsweise SYS:MYSQL\DATA) kopieren. Gleiches gilt für die Datei my.cnf, sofern Sie diese an Ihre Anforderungen angepasst haben. Danach können Sie die alte Kopie von MySQL löschen.

  4. Sie sollten dem Verzeichnis einen anderen, konsistenteren und einfacher zu handhabenden Namen geben. In den Beispielen dieses Handbuchs verwenden wir SYS:MYSQL als Bezeichnung für das Installationsverzeichnis.

    Beachten Sie, dass die MySQL-Installation unter NetWare nicht erkennt, ob eine MySQL-Version außerhalb des NetWare-Releases bereits vorhanden ist. Haben Sie also etwa die aktuelle MySQL-Version (ab MySQL 4.1 oder höher) aus dem Web in SYS:\MYSQL installiert, dann müssen Sie den Ordner umbenennen, bevor Sie den NetWare-Server aktualisieren; andernfalls werden in SYS:\MySQL vorhandene Dateien, die im NetWare Support Pack abgelegt sind, mit der MySQL-Version überschrieben.

  5. Fügen Sie an der Serverkonsole einen Suchpfad für das Verzeichnis hinzu, welches die MySQL-NLMs enthält. Ein Beispiel:

    SERVER:  SEARCH ADD SYS:MYSQL\BIN
    
  6. Initialisieren Sie ggf. das Datenverzeichnis und die Grant-Tabellen, indem Sie mysql_install_db an der Serverkonsole ausführen.

  7. Starten Sie den MySQL Server mit mysqld_safe an der Serverkonsole.

  8. Um die Installation abzuschließen, sollten Sie auch die folgenden Befehle in der Datei autoexec.ncf ergänzen. Wenn Ihre MySQL-Installation beispielsweise in SYS:MYSQL abgelegt ist und Sie MySQL automatisch starten wollen, fügen Sie folgende Befehle hinzu:

    #Starts the MySQL 5.1.x database server
    SEARCH ADD SYS:MYSQL\BIN
    MYSQLD_SAFE
    

    Führen Sie MySQL unter NetWare 6.0 aus, dann empfehlen wir Ihnen dringend die Verwendung der Option --skip-external-locking in der Befehlszeile:

    #Starts the MySQL 5.1.x database server
    SEARCH ADD SYS:MYSQL\BIN
    MYSQLD_SAFE --skip-external-locking
    

    Ferner ist es notwendig, CHECK TABLE und REPAIR TABLE anstelle von myisamchk zu verwenden, da myisamchk externe Sperren verwendet. Die externe Sperrung bereitet bei NetWare 6.0 bekanntermaßen Probleme. Diese wurden jedoch in NetWare 6.5 beseitigt. Beachten Sie, dass die Verwendung von MySQL unter Netware 6.0 nicht offiziell unterstützt wird.

    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. Ein Beispiel:

    #Starts the MySQL 5.1.x database server
    SEARCH ADD SYS:MYSQL\BIN
    MYSQLD_SAFE --autoclose
    

    Das Verhalten von mysqld_safe unter NetWare wird in mysqld_safe, detailliert beschrieben.

  9. Wenn Sie MySQL installieren – sei es zum ersten Mal oder im Zuge der Aktualisierung von einer vorherigen Version –, dann müssen Sie das aktuellste passende Perl-Modul und die geeigneten PHP-Erweiterungen für NetWare herunterladen:

War auf dem NetWare-Server bereits eine MySQL-Installation vorhanden, dann müssen Sie in jedem Fall in der Datei autoexec.ncf nach MySQL-Startbefehlen suchen und diese nach Bedarf bearbeiten oder löschen.

Anmerkung

Für die in den MySQL-Grant-Tabellen aufgeführten Konten gibt es zunächst noch keine Passwörter. Wenn Sie den Server gestartet haben, sollten Sie entsprechend der in Abschnitt 2.11, „Einstellungen und Tests nach der Installation“, beschriebenen Verfahrensweise Passwörter für diese Konten einrichten.

2.9. Installieren von MySQL aus tar.gz-Paketen auf anderen Unix-ähnlichen Systemen

Dieser Abschnitt behandelt die Installation der MySQL-Binärdistributionen, die für die verschiedenen Plattformen in Form komprimierter tar-Dateien (d. h. Dateien mit der Erweiterung .tar.gz) vorliegen. Eine detaillierte Liste finden Sie in Abschnitt 2.1.2.4, „Von Sun Microsystems Inc. kompilierte MySQL-Binärdistributionen“.

Wie Sie sich MySQL beschaffen, lesen Sie in Abschnitt 2.1.3, „Wo können Sie MySQL beziehen?“.

Der Name einer MySQL-tar-Datei mit einer Binärdistribution ist aufgebaut als mysql-VERSION-OS.tar.gz. Dabei ist VERSION eine Zahl (z. B. 5.1.54), während OS das Betriebssystem bezeichnet, für das die Distribution vorgesehen ist (z. B. pc-linux-i686).

Neben diesen Universalpaketen bieten wir für ausgewählte Plattformen auch Binärdateien in plattformspezifischen Paketformaten an. Weitere Informationen zur Installation dieser Pakete finden Sie in Abschnitt 2.2, „MySQL-Standardinstallation mithilfe einer Binärdistribution“.

Um eine MySQL-Binärdistribution in einer tar-Datei zu installieren, benötigen Sie die folgenden Tools:

  • GNU gunzip zum Dekomprimieren der Distribution.

  • Ein anständiges tar zum Entpacken der Distribution. GNU tar funktioniert bekanntermaßen. Bestimmte Betriebssysteme enthalten eine vorinstallierte tar-Version, die aber offenbar problematisch ist. Beispielsweise haben die tar-Varianten früher Versionen von Mac OS X, SunOS 4.x, Solaris 8, Solaris 9, Solaris 10 und OpenSolaris sowie HP-UX Probleme bei langen Dateinamen. Unter Mac OS X können Sie das vorinstallierte Programm gnutar verwenden. Unter Solaris 10 und OpenSolaris können Sie das vorinstallierte gtar verwenden. Auf anderen Systemen mit fehlerhaften tar-Anwendungen sollten Sie zunächst GNU tar installieren.

Sollten Sie auf Probleme stoßen und einen Fehlerbericht speichern wollen, dann gehen Sie vor wie in How to Report Bugs or Problems, beschrieben.

Die wichtigsten Befehle, die bei der Installation und Verwendung einer MySQL-Binärdistribution ausgeführt werden müssen, sind die folgenden:

shell> groupadd mysql
shell> useradd -g mysql mysql
shell> cd /usr/local
shell> gunzip < /path/to/mysql-VERSION-OS.tar.gz | tar xvf -
shell> ln -s full-path-to-mysql-VERSION-OS mysql
shell> cd mysql
shell> chown -R mysql .
shell> chgrp -R mysql .
shell> scripts/mysql_install_db --user=mysql
shell> chown -R root .
shell> chown -R mysql data
shell> bin/mysqld_safe --user=mysql &
Anmerkung

Beim folgenden Vorgang werden keine Passwörter für MySQL-Konten eingerichtet. Wenn Sie den Vorgang abgeschlossen haben, fahren Sie fort bei Abschnitt 2.11, „Einstellungen und Tests nach der Installation“.

Hier nun eine detailliertere Version der vorangegangenen Beschreibung zur Installation einer Binärdistribution:

  1. Fügen Sie einen Anmeldebenutzer und eine Gruppe hinzu, unter denen mysqld ausgeführt wird:

    shell> groupadd mysql
    shell> useradd -g mysql mysql
    

    Diese Befehle fügen die Gruppe mysql und den Benutzer mysql hinzu. Die Syntax für useradd und groupadd kann auf verschiedenen Unix-Versionen etwas abweichen. Es ist auch möglich, dass die Befehle etwas andere Namen haben, wie etwa adduser und addgroup.

    Unter Umständen wollen Sie dem Benutzer und der Gruppe einen anderen Namen als mysql zuweisen. In diesem Fall müssen Sie in den folgenden Schritten den entsprechenden Namen einsetzen.

  2. Wählen Sie das Verzeichnis aus, in das Sie die Distribution entpacken wollen, und rufen Sie dieses auf. Im folgenden Beispiel entpacken wir die Distribution in /usr/local. (Die folgenden Anweisungen setzen deswegen auch voraus, dass Sie Berechtigungen zum Erstellen von Dateien und Verzeichnissen in /usr/local haben. Ist das Verzeichnis geschützt, dann müssen Sie die Installation als root durchführen.)

    shell> cd /usr/local
    
  3. Beschaffen Sie sich wie in Abschnitt 2.1.3, „Wo können Sie MySQL beziehen?“ beschrieben eine Distributionsdatei. Die Binärdistributionen für alle Plattformen werden innerhalb eines Releases aus derselben MySQL-Quelldistribution erstellt.

  4. Entpacken Sie die Distribution. Hierdurch wird das Installationsverzeichnis erstellt. Erstellen Sie dann eine symbolische Verknüpfung zu diesem Verzeichnis:

    shell> gunzip < /path/to/mysql-VERSION-OS.tar.gz | tar xvf -
    shell> ln -s full-path-to-mysql-VERSION-OS mysql
    

    Der Befehl tar erstellt ein Verzeichnis namens mysql-VERSION-OS. Der Befehl ln legt eine symbolische Verknüpfung zu diesem Verzeichnis an. Auf diese Weise können Sie das Installationsverzeichnis einfacher aufrufen als über /usr/local/mysql.

    Bei GNU tar ist kein separater Aufruf von gunzip erforderlich. Sie können die erste Zeile mit dem folgenden Alternativbefehl ersetzen, um die Distribution zu dekomprimieren und zu entpacken:

    shell> tar zxvf /path/to/mysql-VERSION-OS.tar.gz
    
  5. Wechseln Sie nun in das Installationsverzeichnis:

    shell> cd mysql
    

    Sie werden im Verzeichnis mysql verschiedene Dateien und Unterverzeichnisse vorfinden. Die für die Installation wichtigsten Elemente sind die Unterverzeichnisse bin und scripts:

    • Das Verzeichnis bin enthält Clientprogramme und den Server. Sie sollten den vollständigen Pfadnamen dieses Verzeichnisses zu Ihrer Umgebungsvariablen PATH hinzufügen, damit Ihre Shell die MySQL-Programme korrekt findet. Siehe auch Abschnitt 2.14, „Umgebungsvariablen“.

    • Das Verzeichnis scripts enthält das Skript mysql_install_db, welches zur Initialisierung der mysql-Datenbank mit den Grant-Tabellen verwendet wird, in denen die Serverzugriffsberechtigungen gespeichert sind.

  6. Stellen Sie sicher, dass mysql auf den Inhalt der Distribution zugreifen kann. Wenn Sie die Distribution als mysql entpackt haben, sind keine weiteren Maßnahmen notwendig. Wenn Sie die Distribution als root entpackt haben, ist root der Besitzer des Inhalts. Ändern Sie seine Besitzrechte an mysql, indem Sie als root die folgenden Befehle im Installationsverzeichnis ausführen:

    shell> chown -R mysql .
    shell> chgrp -R mysql .
    

    Der erste Befehl setzt das Besitzerattribut der Dateien auf den Benutzer mysql. Der zweite ändert das Gruppenattribut auf die Gruppe mysql.

  7. Wenn Sie MySQL vorher noch nicht installiert hatten, müssen Sie das MySQL-Datenverzeichnis erstellen und die Berechtigungstabellen initialisieren:

    shell> scripts/mysql_install_db --user=mysql
    

    Wenn Sie den Befehl als root ausführen, schließen Sie die Option --user wie hier dargestellt ein. Wenn Sie den Befehl ausführen, während Sie als dieser Benutzer angemeldet sind, können Sie die Option --user weglassen.

    Der Befehl sollte das Datenverzeichnis und seinen Inhalt mit mysql als Besitzer einrichten.

    Nach Erstellung oder Aktualisierung der Grant-Tabellen müssen Sie den Server manuell neu starten.

  8. Wenn Sie mögen, kann der Besitzer des überwiegenden Teils der MySQL-Installation root sein. Davon ausgenommen ist das Datenverzeichnis, dessen Besitzer mysql sein muss. Führen Sie dafür im Installationsverzeichnis die folgenden Befehle als root aus:

    shell> chown -R root .
    shell> chown -R mysql data
    
  9. Wenn Sie wollen, dass MySQL beim Starten des Computers automatisch startet, können Sie support-files/mysql.server in das Verzeichnis kopieren, in dem sich die Startdateien Ihres Systems befinden. Weitere Informationen finden Sie im Skript support-files/mysql.server selbst und in Abschnitt 2.11.2.2, „Automatisches Starten und Beenden von MySQL“.

  10. Neue Konten können Sie mit dem Skript bin/mysql_setpermission einrichten, wenn Sie die Perl-Module DBI und DBD::mysql installieren. So bietet etwa die C-API eine Anzahl von Funktionsaufrufen, die eine API für vorbereitete Anweisungen darstellen. Siehe auch mysql_setpermission. Installationsanweisungen für Perl-Module finden Sie in Abschnitt 2.15, „Anmerkungen zur Perl-Installation“.

  11. Wenn Sie mysqlaccess verwenden wollen und Ihre MySQL-Distribution in einem anderen als dem Standardverzeichnis abgelegt ist, müssen Sie die Position ändern, an der mysqlaccess den mysql-Client vorzufinden erwartet. Bearbeiten Sie das Skript bin/mysqlaccess im Bereich von Zeile 18. Suchen Sie nach einer Zeile, die der folgenden ähnelt:

    $MYSQL     = '/usr/local/bin/mysql';    # path to mysql executable
    

    Ändern Sie den Pfad so ab, dass er die Position wiedergibt, an der mysql tatsächlich auf Ihrem System gespeichert ist. Andernfalls wird die Fehlermeldung Broken Pipe angezeigt, wenn Sie mysqlaccess ausführen.

Nachdem alles entpackt und installiert wurde, sollten Sie Ihre Distribution testen. Verwenden Sie den folgenden Befehl, um den MySQL Server zu starten:

shell> bin/mysqld_safe --user=mysql &

Wenn Sie den Befehl als root ausführen, müssen Sie wie gezeigt die Option --user verwenden. Als Wert der Option tragen Sie den Namen des Anmeldekontos ein, das Sie im ersten Schritt zur Verwendung für die Ausführung des Servers angegeben haben. Wenn Sie den Befehl ausführen, während Sie als mysql angemeldet sind, können Sie die Option --user weglassen.

Wenn der Befehl sofort fehlschlägt und die Meldung mysqld ended ausgibt, finden Sie unter Umständen hilfreiche Informationen in der Datei host_name.err im Datenverzeichnis.

Weitere Informationen zu mysqld_safe können Sie mysqld_safe, entnehmen.

Anmerkung

Für die in den MySQL-Grant-Tabellen aufgeführten Konten gibt es zunächst noch keine Passwörter. Wenn Sie den Server gestartet haben, sollten Sie entsprechend der in Abschnitt 2.11, „Einstellungen und Tests nach der Installation“, beschriebenen Verfahrensweise Passwörter für diese Konten einrichten.

2.10. MySQL-Installation mittels Quelldistribution

Bevor Sie mit einer Installation aus einer Quelldistribution fortfahren, überprüfen Sie zunächst, ob nicht für Ihre Plattform eine Binärdatei von uns angeboten wird, die für Ihre Belange geeignet sein könnte. Wir haben viel Aufwand betrieben, um zu gewährleisten, dass unsere Binärdateien mit den optimalen Optionen erstellt werden.

Wie Sie sich eine MySQL-Quelldistribution beschaffen, erfahren Sie in Abschnitt 2.1.3, „Wo können Sie MySQL beziehen?“. Wenn Sie MySQL aus einer Quelldistribution unter Windows erstellen wollen, siehe Abschnitt 2.10.6, „Installieren von MySQL unter Windows aus dem Quellcode“.

MySQL-Quelldistributionen werden als komprimierte tar-Archive bereitgestellt. Der Dateiname hat den folgenden Aufbau: mysql-VERSION.tar.gz. Hierbei ist VERSION eine Zahl wie beispielsweise 5.1.54.

Zur Installation von MySQL aus einer Quelldistribution benötigen Sie die folgenden Tools:

  • GNU gunzip zum Dekomprimieren der Distribution.

  • Ein anständiges tar zum Entpacken der Distribution. GNU tar funktioniert bekanntermaßen. Bestimmte Betriebssysteme enthalten eine vorinstallierte tar-Version, die aber offenbar problematisch ist. Beispielsweise haben die tar-Varianten früher Versionen von Mac OS X, SunOS 4.x, Solaris 8, Solaris 9, Solaris 10 und OpenSolaris sowie HP-UX Probleme bei langen Dateinamen. Unter Mac OS X können Sie das vorinstallierte Programm gnutar verwenden. Unter Solaris 10 und OpenSolaris können Sie das vorinstallierte gtar verwenden. Auf anderen Systemen mit fehlerhaften tar-Anwendungen sollten Sie zunächst GNU tar installieren.

  • Einen funktionsfähigen ANSI-C++-Compiler. gcc 2.95.2 oder höher, SGI C++ und SunPro C++ sind Compiler, die offensichtlich problemlos funktionieren. libg++ wird bei der Verwendung von gcc nicht benötigt. gcc 2.7.x weist einen Fehler auf, der die Kompilierung bestimmter, hundertprozentig zulässiger C++-Dateien wie etwa sql/sql_base.cc unmöglich macht. Wenn Sie nur gcc 2.7.x haben, müssen Sie Ihr gcc so aktualisieren, dass es MySQL kompilieren kann. Auch gcc 2.8.1 weist bekanntermaßen Probleme auf bestimmten Plattformen auf, sollte also ebenfalls außen vor gelassen werden, sofern auf der betreffenden Plattform ein neuerer Compiler verfügbar ist. gcc 2.95.2 oder höher wird empfohlen.

  • Ein gutes make-Programm. GNU make wird immer empfohlen und ist unter Umständen sogar erforderlich. (BSD make schlägt fehl, make-Implementierungen von Herstellern können ebenso fehlschlagen.) Wenn Sie Probleme haben, verwenden Sie GNU make 3.75 oder höher.

  • libtool 1.5.24 oder höher wird ebenfalls empfohlen.

Benutzen Sie eine Version von gcc, die neu genug ist, um die Option -fno-exceptions zu kennen, dann ist es extrem wichtig, diese Option auch zu verwenden. Andernfalls kompilieren Sie unter Umständen eine Binärdatei, die zu unvorhersagbaren Zeitpunkten abstürzt. Ferner empfehlen wir die Verwendung von -felide-constructors und -fno-rtti mit -fno-exceptions. Im Zweifelsfall tun Sie Folgendes:

CFLAGS="-O3" CXX=gcc CXXFLAGS="-O3 -felide-constructors \
       -fno-exceptions -fno-rtti" ./configure \
       --prefix=/usr/local/mysql --enable-assembler \
       --with-mysqld-ldflags=-all-static

Auf den meisten Systemen erhalten Sie so eine schnelle und stabile Binärdatei.

Sollten Sie auf Probleme stoßen und einen Fehlerbericht speichern wollen, dann gehen Sie vor wie in How to Report Bugs or Problems, beschrieben.

2.10.1. Überblick Quelleninstallation

Die wichtigsten Befehle, die bei der Installation und Verwendung einer MySQL-Quelldistribution ausgeführt werden müssen, sind die folgenden:

shell> groupadd mysql
shell> useradd -g mysql mysql
shell> gunzip < mysql-VERSION.tar.gz | tar -xvf -
shell> cd mysql-VERSION
shell> ./configure --prefix=/usr/local/mysql
shell> make
shell> make install
shell> cp support-files/my-medium.cnf /etc/my.cnf
shell> cd /usr/local/mysql
shell> chown -R mysql .
shell> chgrp -R mysql .
shell> bin/mysql_install_db --user=mysql
shell> chown -R root .
shell> chown -R mysql var
shell> bin/mysqld_safe --user=mysql &

Wenn Sie von einem Quell-RPM ausgehen, tun Sie Folgendes:

shell> rpmbuild --rebuild --clean MySQL-VERSION.src.rpm

Auf diese Weise wird ein Binär-RPM erstellt, das Sie installieren können. Bei älteren RPM-Versionen müssen Sie unter Umständen den Befehl rpmbuild durch rpm ersetzen.

Anmerkung

Beim folgenden Vorgang werden keine Passwörter für MySQL-Konten eingerichtet. Wenn Sie den Vorgang abgeschlossen haben, fahren Sie fort mit Abschnitt 2.11, „Einstellungen und Tests nach der Installation“, wo Konfiguration und Tests nach der Installation beschrieben sind.

Hier nun eine detailliertere Version der vorangegangenen Beschreibung zur MySQL-Installation aus einer Quelldistribution:

  1. Fügen Sie einen Anmeldebenutzer und eine Gruppe hinzu, unter denen mysqld ausgeführt wird:

    shell> groupadd mysql
    shell> useradd -g mysql mysql
    

    Diese Befehle fügen die Gruppe mysql und den Benutzer mysql hinzu. Die Syntax für useradd und groupadd kann auf verschiedenen Unix-Versionen etwas abweichen. Es ist auch möglich, dass die Befehle etwas andere Namen haben, wie etwa adduser und addgroup.

    Unter Umständen wollen Sie dem Benutzer und der Gruppe einen anderen Namen als mysql zuweisen. In diesem Fall müssen Sie in den folgenden Schritten den entsprechenden Namen einsetzen.

  2. Sofern nicht anders angegeben, führen Sie die folgenden Schritte als Benutzer mysql aus.

  3. Wählen Sie das Verzeichnis aus, in das Sie die Distribution entpacken wollen, und rufen Sie dieses auf.

  4. Beschaffen Sie sich wie in Abschnitt 2.1.3, „Wo können Sie MySQL beziehen?“, beschrieben eine Distributionsdatei.

  5. Entpacken Sie die Distribution in das aktuelle Verzeichnis:

    shell> gunzip < /path/to/mysql-VERSION.tar.gz | tar xvf -
    

    Dieser Befehl erstellt ein Verzeichnis namens mysql-VERSION.

    Bei GNU tar ist kein separater Aufruf von gunzip erforderlich. Alternativ verwenden Sie den folgenden Befehl zum Dekomprimieren und Entpacken der Distribution:

    shell> tar zxvf /path/to/mysql-VERSION-OS.tar.gz
    
  6. Wechseln Sie nun in das Stammverzeichnis der entpackten Distribution:

    shell> cd mysql-VERSION
    

    Beachten Sie, dass Sie MySQL derzeit nur von diesem Stammverzeichnis aus installieren können. Sie können es nicht in einem anderen Verzeichnis erstellen.

  7. Konfigurieren Sie den Release und kompilieren Sie alles:

    shell> ./configure --prefix=/usr/local/mysql
    shell> make
    

    Wenn Sie configure ausführen, sollten Sie weitere Optionen festlegen. Führen Sie ./configure --help aus, um eine Liste der Optionen anzuzeigen. Abschnitt 2.10.2, „Typische configure-Optionen“, beschreibt einige der nützlicheren Optionen.

    Wenn Sie eine E-Mail an eine MySQL-Mailingliste senden, weil configure fehlgeschlagen ist und Sie Hilfe benötigen, fügen Sie bitte alle ggf. in der Datei config.log vorhandenen Zeilen hinzu, von denen Sie annehmen, dass sie zur Problembehebung beitragen können. Ferner sollten Sie die letzten paar Zeilen der Ausgabe von configure aufführen. Verwenden Sie zum Übermitteln eines Fehlerberichts die in How to Report Bugs or Problems, beschriebenen Anweisungen.

    Schlägt die Kompilierung fehl, dann finden Sie hilfreiche Informationen in Abschnitt 2.10.4, „Probleme beim Kompilieren von MySQL“.

  8. Installieren Sie die Distribution:

    shell> make install
    

    Sie müssen diesen Befehl unter Umständen als root ausführen.

    Wenn Sie eine Optionsdatei konfigurieren wollen, verwenden Sie eine der im Verzeichnis support-files vorhandenen Dateien als Vorlage. Ein Beispiel:

    shell> cp support-files/my-medium.cnf /etc/my.cnf
    

    Sie müssen diesen Befehl unter Umständen als root ausführen.

    Wenn Sie die Unterstützung für InnoDB-Tabellen konfigurieren wollen, sollten Sie die Datei /etc/my.cnf bearbeiten, das Zeichen # vor den Optionszeilen entfernen, die mit innodb_... beginnen, und die Optionswerte nach Bedarf ändern. Siehe auch Using Option Files, und Abschnitt 9.2, „InnoDB-Konfiguration“.

  9. Wechseln Sie nun in das Installationsverzeichnis:

    shell> cd /usr/local/mysql
    
  10. Wenn Sie den Befehl make install als root ausgeführt haben, ist root der Besitzer der installierten Dateien. Stellen Sie sicher, dass mysql auf die Installation zugreifen kann. Führen Sie dafür im Installationsverzeichnis die folgenden Befehle als root aus:

    shell> chown -R mysql .
    shell> chgrp -R mysql .
    

    Der erste Befehl setzt das Besitzerattribut der Dateien auf den Benutzer mysql. Der zweite ändert das Gruppenattribut auf die Gruppe mysql.

  11. Wenn Sie MySQL vorher noch nicht installiert hatten, müssen Sie das MySQL-Datenverzeichnis erstellen und die Berechtigungstabellen initialisieren:

    shell> bin/mysql_install_db --user=mysql
    

    Wenn Sie den Befehl als root ausführen, schließen Sie die Option --user wie hier dargestellt ein. Wenn Sie den Befehl ausführen, während Sie als mysql angemeldet sind, können Sie die Option --user weglassen.

    Der Befehl sollte das Datenverzeichnis und seinen Inhalt mit mysql als Besitzer einrichten.

    Wenn Sie die Grant-Tabellen mit mysql_install_db erstellt haben, müssen Sie den Server manuell neu starten. Wie dies mit dem Befehl mysqld_safe geht, wird in einem späteren Schritt erläutert.

  12. Wenn Sie mögen, kann der Besitzer des überwiegenden Teils der MySQL-Installation root sein. Davon ausgenommen ist das Datenverzeichnis, dessen Besitzer mysql sein muss. Führen Sie dafür im Installationsverzeichnis die folgenden Befehle als root aus:

    shell> chown -R root .
    shell> chown -R mysql var
    
  13. Wenn Sie wollen, dass MySQL beim Starten des Computers automatisch startet, können Sie support-files/mysql.server in das Verzeichnis kopieren, in dem sich die Startdateien Ihres Systems befinden. Weitere Informationen finden Sie im Skript support-files/mysql.server selbst und in Abschnitt 2.11.2.2, „Automatisches Starten und Beenden von MySQL“.

  14. Neue Konten können Sie mit dem Skript bin/mysql_setpermission einrichten, wenn Sie die Perl-Module DBI und DBD::mysql installieren. So bietet etwa die C-API eine Anzahl von Funktionsaufrufen, die eine API für vorbereitete Anweisungen darstellen. Siehe auch mysql_setpermission. Installationsanweisungen für Perl-Module finden Sie in Abschnitt 2.15, „Anmerkungen zur Perl-Installation“.

Nachdem alles installiert wurde, sollten Sie Ihre Distribution testen. Verwenden Sie den folgenden Befehl, um den MySQL Server zu starten:

shell> /usr/local/mysql/bin/mysqld_safe --user=mysql &

Wenn Sie den Befehl als root ausführen, sollten Sie wie gezeigt die Option --user verwenden. Als Wert der Option tragen Sie den Namen des Anmeldekontos ein, das Sie im ersten Schritt zur Verwendung für die Ausführung des Servers angegeben haben. Wenn Sie den Befehl ausführen, während Sie als dieser Benutzer angemeldet sind, können Sie die Option --user weglassen.

Wenn der Befehl sofort fehlschlägt und die Meldung mysqld ended ausgibt, finden Sie unter Umständen hilfreiche Informationen in der Datei host_name.err im Datenverzeichnis.

Weitere Informationen zu mysqld_safe können Sie mysqld_safe, entnehmen.

Anmerkung

Für die in den MySQL-Grant-Tabellen aufgeführten Konten gibt es zunächst noch keine Passwörter. Wenn Sie den Server gestartet haben, sollten Sie entsprechend der in Abschnitt 2.11, „Einstellungen und Tests nach der Installation“, beschriebenen Verfahrensweise Passwörter für diese Konten einrichten.

2.10.2. Typische configure-Optionen

Das Skript configure bietet Ihnen umfassende Kontrolle darüber, wie Sie Ihre MySQL-Quelldistribution konfigurieren. Normalerweise werden Sie dies mithilfe der Optionen von configure an der Befehlszeile tun. Sie können configure auch über bestimmte Umgebungsvariablen beeinflussen. So bietet etwa die C-API eine Anzahl von Funktionsaufrufen, die eine API für vorbereitete Anweisungen darstellen. Siehe auch Abschnitt 2.14, „Umgebungsvariablen“. Eine vollständige Liste der Optionen, die von configure unterstützt werden, erhalten Sie nach Ausführen des folgenden Befehls:

shell> ./configure --help

Eine Aufstellung der verfügbaren configure-Optionen finden Sie in der folgenden Tabelle.

Tabelle 2.1. configure-Optionen

FormateBeschreibungStandardeinstellungEingeführtEntfernt
--bindir=DIRAusführbare BenutzerdateienEPREFIX/bin  
--build=BUILDFür Erstellung auf BUILD konfigurierenvermutet  
--cache-file=FILEPrüfergebnisse in FILE zwischenspeicherndeaktiviert  
-CAlias für ?--cache-file=config.cache“   
--config-cache    
--datadir=DIRSchreibgeschützte architekturunabhängige DatenPREFIX/share  
--disable-FEATUREFEATURE nicht einschließen   
--disable-dependency-trackingAbhängigkeitsverfolgung deaktivieren   
--disable-grant-optionsGRANT-Optionen deaktivieren   
--disable-largefileÜberstützung für große Dateien weglassen   
--disable-libtool-lockLibtool-Sperre deaktivieren   
--disable-thread-safe-clientClient ohne Threads kompilieren 5.1.7 
--enable-FEATUREFEATURE aktivieren   
--enable-assemblerAssemblerversionen einiger String-Funktionen verwenden, sofern verfügbar   
--enable-dependency-trackingLangsame Abhängigkeits-Extraktionstools nicht zurückweisen   
--enable-fast-installFür schnelle Installation optimierenja  
--enable-local-infileLOAD DATA LOCAL INFILE aktivierendeaktiviert  
--enable-sharedGemeinsame Bibliotheken erstellenja  
--enable-staticStatische Bibliotheken erstellenja  
--enable-thread-safe-clientClient mit Threads kompilieren   
--exec-prefix=EPREFIXArchitekturabhängige Dateien in EPREFIX installieren   
-hDiese Hilfe anzeigen und verlassen   
--help    
--help=shortFür dieses Paket spezifische Optionen zeigen   
--help=recursiveDie Kurzhilfe aller eingeschlossenen Pakete zeigen   
--host=HOSTKreuzkompilieren zum Erstellen von Programmen zur Ausführung auf HOST   
--includedir=DIRC-Header-DateienPREFIX/include  
--infodir=DIRInfo-DokumentationPREFIX/info  
--libdir=DIRObjektcode-BibliothekenEPREFIX/lib  
--libexecdir=DIRAusführbare Dateien programmierenEPREFIX/libexec  
--localstatedir=DIRBearbeitbare EinzelrechnerdatenPREFIX/var  
--mandir=DIRman-DokumentationPREFIX/man  
-nKeine Ausgabe-Dateien einrichten   
--no-create    
--oldincludedir=DIRC-Header-Dateien für non-gcc/usr/include  
--prefix=PREFIXArchitekturunabhängige Dateien in PREFIX installieren   
--program-prefix=PREFIXInstallierten Programmnamen PREFIX voranstellen   
--program-suffix=SUFFIXSUFFIX an installierte Programmnamen anhängen   
--program-transform-name=PROGRAMSed-PROGRAM auf installierten Programmnamen ausführen   
-q`checking...'-Meldungen nicht drucken   
--quiet    
--sbindir=DIRAusführbare System-Admin-DateienEPREFIX/sbin  
--sharedstatedir=DIRÄnderbare architekturunabhängige DatenPREFIX/com  
--srcdir=DIRQuellen in DIR suchenVerzeichnis konfigurieren oder ...  
--sysconfdir=DIRSchreibgeschützte EinzelrechnerdatenPREFIX/etc  
--target=TARGETKonfiguration für Compilererstellung für TARGET   
-VVersionsinformation zeigen und beenden   
--version    
--with-PACKAGEPACKAGE verwenden   
--with-archive-storage-engineSpeicher-Engine Archive aktivierennein  
--with-atomic-opsImplementieren von unteilbaren Operationen mittels Pthread-Rwlocks oder unteilbaren CPU-Anweisungen für Multiprozessorsysteme 5.1.12 
--with-berkeley-dbBerkeley DB aus DIR verwendennein  
--with-berkeley-db-includesBerkeley DB-Header in DIR suchen   
--with-berkeley-db-libsBerkeley DB-Bibliotheken in DIR suchen   
--with-big-tablesTabellen mit mehr als 4-G-Datensätzen auch auf 32-Bit-Plattformen unterstützen   
--with-blackhole-storage-engineSpeicher-Engine Blackhole aktivierennein  
--with-charsetStandardzeichensatz   
--with-client-ldflagsZusätzliche Verknüpfungsargumente für Clients   
--with-collationDefault collation   
--with-commentAnmerkung zur Kompilierumgebung   
--with-csv-storage-engineSpeicher-Engine CSV aktivierenja  
--with-darwin-mwccMetrowerks CodeWarrior-Wrapper unter OS X/Darwin verwenden   
--with-debugDebugcode hinzufügen 5.1.7 
--with-debug=fullDebugcode hinzufügen (fügt Speicherprüfer hinzu, sehr langsam)   
--with-embedded-privilege-controlErstellt Teile zur Prüfung von Benutzerberechtigungen (betrifft nur eingebettete Bibliothek)   
--with-embedded-serverDen eingebetteten Server erstellen   
--with-error-injectFehlerinjektion in MySQL Server aktivieren 5.1.11 
--with-example-storage-engineSpeicher-Engine Example aktivierennein  
--with-extra-charsetsWeitere Zeichensätze neben dem Standard verwenden   
--with-fast-mutexesMit schnellen Mutexen kompilierenaktiviert5.1.5 
--with-federated-storage-engineSpeicher-Engine Federated aktivierennein5.1.35.1.9
--with-gnu-ldAnnehmen, dass der C-Compiler GNU-ld verwendetnein  
--with-innodbSpeicher-Engine Innobase aktivierennein5.1.35.1.9
--with-lib-ccflagsZusätzliche CC-Optionen für Bibliotheken   
--with-libwrap=DIRMit libwrap kompilieren (Unterstützung von tcp_wrappers)   
--with-low-memoryVersuch beim Kompilieren weniger Speicher zu verwenden, um Speicherbegrenzungen zu vermeiden   
--with-machine-typeDen Rechnertyp setzen, z. B. ?powerpc“   
--with-max-indexes=NLegt die maximale Anzahl von Indizes pro Tabelle fest64  
--with-mysqld-ldflagsZusätzliche Verknüpfungsargumente für mysqld   
--with-mysqld-libsZusätzliche Bibliotheken für Verknüpfungen für mysqld   
--with-mysqld-userBenutzer, als der der mysqld-Dämon ausgeführt wird   
--with-mysqlmanagerDie Binärdatei mysqlmanager erstellenBei Servererstellung erstellen  
--with-named-curses-libsAngegebene Curses-Bibliotheken verwenden   
--with-named-thread-libsAngegebene Thread-Bibliotheken verwenden   
--with-ndb-ccflagsZusätzliche CC-Optionen für ndb-Kompilierung   
--with-ndb-docsndbapi- und mgmapi-Dokumentation für NDB-Cluster einschließen   
--with-ndb-portPort für NDB-Cluster-Managementserver   
--with-ndb-port-basePort für NDB-Cluster-Managementserver   
--with-ndb-sci=DIRMySQL mit benutzerdefiniertem Speicherort für sci-Bibliothek versehen   
--with-ndb-testDie ndbapi-Prüfprogramme für NDB-Cluster einschließen   
--with-ndbclusterDen NDB-Cluster-Tabellen-Handler einschließennein  
--with-openssl=DIRDie OpenSSL-Unterstützung einschließen   
--with-openssl-includesOpenSSL-Header in DIR suchen   
--with-openssl-libsOpenSSL-Bibliotheken in DIR suchen   
--with-other-libc=DIRVerknüpfung mit libc und anderen Standard-Bibliotheken, die am angegebenen, nichtstandardmäßigen Ort installiert sind   
--with-picVersuchen, nur PIC/non-PIC-Objekte zu verwendenBeide verwenden  
--with-plugin-PLUGINErzwingt die statische Verknüpfung des genannten Plug-Ins mit mysqld 5.1.11 
--with-pluginsIn mysqld einzuschließende Plug-Inskeine5.1.11 
--with-pstackDie Backtrace-Bibliothek pstack verwenden   
--with-pthreadVerwendung von Pthread-Bibliothek erzwingen   
--with-row-based-replicationZeilenbasierte Replikation einschließen 5.1.55.1.6
--with-server-suffixWert an den Versionsstring anhängen   
--with-ssl=DIRSSL-Unterstützung einschließen 5.1.11 
--with-system-typeDen Systemtyp einstellen, wie ?sun-solaris10“   
--with-tagsZusätzliche Konfigurationen einschließenautomatisch  
--with-tcp-portFür MySQL-Dienste zu verwendender Port3306  
--with-unix-socket-pathOrt für Unix-Domain-Socket   
--with-yasslDie yaSSL-Unterstützung einschließen   
--with-zlib-dir=no|bundled|DIRMySQL mit benutzerdefiniertem Speicherort für Komprimierungsbibliothek versehen   
--without-PACKAGEPACKAGE nicht verwenden   
--without-benchErstellen der Benchmark-Suite überspringen   
--without-debugEine Produktionsversion ohne Debug-Code erstellen   
--without-docsErstellen der Dokumentation überspringen   
--without-extra-toolsErstellen von Hilfsprogrammen im Tools-Verzeichnis überspringen   
--without-geometryGeometriebezogene Teile nicht erstellen   
--without-libeditlibedit anstelle von gepackter Kopie verwenden   
--without-manErstellen der manuellen Seiten überspringen   
--without-ndb-binlogNDB Binlog deaktivieren 5.1.6 
--without-ndb-debugSpezielle NDB-Debug-Funktionen deaktivieren   
--without-plugin-PLUGINPLUGIN ausschließen 5.1.11 
--without-query-cacheAbfragen-Zwischenspeicher nicht erstellen   
--without-readlinereadline anstelle von gepackter Kopie verwenden   
--without-row-based-replicationDatensatzbasierte Replikation nicht einschließen 5.1.75.1.14
--without-serverNur den Client erstellen   
--without-ucaErstellen der nationalen Unicode-Sortierfolgen überspringen   

Eine Auswahl der verfügbaren configure-Optionen wird hier beschrieben. Optionen, die Ihnen bei Schwierigkeiten beim Erstellen von MySQL von Nutzen sein können, finden Sie hier Abschnitt 2.10.4, „Probleme beim Kompilieren von MySQL“.

  • Um nur die Clientbibliotheken und -programme von MySQL (und nicht den Server) zu kompilieren, verwenden Sie die Option --without-server:

    shell> ./configure --without-server
    

    Wenn Sie keinen C++-Compiler haben, können einige Client-Programme wie mysql nicht kompiliert werden, weil sie C++ erfordern. In diesem Fall können Sie den Code, der das Vorhandensein des C++-Compilers prüft, aus configure entfernen und dann ./configure mit der Option --without-server ausführen. In diesem Fall wird bei der Kompilierung zwar versucht, alle Clients zu erstellen, aber Sie können alle Warnungen bezüglich solcher Dateien wie mysql.cc ignorieren. (Wenn make stehen bleibt, geben Sie make -k ein, um das System anzuweisen, die Erstellung auch bei Auftreten von Fehlern abzuschließen.)

  • Wenn Sie die eingebettete MySQL-Bibliothek (libmysqld.a) erstellen wollen, verwenden Sie die Option --with-embedded-server.

  • Wenn Sie nicht wollen, dass Ihre Logdateien und die Datenbankverzeichnisse in /usr/local/var abgelegt werden, verwenden Sie configure in der Art wie folgt:

    shell> ./configure --prefix=/usr/local/mysql
    shell> ./configure --prefix=/usr/local \
               --localstatedir=/usr/local/mysql/data
    

    Der erste Befehl ändert das Installationspräfix, sodass alles in /usr/local/mysql (statt wie standardmäßig vorgesehen in /usr/local) installiert wird. Der zweite Befehl belässt das Installationsstandardpräfix zwar, ersetzt aber die Standardposition der Datenbankverzeichnisse (normalerweise /usr/local/var) durch /usr/local/mysql/data.

    Sie können die Positionen von Installationsverzeichnis und Datenverzeichnis auch zum Zeitpunkt des Serverstarts angeben, indem Sie die Optionen --basedir und --datadir verwenden. Diese können auf der Befehlszeile oder in einer MySQL-Optionsdatei angegeben werden, obwohl es üblicher ist, eine Optionsdatei zu verwenden. Siehe auch Using Option Files.

  • Wenn Sie Unix verwenden und die MySQL-Socketdatei an einer anderen Position als im Standardverzeichnis (normalerweise /tmp oder /var/run) ablegen wollen, verwenden Sie den configure-Befehl wie folgt:

    shell> ./configure \
               --with-unix-socket-path=/usr/local/mysql/tmp/mysql.sock
    

    Der Socketdateiname muss ein absoluter Pfadname sein. Sie können die Position von mysql.sock mithilfe einer Optionsdatei auch zum Zeitpunkt des Serverstarts einstellen. Siehe auch How to Protect or Change the MySQL Unix Socket File.

  • Wenn Sie statisch verknüpfte Programme kompilieren wollen, um etwa eine Binärdistribution zu erstellen, die Leistung zu optimieren oder Probleme mit bestimmten Red Hat Linux-Distributionen zu umgehen, dann führen Sie configure wie folgt aus:

    shell> ./configure --with-client-ldflags=-all-static \
               --with-mysqld-ldflags=-all-static
    
  • Wenn Sie gcc einsetzen und libg++ oder libstdc++ nicht installiert haben, können Sie configure anweisen, gcc als C++-Compiler zu verwenden:

    shell> CC=gcc CXX=gcc ./configure
    

    Verwenden Sie gcc als C++-Compiler, dann wird keine Verknüpfung mit libg++ oder libstdc++ versucht. Dies kann auch dann von Vorteil sein, wenn Sie die betreffenden Bibliotheken installiert haben. In Verbindung mit einigen Versionen dieser Bibliotheken sind bei MySQL-Benutzern in der Vergangenheit nicht nachvollziehbare Probleme aufgetreten.

    Die folgende Liste führt einige Compiler auf. Ferner aufgelistet sind die zugehörigen Einstellungen für Umgebungsvariablen.

    • gcc 2.7.2:

      CC=gcc CXX=gcc CXXFLAGS="-O3 -felide-constructors"
      
    • gcc 2.95.2:

      CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro \
      -felide-constructors -fno-exceptions -fno-rtti"
      
    • pgcc 2.90.29 oder höher:

      CFLAGS="-O3 -mpentiumpro -mstack-align-double" CXX=gcc \
      CXXFLAGS="-O3 -mpentiumpro -mstack-align-double \
      -felide-constructors -fno-exceptions -fno-rtti"
      

    In den meisten Fällen erhalten Sie eine vernünftig optimierte MySQL-Binärdatei, wenn Sie die Optionen der vorangegangenen Tabelle verwenden und die folgenden Optionen in der configure-Befehlszeile hinzufügen:

    --prefix=/usr/local/mysql --enable-assembler \
    --with-mysqld-ldflags=-all-static
    

    Mit anderen Worten: Die vollständige configure-Zeile würde bei allen aktuellen gcc-Versionen ungefähr wie folgt aussehen:

    CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro \
    -felide-constructors -fno-exceptions -fno-rtti" ./configure \
    --prefix=/usr/local/mysql --enable-assembler \
    --with-mysqld-ldflags=-all-static
    

    Alle von uns auf der MySQL-Website unter http://dev.mysql.com/downloads/ bereitgestellten Binärdateien wurden mit optimalen Einstellungen kompiliert und sollten für die meisten Benutzer perfekt geeignet sein. So bietet etwa die C-API eine Anzahl von Funktionsaufrufen, die eine API für vorbereitete Anweisungen darstellen. Siehe auch Abschnitt 2.1.2.4, „Von Sun Microsystems Inc. kompilierte MySQL-Binärdistributionen“. Es gibt einige Konfigurationseinstellungen, durch deren Optimierung Sie eine noch schnellere Binärdatei erstellen können. Diese Einstellungen sind jedoch nur für fortgeschrittene Benutzer geeignet. Siehe auch Abschnitt 4.5.1, „So wirken sich Kompilieren und Verknüpfen auf die Geschwindigkeit von MySQL aus“.

    Schlägt die Erstellung fehl und werden Fehlermeldungen erzeugt, weil Ihr Compiler oder Linker die gemeinsame Bibliothek libmysqlclient.so.N nicht erstellen konnte (wobei N eine Versionsnummer ist), dann können Sie dieses Problem umgehen, indem Sie die Option --disable-shared für configure ergänzen. In diesem Fall erstellt configure die gemeinsame Bibliothek libmysqlclient.so.N nicht.

  • Standardmäßig verwendet MySQL den Zeichensatz latin1 (cp1252 West European). Um den Standardzeichensatz zu ändern, verwenden Sie die Option --with-charset:

    shell> ./configure --with-charset=CHARSET
    

    CHARSET kann einen der folgenden Werte annehmen: binary, armscii8, ascii, big5, cp1250, cp1251, cp1256, cp1257, cp850, cp852, cp866, cp932, dec8, eucjpms, euckr, gb2312, gbk, geostd8, greek, hebrew, hp8, keybcs2, koi8r, koi8u, latin1, latin2, latin5, latin7, macce, macroman, sjis, swe7, tis620, ucs2, ujis, utf8. So bietet etwa die C-API eine Anzahl von Funktionsaufrufen, die eine API für vorbereitete Anweisungen darstellen. Siehe auch Character Set Configuration. (Gegebenenfalls können zusätzliche Zeichensätze verfügbar sein. Die aktuelle Aufstellung finden Sie in der Ausgabe von ./configure --help.)

    Die Standardsortierung kann ebenfalls angegeben werden. Standardmäßig verwendet MySQL die Sortierung latin1_swedish_ci. Um diese Sortierung zu ändern, verwenden Sie die Option --with-collation:

    shell> ./configure --with-collation=COLLATION
    

    Wollen Sie Zeichensatz und Sortierung gleichzeitig ändern, dann verwenden Sie einfach beide Optionen --with-charset und --with-collation. Die Sortierung muss für den gewählten Zeichensatz zulässig sein. (Mit der Anweisung SHOW COLLATION können Sie die für den jeweiligen Zeichensatz zulässige Sortierung ermitteln.)

    Mit der configure-Option --with-extra-charsets=LIST können Sie definieren, welche zusätzlichen Zeichensätze in den Server einkompiliert werden sollen. LIST hat dabei einen der folgenden Werte:

    • eine Liste von Zeichensatznamen, die durch Leerzeichen getrennt sind

    • complex, wenn alle Zeichensätze enthalten sein sollen, die sich nicht dynamisch laden lassen

    • all, wenn grundsätzlich alle Zeichensätze in den Binärdateien enthalten sein sollen

    Clients, die Zeichen zwischen Server und Client konvertieren sollen, müssen die Anweisung SET NAMES verwenden. Siehe auch Server System Variables, und Connection Character Sets and Collations.

  • Um MySQL mit Debugging-Code zu konfigurieren, verwenden Sie die Option --with-debug:

    shell> ./configure --with-debug
    

    Auf diese Weise wird eine sichere Speicherzuweisung in die Konfiguration integriert, die in der Lage ist, bestimmte Fehler zu finden und Informationen zu den Abläufen zu vermitteln. Siehe auch MySQL Internals: Porting.

    Wenn Sie ab MySQL 5.1.12 --with-debug für die Konfiguration von MySQL mit Debug-Support verwenden, können Sie beim Serverstart die Option --debug="d,parser_debug" nutzen. Damit wird der für die Verarbeitung von SQL-Anweisungen verwendete Bison-Parser veranlasst, eine Parser-Spur in die Standardfehlerausgabe des Servers einzutragen. In der Regel wird diese Ausgabe in das Fehlerlog geschrieben.

  • Wenn Ihre Clientprogramme Threads verwenden, müssen Sie eine threadsichere Version der MySQL-Clientbibliothek mit der Konfigurationsoption --enable-thread-safe-client erstellen. Auf diese Weise wird eine Bibliothek libmysqlclient_r angelegt, mit der Sie Ihre Thread-basierten Anwendungen verknüpfen sollten. Siehe auch How to Make a Threaded Client.

  • Für einige Funktionen (z. B. COMPRESS() und UNCOMPRESS()) muss der Server mit Unterstützung für Komprimierungsbibliotheken und Komprimierung des Client-Server-Protokolls erstellt werden. Mit der Option --with-zlib-dir=no|bundled|DIR wird die Unterstützung von Komprimierungsbibliotheken gesteuert. Der Wert no deaktiviert die Komprimierungsunterstützung ausdrücklich. bundled sorgt dafür, dass die zlib-Bibliothek in den zu verwendenden MySQL-Quellen gepackt wird. Ein DIR-Pfadname gibt an, wo sich die Komprimierungsbibliotheksquellen befinden.

  • Es ist möglich, MySQL mit Unterstützung für große Tabellen zu erstellen. Hierzu verwenden Sie die Option --with-big-tables.

    Diese Option sorgt dafür, dass die Variablen, die die Ergebnisse der Datensatzzählungen enthalten, als unsigned long long statt als unsigned long deklariert werden. Sie erlaubt Tabellen die Aufnahme von ca. 1,844E+19 ((232)2) Datensätzen statt 232 (~4,295E+09) Datensätzen. Zuvor war es notwendig gewesen, -DBIG_TABLES manuell an den Compiler zu übergeben, um diese Funktion zu aktivieren.

  • Führen Sie configure mit der Option --disable-grant-options aus, um die Optionen --bootstrap, --skip-grant-tables und --init-file für mysqld zu deaktivieren. Für Windows erkennt das Skript configure.js das Kennzeichen DISABLE_GRANT_OPTIONS, das die gleiche Auswirkung hat. Diese Möglichkeit ist ab MySQL 5.1.15 verfügbar.

  • Mit dieser Option können Funktionen des MySQL Community Servers aktiviert werden. Für einzelne Funktionen sind unter Umständen weitere Optionen notwendig, z. B. --enable-profiling zum Aktivieren der Profilerstellung für Anweisungen. Diese Option wurde in MySQL 5.1.24 hinzugefügt. Ab MySQL 5.1.28 ist sie standardmäßig aktiviert; zum Deaktivieren verwenden Sie --disable-community-features.

  • Im Zusammenhang mit --enable-community-features aktiviert die Option --enable-profiling die Profilierungsfunktion für Anweisungen, die durch die Anweisungen SHOW PROFILE und SHOW PROFILES gezeigt werden. (Siehe auch Abschnitt 8.5.5.33, „SHOW PROFILES-Syntax“.) Diese Option wurde in MySQL 5.1.24 hinzugefügt. Ab MySQL 5.1.28 ist sie standardmäßig aktiviert; zum Deaktivieren verwenden Sie --disable-profiling.

  • Optionen, die für bestimmte Betriebssysteme spezifisch sind, finden Sie in Abschnitt 2.13, „Betriebssystemspezifische Anmerkungen“.

  • Optionen, die zur Konfiguration von MySQL zur Unterstützung sicherer (verschlüsselter) Verbindungen dienen, finden Sie in Using SSL Connections.

  • Einige configure-Optionen gelten für das Auswählen und Erstellen von Plug-Ins:

    --with-plugins=PLUGIN[,PLUGIN]...
    --with-plugins=GROUP
    --with-plugin-PLUGIN
    --without-plugin-PLUGIN
    

    PLUGIN ist ein individueller Plug-In-Name wie csv oder archive.

    Als Kurzschrift ist GROUP ein Konfigurationsgruppenname, wie none (keine Plug-Ins auswählen) oder all (alle Plug-Ins auswählen).

    Sie können Plug-Ins statisch (im Server kompiliert) oder dynamisch (als dynamische Bibliothek erstellt, die vor der Verwendung mit der Anweisung INSTALL PLUGIN installiert werden muss) erstellen. Einige Plug-Ins unterstützen die statische bzw. dynamische Erstellung ggf. nicht.

    configure --help zeigt die folgenden Informationen für Plug-Ins an:

    • Die Optionen für Plug-Ins

    • Die Namen aller verfügbaren Plug-Ins

    • Für jeden Plug-In eine Beschreibung seines Zwecks, die unterstützte Form der Erstellung (statisch oder dynamisch) und zu welcher Plug-In-Gruppe er gehört.

    --with-plugins nimmt eine Liste von einem oder mehreren kommagetrennten Plug-In-Namen oder einen Plug-In-Gruppennamen entgegen. Die genannten Plug-Ins werden für die Erstellung als statische Plug-Ins konfiguriert.

    --with-plugin-PLUGIN konfiguriert den angegebenen Plug-In für die Erstellung als statischer Plug-In.

    --without-plugin-PLUGIN deaktiviert den angegebenen Plug-In für die Erstellung.

    Wenn ein Plug-In sowohl mit einer --with- als auch einer --without-Option bezeichnet wird, ist das Ergebnis undefiniert.

    Für Plug-Ins, die nicht explizit ausgewählt oder deaktiviert sind, wird die dynamische Erstellung ausgewählt, sofern diese vom Plug-In unterstützt wird, ist das nicht der Fall, erfolgt keine Erstellung. (Damit werden alle Plug-Ins, die die dynamische Erstellung unterstützen, in dem Fall, dass keine Plug-In-Optionen angegeben sind, für die Erstellung als dynamische Plug-Ins ausgewählt. Plug-Ins, die die dynamische Erstellung nicht unterstützen, werden nicht erstellt.)

2.10.3. Installation vom Entwicklungs-Source-Tree

Achtung

Sie sollten diesen Abschnitt nur lesen, wenn Sie Interesse daran haben, uns beim Testen unseres neuen Codes behilflich zu sein. Wenn Sie MySQL lediglich in funktionsfähiger Form auf Ihrem System einrichten wollen, sollten Sie einen Standard-Release (entweder als Binär- oder als Quelldistribution) verwenden.

Um unseren aktuellsten Entwicklungs-Source-Tree zu bekommen, müssen Sie zunächst Bazaar herunterladen und installieren. Sie erhalten Bazaar auf der Bazaar VCS-Website. Bazaar wird von jeder Plattform unterstützt, die Python unterstützt, und ist deshalb mit jedem Linux-, Unix-, Windows- oder Mac OS X-Host kompatibel. Anweisungen für das Herunterladen und Installieren von Bazaar auf den verschiedenen Plattformen finden Sie auf der Bazaar-Website.

Alle MySQL-Projekte werden unter Launchpad gehostet. MySQL-Projekte (einschließlich MySQL Server, MySQL Workbench usw.) sind auf der Seite Sun/MySQL Engineering verfügbar. Die ausschließlich auf MySQL Server bezogenen Repositorys finden Sie auf der Seite MySQL Server.

Für die Installation unter Unix/Linux müssen die folgenden Tools installiert sein:

  • GNU make, verfügbar unter http://www.gnu.org/software/make/. Obgleich einige Plattformen über ihre eigene Implementierung von make verfügen, wird empfohlen, unbedingt GNU make zu verwenden. Gegebenenfalls ist es in Ihrem System bereits als gmake verfügbar.

  • autoconf 2.58 (oder neuer), verfügbar unter http://www.gnu.org/software/autoconf/.

  • automake 1.8.1, verfügbar unter http://www.gnu.org/software/automake/.

  • libtool 1.5, verfügbar unter http://www.gnu.org/software/libtool/.

  • m4, verfügbar unter http://www.gnu.org/software/m4/.

  • bison, verfügbar unter http://www.gnu.org/software/bison/. Verwenden Sie nach Möglichkeit die neueste Bison-Version. Version 1.75 und Version 2.1 funktionieren bekanntermaßen. Bei Bison 1.875 sind Probleme bekannt. Wenn Sie Probleme haben, führen Sie ein Upgrade auf eine höhere (anstatt auf eine niedrigere) Version durch. Bison-Versionen, die älter sind als 1.75, zeigen unter Umständen folgenden Fehler an:

    sql_yacc.yy:#####: fatal error: maximum table size (32767) exceeded
    

    Die maximale Tabellengröße wurde mitnichten überschritten; vielmehr wird der Fehler von Bugs in älteren bison-Versionen ausgelöst.

Für das Erstellen unter Windows benötigen Sie die Compilersysteme Microsoft Visual C++ 2005 Express Edition, Visual Studio .Net 2003 (7.1) oder Visual Studio 2005 (8.0).

Nach der erfolgreichen Installation der notwendigen Tools müssen Sie zunächst einen lokalen Zweig des MySQL-Quellcodes auf Ihrem Rechner erstellen:

  1. Um eine Kopie des MySQL-Quellcodes zu erhalten, müssen Sie einen neuen Bazaar-Zweig einrichten. Wenn Sie noch kein Bazaar-Repository-Verzeichnis eingerichtet haben, müssen Sie ein neues Verzeichnis initialisieren:

    shell> mkdir mysql-server
    shell> bzr init-repo --trees mysql-server
  2. Nach dem Initialisieren des Verzeichnisses können Sie mittels branch einen Zweig von den öffentlichen MySQL Server-Repositorys anlegen. So richten Sie einen Zweig einer speziellen Version ein:

    shell> cd mysql-server
    shell> bzr branch lp:mysql-server/5.1 mysql-5.1
  3. Das erste Download kann je nach der Geschwindigkeit Ihrer Verbindung eine Weile dauern. Haben Sie bitte Geduld. Sobald Sie den ersten Baum heruntergeladen haben, sollte das Herunterladen weiterer Bäume merklich weniger Zeit in Anspruch nehmen.

  4. Beim Erstellen aus dem Bazaar-Zweig könnten Sie ggf. eine Kopie Ihres aktiven Zweiges anlegen. Dort haben Sie die Möglichkeit, Konfigurationen und andere Änderungen vorzunehmen, ohne den Inhalt des ursprünglichen Zweiges zu beeinflussen. Sie erreichen dies, indem Sie einen Zweig des ursprünglichen Zweiges anlegen:

    shell> bzr branch mysql-5.1 mysql-5.1-build

Nachdem Sie den lokalen Zweig eingerichtet haben, können Sie mit dem Erstellen des MySQL Servers aus dem Quellcode beginnen. Unter Windows ist der Kompilierungsprozess anders als unter Unix/Linux. Zum Erstellen von MySQL unter Windows siehe auch Abschnitt 2.10.6, „Installieren von MySQL unter Windows aus dem Quellcode“.

Unter Unix/Linux müssen Sie das autoconf-System verwenden, um das configure-Skript zu generieren, mit dem Sie die Erstellungsumgebung vor dem Erstellen konfigurieren können.

  1. Das folgende Beispiel zeigt die typischen Befehle, die zur Konfiguration eines Source-Trees erforderlich sind. Der erste Befehl cd wechselt in das oberste Verzeichnis des Trees. Hierbei ist mysql-5.1 durch den korrekten Verzeichnisnamen zu ersetzen.

    Anmerkung

    Für MySQL 5.1.12 und früher müssen Sie die Speicher-Engine INNODB separat konfigurieren. Führen Sie dafür den folgenden Befehl aus dem Hauptquellenverzeichnis aus:

    shell> (cd storage/innobase; autoreconf --force --install)
    shell> cd mysql-5.1
    shell> autoreconf --force --install
    shell> ./configure  # Add your favorite options here
    shell> make
    

    Alternativ verwenden Sie BUILD/autorun.sh als Abkürzung für die folgende Befehlssequenz:

    shell> aclocal; autoheader
    shell> libtoolize --automake --force
    shell> automake --force --add-missing; autoconf
    

    Die Befehlszeile, mit der das Verzeichnis zum Verzeichnis storage/innobase geändert wird, dient zum Konfigurieren der Speicher-Engine InnoDB. Sie können diese Zeilen auslassen, wenn Sie keine InnoDB-Unterstützung benötigen.

    Anmerkung

    Ab MySQL 5.1 wird Code, der spezifisch für bestimmte Speicher-Engines ist, in ein storage-Verzeichnis verschoben. So liegt beispielsweise InnoDB-Code jetzt in storage/innobase und NDBCLUSTER-Code in storage/ndb.

    Wenn Ihnen in dieser Phase seltsame Fehler angezeigt werden, vergewissern Sie sich, dass libtool tatsächlich installiert wurde.

    Eine Sammlung unserer Standardkonfigurationsskripten befindet sich im Unterverzeichnis BUILD/. Unter Umständen finden Sie es praktischer, statt der vorangegangenen Gruppe von Shell-Befehlen das Skript BUILD/compile-pentium-debug zu verwenden. Um auf einer anderen Architektur zu kompilieren, ändern Sie das Skript ab, indem Sie Pentium-spezifische Flags entfernen, oder verwenden Sie ein anderes Skript, das besser geeignet ist. Diese Skripten werden „as-is“ bereitgestellt. Sie werden nicht offiziell gepflegt und ihr Inhalt kann sich von Release zu Release ändern.

  2. Wenn die Erstellung abgeschlossen ist, führen Sie make install aus. Auf einem Produktionssystem sollten Sie dies allerdings mit Vorsicht tun: Wenn Sie bereits eine andere MySQL-Installation haben, führen Sie ./configure mit anderen als den für den Produktionsserver verwendeten Werten für die Optionen --prefix, --with-tcp-port und --with-unix-socket-path aus.

  3. Prüfen Sie Ihre neue Installation auf Herz und Nieren und versuchen Sie, die neuen Funktionen zum Absturz zu bringen. Führen Sie zunächst make test aus. Siehe auch MySQL Test Suite.

  4. Wenn Sie es bis zur make-Phase geschafft haben, aber die Distribution sich nicht kompilieren lässt, dann geben Sie das Problem in unsere Fehlerdatenbank ein. Beachten Sie hierzu die Anweisungen in How to Report Bugs or Problems. Haben Sie die aktuellen Versionen der erforderlichen GNU-Tools installiert und stürzen diese bei der Verarbeitung unserer Konfigurationsdateien ebenfalls ab, dann teilen Sie uns bitte auch dies mit. Wenn Sie allerdings aclocal ausführen und die Fehlermeldung command not found o. ä. erhalten, melden Sie dies bitte nicht. Überprüfen Sie stattdessen, ob alle notwendigen Tools installiert sind und Ihre Variable PATH korrekt eingestellt ist, damit Ihre Shell sie finden kann.

  5. Wenn Sie das Repository mit bzr kopiert haben, um den Source-Tree zu erhalten, sollten Sie regelmäßig die Option pull ausführen, um Ihre lokale Kopie zu aktualisieren. Zu diesem Zweck können Sie nach der Konfiguration des Repositorys jederzeit den folgenden Befehl verwenden:

    shell> bzr pull
    
  6. Sie können die Changeset-Anmerkungen für den Baum prüfen, indem Sie die Option log auf bzr anwenden:

    shell> bzr log

    Changesets, Anmerkungen und Quellcode können Sie auch online durchsuchen. Unter http://launchpad.net/mysql-server/ können Sie diese Informationen für MySQL 5.1 durchsuchen.

    Wenn Sie über Diffs oder Code stolpern, zu denen Sie Fragen haben, schicken Sie einfach eine E-Mail an die MySQL-Mailingliste internals. So bietet etwa die C-API eine Anzahl von Funktionsaufrufen, die eine API für vorbereitete Anweisungen darstellen. Siehe auch MySQL Mailing Lists. Auch wenn Sie eine gute Idee haben, wie man etwas vielleicht besser lösen könnte, schicken Sie ruhig eine E-Mail mit einem Patch an die Liste.

2.10.4. Probleme beim Kompilieren von MySQL

Alle MySQL-Programme lassen sich bei uns mit gcc sauber und ohne Warnungen unter Solaris oder Linux kompilieren. Auf anderen Systemen werden aufgrund von Unterschieden in den systemspezifischen Include-Dateien unter Umständen Warnungen angezeigt. Informationen dazu, welche Warnungen bei der Verwendung von MIT-pthreads angezeigt werden können, finden Sie in Abschnitt 2.10.5, „Anmerkungen zu MIT-pthreads“. Informationen zu anderen Problemen entnehmen Sie der folgenden Liste.

Die Lösung zahlreicher Probleme erfordert eine Umkonfiguration. Wenn Sie eine Umkonfiguration durchführen müssen, beachten Sie bitte die folgenden Hinweise:

  • Wird configure nach einem vorherigen Aufruf erneut ausgeführt, dann werden unter Umständen Daten zugrunde gelegt, die während des vorherigen Aufrufs ermittelt worden waren. Diese Informationen sind in der Datei config.cache abgelegt. Nach dem Start prüft configure auf das Vorhandensein dieser Datei und liest ihren Inhalt ggf. aus – davon ausgehend, dass die Daten nach wie vor korrekt sind. Dies ist allerdings bei einer Umkonfigurierung nicht mehr der Fall.

  • Jedes Mal, wenn Sie configure ausführen, müssen Sie zur Neukompilierung auch make erneut ausführen. Allerdings sollten Sie alte Objektdateien aus vorherigen Builds entfernen, da diese mit abweichenden Konfigurationsoptionen erstellt wurden.

Um die Verwendung veralteter Konfigurationsdaten oder Objektdateien zu verhindern, führen Sie die folgenden Befehle aus, bevor Sie configure erneut aufrufen:

shell> rm config.cache
shell> make clean

Alternativ können Sie auch make distclean ausführen.

Die folgende Liste enthält die bei der Kompilierung von MySQL am häufigsten auftretenden Probleme:

  • Wenn Sie bei der Kompilierung von sql_yacc.cc Fehler wie die hier aufgeführten erhalten, ist offensichtlich nicht genug Arbeits- oder Auslagerungsspeicher vorhanden.

    Internal compiler error: program cc1plus got fatal signal 11
    Out of virtual memory
    Virtual memory exhausted
    

    Das Problem besteht darin, dass gcc zur Kompilierung von sql_yacc.cc mit Inline-Funktionen eine gewaltige Menge Speicher benötigt. Versuchen Sie in diesem Fall, configure mit der Option --with-low-memory auszuführen:

    shell> ./configure --with-low-memory
    

    Diese Option ergänzt die Kompilierungszeile um den Eintrag -fno-inline, wenn Sie gcc verwenden, bzw. um -O0 bei Verwendung eines anderen Tools. Sie sollten die Option --with-low-memory auch dann verwenden, wenn Sie der Ansicht sind, dass so viel Arbeits- und Auslagerungsspeicher vorhanden ist, dass ein Speichermangel nicht wahrscheinlich ist. Dieses Problem wurde sogar schon auf Systemen mit wirklich großzügigen Hardwarekonfigurationen beobachtet und konnte stets mit der Option --with-low-memory behoben werden.

  • Standardmäßig wählt configure c++ als Compiler-Namen aus, und GNU c++ verknüpft sich mit -lg++. Wenn Sie gcc verwenden, dann kann dieses Verhalten während der Konfiguration zu Problemen wie dem folgenden führen:

    configure: error: installation or configuration problem:
    C++ compiler cannot create executables.
    

    Ferner könnten Sie während der Kompilierung Probleme in Bezug auf g++, libg++ oder libstdc++ beobachten.

    Eine Ursache dieser Probleme besteht darin, dass Sie g++ entweder nicht haben oder dass Sie g++, nicht jedoch libg++ oder libstdc++ haben. Werfen Sie einen Blick in die Datei config.log. Sie sollte den Grund dafür, dass Ihr C++-Compiler nicht funktioniert, exakt angeben. Um derartige Probleme zu vermeiden, können Sie gcc als C++-Compiler verwenden. Setzen Sie die Umgebungsvariable CXX versuchsweise auf ?gcc -O3“. Ein Beispiel:

    shell> CXX="gcc -O3" ./configure
    

    Dies funktioniert, weil gcc C++-Quelldateien ebenso kompiliert, wie es g++ tut, jedoch standardmäßig keine Verknüpfung mit libg++ oder libstdc++ herstellt.

    Eine andere Möglichkeit, diese Probleme zu beheben, besteht in der Installation von g++, libg++ und libstdc++. Allerdings sollten Sie libg++ oder libstdc++ nicht mit MySQL verwenden, da hierdurch nur die mysqld-Binärdatei vergrößert wird – Vorteile ergeben sich ansonsten keine. In Verbindung mit einigen Versionen dieser Bibliotheken sind bei MySQL-Benutzern in der Vergangenheit nicht nachvollziehbare Probleme aufgetreten.

  • Bricht Ihre Kompilierung mit Fehlern wie dem folgenden ab, dann müssen Sie Ihre make-Version auf GNU make aktualisieren:

    making all in mit-pthreads
    make: Fatal error in reader: Makefile, line 18:
    Badly formed macro assignment
    

    Oder:

    make: file `Makefile' line 18: Must be a separator (:
    

    Oder:

    pthread.h: No such file or directory
    

    Es ist bekannt, dass Solaris und FreeBSD problematische make-Programme umfassen.

    GNU make 3.75 funktioniert erfahrungsgemäß.

  • Wenn Sie Flags für die Verwendung durch Ihre C- oder C++-Compiler definieren wollen, sollten Sie dies tun, indem Sie die Flags den Umgebungsvariablen CFLAGS und CXXFLAGS hinzufügen. Sie können auf diese Weise auch die Compiler-Namen über CC und CXX angeben. Ein Beispiel:

    shell> CC=gcc
    shell> CFLAGS=-O3
    shell> CXX=gcc
    shell> CXXFLAGS=-O3
    shell> export CC CFLAGS CXX CXXFLAGS
    

    In Abschnitt 2.1.2.4, „Von Sun Microsystems Inc. kompilierte MySQL-Binärdistributionen“, finden Sie eine Liste der Flag-Definitionen, die sich bei verschiedenen Systemen als nützlich erwiesen haben.

  • Wenn Sie bei der Kompilierung von mysqld Fehlermeldungen wie die nachfolgend gezeigte erhalten, hat configure den Typ des letzten Arguments von accept(), getsockname() oder getpeername() nicht korrekt erkannt:

    cxx: Error: mysqld.cc, line 645: In this statement, the referenced
         type of the pointer value ''length'' is ''unsigned long'',
         which is not compatible with ''int''.
    new_sock = accept(sock, (struct sockaddr *)&cAddr, &length);
    

    Um dieses Problem zu beheben, bearbeiten Sie die Datei config.h (diese wird durch configure erzeugt). Suchen Sie dort nach den folgenden Zeilen:

    /* Define as the base type of the last arg to accept */
    #define SOCKET_SIZE_TYPE XXX
    

    Setzen Sie XXX je nach Betriebssystem auf size_t oder int. (Sie müssen dies bei jeder Ausführung von configure tun, da configure config.h immer neu erstellt.)

  • Die Datei sql_yacc.cc wird aus sql_yacc.yy erstellt. Normalerweise muss bei der Erstellung keine Datei sql_yacc.cc erzeugt werden, da MySQL bereits eine vorab generierte Kopie enthält. Sofern Sie sie aber trotzdem neu erstellen müssen, könnte unter Umständen folgende Fehlermeldung angezeigt werden:

    "sql_yacc.yy", line xxx fatal: default action causes potential...
    

    Dies weist darauf hin, dass Ihre Version von yacc fehlerhaft ist. Sie müssen stattdessen wahrscheinlich bison (die GNU-Variante von yacc) installieren und verwenden.

  • Unter Debian Linux 3.0 müssen Sie gawk anstelle des standardmäßigen mawk installieren.

  • Wenn Sie mysqld oder einen MySQL-Client debuggen müssen, führen Sie configure mit der Option --with-debug aus. Kompilieren Sie Ihre Clients dann neu und verknüpfen Sie sie mit der neuen Clientbibliothek. Siehe auch MySQL Internals: Porting.

  • Wenn Sie unter Linux (z. B. bei SuSE Linux 8.1 oder Red Hat Linux 7.3) einen Kompilierungsfehler ähnlich dem folgenden erhalten, haben Sie wahrscheinlich nicht g++ installiert:

    libmysql.c:1329: warning: passing arg 5 of `gethostbyname_r' from
    incompatible pointer type
    libmysql.c:1329: too few arguments to function `gethostbyname_r'
    libmysql.c:1329: warning: assignment makes pointer from integer
    without a cast
    make[2]: *** [libmysql.lo] Error 1
    

    Standardmäßig versucht das configure-Skript, die korrekte Anzahl der Argumente mithilfe des GNU C++-Compilers g++ zu ermitteln. Dieser Test führt zu falschen Ergebnissen, wenn g++ nicht installiert ist. Es gibt zwei Möglichkeiten, dieses Problem zu umgehen:

    • Stellen Sie sicher, dass der GNU-C++-Compiler g++ installiert ist. Bei manchen Linux-Distributionen heißt das erforderliche Paket gpp, bei anderen gcc-c++.

    • Verwenden Sie gcc als C++-Compiler, indem Sie die Umgebungsvariable CXX auf gcc setzen:

      export CXX="gcc"
      

    Welche Änderungen Sie auch immer durchgeführt haben, nachfolgend müssen Sie configure erneut ausführen. Anmerkungen zu MIT-pthreads

2.10.5. Anmerkungen zu MIT-pthreads

In diesem Abschnitt werden einige Probleme in Zusammenhang mit MIT-pthreads angesprochen.

Unter Linux sollten Sie MIT-pthreads nicht verwenden. Benutzen Sie stattdessen die installierte LinuxThreads-Implementierung. Siehe auch Abschnitt 2.13.1, „Anmerkungen zu Linux“.

Wenn Ihr System keine native Thread-Unterstützung bietet, sollten Sie MySQL mithilfe des MIT-pthreads-Pakets erstellen. Dies gilt für ältere FreeBSD-Systeme, SunOS 4.x, Solaris 2.4 und früher sowie einige andere. Siehe auch Abschnitt 2.1.1, „Betriebssysteme, die von MySQL Community Server unterstützt werden“.

MIT-pthreads ist nicht in der Quelldistribution von MySQL 5.1 enthalten. Wenn Sie dieses Paket benötigen, müssen Sie es gesondert unter http://dev.mysql.com/Downloads/Contrib/pthreads-1_60_beta6-mysql.tar.gz herunterladen.

Extrahieren Sie das Quellarchiv nach dem Download in das oberste MySQL-Quellverzeichnis. Hierdurch wird ein neues Unterverzeichnis namens mit-pthreads erstellt.

  • Auf den meisten Systemen können Sie die Verwendung von MIT-pthreads erzwingen, indem Sie configure mit der Option --with-mit-threads ausführen:

    shell> ./configure --with-mit-threads
    

    Die Erstellung eines Nichtquellverzeichnisses wird bei der Verwendung von MIT-pthreads nicht unterstützt, da wir unsere Änderungen an diesem Code minimieren wollen.

  • Die Tests, mit denen ermittelt wird, ob MIT-pthreads verwendet werden soll, finden nur während derjenigen Phase des Konfigurationsvorgangs statt, in der der Servercode bearbeitet wird. Haben Sie die Distribution mit der Option --without-server konfiguriert, um nur den Clientcode zu erstellen, dann wissen die Clients nicht, ob MIT-pthreads verwendet wird oder nicht; deswegen verwenden sie standardmäßig die Unix-Socketdatei. Da Unix-Socketdateien jedoch auf bestimmten Plattformen unter MIT-pthreads nicht funktionieren, bedeutet dies, dass Sie -h oder --host mit einem anderen Wert als localhost verwenden müssen, wenn Sie Clientprogramme ausführen.

  • Wird MySQL mit MIT-pthreads kompiliert, dann wird die Systemsperrung zum Zweck der Leistungsoptimierung standardmäßig deaktiviert. Mit der Option --external-locking können Sie den Server anweisen, die Systemsperre zu verwenden. Dies ist aber nur erforderlich, wenn Sie zwei MySQL Server ausführen, die auf die gleichen Datendateien zugreifen (hiervon sei aber ohnehin abgeraten).

  • Manchmal schlägt beim pthread-Befehl bind() der Versuch fehl, eine Bindung an den Server vorzunehmen – und dies, ohne dass (zumindest bei Solaris) eine Fehlermeldung erzeugt wird. Nachfolgend schlagen alle Verbindungen zu diesem Server fehl. Ein Beispiel:

    shell> mysqladmin version
    mysqladmin: connect to server at '' failed;
    error: 'Can't connect to mysql server on localhost (146)'
    

    Die Lösung dieses Problems besteht in Terminierung und Neustart des Servers mysqld. Dies ist bei uns nur aufgetreten, wenn wir den Server zwangsweise beendet und unmittelbar darauf neu gestartet haben.

  • Bei MIT-pthreads ist der Systemaufruf sleep() nicht durch SIGINT (Pause) zu unterbrechen. Dies macht sich nur bemerkbar, wenn Sie mysqladmin --sleep ausführen. Sie müssen warten, bis der Aufruf sleep() abgeschlossen ist, bevor der Interrupt bedient und der Prozess angehalten wird.

  • Beim Verknüpfen erhalten Sie (wiederum zumindest unter Solaris) unter Umständen Warnmeldungen wie die folgende, die Sie aber getrost ignorieren können:

    ld: warning: symbol `_iob' has differing sizes:
        (file /my/local/pthreads/lib/libpthread.a(findfp.o) value=0x4;
    file /usr/lib/libc.so value=0x140);
        /my/local/pthreads/lib/libpthread.a(findfp.o) definition taken
    ld: warning: symbol `__iob' has differing sizes:
        (file /my/local/pthreads/lib/libpthread.a(findfp.o) value=0x4;
    file /usr/lib/libc.so value=0x140);
        /my/local/pthreads/lib/libpthread.a(findfp.o) definition taken
    
  • Bestimmte andere Warnungen können ebenfalls ignoriert werden:

    implicit declaration of function `int strtoll(...)'
    implicit declaration of function `int strtoul(...)'
    
  • Wir haben es nicht geschafft, die Verwendung von readline mit MIT-pthreads zu ermöglichen. (Das ist zwar auch nicht notwendig, mag für manchen aber von Interesse sein.)

2.10.6. Installieren von MySQL unter Windows aus dem Quellcode

Diese Anweisungen beschreiben, wie man unter Windows Binärdateien aus dem Quellcode von MySQL 5.1 erstellt. Die Anweisungen beziehen sich auf die Erstellung von Binärdateien aus einer Standardquelldistribution oder aus dem Bazaar-Tree, der den aktuellen Entwicklungsquellcode enthält.

Anmerkung

Die Angaben in diesem Abschnitt sind ausschließlich für Benutzer vorgesehen, die ein der aktuellen Quelldistribution oder dem Bazaar-Tree entstammendes MySQL unter Microsoft Windows testen wollen. Von der Verwendung eines aus dem Quellcode selbst erstellten MySQL Servers in Produktionsumgebungen raten wir ausdrücklich ab. In der Regel ist es am besten, vorkompilierte MySQL-Binärdistributionen zu verwenden, die von Sun Microsystems, Inc. gezielt für eine optimale Leistung unter Windows erstellt wurden. Anweisungen zur Installation einer Binärdistribution finden Sie in Abschnitt 2.3, „Installieren von MySQL unter Windows“.

Um MySQL unter Windows aus dem Quellcode zu erstellen, müssen Sie die folgenden System-, Compiler- und Ressourcenanforderungen erfüllen:

Die exakten Systemvoraussetzungen finden Sie unter: http://msdn.microsoft.com/vstudio/Previous/2003/sysreqs/default.aspx und http://msdn.microsoft.com/vstudio/products/sysreqs/default.aspx

Außerdem brauchen Sie eine MySQL-Quelldistribution für Windows. Es gibt zwei Möglichkeiten, eine Quelldistribution zu erhalten:

Wenn Sie feststellen, dass etwas nicht erwartungsgemäß funktioniert, oder Vorschläge zur Verbesserung des derzeitigen Erstellungsvorgangs unter Windows haben, senden Sie bitte eine Mitteilung an die Mailingliste win32. Siehe auch MySQL Mailing Lists.

2.10.6.1. Erstellen von MySQL aus dem Quellcode mittels CMake und Visual Studio

Sie können MySQL unter Windows mit einer Kombination aus cmake und Microsoft Visual Studio .NET 2003 (7.1), Microsoft Visual Studio 2005 (8.0) oder Microsoft Visual C++ 2005 Express Edition erstellen. Dafür müssen Sie den geeigneten Microsoft Platform SDK installiert haben.

Anmerkung

Um unter Windows vom Quellcode zu kompilieren, müssen Sie die Standard-Quelldistribution verwenden (z. B. mysql-5.1.54.tar.gz). Sie verwenden für die Erstellung die gleiche Distribution wie für das Erstellen von MySQL auf Unix-, Linux- und anderen Plattformen. Verwenden Sie nicht die Windows-Quelldistributionen, da diese das notwendige Konfigurationsskript und andere Dateien nicht enthalten.

Gehen Sie wie folgt vor, um MySQL zu erstellen:

  1. Wenn Sie von einer gepackten Quelldistribution erstellen, legen Sie ein Arbeitsverzeichnis an (z. B. C:\workdir) und entpacken Sie die Quelldistribution mithilfe von WinZip oder einem anderen Windows-Tool, das .zip-Dateien lesen kann, in dieses Verzeichnis. Dieses Dateiverzeichnis ist in den folgenden Anweisungen das Arbeitsverzeichnis.

  2. Navigieren Sie mithilfe einer Befehlsshell zum Arbeitsverzeichnis und führen Sie den folgenden Befehl aus:

    C:\workdir>win\configure.js options
    

    Wenn Sie die Dateierweiterung .js mit einer Anwendung, wie einem Text-Editor verknüpft haben, müssen Sie gegebenenfalls mit dem folgenden Befehl die Ausführung von configure.js als Skript erzwingen:

    C:\workdir>cscript win\configure.js options
    

    Die folgenden Optionen sind für configure.js verfügbar:

    • WITH_INNOBASE_STORAGE_ENGINE: Die Speicher-Engine InnoDB aktivieren.

    • WITH_PARTITION_STORAGE_ENGINE: Benutzerdefinierte Partitionierung aktivieren.

    • WITH_ARCHIVE_STORAGE_ENGINE: Die Speicher-Engine ARCHIVE aktivieren.

    • WITH_BLACKHOLE_STORAGE_ENGINE: Die Speicher-Engine BLACKHOLE aktivieren.

    • WITH_EXAMPLE_STORAGE_ENGINE: Die Speicher-Engine EXAMPLE aktivieren.

    • WITH_FEDERATED_STORAGE_ENGINE: Die Speicher-Engine FEDERATED aktivieren.

    • WITH_NDBCLUSTER_STORAGE_ENGINE (versuchsweise): Die Speicher-Engine NDBCLUSTER im MySQL Server aktivieren; Binärdateien für MySQL Cluster-Management und -Datenknoten, Management-Client und andere Programme erstellen lassen.

      Diese Option wird nur unter MySQL Cluster NDB 7.0 (Speicher-Engine NDBCLUSTER, Versionen 6.4.0 und höher) bei Verwendung der MySQL Cluster-Quellen unterstützt. Sie kann nicht verwendet werden, um die Cluster-Unterstützung in anderen MySQL-Source-Trees oder Distributionen zu aktivieren.

    • MYSQL_SERVER_SUFFIX=suffix: Server-Suffix, Voreinstellung keiner.

    • COMPILATION_COMMENT=comment: Server-Kommentar, Voreinstellung ?Quelldistribution“.

    • MYSQL_TCP_PORT=port: Server-Port, Voreinstellung 3306.

    • DISABLE_GRANT_OPTIONS: Deaktiviert die Optionen --bootstrap, --skip-grant-tables und --init-file für mysqld. Diese Option ist ab MySQL 5.1.15 verfügbar.

    Beispiel (geben Sie den Befehl in einer Zeile ein):

    C:\workdir>win\configure.js WITH_INNOBASE_STORAGE_ENGINE
                 WITH_PARTITION_STORAGE_ENGINE MYSQL_SERVER_SUFFIX=-pro
    
  3. Führen Sie aus dem Arbeitsverzeichnis je nach Ihrer installierten Version von Visual Studio die Datei win\build-vs8.bat oder win\build-vs71.bat aus. Das Skript ruft CMake auf, das die mysql.sln-Lösungsdatei generiert.

    Sie können auch win\build-vs8_x64.bat verwenden, um die 64-Bit-Version von MySQL zu erstellen. Allerdings können Sie die 64-Bit-Version nicht mit Visual Studio Express Edition erstellen. Sie müssen dafür Visual Studio 2005 (8.0) oder höher verwenden.

  4. Öffnen Sie im Arbeitsverzeichnis die generierte Datei mysql.sln mit Visual Studio und wählen Sie im Menü Configuration die benötigte Konfiguration. Das Menü enthält die Optionen Debug, Release, RelwithDebInfo und MinRelInfo. Wählen Sie anschließend Solution > Build aus, um die Lösung zu erstellen.

    Merken Sie sich die Konfiguration, die Sie in diesem Schritt verwenden. Sie benötigen sie später, wenn Sie das Testskript ausführen, weil dieses Skript wissen muss, welche Konfiguration Sie verwendet haben.

  5. Testen Sie den Server. Der Server, den Sie gerade erstellt haben, erwartet die Standardwerte für das MySQL-Basisverzeichnis und das Datenverzeichnis (C:\mysql bzw. C:\mysql\data). Wenn Sie Ihren Server unter Verwendung des Source-Tree-Root-Verzeichnisses und -Datenverzeichnisses als Root- bzw. Datenverzeichnis testen wollen, müssen Sie dem Server die entsprechenden Pfadnamen mitteilen. Sie können dies entweder über die Befehlszeile mit den Optionen --basedir und --datadir tun oder indem Sie die entsprechenden Optionen in einer Optionsdatei ablegen. (Siehe auch Using Option Files.) Wenn Sie ein anderes, bereits an anderer Stelle vorhandenes Datenverzeichnis verwenden wollen, können Sie stattdessen auch dessen Pfadnamen angeben.

    Wenn der Server je nach Ihrer Konfiguration als Anwendung oder Dienst ausgeführt wird, versuchen Sie, mit ihm über das interaktive Befehlszeilen-Hilfsprogramm von mysql eine Verbindung herzustellen.

    Sie können auch das Standard-Testskript mysql-test-run.pl ausführen. Dieses Skript ist in Perl geschrieben. Sie benötigen also entweder Cygwin oder ActiveState Perl, um es auszuführen. Gegebenenfalls müssen Sie auch die vom Skript benötigten Module installieren. Zum Ausführen des Testskripts wechseln Sie im Arbeitsverzeichnis in das Verzeichnis mysql-test, setzen Sie die Umgebungsvariable MTR_VS_CONFIG für die vorher ausgewählte Konfiguration (oder verwenden Sie die Option --vs-config) und rufen Sie mysql-test-run.pl auf. Beispiel (Verwendung von Cygwin und bash-Shell):

    shell> cd mysql-test
    shell> export MTR_VS_CONFIG=debug
    shell> ./mysql-test-run.pl --force --timer
    shell> ./mysql-test-run.pl --force --timer --ps-protocol
    

Wenn Sie zu der Ansicht gekommen sind, dass die von Ihnen erstellten Programme korrekt laufen, beenden Sie den Server. Jetzt können Sie die Distribution installieren. Eine Möglichkeit besteht darin, aus dem Verzeichnis scripts der MySQL-Quelldistribution das Skript make_win_bin_dist zu verwenden (siehe auch make_win_bin_dist). Dies ist ein Shellskript. Bei Ihnen muss also Cygwin installiert sein, wenn Sie es verwenden wollen. Es generiert ein Zip-Archiv aus den erstellten ausführbaren Dateien und Supportdateien, die Sie an den Ort entpacken können, an dem Sie MySQL installieren wollen.

Es ist auch möglich, MySQL zu installieren, indem Sie Verzeichnisse und Dateien direkt kopieren:

  1. Erstellen Sie die Verzeichnisse, in die Sie MySQL installieren wollen. Um etwa MySQL im Verzeichnis C:\mysql zu installieren, verwenden Sie die folgenden Befehle:

    C:\> mkdir C:\mysql
    C:\> mkdir C:\mysql\bin
    C:\> mkdir C:\mysql\data
    C:\> mkdir C:\mysql\share
    C:\> mkdir C:\mysql\scripts
    

    Wenn Sie andere Clients kompilieren und diese mit MySQL verknüpfen wollen, sollten Sie mehrere zusätzliche Verzeichnisse erstellen:

    C:\> mkdir C:\mysql\include
    C:\> mkdir C:\mysql\lib
    C:\> mkdir C:\mysql\lib\debug
    C:\> mkdir C:\mysql\lib\opt
    

    Wenn Sie Benchmarks für MySQL erstellen wollen, legen Sie das folgende Verzeichnis an:

    C:\> mkdir C:\mysql\sql-bench
    

    Für Benchmark-Tests benötigen Sie die Perl-Unterstützung. Siehe auch Abschnitt 2.15, „Anmerkungen zur Perl-Installation“.

  2. Kopieren Sie die folgenden Verzeichnisse aus dem Arbeitsverzeichnis in das Verzeichnis C:\mysql:

    C:\> cd \workdir
    C:\workdir> copy client_release\*.exe C:\mysql\bin
    C:\workdir> copy client_debug\mysqld.exe C:\mysql\bin\mysqld-debug.exe
    C:\workdir> xcopy scripts\*.* C:\mysql\scripts /E
    C:\workdir> xcopy share\*.* C:\mysql\share /E
    

    Wenn Sie andere Clients kompilieren und diese mit MySQL verknüpfen wollen, sollten Sie außerdem verschiedene Bibliotheken und Header-Dateien erstellen:

    C:\workdir> copy lib_debug\mysqlclient.lib C:\mysql\lib\debug
    C:\workdir> copy lib_debug\libmysql.* C:\mysql\lib\debug
    C:\workdir> copy lib_debug\zlib.* C:\mysql\lib\debug
    C:\workdir> copy lib_release\mysqlclient.lib C:\mysql\lib\opt
    C:\workdir> copy lib_release\libmysql.* C:\mysql\lib\opt
    C:\workdir> copy lib_release\zlib.* C:\mysql\lib\opt
    C:\workdir> copy include\*.h C:\mysql\include
    C:\workdir> copy libmysql\libmysql.def C:\mysql\include
    

    Wenn Sie Benchmarks für MySQL erstellen wollen, sollten Sie auch Folgendes tun:

    C:\workdir> xcopy sql-bench\*.* C:\mysql\bench /E
    

Konfigurieren und starten Sie den Server nach der Installation auf die gleiche Weise wie bei Windows-Binärdistributionen. Siehe auch Abschnitt 2.3, „Installieren von MySQL unter Windows“.

2.10.7. Kompilieren von MySQL-Clients unter Windows

In Ihren Quelldateien sollten Sie my_global.h vor mysql.h einsetzen:

#include <my_global.h>
#include <mysql.h>

my_global.h enthält alle Dateien, die für die Windows-Kompatibilität erforderlich sind (z. B. windows.h), wenn Sie Ihr Programm unter Windows kompilieren.

Sie können Ihren Code entweder mit der dynamischen Bibliothek libmysql.lib, die nichts anderes ist, als ein Wrapper, um bei Bedarf libmysql.dll einzuladen, oder mit der statischen Bibliothek mysqlclient.lib verknüpfen.

Die MySQL-Clientbibliotheken werden als Bibliotheken mit Threads kompiliert, d. h., Sie sollten Ihren Code mit Multithread-Unterstützung kompilieren.

2.11. Einstellungen und Tests nach der Installation

Nach der Installation von MySQL gibt es einige Aspekte, die beachtet werden sollten. So sollten Sie etwa unter Unix das Datenverzeichnis initialisieren und die MySQL-Grant-Tabellen erstellen. Bei allen Plattformen besteht ein erhebliches Sicherheitsrisiko darin, dass die bei der Installation in den Grant-Tabellen eingerichteten Konten keine Passwörter aufweisen. Sie sollten Passwörter zuweisen, um unautorisierten Zugriff auf den MySQL Server zu verhindern. Optional können Sie Zeitzonentabellen erstellen, um die Erkennung benannter Zeitzonen zu ermöglichen.

Die folgenden Abschnitte erhalten Angaben zu Maßnahmen nach Abschluss der Installation, die speziell auf Windows- bzw. Unix-Systeme zugeschnitten sind. In Abschnitt 2.11.2.3, „Starten des MySQL Servers und Fehlersuche“, finden Sie zudem Informationen, die für alle Plattformen gelten. Dort wird beschrieben, was Sie tun können, wenn Sie Probleme mit dem Starten des Servers haben. Auch Abschnitt 2.11.3, „Kennwortschutz für vorgabeseitige MySQL-Konten“, betrifft alle Plattformen. Sie sollten den Anweisungen folgen, um zu gewährleisten, dass Ihre MySQL-Konten durch Konfiguration von Passwörtern angemessen geschützt sind.

Wenn Sie so weit sind, dass Sie weitere Benutzerkonten erstellen wollen oder müssen, finden Sie Informationen zum MySQL-Zugriffssteuerungssystem und zur Kontenverwaltung in The MySQL Access Privilege System, und MySQL User Account Management.

2.11.1. Schritte nach der Installation unter Windows

Nach der Installation unter Windows durchzuführende Schritte Unter Windows müssen Datenverzeichnis und Grant-Tabellen nicht erstellt werden. Windows-Distributionen von MySQL enthalten bereits Grant-Tabellen mit vorinitialisierten Konten in der mysql-Datenbank im Datenverzeichnis. Insofern ist es nicht notwendig, das Skript mysql_install_db auszuführen, das unter Unix obligatorisch ist. Was Passwörter betrifft, so haben Sie diese unter Umständen bereits für die Konten vergeben, sofern Sie MySQL mit dem Windows-Installations-Assistenten installiert haben. (Siehe auch Abschnitt 2.3.3, „Verwenden des MySQL-Installations-Assistenten“.) Andernfalls müssen Sie die in Abschnitt 2.11.3, „Kennwortschutz für vorgabeseitige MySQL-Konten“, beschriebene Vorgehensweise zur Vergabe von Passwörtern befolgen.

Bevor Sie Passwörter konfigurieren, sollten Sie einige Clientprogramme ausführen, um sicherzustellen, dass sich Serververbindungen herstellen lassen und einwandfrei arbeiten. Vergewissern Sie sich, dass der Server läuft (siehe Abschnitt 2.3.9, „Erstmaliges Starten des Servers“), und geben Sie dann die folgenden Befehle ein, um nachzuprüfen, ob Sie Daten vom Server abrufen können. Die Ausgabe sollte ähnlich wie nachfolgend aufgeführt aussehen:

C:\> C:\mysql\bin\mysqlshow
+--------------------+
|     Databases      |
+--------------------+
| information_schema |
| mysql              |
| test               |
+--------------------+
C:\> C:\mysql\bin\mysqlshow mysql
Database: mysql
+---------------------------+
|          Tables           |
+---------------------------+
| columns_priv              |
| db                        |
| event                     |
| func                      |
| general_log               |
| help_category             |
| help_keyword              |
| help_relation             |
| help_topic                |
| host                      |
| plugin                    |
| proc                      |
| procs_priv                |
| servers                   |
| slow_log                  |
| tables_priv               |
| time_zone                 |
| time_zone_leap_second     |
| time_zone_name            |
| time_zone_transition      |
| time_zone_transition_type |
| user                      |
+---------------------------+
C:\> C:\mysql\bin\mysql -e "SELECT Host,Db,User FROM db" mysql
+------+-------+------+
| host | db    | user |
+------+-------+------+
| %    | test% |      |
+------+-------+------+

Gegebenenfalls müssen Sie ein anderes Verzeichnis als das obige angeben. Wenn Sie den Windows-Installations-Assistenten verwendet haben, ist das Standardverzeichnis C:\Program Files\MySQL\MySQL Server 5.1 und die Client-Programme mysql und mysqlshow befinden sich unter C:\Program Files\MySQL\MySQL Server 5.1\bin. Weitere Informationen finden Sie in Abschnitt 2.3.3, „Verwenden des MySQL-Installations-Assistenten“.

Wenn Sie bereits die ersten MySQL-Konten gesichert haben, müssen Sie gegebenenfalls die Optionen -u und -p verwenden, um den Client-Programmen mysqlshow und mysql einen Benutzernamen und ein Kennwort zuzuweisen. Ansonsten können die Programme in einem Fehler resultieren oder Sie sind möglicherweise nicht in der Lage, alle Datenbanken anzuzeigen. Wenn Sie beispielsweise dem MySQL-Konto root das Kennwort „secretpass“ zugewiesen haben, können Sie mysqlshow und mysql wie hier gezeigt aufrufen:

C:\> C:\mysql\bin\mysqlshow -uroot -psecretpass
+--------------------+
|     Databases      |
+--------------------+
| information_schema |
| mysql              |
| test               |
+--------------------+
C:\> C:\mysql\bin\mysqlshow -uroot -psecretpass mysql
Database: mysql
+---------------------------+
|          Tables           |
+---------------------------+
| columns_priv              |
| db                        |
| event                     |
| func                      |
| general_log               |
| help_category             |
| help_keyword              |
| help_relation             |
| help_topic                |
| host                      |
| plugin                    |
| proc                      |
| procs_priv                |
| servers                   |
| slow_log                  |
| tables_priv               |
| time_zone                 |
| time_zone_leap_second     |
| time_zone_name            |
| time_zone_transition      |
| time_zone_transition_type |
| user                      |
+---------------------------+
C:\> C:\mysql\bin\mysql -uroot -psecretpass -e "SELECT Host,Db,User FROM db" mysql
+------+-------+------+
| host | db    | user |
+------+-------+------+
| %    | test% |      |
+------+-------+------+

Weitere Informationen zu diesen Programmen finden Sie in Abschnitt 3.6, „mysqlshow — Anzeigen von Datenbank-, Tabellen- und Spalteninformationen“ und Abschnitt 3.1, „mysql — Das MySQL Command-Line Tool“.

Wenn Sie eine Windows-Version verwenden, die Dienste unterstützt, und Sie wollen, dass der MySQL Server beim Start von Windows automatisch gestartet wird, finden Sie Informationen in Abschnitt 2.3.11, „Starten von MySQL als Windows-Dienst“.

2.11.2. Schritte nach der Installation unter Unix

Nachdem Sie MySQL unter Unix installiert haben, müssen Sie die Grant-Tabellen initialisieren, den Server starten und sicherstellen, dass dieser korrekt arbeitet. Ferner sollten Sie das automatische Starten und Beenden des Servers beim Starten bzw. Herunterfahren des Systems konfigurieren. Zudem sind Passwörter für die Konten in den Grant-Tabellen zu erstellen.

Unter Unix werden die Grant-Tabellen durch das Programm mysql_install_db eingerichtet. Bei einigen Installationsmethoden wird dieses Programm für Sie automatisch ausgeführt:

  • Wenn Sie MySQL unter Linux mithilfe von RPM-Distributionen installieren, startet das Server-RPM mysql_install_db.

  • Wenn Sie MySQL unter Mac OS X mithilfe einer PKG-Distribution installieren, startet das Installationsprogramm mysql_install_db.

In allen anderen Fällen müssen Sie mysql_install_db selbst ausführen.

Die nachfolgende Vorgehensweise beschreibt, wie man die Grant-Tabellen initialisiert (soweit dies noch nicht geschehen ist) und dann den Server startet. Ferner werden einige Befehle vorgeschlagen, mit denen Sie testen können, ob der Server zugänglich ist und korrekt arbeitet. Informationen zum automatischen Starten und Beenden des Servers finden Sie in Abschnitt 2.11.2.2, „Automatisches Starten und Beenden von MySQL“.

Wenn Sie den Vorgang abgeschlossen haben und der Server läuft, sollten Sie für die von mysql_install_db erstellten Konten Passwörter erstellen. Eine Anleitung hierzu finden Sie in Abschnitt 2.11.3, „Kennwortschutz für vorgabeseitige MySQL-Konten“.

In den nachfolgenden Beispielen läuft der Server unter der Benutzer-ID des Anmeldekontos mysql. Dies setzt natürlich voraus, dass dieses Konto auch existiert. Ist dies nicht der Fall, dann müssen Sie das Konto entweder erstellen oder den Namen eines anderen vorhandenen Anmeldekontos ersetzen, das Sie für die Ausführung des Servers verwenden wollen.

  1. Wechseln Sie in das oberste Verzeichnis Ihrer MySQL-Installation (dieses wird hier als BASEDIR dargestellt):

    shell> cd BASEDIR
    

    BASEDIR ist dabei so etwas wie /usr/local/mysql oder /usr/local. Die folgenden Schritte setzen voraus, dass Sie in dieses Verzeichnis gewechselt sind.

  2. Sofern notwendig, führen Sie mysql_install_db aus, um die vorgabeseitigen MySQL-Grant-Tabellen mit den Berechtigungen einzurichten, die bestimmen, wie Benutzer mit dem Server Verbindungen herstellen können. Sie müssen das tun, wenn Sie einen Distributionstyp verwendet haben, bei dessen Installation das Programm nicht automatisch ausgeführt wird.

    Normalerweise muss mysql_install_db nur bei der Erstinstallation von MySQL ausgeführt werden; Sie können diesen Schritt also überspringen, wenn Sie eine vorhandene Installation aktualisieren. Allerdings überschreibt mysql_install_db keine vorhandenen Berechtigungstabellen, kann also in allen Situationen problemlos ausgeführt werden.

    Um die Berechtigungstabellen zu initialisieren, verwenden Sie einen der folgenden Befehle (je nachdem, ob sich mysql_install_db im Verzeichnis bin oder scripts befindet):

    shell> bin/mysql_install_db --user=mysql
    shell> scripts/mysql_install_db --user=mysql
    

    Gegebenenfalls müssen andere Optionen angegeben werden, wie --basedir oder --datadir, wenn mysql_install_db nicht die richtigen Speicherorte für das Installationsverzeichnis oder das Datenverzeichnis verwendet. Ein Beispiel:

    shell> bin/mysql_install_db --user=mysql \
             --basedir=/opt/mysql/mysql \
             --datadir=/opt/mysql/mysql/data
    

    Das Skript mysql_install_db erstellt das Datenverzeichnis des Servers. In diesem Datenverzeichnis werden Verzeichnisse für die mysql-Datenbank, die alle Datenbankberechtigungen enthält, und die test-Datenbank erstellt, die Sie zum Testen von MySQL verwenden können. Das Skript erstellt außerdem Einträge für root-Konten und Konten für anonyme Benutzer in den Berechtigungstabellen. Diese Konten haben anfangs kein Passwort. Eine Beschreibung ihrer Ausgangsberechtigungen finden Sie in Abschnitt 2.11.3, „Kennwortschutz für vorgabeseitige MySQL-Konten“. Kurz gesagt, ermöglichen diese Berechtigungen dem MySQL-root-Benutzer alles und erlauben jedem Benutzer zudem die Erstellung und Verwendung von Datenbanken mit dem Namen test oder einem Namen, der mit test_ beginnt.

    Es ist wichtig sicherzustellen, dass die Datenbankverzeichnisse und -dateien im Besitz des Kontos mysql sind, damit der Server bei der späteren Ausführung Lese- und Schreibzugriff darauf hat. Um dies zu gewährleisten, sollte die Option --user wie nachfolgend gezeigt verwendet werden, wenn Sie mysql_install_db als root ausführen. Andernfalls sollten Sie das Skript ausführen, während Sie als mysql angemeldet sind; in diesem Fall können Sie die Option --user in dem Befehl weglassen.

    mysql_install_db erstellt eine Reihe von Tabellen in der mysql-Datenbank, darunter u. a. user, db, host, tables_priv, columns_priv, func usw. Eine vollständige Auflistung und Beschreibung dieser Tabellen finden Sie in The MySQL Access Privilege System.

    Wenn Sie die test-Datenbank nicht brauchen, können Sie sie nach dem Starten des Servers mit dem Befehl mysqladmin -u root drop test entfernen.

    Sollten Sie an dieser Stelle Probleme mit mysql_install_db haben, dann finden Sie weitere Informationen in Abschnitt 2.11.2.1, „Probleme beim Ausführen von mysql_install_db.

  3. Starten Sie den MySQL Server:

    shell> bin/mysqld_safe --user=mysql &
    

    Es ist wichtig, dass der MySQL Server über ein berechtigungsloses Anmeldekonto (d. h. kein root-Konto) ausgeführt wird. Um dies zu gewährleisten, sollte die Option --user wie nachfolgend gezeigt verwendet werden, wenn Sie mysql_safe als System-root ausführen. Andernfalls sollten Sie das Skript ausführen, während Sie als mysql am System angemeldet sind; in diesem Fall können Sie die Option --user in dem Befehl weglassen.

    Weitere Anweisungen zur Ausführung von MySQL als berechtigungsloser Benutzer finden Sie in How to Run MySQL as a Normal User.

    Wenn Sie vor Durchführung dieses Schritts vergessen haben, die Grant-Tabellen zu erstellen, dann erscheint die folgende Meldung im Fehlerlog, wenn Sie den Server starten:

    mysqld: Can't find file: 'host.frm'
    

    Bei Auftreten anderer Probleme während des Serverstarts finden Sie Informationen in Abschnitt 2.11.2.3, „Starten des MySQL Servers und Fehlersuche“.

  4. Stellen Sie mit mysqladmin sicher, dass der Server ausgeführt wird. Die folgenden Befehle ermöglichen einfache Tests, um zu prüfen, ob der Server aktiv ist und auf Verbindungen reagiert:

    shell> bin/mysqladmin version
    shell> bin/mysqladmin variables
    

    Die Ausgabe von mysqladmin version kann je nach Plattform und MySQL-Version variieren, sollte aber der nachfolgend abgebildeten ähneln:

    shell> bin/mysqladmin version
    mysqladmin  Ver 14.12 Distrib 5.1.54, for pc-linux-gnu on i686
    ...
    Server version          5.1.54
    Protocol version        10
    Connection              Localhost via UNIX socket
    UNIX socket             /var/lib/mysql/mysql.sock
    Uptime:                 14 days 5 hours 5 min 21 sec
    Threads: 1  Questions: 366  Slow queries: 0
    Opens: 0  Flush tables: 1  Open tables: 19
    Queries per second avg: 0.000
    

    Wenn Sie wissen wollen, was Sie mit mysqladmin noch machen können, rufen Sie es mit der Option --help auf.

  5. Überprüfen Sie, ob Sie den Server herunterfahren können:

    shell> bin/mysqladmin -u root shutdown
    
  6. Als Nächstes prüfen Sie, ob Sie den Server neu starten können. Hierzu verwenden Sie mysqld_safe oder rufen mysqld direkt auf. Ein Beispiel:

    shell> bin/mysqld_safe --user=mysql --log &
    

    Schlägt mysqld_safe fehl, dann lesen Sie Abschnitt 2.11.2.3, „Starten des MySQL Servers und Fehlersuche“.

  7. Führen Sie einige einfache Tests durch, um sicherzustellen, dass Sie Daten am Server abrufen können. Die Ausgabe sollte ähnlich wie nachfolgend aufgeführt aussehen:

    shell> bin/mysqlshow
    +-----------+
    | Databases |
    +-----------+
    | mysql     |
    | test      |
    +-----------+
    shell> bin/mysqlshow mysql
    Database: mysql
    +---------------------------+
    |          Tables           |
    +---------------------------+
    | columns_priv              |
    | db                        |
    | func                      |
    | help_category             |
    | help_keyword              |
    | help_relation             |
    | help_topic                |
    | host                      |
    | proc                      |
    | procs_priv                |
    | tables_priv               |
    | time_zone                 |
    | time_zone_leap_second     |
    | time_zone_name            |
    | time_zone_transition      |
    | time_zone_transition_type |
    | user                      |
    +---------------------------+
    shell> bin/mysql -e "SELECT Host,Db,User FROM db" mysql
    +------+--------+------+
    | host | db     | user |
    +------+--------+------+
    | %    | test   |      |
    | %    | test_% |      |
    +------+--------+------+
    
  8. Im Verzeichnis sql-bench (dieses befindet sich im MySQL-Installationsverzeichnis) befindet sich eine Benchmark-Reihe, die Sie verwenden können, um die Leistungsfähigkeit von MySQL auf verschiedenen Plattformen zu vergleichen. Diese Benchmark-Reihe ist in Perl geschrieben. Sie erfordert das Perl-DBI-Modul, welches eine datenbankunabhängige Schnittstelle zu verschiedenen Datenbanken bereitstellt, sowie einige weitere Perl-Module:

    DBI
    DBD::mysql
    Data::Dumper
    Data::ShowTable
    

    Diese Module erhalten Sie bei CPAN (http://www.cpan.org/). Siehe auch Abschnitt 2.15.1, „Installieren von Perl unter Unix“.

    Das Verzeichnis sql-bench/Results enthält die Ergebnisse vieler Testläufe mit unterschiedlichen Datenbanken und Plattformen. Um alle Tests durchzuführen, setzen Sie die folgenden Befehle ab:

    shell> cd sql-bench
    shell> perl run-all-tests
    

    Wenn das Verzeichnis sql-bench bei Ihnen nicht vorhanden ist, haben Sie MySQL wahrscheinlich aus anderen RPM-Dateien als dem Quell-RPM installiert. (Das Quell-RPM enthält das Benchmark-Verzeichnis sql-bench.) In diesem Fall müssen Sie die Benchmark-Reihe zunächst installieren, bevor Sie sie verwenden können. Es gibt separate Benchmark-RPMs namens mysql-bench-VERSION.i386.rpm, die den Benchmark-Code und die Daten enthalten.

    Wenn Sie mit einer Quelldistribution arbeiten, finden Sie in deren Unterverzeichnis tests weitere Tests, die Sie ausführen können. Um etwa auto_increment.tst auszuführen, setzen Sie den folgenden Befehl im obersten Verzeichnis Ihrer Quelldistribution ab:

    shell> mysql -vvf test < ./tests/auto_increment.tst
    

    Die erwarteten Testergebnisse finden Sie in der Datei ./tests/auto_increment.res.

  9. An dieser Stelle sollte der Server bereits laufen. Allerdings verfügt keines der vorgabeseitigen MySQL-Konten über ein Kennwort. Weisen Sie deswegen entsprechend der Beschreibung in Abschnitt 2.11.3, „Kennwortschutz für vorgabeseitige MySQL-Konten“ Kennwörter zu.

Der Installationsvorgang für MySQL 5.1 erstellt Zeitzonentabellen in der Datenbank mysql. Sie müssen die Tabellen allerdings manuell ausfüllen; wie das geht, steht in MySQL Server Time Zone Support.

2.11.2.1. Probleme beim Ausführen von mysql_install_db

Der Zweck des Skripts mysql_install_db besteht in der Generierung neuer MySQL-Berechtigungstabellen. Hierbei werden vorhandene MySQL-Berechtigungstabellen nicht überschrieben, und auch andere Daten werden nicht beeinträchtigt.

Wollen Sie Ihre Berechtigungstabellen neu erstellen, dann beenden Sie zunächst den mysqld-Server, sofern dieser läuft. Benennen Sie das Verzeichnis mysql im Datenverzeichnis dann um, um es zu speichern, und führen Sie nachfolgend mysql_install_db aus. Nehmen wir an, Ihr aktuelles Verzeichnis ist das MySQL-Installationsverzeichnis, mysql_install_db befindet sich im Verzeichnis bin und das Datenverzeichnis heißt data. Um die mysql-Datenbank umzubenennen und mysql_install_db erneut auszuführen, verwenden Sie die folgenden Befehle:

shell> mv data/mysql data/mysql.old
shell> bin/mysql_install_db --user=mysql

Wenn Sie mysql_install_db ausführen, können die folgenden Probleme auftreten:

  • mysql_install_db kann die Berechtigungstabellen nicht installieren.

    Unter Umständen stellen Sie fest, dass mysql_install_db die Grant-Tabellen nicht installieren kann und nach Anzeige der folgenden Meldungen beendet wird:

    Starting mysqld daemon with databases from XXXXXX
    mysqld ended
    

    In diesem Fall sollten Sie die Fehlerlogdatei sehr aufmerksam lesen. Das Fehlerlog sollte sich im Verzeichnis XXXXXX befinden (dieses ist nach der Fehlermeldung benannt) und angeben, warum mysqld nicht gestartet wurde. Wenn Sie nicht verstehen, was geschehen ist, hängen Sie das Log an, wenn Sie einen Bugreport einsenden. Siehe auch How to Report Bugs or Problems.

  • Ein mysqld-Prozess wird ausgeführt.

    Dies weist darauf hin, dass der Server läuft und die Grant-Tabellen wahrscheinlich bereits erstellt wurden. In diesem Fall müssen Sie mysql_install_db überhaupt nicht ausführen, da es nur einmal gestartet werden muss (nämlich dann, wenn Sie MySQL zum ersten Mal installieren).

  • Die Installation eines zweiten mysqld-Servers schlägt fehl, wenn ein Server bereits läuft.

    Dies kann passieren, wenn eine MySQL-Installation bereits vorhanden ist, Sie aber eine neue Installation an einer anderen Position ablegen wollen. So haben Sie vielleicht eine Produktionsinstallation, wollen aber eine zweite Installation zu Testzwecken einrichten. Meist tritt dieses Problem auf, wenn Sie einen zweiten Server ausführen wollen, der auf eine Netzwerkschnittstelle zuzugreifen versucht, die bereits vom ersten Server verwendet wird. In diesem Fall werden Sie eine der folgenden Fehlermeldungen sehen:

    Can't start server: Bind on TCP/IP port:
    Address already in use
    Can't start server: Bind on unix socket...
    

    Anweisungen zur Einrichtung mehrerer Server finden Sie in Running Multiple MySQL Servers on the Same Machine.

  • Sie haben keinen Schreibzugriff auf das Verzeichnis /tmp.

    Wenn Sie keinen Schreibzugriff erhalten, um Temporärdateien oder eine Unix-Socketdatei im Standardverzeichnis (/tmp) zu erstellen, dann tritt ein Fehler auf, wenn Sie mysql_install_db oder den mysqld-Server ausführen wollen.

    Sie können verschiedene Orte für das Temporärverzeichnis und die Unix-Socketdatei angeben, indem Sie die folgenden Befehle vor dem Starten von mysql_install_db oder mysqld ausführen (hierbei ist some_tmp_dir der vollständige Pfadname eines Verzeichnisses, für das Sie Schreibzugriff haben):

    shell> TMPDIR=/some_tmp_dir/
    shell> MYSQL_UNIX_PORT=/some_tmp_dir/mysql.sock
    shell> export TMPDIR MYSQL_UNIX_PORT
    

    Danach sollten Sie in der Lage sein, mysql_install_db mit den folgenden Befehlen auszuführen und den Server zu starten:

    shell> bin/mysql_install_db --user=mysql
    shell> bin/mysqld_safe --user=mysql &
    

    Wenn sich mysql_install_db im Verzeichnis scripts befindet, ändern Sie den ersten Befehl zu scripts/mysql_install_db.

    Siehe auch How to Protect or Change the MySQL Unix Socket File, und Abschnitt 2.14, „Umgebungsvariablen“.

Es gibt einige Alternativen zur Ausführung des Skripts mysql_install_db, welches Bestandteil der MySQL-Distribution ist:

  • Wenn Sie wollen, dass die Ausgangsberechtigungen sich von den Standardwerten unterscheiden, können Sie mysql_install_db vor der Ausführung bearbeiten. Allerdings bietet es sich eher an, mit GRANT und REVOKE die Berechtigungen zu ändern, nachdem die Berechtigungstabellen eingerichtet wurden. Mit anderen Worten, Sie können mysql_install_db ausführen und dann mithilfe von mysql -u root mysql eine Verbindung zum Server als MySQL-root-Benutzer herstellen, damit Sie die erforderlichen GRANT- und REVOKE-Anweisungen absetzen können.

    Wenn Sie MySQL auf mehreren Computern mit denselben Berechtigungen installieren wollen, können Sie die GRANT- und REVOKE-Anweisungen auch in einer Datei ablegen und diese Datei mithilfe von mysql als Skript ausführen, nachdem Sie mysql_install_db gestartet haben. Ein Beispiel:

    shell> bin/mysql_install_db --user=mysql
    shell> bin/mysql -u root < your_script_file
    

    Auf diese Weise müssen Sie die Anweisungen nicht manuell auf jedem einzelnen Computer eingeben.

  • Es ist möglich, die Grant-Tabellen nach ihrer Erstellung vollständig neu zu erstellen. Dies müssen Sie unter Umständen tun, wenn Sie gerade erst lernen, wie man GRANT und REVOKE verwendet, und nach der Ausführung von mysql_install_db derart viele Änderungen vorgenommen haben, dass Sie die Tabellen komplett löschen und von vorn beginnen wollen.

    Um die Berechtigungstabellen neu zu erstellen, entfernen Sie alle .frm-, .MYI- und .MYD-Dateien im mysql-Datenbankverzeichnis. Danach führen Sie das Skript mysql_install_db erneut aus.

  • Sie können mysqld manuell mithilfe der Option --skip-grant-tables starten und die Berechtigungsdaten selbst unter Verwendung von mysql hinzufügen:

    shell> bin/mysqld_safe --user=mysql --skip-grant-tables &
    shell> bin/mysql mysql
    

    Von mysql führen Sie die in mysql_install_db enthaltenen SQL-Befehle manuell aus. In jedem Fall müssen Sie danach mysqladmin flush-privileges oder mysqladmin reload ausführen, um dem Server mitzuteilen, dass er die Berechtigungstabellen neu laden muss.

    Beachten Sie, dass Sie, wenn Sie mysql_install_db nicht benutzen, die Grant-Tabellen nicht nur manuell ausfüllen, sondern sie zuvor auch noch erstellen müssen. MySQL automatisch starten und anhalten

2.11.2.2. Automatisches Starten und Beenden von MySQL

Normalerweise starten Sie den mysqld-Server unter Verwendung einer der folgenden Möglichkeiten:

  • Durch direkten Aufruf von mysqld. Das funktioniert auf allen Plattformen.

  • Durch Ausführung des MySQL Servers als Windows-Dienst. Der Dienst kann entweder so konfiguriert werden, dass der Server automatisch mit Windows startet, oder als manueller Dienst, den Sie manuell starten müssen. Informationen zur Vorgehensweise finden Sie in Abschnitt 2.3.11, „Starten von MySQL als Windows-Dienst“.

  • Durch Aufruf von mysqld_safe. Hierbei wird versucht, die passenden Optionen für mysqld zu ermitteln und es dann mit diesen Optionen zu starten. Dieses Skript wird unter Unix und Unix-ähnlichen Systemen verwendet. Siehe auch mysqld_safe.

  • Durch den Aufruf von mysql.server. Dieses Skript wird in erster Linie beim Starten und Beenden von Systemen verwendet, die Ausführungsverzeichnisse im System V-Stil verwenden, wo es normalerweise unter dem Namen mysql installiert ist. Das Skript mysql.server startet den Server, indem es mysqld_safe aufruft. Siehe auch mysql.server.

  • Unter Mac OS X können Sie ein separates MySQL-Startobjektpaket installieren, um den automatischen Start von MySQL beim Systemstart zu aktivieren. Das Startobjekt startet den Server durch Aufruf von mysql.server. Einzelheiten siehe Abschnitt 2.5, „Installieren von MySQL unter Mac OS X“.

Die Skripten mysqld_safe und mysql.server und das Mac OS X-Startobjekt können für den manuellen Start des Servers oder für seinen automatischen Start beim Systemstart verwendet werden. mysql.server und das Startobjekt erlauben zudem das Beenden des Servers.

Um den Server mit mysql.server manuell zu starten oder zu beenden, rufen Sie es mit dem Argument start bzw. stop auf:

shell> mysql.server start
shell> mysql.server stop

Bevor mysql.server den Server startet, wechselt es in das MySQL-Installationsverzeichnis und ruft dann mysqld_safe auf. Wenn Sie wollen, dass der Server als ein bestimmter Benutzer ausgeführt wird, fügen Sie die entsprechende Option user im Abschnitt [mysqld] der Optionsdatei /etc/my.cnf hinzu. Eine Erklärung erhalten Sie im weiteren Verlauf dieses Abschnitts. (Unter Umständen müssen Sie mysql.server bearbeiten, wenn Sie eine Binärdistribution von MySQL in einem anderen als dem Standardverzeichnis installiert haben. Ändern Sie es so, dass es in das korrekte Verzeichnis wechselt, bevor es mysqld_safe ausführt. Beachten Sie allerdings, dass Ihre geänderte Version von mysql.server 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.)

mysql.server stop beendet den Server, indem es ein Signal an ihn schickt. Sie können den Server auch manuell beenden, indem Sie mysqladmin shutdown ausführen.

Um MySQL automatisch auf Ihrem Server zu starten und zu beenden, müssen Sie Start- und Stoppbefehle an den entsprechenden Stellen Ihrer /etc/rc*-Dateien einfügen.

Wenn Sie das Linux-Server-RPM-Paket (MySQL-server-VERSION.rpm) verwenden, 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, „Installieren von MySQL aus RPM-Paketen unter Linux“.

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. Sie finden das Skript im Verzeichnis support-files, das sich im MySQL-Installationsverzeichnis befindet, oder in einem MySQL-Source-Tree.

Um mysql.server manuell zu installieren, kopieren Sie es unter dem Namen mysql in das Verzeichnis /etc/init.d und machen es dann ausführbar. Dies tun Sie, indem Sie in das entsprechende Verzeichnis wechseln, in dem sich mysql.server befindet, und dann die folgenden Befehle ausführen:

shell> cp mysql.server /etc/init.d/mysql
shell> chmod +x /etc/init.d/mysql

Ältere Red Hat-Systeme verwenden das Verzeichnis /etc/rc.d/init.d statt /etc/init.d. In diesem Fall müssen Sie die obigen Befehle entsprechend ändern. Alternativ erstellen Sie zunächst /etc/init.d als symbolische Verknüpfung, die auf /etc/rc.d/init.d verweist:

shell> cd /etc
shell> ln -s rc.d/init.d .

Nach der Installation des Skripts hängt der Befehl, der zur Aktivierung der Ausführung beim Systemstart erforderlich ist, von Ihrem Betriebssystem ab. Unter Linux können Sie chkconfig verwenden:

shell> chkconfig --add mysql

Unter manchen Linux-Systemen scheint auch der folgende Befehl notwendig zu sein, um das Skript mysql vollständig zu aktivieren:

shell> chkconfig --level 345 mysql on

Unter FreeBSD sollten Startskripten generell in /usr/local/etc/rc.d/ abgelegt werden. Die Handbuchseite rc(8) gibt an, dass Skripten in diesem Verzeichnis nur dann ausgeführt werden, wenn ihr Basisname dem Shell-Muster für Dateinamen *.sh entspricht. Alle anderen Dateien oder Verzeichnisse, die in diesem Verzeichnis vorhanden sind, werden stillschweigend ignoriert. Mit anderen Worten: Unter FreeBSD müssen Sie das Skript mysql.server als /usr/local/etc/rc.d/mysql.server.sh installieren, um den automatischen Start zu aktivieren.

Als Alternative zur obigen Konfiguration verwenden manche Betriebssysteme auch /etc/rc.local oder /etc/init.d/boot.local, um zusätzliche Dienste beim Systemstart zu starten. Um MySQL auf diese Weise zu starten, könnten Sie einen Befehl wie den folgenden an die entsprechende Startdatei anhängen:

/bin/sh -c 'cd /usr/local/mysql; ./bin/mysqld_safe --user=mysql &'

Bei anderen Systemen lesen Sie in der Dokumentation zu Ihrem Betriebssystem nach, um zu erfahren, wie Startskripten installiert werden.

Sie können Optionen für mysql.server in einer globalen Datei /etc/my.cnf ablegen. Eine /etc/my.cnf-Datei sieht normalerweise so aus:

[mysqld]
datadir=/usr/local/mysql/var
socket=/var/tmp/mysql.sock
port=3306
user=mysql
[mysql.server]
basedir=/usr/local/mysql

Das Skript mysql.server unterstützt die folgenden Optionen: basedir, datadir und pid-file. Sofern angegeben, müssen diese in einer Optionsdatei und nicht in der Befehlszeile abgelegt sein. mysql.server unterstützt nur start und stop als Befehlszeilenargumente.

Die folgende Tabelle zeigt, welche Optionsgruppen der Server und die jeweiligen Startskripten aus den Optionsdateien auslesen.

SkriptOptionsgruppen
mysqld[mysqld], [server], [mysqld-major_version]
mysqld_safe[mysqld], [server], [mysqld_safe]
mysql.server[mysqld], [mysql.server], [server]

[mysqld-major_version] bedeutet, dass Abschnitte mit Namen wie [mysqld-5.0] und [mysqld-5.1] von Servern der Versionen 5.0.x, 5.1.x usw. ausgelesen werden. Diese Funktion kann verwendet werden, um Optionen anzugeben, die nur von Servern einer bestimmten Release-Serie ausgelesen werden können.

Zwecks Abwärtskompatibilität liest mysql.server auch den Abschnitt [mysql_server] und mysqld_safe den Abschnitt [safe_mysqld] aus. Allerdings sollten Sie Ihre Optionsdateien so aktualisieren, dass sie stattdessen die Abschnitte [mysql.server] und [mysqld_safe] auslesen, wenn Sie MySQL 5.1 verwenden.

Siehe auch Using Option Files.

2.11.2.3. Starten des MySQL Servers und Fehlersuche

Dieser Abschnitt enthält Vorschläge zur Fehlersuche, wenn unter Unix Probleme beim Start des Servers auftreten. Wenn Sie Windows verwenden, finden Sie Informationen in Abschnitt 2.3.13, „Fehlersuche und -behebung in MySQL-Installationen unter Windows“.

Haben Sie Probleme beim Starten des Servers, dann probieren Sie folgende Schritte:

  • Suchen Sie im Fehlerlog nach Ursachen dafür, dass der Server nicht startet.

  • Geben Sie alle Sonderoptionen an, die von den von Ihnen verwendeten Speicher-Engines benötigt werden.

  • Stellen Sie sicher, dass der Server die Position des Datenverzeichnisses kennt.

  • Stellen Sie auch sicher, dass der Server auf das Datenverzeichnis zugreifen kann. Besitzrechte und Berechtigungen für das Datenverzeichnis und seine Inhalte müssen so konfiguriert sein, dass der Server sie lesen und ändern kann.

  • Überprüfen Sie, ob die Netzwerkschnittstellen, die der Server verwenden will, vorhanden sind.

Einige Speicher-Engines haben Optionen, die ihr Verhalten steuern. Sie können eine Datei my.cnf erstellen und darin die Startoptionen der Engines angeben, die Sie zu verwenden beabsichtigen. Wenn Sie Speicher-Engines verwenden wollen, die transaktionssichere Tabellen (InnoDB, NDB) unterstützen, dann vergewissern Sie sich, dass diese wie gewünscht konfiguriert sind, bevor Sie den Server starten:

Speicher-Engines verwenden, sofern keine Optionswerte definiert sind, die Vorgabewerte. Wir empfehlen deswegen, die verfügbaren Optionen zu prüfen und explizite Werte für diejenigen Optionen anzugeben, bei denen die Vorgabewerte nicht für Ihre Installation geeignet sind.

Wenn der mysqld-Server startet, wechselt er in das Datenverzeichnis. In diesem Verzeichnis erwartet er das Vorhandensein der Datenbanken, und hier wird er auch seine Logdateien speichern. Auch die PID-Datei (Process ID, Prozesskennung) wird im Datenverzeichnis abgelegt.

Das Datenverzeichnis wird bei der Kompilierung des Servers fest zugeordnet. Standardmäßig sucht der Server deswegen an der angegebenen Position nach diesem Verzeichnis. Befindet sich das Datenverzeichnis in Ihrem System an anderer Stelle, dann funktioniert der Server nicht einwandfrei. Durch Aufruf des Befehls mysqld mit den Optionen --verbose und --help können Sie die Vorgaben für die Pfadeinstellungen ermitteln.

Wenn die Standard-Speicherorte dem MySQL-Installationslayout auf Ihrem System nicht entsprechen, können Sie sie durch Angabe von Optionen für mysqld oder mysqld_safe auf der Befehlszeile oder in einer Optionsdatei außer Kraft setzen.

Um die Position des Datenverzeichnisses explizit anzugeben, verwenden Sie die Option --datadir. Allerdings können Sie mysqld die Position des Basisverzeichnisses angeben, in dem MySQL installiert ist; mysqld wird dann in diesem Verzeichnis nach dem Datenverzeichnis suchen. Die Angabe erfolgt mit der Option --basedir.

Um die Auswirkungen der Optionen zur Pfadangabe zu überprüfen, rufen Sie mysqld mit diesen Optionen auf, gefolgt von den Optionen --verbose und --help. Wenn Sie beispielsweise in das Verzeichnis wechseln, in dem mysqld installiert ist, und dann den folgenden Befehl ausführen, werden die Auswirkung des Serverstarts bei einem Basisverzeichnis /usr/local angezeigt:

shell> ./mysqld --basedir=/usr/local --verbose --help

Sie können auch andere Optionen wie --datadir spezifizieren; allerdings sind --verbose und --help jeweils als letzte Optionen aufzuführen.

Wenn Sie die gewünschten Pfadeinstellungen ermittelt haben, starten Sie den Server ohne --verbose und --help.

Wird mysqld gerade ausgeführt, dann können Sie die verwendeten Pfadeinstellungen durch Absetzen des folgenden Befehls ermitteln:

shell> mysqladmin variables

Oder:

shell> mysqladmin -h host_name variables

host_name ist der Name des MySQL Server-Hosts.

Erhalten Sie beim Starten von mysqld die Fehlermeldung Errcode 13 (Permission denied, Berechtigung verweigert), dann gestatten die Berechtigungen des Datenverzeichnisses oder seiner Inhalte keinen Serverzugriff. In diesem Fall ändern Sie die Berechtigungen für die betreffenden Dateien und Verzeichnisse so, dass der Server das Recht hat, sie zu verwenden. Sie können den Server auch als root starten, wovon aus sicherheitstechnischer Sicht jedoch dringend abgeraten wird.

Wechseln Sie unter Unix in das Datenverzeichnis und überprüfen Sie die Besitzrechte für das Datenverzeichnis und seinen Inhalt, um den Serverzugriff zu gewährleisten. Verwenden Sie etwa folgenden Befehl, wenn das Datenverzeichnis /usr/local/mysql/var ist:

shell> ls -la /usr/local/mysql/var

Wenn die Besitzrechte für das Datenverzeichnis oder seine Unterverzeichnisse nicht bei dem Anmeldekonto liegen, das Sie zur Ausführung des Servers verwenden, dann müssen Sie die Besitzrechte für diese Ressourcen dem Konto zuweisen. Heißt das Konto mysql, dann verwenden Sie folgende Befehle:

shell> chown -R mysql /usr/local/mysql/var
shell> chgrp -R mysql /usr/local/mysql/var

Wenn der Server nicht korrekt startet, prüfen Sie das Fehlerlog. Logdateien befinden sich im Datenverzeichnis (unter Windows normalerweise C:\Program Files\MySQL\MySQL Server 5.1\data, bei Unix-Binärdistributionen in /usr/local/mysql/data und bei Unix-Quelldistributionen in /usr/local/var). Suchen Sie im Datenverzeichnis nach Dateien mit Namen des Typs host_name.err und host_name.log, wobei host_name der Name des Serverhosts ist. Überprüfen Sie nun die letzten paar Zeilen dieser Dateien. Unter Unix können Sie sie mit tail anzeigen:

shell> tail host_name.err
shell> tail host_name.log

Das Fehlerlog sollte Informationen dazu enthalten, warum der Server nicht starten konnte.

Tritt einer der folgenden Fehler auf, dann bedeutet dies, dass ein anderes Programm (vielleicht ein anderer mysqld-Server) den TCP/IP-Port bzw. die Unix-Socketdatei verwendet, die mysqld für sich beansprucht:

Can't start server: Bind on TCP/IP port: Address already in use
Can't start server: Bind on unix socket...

Ermitteln Sie mit dem Befehl ps, ob ein anderer mysqld-Server ausgeführt wird. Ist dies der Fall, dann fahren Sie den Server herunter, bevor Sie mysqld erneut starten. (Wenn ein anderer Server ausgeführt wird und Sie tatsächlich mehrere Server gleichzeitig betreiben wollen, finden Sie Informationen zur Vorgehensweise in Running Multiple MySQL Servers on the Same Machine.)

Läuft kein anderer Server, dann führen Sie den Befehl telnet your_host_name tcp_ip_port_number aus. (Die Standardportnummer von MySQL ist 3306.) Betätigen Sie dann mehrfach die Eingabetaste. Erhalten Sie keine Fehlermeldung in der Art von telnet: Unable to connect to remote host: Connection refused, dann verwendet ein anderes Programm den TCP/IP-Port, den mysqld benutzen will. Sie müssen dann ermitteln, welches Programm dies ist, und es deaktivieren; alternativ können Sie mysqld mit der Option --port auch anweisen, an einem anderen Port zu lauschen. In diesem Fall müssen Sie auch die Portnummer für Clientprogramme angeben, die über TCP/IP eine Verbindung mit dem Server herstellen wollen.

Ein anderer Grund, warum kein Zugriff auf den Port möglich ist, könnte eine laufende Firewall sein, die Verbindungen zu diesem Port unterbindet. In diesem Fall müssen Sie die Firewall-Einstellungen so abändern, dass ein Zugriff möglich ist.

Wenn der Server startet, Sie aber keine Verbindung zu ihm herstellen können, dann sollten Sie sicherstellen, dass ein Eintrag wie der folgende in /etc/hosts vorhanden ist:

127.0.0.1       localhost

Dieses Problem tritt nur bei Systemen auf, die über keine funktionierende Thread-Bibliothek verfügen und für die MySQL zur Verwendung von MIT-pthreads konfiguriert sein muss.

Wenn Sie mysqld nicht zum Laufen bringen, können Sie versuchen, unter Verwendung der Option --debug eine Trace-Datei zu erstellen, um das Problem zu ermitteln. Siehe auch MySQL Internals: Porting.

2.11.3. Kennwortschutz für vorgabeseitige MySQL-Konten

Eine wesentliche Komponente des MySQL-Installationsprozesses ist die Einrichtung der mysql-Datenbank, die die Grant-Tabellen enthält:

  • Windows-Distributionen enthalten vorinitialisierte Grant-Tabellen, die automatisch installiert werden.

  • Unter Unix werden die Grant-Tabellen durch das Programm mysql_install_db ausgefüllt. Einige Installationsmethoden führen dieses Programm für Sie aus. Andere wiederum erfordern eine manuelle Ausführung. Detaillierte Informationen finden Sie in Abschnitt 2.11.2, „Schritte nach der Installation unter Unix“.

Die Grant-Tabellen definieren die vorgabeseitigen MySQL-Benutzerkonten und deren Zugriffsberechtigungen. Diese Konten werden wie folgt eingerichtet:

  • Es werden Konten mit dem Benutzernamen root erstellt. Dies sind Superuser-Konten, die alles dürfen. Anfänglich sind die Kennwörter der root-Konten leer, d. h., jeder kann als rootohne Kennwort – eine Verbindung mit dem MySQL Server herstellen und erhält alle Berechtigungen.

    • Unter Windows wird genau ein root-Konto erstellt. Dieses erlaubt nur eine Verbindung über den lokalen Host. Das Windows-Installationsprogramm erstellt optional ein Konto, welches Verbindungen von beliebigen Hosts ermöglicht. Dieses Konto wird jedoch nur dann angelegt, wenn die Option Enable root access from remote machines während der Installation gewählt wurde.

    • Unter Unix sind beide root-Konten für Verbindungen vom lokalen Host vorgesehen. Verbindungen vom lokalen Host müssen unter Angabe von localhost für das eine Konto bzw. des tatsächlichen Hostnamens oder der IP-Nummer für das andere Konto hergestellt werden.

  • Es werden zwei Konten für anonyme Benutzer erstellt; bei beiden ist der Benutzername leer. Die anonymen Konten haben kein Kennwort, d. h., jeder kann über sie eine Verbindung zum MySQL Server herstellen.

    • Unter Windows wird ein anonymes Konto für Verbindungen vom lokalen Host eingerichtet. Es hat keine globalen Berechtigungen. (Vor MySQL 5.1.16 hat es ebenso wie die root-Konten alle globalen Berechtigungen.) Das andere Konto ist für Verbindungen von beliebigen Hosts vorgesehen und hat alle Berechtigungen für die test-Datenbank und für alle Datenbanken, deren Name mit test beginnt.

    • Unter Unix sind beide anonymen Konten für Verbindungen vom lokalen Host vorgesehen. Verbindungen vom lokalen Host müssen unter Angabe von localhost für das eine Konto bzw. des tatsächlichen Hostnamens oder der IP-Nummer für das andere Konto hergestellt werden. Diese Konten haben alle Berechtigungen für die Datenbank test und für alle Datenbanken, deren Name mit test_ beginnt.

Wie bereits angemerkt, hat keines der Vorgabekonten ein Passwort. Das bedeutet, dass Ihre MySQL-Installation nicht geschützt ist, bis Sie etwas Entsprechendes unternehmen:

  • Wenn Sie verhindern wollen, dass Clients sich ohne Angabe eines Passworts als anonyme Benutzer anmelden können, sollten Sie entweder für jedes anonyme Konto ein Passwort einrichten oder die Konten ganz entfernen.

  • Sie sollten allen MySQL-root-Konten Kennwörter zuweisen.

Die folgenden Angaben erläutern, wie Sie den vorgegebenen MySQL-Konten Kennwörter zuweisen – erst den anonymen Konten und dann den root-Konten. Ersetzen Sie „newpwd“ in den Beispielen durch das Kennwort, welches Sie verwenden wollen. Die Erläuterungen behandeln auch die Frage, wie Sie die anonymen Konten entfernen können, wenn Sie anonymen Zugriff überhaupt nicht gestatten wollen.

Sie sollten die Einstellung der Passwörter auf einen späteren Zeitpunkt verschieben, damit Sie sie nicht angeben müssen, wenn Sie weitere Konfigurations- oder Testschritte durchführen. Achten Sie allerdings darauf, sie einzurichten, bevor Sie Ihre Installation für Produktionszwecke einsetzen.

Zuweisung von Kennwörtern für anonyme Konten

Um Kennwörter für anonyme Konten zu konfigurieren, stellen Sie als root eine Verbindung zum Server her und verwenden entweder SET PASSWORD oder UPDATE. In beiden Fällen müssen Sie das Passwort mit der PASSWORD()-Funktion verschlüsseln.

SET PASSWORD verwenden Sie unter Windows wie folgt:

shell> mysql -u root
mysql> SET PASSWORD FOR ''@'localhost' = PASSWORD('newpwd');
mysql> SET PASSWORD FOR ''@'%' = PASSWORD('newpwd');

SET PASSWORD verwenden Sie unter Unix wie folgt:

shell> mysql -u root
mysql> SET PASSWORD FOR ''@'localhost' = PASSWORD('newpwd');
mysql> SET PASSWORD FOR ''@'host_name' = PASSWORD('newpwd');

In der zweiten SET PASSWORD-Anweisung ersetzen Sie host_name durch den Namen des Serverhosts. Es handelt sich dabei um den Namen, den Sie in der Spalte Host desjenigen root-Datensatzes in der Tabelle user angegeben haben, der nicht mit localhost verknüpft wird. Wenn Sie diesen Hostnamen nicht kennen, setzen Sie die folgende Anweisung vor der Verwendung von SET PASSWORD ab:

mysql> SELECT Host, User FROM mysql.user;

Suchen Sie nach dem Datensatz, bei dem root in der Spalte User und etwas anderes als localhost in der Spalte Host steht. Verwenden Sie dann diesen Host-Wert in der zweiten SET PASSWORD-Anweisung.

Entfernen von anonymen Konten

Wenn Sie die anonymen Konten stattdessen ganz entfernen wollen, gehen Sie wie folgt vor:

shell> mysql -u root
mysql> DROP USER '';

Die DROP-Anweisung gilt für Windows und Unix gleichermaßen. Wenn Sie unter Windows nur das anonyme Konto entfernen wollen, das die gleichen Berechtigungen wie root hat, geben Sie stattdessen Folgendes ein:

shell> mysql -u root
mysql> DROP USER ''@'localhost';

Dieses Konto gewährt anonymen Zugriff, verfügt aber über Vollzugriff; insofern verbessern Sie die Sicherheit, wenn Sie es entfernen.

Zuweisung von Kennwörtern für root-Konten

Sie können den root-Konten Passwörter auf mehreren unterschiedlichen Wegen zuweisen. Im Folgenden wollen wir drei Methoden demonstrieren:

  • Verwenden der SET PASSWORD-Anweisung

  • Verwenden des befehlszeilenbasierten Clientprogramms mysqladmin

  • Verwenden der UPDATE-Anweisung

Um Kennwörter mit SET PASSWORD zuzuweisen, stellen Sie als root eine Verbindung zum Server her und setzen SET PASSWORD-Anweisungen ab. Beachten Sie dabei, dass Sie das Passwort mit der PASSWORD()-Funktion verschlüsseln müssen.

Unter Windows geben Sie Folgendes ein:

shell> mysql -u root
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpwd');
mysql> SET PASSWORD FOR 'root'@'%' = PASSWORD('newpwd');

Unter Unix geben Sie Folgendes ein:

shell> mysql -u root
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpwd');
mysql> SET PASSWORD FOR 'root'@'host_name' = PASSWORD('newpwd');

In der zweiten SET PASSWORD-Anweisung ersetzen Sie host_name durch den Namen des Serverhosts. Dies ist derselbe Hostname, den Sie bei der Zuweisung der Kennwörter für die anonymen Konten verwendet haben.

Wenn die Tabelle user ein Konto enthält, das unter User und Host die Werte 'root' und '127.0.0.1' hat, richten Sie das Kennwort für dieses Konto mit einer weiteren SET PASSWORD-Anweisung ein:

mysql> SET PASSWORD FOR 'root'@'127.0.0.1' = PASSWORD('newpwd');

Um für die root-Konten Passwörter mit mysqladmin zu konfigurieren, führen Sie folgende Befehle aus:

shell> mysqladmin -u root password "newpwd"
shell> mysqladmin -u root -h host_name password "newpwd"

Diese Befehle gelten für Windows und Unix gleichermaßen. Im zweiten Befehl ersetzen Sie host_name durch den Namen des Serverhosts. Die doppelten Anführungszeichen, die das Passwort umgeben, sind nicht immer erforderlich; Sie sollten sie aber verwenden, wenn das Passwort Leerzeichen oder andere Zeichen enthält, die Ihr Befehls-Interpreter als Sonderzeichen interpretiert.

Die zweite Methode, das Kennwort des root-Kontos mit mysqladmin zuzuweisen, weist dem Konto 'root'@'127.0.0.1' kein Kennwort zu. Dafür müssen Sie SET-PASSWORD wie oben beschrieben verwenden.

Sie können auch mithilfe von UPDATE die Tabelle user direkt bearbeiten. Die folgende UPDATE-Anweisung weist allen root-Konten gleichzeitig ein Kennwort zu:

shell> mysql -u root
mysql> UPDATE mysql.user SET Password = PASSWORD('newpwd')
    ->     WHERE User = 'root';
mysql> FLUSH PRIVILEGES;

Die UPDATE-Anweisung gilt für Windows und Unix gleichermaßen.

Nachdem die Passwörter konfiguriert wurden, müssen Sie immer, wenn Sie eine Serververbindung herstellen, das Passwort angeben. Wollen Sie also etwa mysqladmin zum Herunterfahren des Servers verwenden, dann tun Sie das mit folgendem Befehl:

shell> mysqladmin -u root -p shutdown
Enter password: (enter root password here)
Anmerkung

Wenn Sie Ihr root-Passwort nach der Konfiguration vergessen haben, finden Sie in How to Reset the Root Password, Informationen dazu, wie Sie das Passwort zurücksetzen.

Um weitere Konten einzurichten, können Sie die Anweisung GRANT verwenden. Informationen zur Vorgehensweise finden Sie in Adding User Accounts.

2.12. Aktualisieren von MySQL mittels Upgrade/Downgrade

2.12.1. Upgrade von MySQL

Generell sollten Sie Upgrades nur von einer Release-Serie zur nächsten durchführen und keine Serien auslassen. Wenn Sie von einer Release-Serie vor MySQL 5.0 aus ein Upgrade durchführen wollen, sollten Sie nacheinander von Release-Serie zu Release-Serie aktualisieren, bis Sie MySQL 5.0 erreicht haben; danach können Sie auf MySQL 5.1 aktualisieren. Wenn Sie beispielsweise derzeit MySQL 4.0 verwenden und dann auf eine neuere Serie aktualisieren wollen, führen Sie zunächst ein Upgrade auf MySQL 4.1 usw. durch, bis Sie 5.0 erreichen. Informationen zum Aktualisieren auf MySQL 5.0 finden Sie in MySQL 5.0 Reference Manual; für frühere Releases siehe MySQL 3.23, 4.0, 4.1 Referenzhandbuch.

Verwenden Sie für Upgrades von MySQL 5.0 auf 5.1 die Positionen aus der folgenden Checkliste als Anhaltspunkt:

  • Sichern Sie vor dem Upgrade Ihre Datenbanken einschließlich der mysql-Datenbank, die die Berechtigungstabellen enthält. Siehe auch Database Backup Methods.

  • Lesen Sie alle Hinweise in Abschnitt 2.12.1.1, „Aktualisieren von MySQL 5.0 auf 5.1“. Diese liefern Informationen zu Fragen beim Upgrade, die für Ihre aktuelle MySQL-Installation gelten. Einige in diesem Abschnitt diskutierte Inkompatibilitäten müssen Sie vor dem Upgrade unbedingt beachten. Andere sind nach dem Upgrade wichtig.

  • Lesen Sie auch MySQL Change History. Hier finden Sie Informationen zu Funktionen, die bei MySQL 5.1 neu sind oder sich von jenen in MySQL 5.0 unterscheiden.

  • Nachdem Sie ein Upgrade auf eine neue MySQL-Version vorgenommen haben, führen Sie mysql_upgrade aus (siehe auch mysql_upgrade). Dieses Programm überprüft Ihre Tabellen und versucht sie im Bedarfsfall zu reparieren. Es aktualisiert außerdem Ihre Berechtigungstabellen, um sicherzustellen, dass sie die aktuelle Struktur haben und die neuen Möglichkeiten somit auch genutzt werden können. (Einige Releases von MySQL enthalten Änderungen an der Struktur der Berechtigungstabellen, damit neue Berechtigungen oder Funktionen hinzugefügt werden können.)

  • Wenn Sie MySQL Server unter Windows betreiben, lesen Sie Abschnitt 2.3.14, „Aktualisieren von MySQL unter Windows“.

  • Wenn Sie die Replikation nutzen, finden Sie in Upgrading a Replication Setup, weitere Informationen zur Aktualisierung Ihrer Replikationskonfiguration.

  • Wenn Sie ein Upgrade einer Installation durchführen, die ursprünglich durch die Installation mehrerer RPM-Pakete erzeugt wurde, ist es am besten, nicht nur einige, sondern alle Pakete zu aktualisieren. Haben Sie also beispielsweise bereits die Server- und Client-RPMs installiert, aktualisieren Sie nicht nur das Server-RPM.

  • Ab MySQL 5.1.9 ist der mysqld-max-Server Bestandteil der Binärdistributionen. Es gibt keine gesonderte MySQL-Max-Distribution. Ab MySQL 5.1.12 enthalten Binärdistributionen keinen mysqld-max-Server mehr. Sie beinhalten stattdessen einen Server, der die vorher in mysqld-max enthaltenen Funktionen umfasst.

  • Wenn Sie eine benutzerdefinierte Funktion (UDF) mit einem bestimmten Namen eingerichtet haben und MySQL auf eine Version aktualisieren, die eine neu integrierte Funktion mit dem gleichen Namen implementiert, kann auf die UDF nicht mehr zugegriffen werden. Dies korrigieren Sie, indem Sie die UDF mithilfe von DROP FUNCTION entfernen und anschließend mit CREATE FUNCTION mit einem anderen Namen neu erstellen, der keinen Konflikt erzeugt. Gleiches gilt, wenn die neue MySQL-Version eine integrierte Funktion implementiert, die den gleichen Namen hat wie eine vorhandene gespeicherte Funktion. Unter Abschnitt 5.2.4, „Funktionsnamensanalyse und Auflösung“ finden Sie die Regeln, nach denen der Server Referenzierungen unterschiedlicher Arten von Funktionen interpretiert.

Sie können die Format- und Datendateien von MySQL jederzeit zwischen verschiedenen Versionen auf Systemen mit derselben Architektur hin- und herschieben, solange Sie die Release-Serie nicht wechseln.

Wenn Sie in Bezug auf neue Versionen eher vorsichtig sind, können Sie Ihr vorhandenes mysqld immer umbenennen, bevor Sie eine neue Version installieren. Verwenden Sie beispielsweise MySQL 5.0.13 und wollen auf 5.1.10 aktualisieren, dann benennen Sie Ihren aktuellen Server von mysqld zu mysqld-5.0.13 um. Tut Ihr neuer Server mysqld dann etwas Unerwartetes, können Sie ihn einfach herunterfahren und mit Ihrem alten mysqld neu starten.

Wenn Sie nach Durchführung eines Upgrades auf Probleme in Zusammenhang mit neu kompilierten Clientprogrammen (z. B. die Fehlermeldung Commands out of sync) stoßen oder unerwartete Speicherauszüge auftreten, dann haben Sie bei der Kompilierung Ihrer Programme wahrscheinlich alte Header- oder Bibliotheksdateien angegeben. In diesem Fall sollten Sie das Datum Ihrer Datei mysql.h und der Bibliothek libmysqlclient.a überprüfen, um sicherzustellen, dass diese der aktuellen MySQL-Distribution entstammen. Andernfalls müssen Sie Ihre Programme mit den neuen Headern und Bibliotheken neu kompilieren.

Wenn Probleme in der Art auftreten, dass der neue mysqld-Server nicht startet oder Sie ohne Passwort keine Verbindung herstellen können, dann schauen Sie nach, ob Sie nicht noch eine alte my.cnf-Datei von Ihrer vorherigen Installation verwenden. Diese Überprüfung können Sie mithilfe der Option --print-defaults vornehmen (z. B. mysqld --print-defaults). Wenn dieser Befehl etwas anderes als den Programmnamen anzeigt, dann beeinträchtigt eine aktive my.cnf den Server- oder Clientbetrieb.

Wenn Ihre MySQL-Installation viele Daten enthält, deren Konvertierung nach einem Vor-Ort-Upgrade lange Zeit in Anspruch nehmen kann, könnten Sie eine „Dummy“-Datenbankinstanz erstellen, in der beurteilt wird, welche Konvertierungen erforderlich und welche Arbeiten dafür notwendig sind. Erstellen Sie eine Kopie Ihrer MySQL-Instanz, die eine vollständige Kopie Ihrer mysql-Datenbank sowie aller anderen Datenbanken ohne Daten enthält. Führen Sie Ihr Upgrade an dieser Dummy-Datenbank durch, um so festzustellen, welche Maßnahmen erforderlich sind. Anhand dessen können Sie besser einschätzen, welche Maßnahmen sie bei der eigentlichen Datenkonvertierung in Ihrer Originaldatenbank ausführen müssen.

Wenn Sie einen neuen MySQL-Release installieren, bietet es sich immer an, das Perl-Modul DBD::mysql neu zu erstellen und zu installieren. Gleiches gilt auch für die anderen MySQL-Schnittstellen wie die PHP-Erweiterungen mysql und das Python-Modul MySQLdb.

2.12.1.1. Aktualisieren von MySQL 5.0 auf 5.1

Wenn Sie von einer 5.0-Installation auf 5.0.10 oder höher aktualisieren, beachten Sie, dass es unumgänglich ist, Ihre Berechtigungstabellen zu aktualisieren. Andernfalls wird die Erstellung gespeicherter Prozeduren und Funktionen unter Umständen nicht funktionieren. Um dieses Upgrade durchzuführen, führen Sie mysql_upgrade aus.

Anmerkung

Es ist gängige Praxis, Ihre Daten vor der Installation einer neuen Softwareversion zu sichern. Auch wenn MySQL mit Eifer daran arbeitet, ein möglichst hohes Qualitätsniveau zu erzielen, sollten Sie Ihre Daten immer schützen, indem Sie eine Sicherungskopie erstellen.

MySQL empfiehlt, dass Sie beim Upgrade auf 5.1 von einer vorherigen Version Ihre Tabellen vor dem Upgrade mit mysqldump speichern und nach dem Upgrade neu laden.

Generell sollten Sie beim Upgrade von MySQL 5.0 auf 5.1 Folgendes tun:

  • Lesen Sie alle Punkte in den folgenden Abschnitten, um festzustellen, ob einer davon Auswirkungen auf Ihre Programme haben könnte:

    • Abschnitt 2.12.1, „Upgrade von MySQL“ enthält allgemeine Informationen zum Update.

    • Anhand der in den Änderungslisten unten beschriebenen Punkte können Sie Probleme beim Upgrade identifizieren, die sich auf Ihre aktuelle MySQL-Installation beziehen.

    • Die Änderungshistorie für MySQL 5.1 beschreibt wichtige neue Funktionen, die Sie in 5.1 verwenden können bzw. die von denen in MySQL 5.0 abweichen. Einige dieser Änderungen können zu Inkompatibilitäten führen. Siehe auch Changes in Release 5.1.x (Production).

  • Beachten Sie insbesondere alle Änderungen, die als Bekannter Fehler oder Inkompatible Änderung gekennzeichnet sind. Diese Inkompatibilitäten mit früheren MySQL-Versionen können Ihre Aufmerksamkeit bereits vor Durchführung des Upgrades erfordern.

    Unser Ziel ist, diese Änderungen zu vermeiden, gelegentlich sind sie jedoch notwendig, um Probleme zu korrigieren, die schlimmer wären als eine Inkompatibilität zwischen einzelnen Releases. Wenn ein für Ihre Installation zutreffendes Upgradeproblem eine Inkompatibilität beinhaltet, die besondere Maßnahmen erfordert, folgen Sie den Anweisungen in der entsprechenden Beschreibung der Inkompatibilität. Häufig handelt es sich dabei um das Erstellen und Wiedereinladen von Speicherauszügen oder die Anwendung einer Anweisung wie CHECK TABLE oder REPAIR TABLE.

    Anweisungen zum Erstellen und Wiedereinladen von Speicherauszügen finden Sie in Abschnitt 2.12.4, „Reparieren und Neuerstellen von Tabellen und Indizes“. Alle Verfahren, die REPAIR TABLE mit der Option USE_FRM umfassen, müssen vor dem Upgrade durchgeführt werden. Wird diese Anweisung mit einer anderen MySQL-Version verwendet als der, die für die Einrichtung der Tabelle verwendet wurde (also nach dem Upgrade), kann die Tabelle dadurch beschädigt werden. Siehe auch Abschnitt 8.5.2.6, „REPAIR TABLE-Syntax“.

  • Nachdem Sie ein Upgrade auf eine neue MySQL-Version vorgenommen haben, führen Sie mysql_upgrade aus (siehe auch mysql_upgrade). Dieses Programm überprüft Ihre Tabellen und versucht sie im Bedarfsfall zu reparieren. Es aktualisiert außerdem Ihre Berechtigungstabellen, um sicherzustellen, dass sie die aktuelle Struktur haben und die neuen Möglichkeiten somit auch genutzt werden können. (Einige Releases von MySQL enthalten Änderungen an der Struktur der Berechtigungstabellen, damit neue Berechtigungen oder Funktionen hinzugefügt werden können.)

  • Lesen Sie in Abschnitt 2.12.3, „Prüfen ob Tabellenindizes neu erstellt werden müssen“, ob Änderungen an Zeichensätzen oder Sortierungen vorgenommen wurden, die gegebenenfalls Auswirkungen auf Ihre Tabellenindizes haben. Ist das der Fall, müssen Sie die betreffenden Indizes entsprechend den Anweisungen in Abschnitt 2.12.4, „Reparieren und Neuerstellen von Tabellen und Indizes“ neu erstellen.

  • Wenn Sie MySQL Server unter Windows betreiben, lesen Sie Abschnitt 2.3.14, „Aktualisieren von MySQL unter Windows“.

  • Wenn Sie die Replikation nutzen, finden Sie in Upgrading a Replication Setup, weitere Informationen zur Aktualisierung Ihrer Replikationskonfiguration.

Wenn Ihre MySQL-Installation viele Daten enthält, deren Konvertierung nach einem Vor-Ort-Upgrade lange Zeit in Anspruch nehmen kann, könnten Sie eine „Dummy“-Datenbankinstanz erstellen, in der beurteilt wird, welche Konvertierungen erforderlich und welche Arbeiten dafür notwendig sind. Erstellen Sie eine Kopie Ihrer MySQL-Instanz, die eine vollständige Kopie Ihrer mysql-Datenbank sowie aller anderen Datenbanken ohne Daten enthält. Führen Sie Ihr Upgrade an dieser Dummy-Datenbank durch, um so festzustellen, welche Maßnahmen erforderlich sind. Anhand dessen können Sie besser einschätzen, welche Maßnahmen sie bei der eigentlichen Datenkonvertierung in Ihrer Originaldatenbank ausführen müssen.

Die nachfolgenden Listen beschreiben Änderungen, die Anwendungen unter Umständen betreffen können und die Sie beachten sollten, wenn Sie auf MySQL 5.1 aktualisieren.

Änderungen der Konfiguration:

  • Vor MySQL 5.1.11 würden Sie zum Erstellen von MySQL aus dem Quellcode mit aktivierter SSL-Unterstützung configure mit der Option --with-openssl oder --with-yassl aufrufen. In MySQL 5.1.11 wurden diese Optionen durch die Option --with-ssl ersetzt. Standardmäßig veranlasst --with-ssl die Verwendung der gepackten yaSSL-Bibliothek. Um stattdessen OpenSSL auszuwählen, geben Sie die Option als --with-ssl=path ein, wobei path das Verzeichnis ist, in dem sich die OpenSSL-Headerdateien und -Bibliotheken befinden.

Änderungen des Servers:

  • Bekannter Fehler: Mit Sicherungen, die mittels mysqldump zur Erzeugung einer Speicherauszugsdatei vor dem Upgrade sowie zum Einladen der Datei nach dem Upgrade durchgeführt werden, gibt es das folgende Problem:

    Vor MySQL 5.0.40 zeigt mysqldump SPATIAL-Indexdefinitionen unter Verwendung von Präfixlängen für die indizierten Spalten. Diese Präfixlängen werden in MySQL 5.0, nicht aber ab MySQL 5.1 akzeptiert. Wenn Sie mysqldump von MySQL-Versionen vor 5.0.40 verwenden, verursachen Tabellen mit SPATIAL-Indizes einen Fehler, wenn die Speicherauszugsdatei in MySQL 5.1 oder höher wieder geladen wird.

    Eine Tabellendefinition, für die in MySQL 5.0 ein Speicherauszug erstellt wurde, kann beispielsweise so aussehen:

    CREATE TABLE `t` (
     `g` geometry NOT NULL,
     SPATIAL KEY `g` (`g`(32))
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1
    

    Die SPATIAL-Indexdefinition wird in MySQL 5.1 nicht akzeptiert. Um dies zu umgehen, bearbeiten Sie die Speicherauszugsdatei so, dass der Präfix entfernt wird:

    CREATE TABLE `t` (
     `g` geometry NOT NULL,
     SPATIAL KEY `g` (`g`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1
    

    Speicherauszugsdateien können groß sein, deshalb ist es gegebenenfalls vorteilhaft, Speicherauszüge für Tabellendefinitionen und Daten gesondert zu erstellen. Das erleichtert das Bearbeiten der Definitionen:

    shell> mysqldump --no-data other_args > definitions.sql
    shell> mysqldump --no-create-info other_args > data.sql
    

    Bearbeiten Sie dann definitions.sql vor dem erneuten Einladen von definitions.sql und anschließend data.sql in der angegebenen Reihenfolge.

    Wenn Sie vor dem Upgrade auf MySQL 5.1 ein Upgrade auf eine Version von MySQL 5.0 durchführen, die höher ist als 5.0.40, tritt dieses Problem nicht auf.

  • Bekannter Fehler: Vor MySQL 5.1.30 hat die Anweisung CHECK TABLE ... FOR UPGRADE keine Prüfung auf inkompatible Änderungen der Sortierung in MySQL 5.1.24 durchgeführt. (Das betrifft auch mysqlcheck und mysql_upgrade, die die Ausführung dieser Anweisung veranlassen.)

    Vor der Korrektur in 5.1.30 würde ein binäres Upgrade (bei dem keine Speicherauszüge von Tabellen vor dem Upgrade mittels mysqldump erstellt und nach dem Upgrade geladen werden) Tabellen zerstören. Nach der Korrektur erkennt CHECK TABLE ... FOR-UPGRADE das Problem richtig und weist auf reparaturbedürftige Tabellen hin.

    Allerdings ist diese Korrektur nicht abwärtskompatibel und kann unter diesen Umständen in einem Problem beim Downgrade resultieren:

    1. Führen Sie ein binäres Upgrade auf eine MySQL-Version aus, das die Korrektur einschließt.

    2. Führen Sie CHECK TABLE ... FOR UPGRADE (oder mysqlcheck oder mysql_upgrade) aus, um die Tabellen zu aktualisieren.

    3. Führen Sie ein binäres Downgrade auf eine MySQL-Version aus, das die Korrektur nicht einschließt.

    Die Lösung besteht darin, vor dem Downgrade mittels mysqldump Speicherauszüge der Tabellen zu erstellen und nach dem Downgrade wieder zu laden. Alternativ entfernen Sie betroffene Indexe und erstellen Sie sie neu.

  • Bekannter Fehler: MySQL führt die Codierung von Tabellennamen ein, die Nicht-ASCII-Zeichen enthalten (siehe auch Abschnitt 5.2.3, „Abbilden von Bezeichnern auf Dateinamen“). Nach einem binären Upgrade von MySQL 5.0 auf 5.1 oder höher, erkennt der Server Namen, die Nicht-ASCII-Zeichen enthalten, und fügt ihnen einen #mysql50#-Präfix hinzu.

    Ab MySQL 5.1.31 verschlüsselt mysql_upgrade diese Namen durch die Ausführung des folgenden Befehls:

    mysqlcheck --all-databases --check-upgrade --fix-db-names --fix-table-names
    

    Vor MySQL 5.1.31 führt mysql_upgrade diesen Befehl nicht aus. Deshalb sollten Sie ihn manuell ausführen, wenn Sie Datenbank- oder Tabellennamen haben, die nichtalphanumerische Zeichen enthalten.

    Vor MySQL 5.1.23 führt der Befehl mysqlcheck die Namenscodierung für Views nicht aus. Um dieses Problem zu umgehen, entfernen Sie jede betroffene View und erstellen Sie sie neu.

    mysqlcheck kann keine Namen mit literalen Instanzen des Zeichens @ korrigieren, das dem Verschlüsseln von Sonderzeichen dient. Wenn Sie Datenbanken oder Tabellen haben, die dieses Zeichen enthalten, erstellen Sie vor dem Upgrade auf MySQL 5.1 mittels mysqldump Speicherauszüge davon und laden sie nach dem Upgrade wieder.

  • Bekannter Fehler: Beim Upgrade von MySQL 5.0 auf Versionen von 5.1 vor 5.1.23 schlägt die Ausführung von mysqlcheck (oder mysql_upgrade, das mysqlcheck ausführt) zum Aktualisieren von Tabellen bei Namen fehl, die als Bezeichner in Anführungszeichen geschrieben werden müssen. Um dieses Problem zu beheben, geben Sie jeder betroffenen Tabelle einen Namen, in dem keine Anführungszeichen benötigt werden:

    RENAME TABLE `tab``le_a` TO table_a;
    RENAME TABLE `table b` TO table_b;
    

    Nachdem Sie die Tabellen umbenannt haben, führen Sie das Programm mysql_upgrade aus. Ändern Sie anschließend den Namen der Tabelle wieder zurück zum ursprünglichen Namen:

    RENAME TABLE table_a TO `tab``le_a`;
    RENAME TABLE table_b TO `table b`;
    
  • Bekannter Fehler: In Verbindung mit dem Erstellen von Views hat der Server arc-Verzeichnisse in Datenbankverzeichnissen erstellt und dort unnütze Kopien von .frm-Dateien aufbewahrt. Die Verfahren zum Erstellen und Umbenennen dieser Kopien sowie die Einrichtung von arc-Verzeichnissen sind in MySQL 5.1.29 nicht mehr enthalten.

    Diese Änderung verursacht ein Problem beim Downgrade auf ältere Serverversionen, das sich unter diesen Umständen manifestiert:

    1. Richten Sie eine View v_orig in MySQL 5.1.29 oder höher ein.

    2. Benennen Sie die View in v_new und anschließend zurück in v_orig um.

    3. Führen Sie ein Downgrade auf einen älteren 5.1.x-Server durch und führen Sie mysql_upgrade aus.

    4. Versuchen Sie erneut, v_orig in v_new umzubenennen. Diese Operation scheitert.

    Als Workaround zur Vermeidung dieses Problems gibt es die folgenden Möglichkeiten:

    • Erstellen Sie vor dem Downgrade mittels mysqldump einen Speicherauszug Ihrer Daten und laden Sie die Speicherauszugsdatei nach dem Downgrade wieder.

    • Anstatt eine View nach dem Downgrade umzubenennen, können Sie sie auch entfernen und neu erstellen.

  • Inkompatible Änderung: In MySQL 5.1.21, 5.1.23 und 5.1.24 wurden Zeichensatz- und Sortierungsänderungen vorgenommen, die ein erneutes Erstellen der Tabellenindizes erfordern. Detaillierte Informationen finden Sie in Abschnitt 2.12.3, „Prüfen ob Tabellenindizes neu erstellt werden müssen“.

  • Inkompatible Änderung: MySQL 5.1 implementiert die Unterstützung einer Plug-In-API, die das Laden und Entladen verschiedener Komponenten während der Laufzeit gestattet, ohne dass der Server neu gestartet werden müsste. The MySQL Plugin API. Die Plug-In-API benötigt die Tabelle mysql.plugin. Nach dem Upgrade von einer älteren MySQL-Version sollten Sie den Befehl mysql_upgrade ausführen, um diese Tabelle zu erstellen. Siehe auch mysql_upgrade.

    Plug-Ins werden in das Verzeichnis installiert, welches in der Systemvariablen plugin_dir spezifiziert ist. Diese Variable steuert auch die Position, von der der Server benutzerdefinierte Funktionen (User-Defined Functions, UDFs) lädt; dies stellt eine Änderung zu früheren Versionen von MySQL dar. Mithin müssen alle UDF-Bibliotheksdateien von jetzt an in das Plug-In-Verzeichnis installiert werden. Wenn Sie von einer älteren MySQL-Version aktualisieren, müssen Sie Ihre UDF-Dateien in das Plug-In-Verzeichnis migrieren.

  • Inkompatible Änderung: Die Systemvariable table_cache wurde umbenannt in table_open_cache. Skripten, die table_cache verwenden, müssen so angepasst werden, dass sie den neuen Namen benutzen.

  • Inkompatible Änderung: In MySQL 5.1.36 wurden Optionen zum Laden von Plug-Ins, wie modularen Speicher-Engines, vom booleschen Format in ein Format geändert, das drei Werte zulässt. Die Implementierungen überschneiden sich. Wenn Sie jedoch bisher Optionen der Form --plugin_name=0 oder --plugin_name=1 verwendet haben, sollten Sie nun stattdessen --plugin_name=OFF beziehungsweise --plugin_name=ON verwenden. Detaillierte Informationen finden Sie in Server Options for Loading Plugins.

  • Inkompatible Änderung: Von MySQL 5.1.24 zu 5.1.31 wurde die Anweisung UPDATE so verändert, dass die Zuweisung von NULL zu einer NOT NULL-Spalte auch dann einen Fehler verursachte, wenn der strikte SQL-Modus nicht aktiviert war. Das ursprüngliche Verhalten vor MySQL 5.1.24 war, dass solche Zuweisungen nur im strikten SQL-Modus einen Fehler verursachten, ansonsten jedoch die Spalte auf den impliziten Standardwert für den Spaltendatentyp gesetzt und eine Warnung generiert haben. (Information zu impliziten Standardwerten finden Sie in Abschnitt 6.1.4, „Datentyp-Standardwerte“.)

    Die Änderung resultierte in Kompatibilitätsproblemen bei Anwendungen, die auf das ursprüngliche Verhalten angewiesen sind. Außerdem verursachte es Replikationsprobleme zwischen Servern mit und ohne ursprünglichem Verhalten bei Anwendungen, die bei nicht aktiviertem striktem SQL-Modus in UPDATE-Anweisungen NOT NULL-Spalten NULL zuwiesen. Die Änderung wurde in MySQL 5.1.32 rückgängig gemacht, sodass UPDATE wieder das ursprüngliche Verhalten aufweist. Dennoch können Probleme beim Replizieren zwischen Servern, die das veränderte Verhalten von UPDATE aufweisen und solchen, bei denen dies nicht gegeben ist, auftreten.

  • Inkompatible Änderung: Ab MySQL 5.1.29 wurde der Standardmodus für das Binär-Logging von MIXED in STATEMENT geändert, um die Kompatibilität mit MySQL 5.0 herzustellen.

  • Inkompatible Änderung: In MySQL 5.1.25 wurde die Handhabung vorbereiteter Anweisungen durch den Server geändert. Das betrifft vorbereitete Anweisungen, die auf SQL-Ebene verarbeitet werden (unter Verwendung der Anweisung PREPARE) und solche, die mit dem binären Client-Server-Protokoll verarbeitet werden (unter Verwendung der C-API-Funktion mysql_stmt_prepare()).

    Vorher konnten Änderungen an Metadaten von Tabellen oder Views, die in einer vorbereiteten Anweisung referenziert wurden, bei der folgenden Ausführung der Anweisung einen Serverabsturz bzw. einen Fehler während der Ausführung mit einem späteren Absturz verursachen. Das war beispielsweise möglich, nachdem eine Tabelle entfernt und mit einer anderen Definition wieder erstellt wurde.

    Jetzt werden Metadaten-Änderungen von Tabellen oder Views, die in vorbereiteten Anweisungen referenziert werden, entdeckt und sorgen für eine automatische erneute Vorbereitung der Anweisung bei ihrer nächsten Ausführung. Metadaten-Änderungen treten beispielsweise bei DDL-Anweisungen auf, die Tabellen erstellen, verwerfen, ändern, umbenennen oder kürzen bzw. analysieren, optimieren oder reparieren. Eine erneute Vorbereitung tritt auch dann ein, wenn referenzierte Tabellen oder Views aus dem Zwischenspeicher für Tabellendefinitionen (implizit, um Platz zu schaffen für neue Zwischenspeichereinträge, oder explizit durch FLUSH TABLES) gelöscht wurden.

    Die erneute Vorbereitung läuft automatisch ab, allerdings verringert sich die Leistung der vorbereiteten Anweisungen im entsprechenden Umfang.

    Änderungen von Tabelleninhalten (zum Beispiel mit INSERT oder UPDATE) veranlassen keine erneute Vorbereitung. Dies ist auch bei SELECT-Anweisungen nicht der Fall.

    Eine Inkompatibilität mit Vorgängerversionen von MySQL besteht darin, dass eine vorbereitete Anweisung jetzt von einer Ausführung zur nächsten gegebenenfalls eine andere Spaltengruppe oder andere Spaltentypen zurückgeben kann. Lautet die vorbereitete Anweisung beispielsweise SELECT * FROM t1, führt ein Abändern von t1 auf eine andere Spaltenanzahl dazu, dass die nächste Ausführung eine andere Spaltenanzahl zurückgibt als die vorhergehende Ausführung.

    Ältere Versionen der Clientbibliothek können diese Verhaltensänderung nicht handhaben. Deshalb wird für Anwendungen, die vorbereitete Anweisungen mit dem neuen Server verwenden, ein Upgrade zur neuen Clientbibliothek unbedingt empfohlen.

    Im Zusammenhang mit dieser Änderung zur erneuten Vorbereitung von Anweisungen wurde der Standardwert der Systemvariablen table_definition_cache von 128 auf 256 erhöht. Diese Erhöhung soll die Wahrscheinlichkeit senken, dass vorbereitete Anweisungen aufgrund von referenzierten Tabellen/Views, die aus dem Zwischenspeicher gelöscht wurden, um Platz für neue Einträge zu schaffen, erneut vorbereitet werden müssen.

    Eine neue Statusvariable, Com_stmt_reprepare, wurde eingeführt, um die Anzahl der erneuten Vorbereitungen verfolgen zu können.

  • Inkompatible Änderung: Ab MySQL 5.1.23 ist es innerhalb einer gespeicherten Routine nicht mehr zulässig, einen Cursor für eine SHOW- oder DESCRIBE-Anweisung zu deklarieren. Dies hat in einigen Fällen funktioniert, wird aber nicht mehr unterstützt. In vielen Fällen ist ein Workaround für diese Änderung, den Cursor mit einer SELECT-Abfrage zu verwenden, um eine INFORMATION_SCHEMA-Tabelle auszulesen, die die gleichen Informationen wie die Anweisung SHOW erzeugt.

  • Inkompatible Änderung: SHOW CREATE VIEW zeigt View-Definitionen mit einer AS alias_name-Klausel für jede Spalte an. Wenn eine Spalte von einem Ausdruck eingerichtet wird, dient der Ausdruckstext als Standard-Alias, der recht lang sein kann. Ab MySQL 5.1.23 werden Aliasse für Spaltennamen in CREATE VIEW-Anweisungen mit der maximalen Spaltenlänge von 64 Zeichen verglichen (anstelle der maximalen Alias-Länge von 256 Zeichen). Somit schlagen Views, die aus der Ausgabe von SHOW CREATE VIEW erstellt werden, fehl, wenn ein Spalten-Alias länger ist als 64 Zeichen. Das kann Probleme bei der Replikation und beim Laden von Speicherauszugsdateien verursachen. Weitere Informationen und Workarounds finden Sie in Restrictions on Views.

  • Inkompatible Änderung: Für gespeicherte Programme (gespeicherte Prozeduren und Funktionen, Trigger und Ereignisse) und Views mit Nicht-ASCII-Symbolen wurden verschiedene Probleme festgestellt. Diese betrafen Konvertierungsfehler aufgrund unvollständiger Zeichensatzinformation beim Übersetzen dieser Objekte in das gespeicherte Format und zurück.

    Um diese Probleme zu umgehen, wurde die Darstellung für diese Objekte in MySQL 5.1.21 verändert. Allerdings wirken sich die Korrekturen auf alle gespeicherten Programme und Views aus. (Sie werden beispielsweise Warnungen wie „no creation context“ erhalten.) Um Warnungen des Servers bezüglich der Verwendung alter Definitionen aus Releases vor 5.1.21 zu vermeiden, sollten Sie nach dem Upgrade auf 5.1.21 oder höher für gespeicherte Programme und Views mit mysqldump Speicherauszüge erstellen und anschließend neu laden, um sie mit neuen Definitionen neu zu erstellen. Rufen Sie mysqldump mit einer --default-character-set-Option auf, die den Nicht-ASCII-Zeichensatz verwendet, mit dem die Objekte bei der ursprünglichen Definition definiert wurden.

  • Inkompatible Änderung: Ab MySQL 5.1.20 unterstützt mysqld_safe das Erstellen von Fehlerlogs in syslog auf Systemen, die den Befehl logger unterstützen. Die neuen Optionen --syslog und --skip-syslog können anstelle der Option --log-error verwendet werden, um das Loggingverhalten zu steuern (siehe auch mysqld_safe).

    In 5.1.21 und höher lautet die Voreinstellung --skip-syslog. Diese ist mit dem Standardverhalten für das Schreiben von Fehlerlogdateien für Releases vor 5.1.20 kompatibel.

    Nur für 5.1.20 gelten die folgenden Bedingungen: 1) syslog wird standardmäßig verwendet, was mit Releases vor 5.1.20 nicht kompatibel ist. 2) Das Loggen nach syslog funktioniert gegebenenfalls in einigen Fällen nicht richtig. Vermeiden Sie aus diesen Gründen den Einsatz von MySQL 5.1.20.

  • Inkompatible Änderung: Ab MySQL 5.1.18 wurden die Plug-In-Schnittstelle und deren Handhabung von Systemvariablen geändert. Befehlszeilenoptionen wie --skip-innodb verursachen jetzt einen Fehler, wenn InnoDB nicht integriert oder über Plug-In geladen ist. Sie sollten --loose-skip-innodb verwenden, wenn Sie auch dann keinen Fehler wünschen, wenn InnoDB nicht verfügbar ist. Der Präfixmodifizierer --loose sollte für alle Befehlszeilenoptionen verwendet werden, bei denen Sie nicht genau wissen, ob der Plug-In existiert, und wünschen, dass die Operation auch dann fortgesetzt wird, wenn die Option notwendigerweise aufgrund des fehlenden Plug-Ins ignoriert wird. (Eine Beschreibung der Funktionsweise von --loose finden Sie in Using Options on the Command Line.)

  • Inkompatible Änderung: Ab MySQL 5.1.15 rollt InnoDB bei einer Transaktionszeitüberschreitung nur die letzte Anweisung zurück. Eine neue Option (--innodb_rollback_on_timeout) veranlasst InnoDB, die gesamte Transaktion abzubrechen und zurückzurollen, wenn eine Transaktionszeitüberschreitung eintritt (gleiches Verhalten wie in MySQL 4.1).

  • Inkompatible Änderung: Ab MySQL 5.1.15 gelten die folgenden Bedingungen für die Aktivierung der Systemvariablen read_only:

    • Wenn Sie read_only aktivieren wollen, während explizite Sperren (mit LOCK TABLES erwirkt) oder ausstehende Transaktionen vorliegen, tritt ein Fehler auf.

    • Wenn auf anderen Clients explizite Tabellensperren oder ausstehende Transaktionen vorliegen, ist die Aktivierung von read_only so lange gesperrt, bis die Sperren freigegeben und die Transaktionen beendet wurden. Während die versuchte Aktivierung von read_only offen ist, werden von anderen Clients angeforderte Tabellensperren und Transaktionsstarts ebenfalls blockiert, bis read_only gesetzt wurde.

    • read_only kann aktiviert werden, während Sie eine globale Lesesperre (erwirkt mit FLUSH TABLES WITH READ LOCK) vorhalten, da diese keine Tabellensperren umfasst.

    Früher erfolgte die Rückgabe nach der versuchten Aktivierung von read_only sofort, auch wenn explizite Sperren oder Transaktionen ausstanden, sodass gleichzeitig einzelne Datenänderungen aufgrund von im Server ausgeführten Anweisungen auftreten konnten.

  • Inkompatible Änderung: Die Anzahl von Funktionsnamen, auf die sich IGNORE_SPACE auswirkt, wurde in MySQL 5.1.13 von ca. 200 auf ca. 30 erheblich reduziert. (Details zu IGNORE_SPACE finden Sie unter Abschnitt 5.2.4, „Funktionsnamensanalyse und Auflösung“.) Diese Änderung verbessert die Beständigkeit der Parserfunktionen. Allerdings trägt sie auch die Möglichkeit einer Inkompatibilität für alten SQL-Code ein, der von den folgenden Bedingungen abhängig ist:

    • IGNORE_SPACE wird deaktiviert.

    • Das Vorliegen bzw. Fehlen von Whitespace-Zeichen nach einem Funktionsnamen dient der Unterscheidung zwischen integrierten und gespeicherten Funktionen mit demselben Namen (z. B. PI() und PI ()).

    Bei Funktionen, auf die sich IGNORE_SPACE ab MySQL 5.1.13 nicht mehr auswirkt, funktioniert diese Strategie nicht mehr. Wenn Sie Code haben, der der vorgenannten Inkompatibilität unterliegt, können Sie nach einem der folgenden Ansätze vorgehen:

    • Wenn eine gespeicherte Funktion einen Namen hat, der mit einer integrierten Funktion kollidiert, referenzieren Sie die gespeicherte Funktion ungeachtet der Tatsache, ob ein Whitespace-Zeichen vorhanden ist, mit einem Schemanamenskennzeichner. Schreiben Sie beispielsweise schema_name.PI() oder schema_name.PI ().

    • Alternativ können Sie die gespeicherte Funktion so umbenennen, dass die Namen nicht mehr kollidieren, und die Funktionsaufrufe auf die neuen Namen ändern.

  • Inkompatible Änderung: Für utf8-Spalten hat der Volltextparser verschiedene Interpunktions- und Whitespace-Zeichen, die nicht zu Wörtern gehören, fälschlicherweise als Wortzeichen betrachtet, was in einigen Fällen zur Rückgabe fehlerhafter Suchergebnisse führte. Die Korrektur umfasst eine Änderung des Volltextparsers in MySQL 5.1.12, sodass ab 5.1.12 alle Tabellen mit FULLTEXT-Indizes auf utf8-Spalten mit REPAIR TABLE repariert werden müssen:

    REPAIR TABLE tbl_name QUICK;
    
  • Inkompatible Änderung: Speicher-Engines können zur Laufzeit modular verwendet werden, die Unterscheidung zwischen deaktivierten und ungültigen Speicher-Engines ist also nicht mehr zutreffend. Ab MySQL 5.1.12 wirkt sich dies auf den SQL-Modus NO_ENGINE_SUBSTITUTION aus. Siehe Beschreibung in Server SQL Modes.

  • Inkompatible Änderung: Die Struktur von FULLTEXT-Indizes wurde in MySQL 5.1.6. geändert. Nach dem Upgrade auf MySQL 5.1.6 oder höher müssen alle Tabellen mit FULLTEXT-Indizes mit REPAIR TABLE repariert werden:

    REPAIR TABLE tbl_name QUICK;
    
  • Inkompatible Änderung: In MySQL 5.1.6 war das Standard-Logziel für die allgemeine Abfrage und die langsame Abfrage bei implementierten Logtabellen TABLE. Ab MySQL 5.1.21 wurde diese Voreinstellung in FILE geändert. Dies ist mit MySQL 5.0 kompatibel, jedoch nicht mit früheren Releases von MySQL 5.1. Wenn Sie ein Upgrade von MySQL 5.0 auf 5.1.21 oder höher durchführen, sollten keine Änderungen von Loggingoptionen notwendig sein. Wenn Sie jedoch von 5.1.6 über 5.1.20 auf 5.1.21 oder höher aktualisieren und das TABLE-Logging verwendet haben, benutzen Sie explizit die Option --log-output=TABLE, um das Tabellen-Logging Ihres Servers beizubehalten.

  • Inkompatible Änderung: Für ENUM-Spalten mit Aufzählungswerten, die Kommas enthalten, wurden die Kommas intern 0xff zugeordnet. Allerdings waren die Kommas dadurch von echten 0xff-Zeichen in den Werten nicht mehr zu unterscheiden. Dies tritt nicht mehr auf. Allerdings müssen Sie für die Korrektur von allen Tabellen mit ENUM-Spalten, die in ihren Werten echte 0xff enthalten, Speicherauszüge erstellen: Erstellen Sie mittels mysqldump Speicherauszüge der Tabellen mit dem aktuellen Server, bevor Sie ein Upgrade von einer Version von MySQL 5.1 vor 5.1.15 auf Version 5.1.15 oder höher durchführen.

  • Ab MySQL 5.1.12 gibt die Systemvariable lc_time_names das Gebietsschema an, das die für die Anzeige von Tages- und Monatsnamen sowie Abkürzungen verwendete Sprache regelt. Diese Variable wirkt sich auf die Ergebnisse der Funktionen DATE_FORMAT(), DAYNAME() und MONTHNAME() aus. Siehe auch MySQL Server Locale Support.

  • Ab MySQL 5.1.9 ruft mysqld_safe mysqld-max nicht mehr implizit auf (sofern vorhanden). Stattdessen ruft es mysqld auf, es sei denn, es wird eine --mysqld oder --mysqld-version-Option angegeben, die explizit einen anderen Server festlegt. Wenn Sie früher den impliziten Aufruf von mysqld-max genutzt haben, sollten Sie jetzt eine entsprechende Option verwenden. Ab MySQL 5.1.12 gibt es keinen gesonderten mysqld-max-Server, sodass keine Änderung notwendig sein sollte.

SQL-Änderungen:

  • Bekannter Fehler: Vor MySQL 5.1.17 akzeptierte der Parser ungültigen Code in SQL-Bedingungshandlern, was zu Serverabstürzen oder unerwartetem Ausnahmeverhalten in gespeicherten Programmen führt. Insbesondere gestattete der Parser, dass Bedingungshandler Kennsätze für Blöcke referenzieren, die die Handlerdeklaration beinhalten. Das war falsch, da Blockkennsätze den Code für Handler, die im Block selbst deklariert sind, nicht einschließen.

    Ab 5.1.17 weist der Parser dieses ungültige Konstrukt zurück. Wenn Sie jedoch ein binäres Upgrade ausführen (ohne Speicherauszüge Ihrer Datenbanken zu erstellen und zu laden), sind vorhandene Handler, die das Konstrukt enthalten, nach wie vor ungültig und müssen neu geschrieben werden, auch wenn sie offenbar erwartungsgemäß funktionieren.

    Für die Suche nach betroffenen Handlern erstellen Sie mittels mysqldump Speicherauszüge aller gespeicherten Prozeduren, Funktionen, Trigger und Ereignisse. Laden Sie diese anschließend in einen aktualisierten Server. Handler, die unzulässige Kennsatzreferenzen enthalten, werden zurückgewiesen.

    Weitere Informationen zu Bedingungshandlern und wie diese geschrieben werden, um ungültige Sprünge zu vermeiden, finden Sie in Abschnitt 8.8.4.2, „DECLARE für Handler“.

  • Inkompatible Änderung: Der Parser hat Anweisungen akzeptiert, die /* ... */ enthielten, die nicht mittels */ ordnungsgemäß abgeschlossen waren, wie SELECT 1 /* + 2. Ab MySQL 5.1.23 werden Anweisungen mit nicht abgeschlossenen /*-Anmerkungen mit einem Syntaxfehler zurückgewiesen.

    Diese Korrektur kann zu potenziellen Inkompatibilitäten führen. Aufgrund von Bug#26302, durch den */ am Ende von Anmerkungen in Views, gespeicherten Routinen, Triggern und Ereignissen abgeschnitten wurde, können Objekte dieser Art mit Definitionen gespeichert worden sein, die nun als syntaktisch ungültig zurückgewiesen werden. Solche Objekte sollten verworfen und neu eingerichtet werden, sodass ihre Definitionen keine gekürzten Anmerkungen enthalten.

  • Inkompatible Änderung: DELETE-Anweisungen für mehrere Tabellen, die mehrdeutige Aliasse enthalten, können unbeabsichtigte Nebenwirkungen, wie das Löschen von Datensätzen aus der falschen Tabelle, haben. Beispiel:

    DELETE FROM t1 AS a2 USING t1 AS a1 INNER JOIN t2 AS a2;
    

    Ab MySQL 5.1.23 können Alias-Deklarationen nur im Teil table_references festgelegt werden. An anderen Stellen der Anweisung sind zwar Alias-Referenzierungen, jedoch keine Alias-Deklarationen zulässig. Anweisungen mit nicht mehr zulässigen Aliassen müssen neu geschrieben werden.

  • Inkompatible Änderung: Ab MySQL 5.1.8 wird TYPE = engine_name noch als Synonym für die Tabellenoption ENGINE = engine_name akzeptiert, erzeugt jedoch eine Warnung. Beachten Sie, dass diese Option in MySQL 5.1.7 nicht verfügbar ist, ab MySQL 5.5 komplett entfernt wird und einen Syntaxfehler erzeugt.

    TYPE ist seit MySQL 4.0 veraltet.

  • Inkompatible Änderung: Der Namespace für Trigger wurde in MySQL 5.0.10 geändert. Vorher mussten Trigger-Namen je Tabelle eindeutig sein. Nun muss eine Eindeutigkeit innerhalb des Schemas (Datenbank) gegeben sein. Eine Auswirkung dieser Änderung besteht darin, dass die Syntax DROP TRIGGER nun statt eines Tabellennamens einen Schemanamen verwendet (wobei dieser Schemaname optional ist; wird er weggelassen, dann wird das aktuelle Schema verwendet).

    Wenn Sie von einer Version von MySQL 5, die älter ist als 5.0.10 auf MySQL 5.0.10 oder höher aktualisieren, müssen Sie alle Trigger löschen und neu erstellen; andernfalls funktioniert DROP TRIGGER nach dem Upgrade nicht. Gehen Sie am besten wie folgt vor:

    1. Aktualisieren Sie auf MySQL 5.0.10 oder höher, um auf die Trigger-Daten in der Tabelle INFORMATION_SCHEMA.TRIGGERS zugreifen zu können. (Dies sollte auch für Trigger aus Versionen vor 5.0.10 funktionieren.)

    2. Speichern Sie alle Trigger-Definitionen mithilfe der folgenden SELECT-Anweisung:

      SELECT CONCAT('CREATE TRIGGER ', t.TRIGGER_SCHEMA, '.', t.TRIGGER_NAME,
                    ' ', t.ACTION_TIMING, ' ', t.EVENT_MANIPULATION, ' ON ',
                    t.EVENT_OBJECT_SCHEMA, '.', t.EVENT_OBJECT_TABLE,
                    ' FOR EACH ROW ', t.ACTION_STATEMENT, '//' )
      INTO OUTFILE '/tmp/triggers.sql'
      FROM INFORMATION_SCHEMA.TRIGGERS AS t;
      

      Die Anweisung verwendet INTO OUTFILE, d. h., Sie müssen die Berechtigung FILE haben. Die Datei wird auf dem Serverhost eingerichtet. Wenn Sie wollen, können Sie einen anderen Dateinamen verwenden. Um hundertprozentig sicher zu sein, überprüfen Sie die Trigger-Definitionen in der Datei triggers.sql und fertigen unter Umständen eine Sicherung der Datei an.

    3. Beenden Sie den Server und löschen Sie alle Trigger, indem Sie sämtliche .TRG-Dateien in Ihren Datenbankverzeichnissen entfernen. Wechseln Sie dann in Ihr Datenverzeichnis und setzen Sie folgenden Befehl ab:

      shell> rm */*.TRG
      
    4. Starten Sie den Server und erstellen Sie alle Trigger mithilfe der triggers.sql-Datei neu:

      mysql> delimiter // ;
      mysql> source /tmp/triggers.sql //
      
    5. Vergewissern Sie sich, dass alle Trigger mit der SHOW TRIGGERS-Anweisung erfolgreich erstellt wurden.

  • Inkompatible Änderung: MySQL 5.1.6 hat die Berechtigung TRIGGER neu eingeführt. Zuvor benötigte man die Berechtigung SUPER zum Erstellen oder Löschen von Triggern. Jetzt ist für derartige Vorgänge die Berechtigung TRIGGER erforderlich. Dies ist eine Sicherheitsoptimierung, da Sie Benutzern nun nicht länger die Berechtigung SUPER gewähren müssen, damit diese Trigger erstellen können. Allerdings wurde die Anforderung, dass das Konto, welches in der DEFINER-Klausel eines Triggers genannt wird, die Berechtigung SUPER haben muss, dadurch ersetzt, dass das Konto nun die Berechtigung TRIGGER erfordert. Wenn Sie von einer früheren Version von MySQL 5.0 oder 5.1 auf MySQL 5.1.6 oder höher aktualisieren, müssen Sie Ihre Berechtigungstabellen aktualisieren, indem Sie mysql_upgrade ausführen. Dadurch wird die Berechtigung TRIGGER allen Konten zugewiesen, die die Berechtigung SUPER hatten. Wenn Sie die Berechtigungstabellen nicht aktualisieren, können Trigger bei ihrer Aktivierung fehlschlagen. Nach dem Aktualisieren der Berechtigungstabellen können Sie die Berechtigung SUPER für die Konten widerrufen, für die sie anderweitig nicht mehr erforderlich ist.

  • Einige Schlüsselwörter sind in MySQL 5.1 reserviert, bei denen dies in MySQL 5.0 nicht der Fall war. Siehe auch Abschnitt 5.3, „Reservierte Wörter“.

  • Die Anweisungen LOAD DATA FROM MASTER und LOAD TABLE FROM MASTER sind veraltet. Empfohlene Alternativen finden Sie in Abschnitt 8.6.2.2, „LOAD DATA FROM MASTER.

  • Die Anweisungen INSTALL PLUGIN und UNINSTALL PLUGIN, die für die Plug-In-API verwendet werden, sind neu. Gleiches gilt für die Klausel WITH PARSER der FULLTEXT-Indexerstellung, die ein Parser-Plug-In mit einem Volltextindex verknüpft. The MySQL Plugin API.

C-API-Änderungen:

  • Inkompatible Änderung: Ab MySQL 5.1.7 gibt die C-API-Funktion mysql_stmt_attr_get() einen booleschen anstelle eines vorzeichenlosen int-Wertes für STMT_ATTR_UPDATE_MAX_LENGTH zurück. (Bug#16144)

2.12.2. Downgrade von MySQL

Dieser Abschnitt erläutert, was Sie tun sollten, um in dem unwahrscheinlichen Fall, dass eine ältere MySQL-Version besser funktionierte als eine neue Version, ein Downgrade durchzuführen.

Führen Sie das Downgrade innerhalb derselben Release-Serie durch (z. B. von 5.0.13 auf 5.0.12), dann müssen Sie in der Regel nur die neuen Binärdateien über die alten installieren. Mit den Datenbanken müssen Sie nichts machen. Allerdings empfiehlt es sich wie immer auch hier, ein Backup zu erstellen.

Die folgende Checkliste sollten Sie immer überprüfen, wenn Sie ein Downgrade durchführen:

  • Lesen Sie den Abschnitt zum Upgrade auf die Release-Serie, von der aus Sie das Downgrade durchführen, um sicherzustellen, dass diese nicht bestimmte Funktionen enthält, die Sie doch benötigen. Siehe auch Abschnitt 2.12.1, „Upgrade von MySQL“.

  • Wenn für die betreffende Version ein Abschnitt zum Downgrade vorhanden ist, sollten Sie diesen ebenfalls sorgfältig lesen.

  • Welche neuen Funktionen zwischen der Version, auf die Sie das Downgrade durchführen wollen, und Ihrer aktuellen Version hinzugekommen sind, können Sie den Änderungslogs entnehmen (MySQL Change History).

  • Prüfen Sie in Abschnitt 2.12.3, „Prüfen ob Tabellenindizes neu erstellt werden müssen“, ob Änderungen an Zeichensätzen oder Sortierungen zwischen Ihrer aktuellen MySQL-Version und der Version vorgenommen wurden, zu der Sie das Downgrade durchführen wollen. Wenn das der Fall ist und sich diese Änderungen auf Ihre Tabellenindizes auswirken, müssen Sie die betreffenden Indizes entsprechend den Anweisungen in Abschnitt 2.12.4, „Reparieren und Neuerstellen von Tabellen und Indizes“ neu erstellen.

In den meisten Fällen können Sie die Format- und Datendateien von MySQL zwischen verschiedenen Versionen derselben Architektur hin- und herschieben, solange Sie die Release-Serie nicht wechseln.

Wenn Sie das Downgrade von einer Release-Serie auf eine andere durchführen, kann es bei den Speicherformaten der Tabellen zu Inkompatibilitäten kommen. In diesem Fall können Sie Ihre Tabellen vor dem Downgrade mithilfe von mysqldump sichern. Laden Sie nach Abschluss des Downgrades die Speicherauszugsdatei mit mysql oder mysqlimport, um die Tabellen neu zu erstellen. Beispiele finden Sie in Abschnitt 2.12.5, „Kopieren von MySQL-Datenbanken auf einen anderen Rechner“.

Ein typisches Symptom bei Downgrade-Inkompatibilitäten des Tabellenformats besteht darin, dass Sie Tabellen nicht öffnen können. Gehen Sie in diesem Fall wie folgt vor:

  1. Beenden Sie den älteren MySQL Server, auf den Sie das Downgrade durchführen.

  2. Starten Sie den neueren MySQL Server, von dem aus Sie das Downgrade durchführen.

  3. Speichern Sie alle Tabellen, auf die der ältere Server nicht zugreifen konnte, mithilfe von mysqldump, um eine Speicherauszugsdatei zu erstellen.

  4. Beenden Sie den neueren MySQL Server und starten Sie den älteren neu.

  5. Laden Sie die Speicherauszugsdatei in den älteren Server. Nun sollten Sie auf Ihre Tabellen zugreifen können.

Es ist auch möglich, dass sich die Struktur der Systemtabellen in der mysql-Datenbank geändert hat und das Downgrade zu Funktionalitätsverlusten führt oder Anpassungen erfordert. Hier sind einige Beispiele:

  • Für die Trigger-Erstellung ist ab MySQL 5.1 die Berechtigung TRIGGER notwendig. In MySQL 5.0 gibt es die Berechtigung TRIGGER nicht, stattdessen ist hier SUPER erforderlich. Bei einem Downgrade von MySQL 5.1 auf 5.0 müssen Sie den Konten, die in 5.1 die Berechtigung TRIGGER hatten, die Berechtigung SUPER zuweisen.

  • Trigger wurden in MySQL 5.0 hinzugefügt, wenn Sie also ein Downgrade von 5.0 auf 4.1 ausführen, können Sie Trigger überhaupt nicht verwenden.

2.12.2.1. Downgrade auf MySQL 5.0

Beim Downgrade auf MySQL 5.0 von MySQL 5.1 oder einer späteren Version sollten Sie die folgenden Punkte zu Funktionen berücksichtigen, die in MySQL 5.1 und höher vorhanden sind, nicht aber in MySQL 5.0:

  • Partitionierung.  MySQL 5.0 unterstützt keine benutzerdefinierte Partitionierung. Wenn eine Tabelle in 5.1 als partitionierte Tabelle eingerichtet wurde (oder wenn eine in einer Vorgängerversion von MySQL eingerichtete Tabelle so verändert wurde, dass sie nach dem Upgrade auf 5.1 Partitionen enthält), kann auf die Tabelle nach dem Downgrade nur zugegriffen werden, wenn Sie eine der folgenden Optionen ausführen:

    • Exportieren Sie die Tabelle mit mysqldump und entfernen Sie sie in MySQL 5.1; importieren Sie die Tabelle nach dem Downgrade auf MySQL 5.0 wieder.

    • Entfernen Sie vor dem Downgrade die Partitionierung der Tabelle mithilfe von ALTER TABLE table_name REMOVE PARTITIONING.

  • Ereignisplaner.  MySQL 5.0 unterstützt keine geplanten Ereignisse. Wenn Ihre Datenbanken Definitionen geplanter Ereignisse enthalten, sollten Sie verhindern, dass diese bei der Verwendung von mysqldump gesichert werden, indem Sie die Option --skip-events wählen. (Siehe auch Abschnitt 3.4, „mysqldump — ein Datenbanksicherungsprogramm“.)

  • Gespeicherte Routinen.  MySQL 5.1.21 hat in der Tabelle mysql.proc, in der Definitionen für gespeicherte Routinen gespeichert werden, einige neue Spalten hinzugefügt. Beim Downgrade von MySQL 5.1.21 oder höher auf MySQL 5.0 können Sie die Routinendefinitionen aus MySQL 5.1 nicht mit dem Auszug von mysql.proc in MySQL 5.0.46 oder früher importieren, den Sie mithilfe von mysqldump erstellt haben (wie bei Verwendung der Option --all-databases). Führen Sie stattdessen vor dem Downgrade mysqldump --routines und nach dem Downgrade die DDL-Anweisungen der gespeicherten Routinen aus.

    Weitere Informationen finden Sie in Bug#11986, Bug#30029 und Bug#30660.

  • Trigger.  Für die Trigger-Erstellung ist ab MySQL 5.1 die Berechtigung TRIGGER notwendig. In MySQL 5.0 gibt es die Berechtigung TRIGGER nicht, stattdessen ist hier SUPER erforderlich. Bei einem Downgrade von MySQL 5.1 auf 5.0 müssen Sie den Konten, die in 5.1 die Berechtigung TRIGGER hatten, die Berechtigung SUPER zuweisen.

2.12.3. Prüfen ob Tabellenindizes neu erstellt werden müssen

Ein binäres Upgrade oder Downgrade ist eins, das eine MySQL-Version „an Ort und Stelle“ über einer existierenden Version installiert, ohne Speicherauszüge von Tabellen zu erstellen und neu zu laden:

  1. Beenden Sie den Server für die vorhandene Version, sofern er läuft.

  2. Installieren Sie eine andere MySQL-Version. Dabei handelt es sich um ein Upgrade, wenn die neue Version höher ist als die Originalfassung, und um ein Downgrade wenn die Version niedriger ist.

  3. Starten Sie den Server für die neue Version.

In vielen Fällen können die Tabellen aus der MySQL-Vorgängerversion unverändert von der neuen Version verwendet werden. Manchmal werden jedoch Änderungen an der Handhabung von Zeichensätzen oder Sortierungen vorgenommen, die die Sortierreihenfolge von Zeichen verändern. Infolgedessen wird die Sortierung von Einträgen in Indizes, die einen betroffenen Zeichensatz oder eine solche Sortierung verwenden, falsch. Solche Änderungen können zu verschiedenen Problemen führen:

  • Vergleichsergebnisse, die von früheren Ergebnissen abweichen

  • Unvermögen, einzelne Indexwerte zu finden, da Indexeinträge falsch sortiert wurden

  • Falsch sortierteORDER By-Ergebnisse

  • Tabellen, für die CHECK TABLE einen Reparaturbedarf ausgibt

Die Lösung dieser Probleme besteht darin, die Indizes neu zu erstellen, die betroffene Zeichensätze oder Sortierungen verwenden, indem die Indizes entweder verworfen und neu erstellt werden oder ein Speicherauszug der gesamten Tabelle erstellt und neu geladen wird. Informationen zur Neuerstellung von Indizes finden Sie in Abschnitt 2.12.4, „Reparieren und Neuerstellen von Tabellen und Indizes“.

Ob eine Tabelle über Indizes verfügt, die neu erstellt werden müssen, können Sie der Liste unten entnehmen. Sie zeigt, welche MySQL-Versionen Zeichensatz- oder Sortierungsänderungen eingeführt haben, die eine Neuerstellung von Indizes erfordern. Jeder Eintrag enthält die Version, in der die Änderung auftrat, und die Zeichensätze oder Sortierungen, auf die sie sich auswirkt. Wenn die Änderung mit einem bestimmten Bug-Bericht verbunden ist, ist die Bug-Nummer angegeben.

Die Liste gilt für binäre Up- und Downgrades. Bug#29461 wurde beispielsweise in MySQL 5.0.48 korrigiert. Die Angaben gelten also für Upgrades von älteren Versionen als 5.0.48 auf 5.0.48 und höher sowie für Downgrades von 5.0.48 und höher auf Versionen, die älter sind als 5.0.48.

Wenn Sie Tabellen mit betroffenen Indizes haben, erstellen Sie die Indizes entsprechend den Anweisungen aus Abschnitt 2.12.4, „Reparieren und Neuerstellen von Tabellen und Indizes“ neu.

In vielen Fällen können Sie Tabellen, bei denen eine Neuerstellung des Index notwendig ist, mithilfe von CHECK TABLE ... FOR UPGRADE erkennen. (Die Meldung lautet: Table upgrade required. Please do "REPAIR TABLE `tbl_name`" or dump/reload to fix it!). Hier können Sie auch mysqlcheck --check-upgrade oder mysql_upgrade verwenden, die CHECK TABLE ausführen. Die Anwendung von CHECK TABLE trifft jedoch nur nach Upgrades zu, nicht nach Downgrades. Außerdem ist CHECK TABLE nicht für alle Speicher-Engines verwendbar. Welche Speicher-Engines CHECK TABLE unterstützt, finden Sie in Abschnitt 8.5.2.3, „CHECK TABLE-Syntax“.

Änderungen, durch die eine Neuerstellung des Index notwendig ist:

  • MySQL 5.0.48 (Bug#29461)

    Betrifft Indizes für Spalten, die folgende Zeichensätze verwenden: eucjpms, euc_kr, gb2312, latin7, macce, ujis

    Betroffene Tabellen können ab MySQL 5.1.29, 6.0.8 mit CHECK TABLE ... FOR UPGRADE ermittelt werden (siehe Bug#39585).

  • MySQL 5.0.48 (Bug#27562)

    Betrifft Indizes, die die Sortierung ascii_general_ci für Spalten verwenden, die folgende Zeichen enthalten: '`' GRAVE ACCENT, '[' LEFT SQUARE BRACKET, '\' REVERSE SOLIDUS, ']' RIGHT SQUARE BRACKET, '~' TILDE

    Betroffene Tabellen können ab MySQL 5.1.29, 6.0.8 mit CHECK TABLE ... FOR UPGRADE ermittelt werden (siehe Bug#39585).

  • MySQL 5.1.21 (Bug#29461)

    Betrifft Indizes für Spalten, die folgende Zeichensätze verwenden: eucjpms, euc_kr, gb2312, latin7, macce, ujis

    Betroffene Tabellen können ab MySQL 5.1.29, 6.0.8 mit CHECK TABLE ... FOR UPGRADE ermittelt werden (siehe Bug#39585).

  • MySQL 5.1.23 (Bug#27562)

    Betrifft Indizes, die die Sortierung ascii_general_ci für Spalten verwenden, die folgende Zeichen enthalten: '`' GRAVE ACCENT, '[' LEFT SQUARE BRACKET, '\' REVERSE SOLIDUS, ']' RIGHT SQUARE BRACKET, '~' TILDE

    Betroffene Tabellen können ab MySQL 5.1.29, 6.0.8 mit CHECK TABLE ... FOR UPGRADE ermittelt werden (siehe Bug#39585).

  • MySQL 5.1.24 (Bug#27877)

    Betrifft Indizes, die die Sortierung utf8_general_ci oder ucs2_general_ci für Spalten verwenden, die 'ß' (LATIN SMALL LETTER SHARP S, Deutsch) enthalten.

    Betroffene Tabellen können ab MySQL 5.1.30, 6.0.8 mit CHECK TABLE ... FOR UPGRADE ermittelt werden (siehe Bug#40053).

  • * MySQL 6.0.1 (WL#3664)

    Betrifft Indizes, die die Sortierung latin2_czech_cs verwenden.

    Betroffene Tabellen können ab MySQL 5.4.4, 6.0.9 mit CHECK TABLE ... FOR UPGRADE ermittelt werden (siehe Bug#40054).

    MySQL 6.0.5 (Bug#33452)

    Betrifft Indizes, die die Sortierung latin2_czech_cs verwenden.

    Betroffene Tabellen können ab MySQL 5.4.4, 6.0.9 mit CHECK TABLE ... FOR UPGRADE ermittelt werden (siehe Bug#40054).

  • MySQL 6.0.5 (Bug#27877)

    Betrifft Indizes, die die Sortierung utf8_general_ci oder ucs2_general_ci für Spalten verwenden, die '????' (LATIN SMALL LETTER SHARP S, Deutsch) enthalten.

    Betroffene Tabellen können ab MySQL 6.0.8 mit CHECK TABLE ... FOR UPGRADE ermittelt werden (siehe Bug#40053).

  • MySQL 6.0.6 (Bug#25420)

    Betrifft Indizes, die die folgenden Sortierungen verwenden, wenn die Spalten die angegebenen Zeichen enthalten: big5_chinese_ci: '~' TILDE oder '`' GRAVE ACCENT; cp866_general_ci: j LATIN SMALL LETTER J; gb2312_chinese_ci: '~' TILDE; gbk_chinese_ci: '~' TILDE

    Betroffene Tabellen können ab MySQL 5.4.4, 6.0.9 mit CHECK TABLE ... FOR UPGRADE ermittelt werden (siehe Bug#40054).

2.12.4. Reparieren und Neuerstellen von Tabellen und Indizes

Dieser Abschnitt beschreibt, wie er Tabellen neu erstellt werden. Das kann aufgrund von Änderungen in MySQL, wie der Art und Weise der Handhabung von Datentypen, oder Änderungen der Zeichensatzhandhabung notwendig sein. Beispielsweise muss eine Tabelle nach dem Beseitigen eines Fehlers in einer Sortierung neu erstellt werden, um die Indizes für Zeichenspalten neu zu generieren, die die betreffende Sortierung verwenden. Außerdem wären Tabellenreparaturen oder Tabellenupgrades denkbar, die entsprechend der Ausgabe einer Tabellenprüfoperation, wie den von CHECK TABLE, mysqlcheck und mysql_upgrade ausgeführten, durchgeführt werden sollen.

Methoden zur Neuerstellung von Tabellen umfassen die Erstellung von Speicherauszügen und das erneute Laden oder die Verwendung von ALTER TABLE bzw. REPAIR TABLE.

Anmerkung

Wenn Sie Tabellen neu erstellen, da eine andere MySQL-Version sie nach einem binären Up- oder Downgrade nicht verarbeiten kann, müssen Sie nach der Methode des Sicherns und erneuten Ladens vorgehen. Erstellen Sie Speicherauszüge der Tabellen vor dem Up- oder Downgrade (mit Ihrer Original-Version von MySQL) und laden Sie die Tabellen nach dem Up- oder Downgrade (nach Installation der neuen Version).

Wenn Sie die Methode ?Sichern und Laden“ zur Neuerstellung von Tabellen nur zur erneuten Generierung von Indizes verwenden, können Sie den Speicherauszug vor oder nach dem Up- oder Downgrade erstellen. Das Laden muss jedoch danach erfolgen.

Um eine Tabelle durch ?Sichern und Laden“ neu zu erstellen, verwenden Sie mysqldump zur Herstellung der Speicherauszugsdatei und mysql zum Wiedereinladen der Datei:

shell> mysqldump db_name t1 > dump.sql
shell> mysql db_name < dump.sql

Wenn Sie alle Tabellen einer Datenbank neu erstellen wollen, geben Sie den Datenbanknamen ohne darauffolgenden Tabellennamen an:

shell> mysqldump db_name > dump.sql
shell> mysql db_name < dump.sql

Wenn Sie alle Tabellen in allen Datenbanken neu erstellen wollen, verwenden Sie die Option --all-databases:

shell> mysqldump --all-databases > dump.sql
shell> mysql < dump.sql

Um eine Tabelle mit ALTER TABLE neu zu erstellen, verwenden Sie eine Anweisung, die die Tabelle so „ändert“, dass die bereits vorhandene Speicher-Engine verwendet wird. Beispiel: Wenn t1 eine MyISAM-Tabelle ist, verwenden Sie diese Anweisung:

mysql> ALTER TABLE t1 ENGINE = MyISAM;

Wenn Sie nicht sicher sind, welche Speicher-Engine in der Anweisung ALTER TABLE anzugeben ist, zeigen Sie die Tabellendefinition mit SHOW CREATE TABLE an.

Wenn Sie eine Tabelle neu erstellen müssen, weil eine Tabellenprüfoperation ergeben hat, dass die Tabelle beschädigt ist oder aktualisiert werden muss, können Sie REPAIR TABLE verwenden, wenn diese Anweisung die Speicher-Engine der Tabelle unterstützt. Um zum Beispiel eine MyISAM-Tabelle zu reparieren, verwenden Sie diese Anweisung:

mysql> REPAIR TABLE t1;

Bei Speicher-Engines wie InnoDB, die REPAIR TABLE nicht unterstützt, erstellen Sie wie oben beschrieben mittels mysqldump eine Speicherauszugsdatei, die Sie mit mysql wieder laden.

Welche Speicher-Engines REPAIR TABLE unterstützt, finden Sie in Abschnitt 8.5.2.6, „REPAIR TABLE-Syntax“.

2.12.5. Kopieren von MySQL-Datenbanken auf einen anderen Rechner

Sie können die .frm-, .MYI- und .MYD-Dateien für MyISAM-Tabellen zwischen verschiedenen Architekturen kopieren, die dasselbe Fließkommaformat unterstützen. (MySQL sorgt automatisch für das erforderliche Austauschen von Bytes.) Siehe auch The MyISAM Storage Engine.

In Fällen, in denen Sie Datenbanken zwischen verschiedenen Architekturen transferieren müssen, können Sie mit mysqldump eine Datei mit SQL-Anweisungen erstellen. Danach übertragen Sie die Datei auf das andere System und verwenden es dort als Eingabe für den mysql-Client.

Mit mysqldump --help erfahren Sie, welche Optionen vorhanden sind.

Die einfachste (wenn auch nicht schnellste) Möglichkeit, eine Datenbank zwischen zwei Computern zu verschieben, besteht darin, die folgenden Befehle auf dem Rechner auszuführen, auf dem die Datenbank sich befindet:

shell> mysqladmin -h 'other_hostname' create db_name
shell> mysqldump db_name | mysql -h 'other_hostname' db_name

Wollen Sie eine Datenbank von einem entfernten Computer über ein langsames Netzwerk kopieren, dann können Sie die folgenden Befehle verwenden:

shell> mysqladmin create db_name
shell> mysqldump -h 'other_hostname' --compress db_name | mysql db_name

Sie können die Daten auch in einer Datei ablegen, diese auf den Zielcomputer übertragen und dann dort in die Datenbank einladen. So können Sie etwa eine Datenbank wie folgt in einer komprimierten Datei auf dem Quellcomputer speichern:

shell> mysqldump --quick db_name | gzip > db_name.gz

Übertragen Sie die Datei mit den Datenbankinhalten auf den Zielcomputer und führen Sie dort folgende Befehle aus:

shell> mysqladmin create db_name
shell> gunzip < db_name.gz | mysql db_name

Sie können auch mysqldump und mysqlimport zur Übertragung der Datenbank verwenden. Bei großen Tabellen ist das wesentlich schneller als die einfache Verwendung von mysqldump. Bei den folgenden Befehlen steht DUMPDIR für den vollständigen Pfadnamen des Verzeichnisses, in dem Sie die Ausgabe von mysqldump speichern.

Zunächst erstellen Sie das Verzeichnis für die Ausgabedateien und speichern dann die Datenbank:

shell> mkdir DUMPDIR
shell> mysqldump --tab=DUMPDIR db_name

Danach übertragen Sie die Dateien im Verzeichnis DUMPDIR in das entsprechende Verzeichnis auf dem Zielcomputer und laden die Dateien dann dort in MySQL ein:

shell> mysqladmin create db_name           # create database
shell> cat DUMPDIR/*.sql | mysql db_name   # create tables in database
shell> mysqlimport db_name DUMPDIR/*.txt   # load data into tables

Vergessen Sie nicht, die mysql-Datenbank zu kopieren, da darin die Grant-Tabellen gespeichert sind. Unter Umständen müssen Sie die Befehle auf dem neuen Computer als MySQL-root-Benutzer ausführen, bis Ihre mysql-Datenbank fertiggestellt ist.

Nachdem Sie die mysql-Datenbank auf dem neuen System importiert haben, führen Sie mysqladmin flush-privileges aus, damit der Server die Grant-Tabelle-Daten neu lädt. Downgrade von MySQL

2.13. Betriebssystemspezifische Anmerkungen

2.13.1. Anmerkungen zu Linux

Dieser Abschnitt beschreibt Probleme, die unter Linux aufgetreten sind. Die ersten Teilabschnitte schildern dabei betriebssystemspezifische Probleme allgemeiner Art, Probleme in Bezug auf die Verwendung von Binär- oder Quelldistributionen und Probleme nach Abschluss der Installation. Im Weiteren werden Probleme erläutert, die unter Linux auf bestimmten Plattformen auftreten.

Beachten Sie, dass die meisten dieser Probleme unter älteren Linux-Versionen auftreten. Wenn Sie eine neuere Version verwenden, werden Sie wahrscheinlich gar nichts bemerken.

2.13.1.1. Anmerkungen zum Betriebssystem Linux

Anmerkungen zum Betriebssystem Linux MySQL setzt die Linux-Version 2.0 oder höher voraus.

Warnung

Auf SMP-Systemen sind merkwürdige Probleme bei der Kombination von Linux 2.2.14 und MySQL aufgetreten. Ferner haben uns einige MySQL-Benutzer mitgeteilt, dass sie schwerwiegende Stabilitätsprobleme bei der Verwendung von MySQL mit dem Kernel 2.2.14 hatten. Wenn Sie diesen Kernel verwenden, sollten Sie auf die Kernel-Version 2.2.19 (oder höher) oder auf Version 2.4 aktualisieren. Bei Multiprozessorsystemen sollten Sie die Verwendung der Kernel-Version 2.4 in jedem Fall in Betracht ziehen, da Sie dadurch einen erheblichen Geschwindigkeitszuwachs erfahren werden. Außerdem wird sich so die Stabilität Ihres Systems erhöhen.

Wenn Sie LinuxThreads verwenden, sollten mindestens drei laufende mysqld-Prozesse angezeigt werden. Das sind tatsächlich Threads. Ein Thread ist für den LinuxThreads-Manager, ein weiterer zur Verwaltung der Verbindungen und der dritte zur Verwaltung von Alarmmeldungen und Signalen.

2.13.1.2. Anmerkungen zur Linux-Binärdistribution

Die MySQL-Binär- und -RPM-Releases für die Linux-Intel-Kombination sind für optimale Geschwindigkeit konfiguriert. Wir versuchen immer, den schnellsten stabilen Compiler zu finden, der verfügbar ist.

Der Binär-Release wird mit -static verknüpft, d. h., Sie müssen sich in der Regel keine Gedanken darüber machen, welche Version der Systembibliotheken Sie haben. Sie müssen auch LinuxThreads nicht installieren. Ein mit -static verknüpftes Programm ist ein wenig größer als ein dynamisch verknüpftes Programm, aber auch ein bisschen schneller (ca. 3 bis 5 Prozent). Allerdings besteht ein Problem bei statisch verknüpften Programmen darin, dass Sie keine UDFs (User-Defined Functions, benutzerdefinierte Funktionen) verwenden können. Wenn Sie UDFs schreiben oder verwenden wollen (dies ist nur etwas für C- oder C++-Programmierer), dann müssen Sie MySQL selbst mit dynamischer Verknüpfung kompilieren.

Ein bekanntes Problem bei Binärdistributionen besteht darin, dass auf älteren Linux-Systemen, die libc verwenden (also z. B. Red Hat 4.x oder Slackware), gelegentlich Schwierigkeiten in Verbindung mit der Auflösung der Hostnamen auftreten (diese sind jedoch nicht schwerwiegend). Verwendet Ihr System libc statt glibc2, dann werden Sie wahrscheinlich Probleme in Verbindung mit der Hostnamensauflösung und getpwnam() haben. Diese treten auf, weil glibc (leider) auf einige externe Bibliotheken angewiesen ist, um die Namensauflösung und getpwent() implementieren zu können – und zwar auch dann, wenn mit der Option -static kompiliert wurde. Diese Probleme äußern sich auf zweierlei Weise:

  • Bei der Ausführung von mysql_install_db erhalten Sie die folgende Fehlermeldung:

    Sorry, the host 'xxxx' could not be looked up
    

    Sie können dieses Problem beheben, indem Sie mysql_install_db --force ausführen, was dazu führt, dass der Test resolveip in mysql_install_db nicht ausgeführt wird. Der Nachteil besteht darin, dass Sie Hostnamen nicht in den Berechtigungstabellen verwenden können; mit Ausnahme von localhost müssen Sie dann immer die entsprechenden IP-Adressen angeben. Wenn Sie eine alte MySQL-Version verwenden, die --force nicht unterstützt, dann müssen Sie den Test resolveip in mysql_install_db manuell mit einem Texteditor entfernen.

  • Unter Umständen erhalten Sie auch die folgende Fehlermeldung, wenn Sie versuchen, mysqld mit der Option --user auszuführen:

    getpwnam: No such file or directory
    

    Um dieses Problem zu umgehen, starten Sie mysqld mit dem Befehl su statt durch Angabe der Option --user. Auf diese Weise ändert das System die Benutzerkennung des mysqld-Prozesses selbst, d. h. mysqld muss dies nicht erledigen.

Eine andere Lösung, die beide Probleme behebt, besteht darin, keine Binärdistribution zu verwenden. Beschaffen Sie sich eine MySQL-Quelldistribution (im RPM- oder tar.gz-Format) und installieren Sie diese stattdessen.

Bei manchen Linux 2.2-Versionen erhalten Sie unter Umständen die Fehlermeldung Resource temporarily unavailable, wenn Clients über TCP/IP sehr schnell viele neue Verbindungen mit einem mysqld-Server herstellen. Das Problem besteht darin, dass bei Linux zwischen dem Moment, zu dem ein TCP/IP-Socket von Ihnen geschlossen wird, und dem Zeitpunkt der tatsächlichen Freigabe des Sockets eine Verzögerung auftritt. Es ist nur für eine endliche Anzahl von TCP/IP-Slots Platz vorhanden; deswegen sind zu wenig Ressourcen vorhanden, wenn Clients innerhalb kurzer Zeit zu viele neue TCP/IP-Verbindungen anfordern. Beispielsweise tritt dieser Fehler auf, wenn Sie den MySQL-Benchmark test-connect über TCP/IP ausführen.

Wir haben dieses Problem einige Male auf verschiedenen Linux-Mailinglisten beschrieben, konnten aber niemals eine geeignete Lösung finden. Der einzige bekannte „Fix“ besteht darin, dass Clients Permanentverbindungen verwenden oder Sie, wenn Sie den Datenbankserver und die Clients auf demselben Rechner ausführen, Verbindungen via Unix-Socketdatei statt TCP/IP-Verbindungen einsetzen.

2.13.1.3. Anmerkungen zur Linux-Quelldistribution

Die folgenden Anmerkungen zu glibc betreffen Sie nur, wenn Sie MySQL selbst erstellen. Wenn Sie Linux auf einem x86-Computer ausführen, sollten Sie in den meisten Fällen besser unsere Binärdistribution verwenden. Wir verknüpfen unsere Binärdateien zur jeweils am besten gepatchten Version von glibc, die wir finden können, und mit den bestmöglichen Compiler-Einstellungen, um sie so für hochbeanspruchte Server zu optimieren. Für normale Benutzer ist unsere Binärdistribution auch in Setups mit vielen gleichzeitigen Verbindungen oder Tabellen, die die 2-Gbyte-Grenze sprengen, in den meisten Fällen erste Wahl. Wenn Sie nach der Lektüre des folgenden Texts nicht genau wissen, wie Sie vorgehen sollen, probieren Sie zunächst unsere Binärdatei aus, um zu ermitteln, ob diese für Ihre Anforderungen geeignet ist. Sollten Sie feststellen, dass dies nicht der Fall ist, dann sollten Sie eine selbsterstellte Version erproben. In diesem Fall würden wir uns freuen, wenn Sie uns dies mitteilen würden, damit wir beim nächsten Mal eine bessere Binärdistribution erstellen können.

MySQL verwendet LinuxThreads unter Linux. Wenn Sie eine alte Linux-Version verwenden, die glibc2 nicht enthält, dann müssen Sie LinuxThreads installieren, bevor Sie MySQL zu kompilieren versuchen. LinuxThreads erhalten Sie unter http://dev.mysql.com/downloads/os-linux.html.

Beachten Sie, dass glibc-Versionen bis einschließlich 2.1.1 beim Umgang mit pthread_mutex_timedwait(), welches beim Absetzen von INSERT DELAYED-Anweisungen verwendet wird, einen schweren Bug aufweisen. Verwenden Sie INSERT DELAYED erst nach dem Upgrade von glibc.

Beachten Sie, dass der Linux-Kernel und die LinuxThread-Bibliothek standardmäßig maximal 1024 Threads verwalten können. Wenn Sie mehr als 1000 gleichzeitige Verbindungen vorsehen, dann müssen Sie wie folgt ein paar Änderungen an LinuxThreads vornehmen:

  • Erhöhen Sie den Wert PTHREAD_THREADS_MAX in sysdeps/unix/sysv/linux/bits/local_lim.h auf 4096 und verringern Sie STACK_SIZE in linuxthreads/internals.h auf 256 KB. Die Pfade sind relativ zum Stammverzeichnis von glibc. (Beachten Sie, dass MySQL bei 600 bis 1000 Verbindungen nicht stabil läuft, wenn STACK_SIZE auf der Vorgabe von 2 MB belassen wird.)

  • Kompilieren Sie LinuxThreads erneut, um eine neue libpthread.a-Bibliothek zu erzeugen, und verknüpfen Sie MySQL dann wieder damit.

Es gibt noch ein weiteres Problem, das die Leistung von MySQL insbesondere auf SMP-Systemen erheblich beeinträchtigt. glibc 2.1 weist eine sehr schwache Mutex-Implementierung in LinuxThreads für Programme mit vielen Threads auf, die das Mutex nur für eine kurze Zeit halten. Die Folgen sind paradox: Wenn Sie MySQL mit einer nicht modifizierten LinuxThreads-Version verbinden, können Sie die Leistung von MySQL in vielen Fällen verbessern, indem Sie Prozessoren aus dem SMP entfernen. Wir haben für glibc 2.1.3 unter http://dev.mysql.com/Downloads/Linux/linuxthreads-2.1-patch einen Patch bereitgestellt, der dieses Verhalten korrigiert.

Bei glibc 2.2.2 verwendet MySQL das adaptive Mutex, welches wesentlich besser ist als bei glibc 2.1.3 (auch in der gepatchten Version). Wir wollen aber darauf hinweisen, dass der aktuelle Mutex-Code in glibc 2.2.2 gelegentlich zu viel des Guten tut, wodurch die MySQL-Leistung wieder beeinträchtigt wird. Die Wahrscheinlichkeit, dass ein solches Verhalten auftritt, kann dadurch verringert werden, dass man dem Prozess mysqld die höchste Priorität zuweist. Wir konnten das Problem zudem ebenfalls mit einem Patch beheben, den Sie unter http://dev.mysql.com/Downloads/Linux/linuxthreads-2.2.2.patch finden. Dieser Patch korrigiert das Problem der Stack-Größe, die Thread-Beschränkung und das Mutex-Problem. Er muss im Verzeichnis linuxthreads mit patch -p0 </tmp/linuxthreads-2.2.2.patch angewendet werden. Wir hoffen, dass er in irgendeiner Form in zukünftigen Releases von glibc 2.2 enthalten sein wird. In jedem Fall müssen Sie bei der Verknüpfung mit glibc 2.2.2 STACK_SIZE und PTHREAD_THREADS_MAX korrigieren. Wir hoffen, dass die Standardeinstellungen in Zukunft auf Werte korrigiert werden, die für hoch beanspruchte MySQL Server geeigneter sind; in diesem Fall ließen sich die Befehle zur Erstellung eines eigenen Builds auf ./configure; make; make install beschränken.

Wenn Sie diese Patches zur Erstellung einer speziellen statischen Version von libpthread.a verwenden, sollten Sie sie nur für die statische Verknüpfung mit MySQL nutzen. Wir wissen, dass diese Patches in Verbindung mit MySQL einwandfrei funktionieren und die Leistungsfähigkeit erheblich verbessern, können jedoch nichts zu ihren Auswirkungen auf andere Anwendungen sagen. Wenn Sie andere Anwendungen verknüpfen, die LinuxThreads mit einer anderen als der gepatchten statischen Version der Bibliothek benötigen, oder eine gepatchte gemeinsame Version erstellen und diese auf Ihrem System installieren, dann tun Sie dies auf eigenes Risiko.

Sollten während der Installation von MySQL merkwürdige Probleme auftreten oder bestimmte gängige Hilfsprogramme stehen bleiben, dann ist dies mit hoher Wahrscheinlichkeit durch die Bibliothek oder den Compiler verursacht. Wenn dies der Fall ist, dann können Sie diese Probleme mithilfe unserer Binärdistribution lösen.

Wenn Sie eigene MySQL-Clientprogramme verknüpfen, dann wird unter Umständen die folgende Fehlermeldung zur Laufzeit angezeigt:

ld.so.1: fatal: libmysqlclient.so.#:
open failed: No such file or directory

Dieses Problem lässt sich auf eine der folgenden Weisen lösen:

  • Verknüpfen Sie die Clients mit dem Flag -Wl,r/full/path/to/libmysqlclient.so statt mit -Lpath.

  • Kopieren Sie libmysqclient.so nach /usr/lib.

  • Fügen Sie den Pfadnamen des Verzeichnisses, in dem sich libmysqlclient.so befindet, der Umgebungsvariablen LD_RUN_PATH hinzu, bevor Sie Ihren Client ausführen.

Wenn Sie den Fujitsu-Compiler (fcc/FCC) verwenden, treten unter Umständen Probleme bei der Kompilierung von MySQL auf, weil die Linux-Header-Dateien sehr stark auf gcc ausgerichtet sind. Der folgende configure-Befehl sollte auch für fcc/FCC funktionieren:

CC=fcc CFLAGS="-O -K fast -K lib -K omitfp -Kpreex -D_GNU_SOURCE \
    -DCONST=const -DNO_STRTOLL_PROTO" \
CXX=FCC CXXFLAGS="-O -K fast -K lib \
    -K omitfp -K preex --no_exceptions --no_rtti -D_GNU_SOURCE \
    -DCONST=const -Dalloca=__builtin_alloca -DNO_STRTOLL_PROTO \
    '-D_EXTERN_INLINE=static __inline'" \
./configure \
    --prefix=/usr/local/mysql --enable-assembler \
    --with-mysqld-ldflags=-all-static --disable-shared \
    --with-low-memory

2.13.1.4. Anmerkungen zu Linux: Installationsabschluss

mysql.server finden Sie im Verzeichnis support-files, das sich im MySQL-Installationsverzeichnis befindet, oder in einem MySQL-Source-Tree. Sie können es als /etc/init.d/mysql installieren, um MySQL automatisch zu starten und zu beenden. Siehe auch Abschnitt 2.11.2.2, „Automatisches Starten und Beenden von MySQL“.

Wenn MySQL nicht genügend Dateien oder Verbindungen öffnen kann, haben Sie Linux möglicherweise nicht so konfiguriert, dass es genug Dateien verwalten kann.

Unter Linux 2.2 und höher können Sie die Anzahl zugewiesener Datei-Handles wie folgt überprüfen:

shell> cat /proc/sys/fs/file-max
shell> cat /proc/sys/fs/dquot-max
shell> cat /proc/sys/fs/super-max

Wenn Sie mehr als 16 MB Speicher haben, sollten Sie Ihre Skripten durch einen Zusatz in der Art des folgenden ergänzen (z. B. /etc/init.d/boot.local unter SuSE Linux):

echo 65536 > /proc/sys/fs/file-max
echo 8192 > /proc/sys/fs/dquot-max
echo 1024 > /proc/sys/fs/super-max

Sie können die echo-Befehle auf der Befehlszeile auch als root ausführen, aber diese Einstellungen gehen beim nächsten Neustart Ihres Computers verloren.

Alternativ stellen Sie diese Parameter für den Start mithilfe des Tools sysctl ein, welches von vielen Linux-Distributionen (einschließlich SuSE Linux 8.0 und höher) verwendet wird. Tragen Sie die folgenden Werte in eine Datei namens /etc/sysctl.conf ein:

# Increase some values for MySQL
fs.file-max = 65536
fs.dquot-max = 8192
fs.super-max = 1024

Außerdem sollten Sie Folgendes in /etc/my.cnf ergänzen:

[mysqld_safe]
open-files-limit=8192

Auf diese Weise konfigurieren Sie für den Server eine Gesamtbeschränkung der Verbindungen und offenen Dateien auf 8192.

Die Konstante STACK_SIZE in LinuxThreads steuert das Spacing von Thread-Stapeln im Adressraum. Dieses muss groß genug sein, um genügend Raum für jeden einzelnen Thread-Stapel bereitzustellen, aber auch klein genug, um zu verhindern, dass der Stapel bestimmter Threads mit den globalen mysqld-Daten kollidiert. Leider trennt, wie wir durch Experimentieren festgestellt haben, die Linux-Implementierung von mmap() einen bereits zugeordneten Bereich wieder auf, wenn Sie sie anweisen, die Zuordnung einer derzeit verwendeten Adresse aufzulösen: Es wird kein Fehler zurückgegeben, sondern alle Daten auf der gesamten Seite werden auf null gesetzt. Insofern hängt die Sicherheit von mysqld und allen anderen Thread-basierten Anwendungen vom „wohlwollenden“ Verhalten des Codes ab, der die Threads erstellt. Der Benutzer muss Maßnahmen ergreifen, um sicherzustellen, dass die Anzahl laufender Threads jederzeit so niedrig ist, dass es nicht zum Konflikt zwischen den Thread-Stapeln und dem globalen Bereich kommt. Bei mysqld sollten Sie dieses Verhalten erzwingen, indem Sie der Variablen max_connections einen sinnvollen Wert zuweisen.

Wenn Sie MySQL selbst erstellen, können Sie LinuxThreads für eine bessere Stapelnutzung patchen. So bietet etwa die C-API eine Anzahl von Funktionsaufrufen, die eine API für vorbereitete Anweisungen darstellen. Siehe auch Abschnitt 2.13.1.3, „Anmerkungen zur Linux-Quelldistribution“. Wenn Sie LinuxThreads nicht patchen wollen, sollten Sie max_connections auf einen Wert setzen, der 500 nicht überschreitet. Arbeiten Sie mit einem großen Schlüsselpuffer, großen Heap-Tabellen oder anderen Materialien, die zu einer umfassenden Speicherzuweisung durch mysqld führen, oder verwenden Sie die Kernel-Version 2.2 mit einem 2-GB-Patch, dann sollte der Wert noch kleiner sein. Wenn Sie unsere Binär- oder RPM-Version verwenden, können Sie max_connections beruhigt auf 1500 setzen, sofern Sie weder große Schlüsselpuffer noch datenintensive Heap-Tabellen benutzen. Je stärker Sie STACK_SIZE in LinuxThreads verringern, desto mehr Threads können Sie gefahrlos erstellen. Wir empfehlen Werte zwischen 128 KB und 256 KB.

Wenn Sie zahlreiche nebenläufige Verbindungen verwenden, können Sie einem „Feature“ im Kernel 2.2 zum Opfer fallen, das Fork-Bomb-Angriffe verhindern soll, indem Prozesse, die untergeordnete Prozesse aufspalten oder klonen, eine Strafe erhalten. Hierdurch wird die Skalierbarkeit zunehmend beeinträchtigt, je größer die Anzahl nebenläufiger Clients ist. Auf Systemen mit nur einem Prozessor manifestiert sich dies unseren Beobachtungen zufolge in einer sehr langsamen Thread-Erstellung: Die Verbindungsherstellung mit MySQL kann sehr lange (bis zu einer Minute) dauern; Gleiches gilt für das Abbauen der Verbindung. Auf Multiprozessorsystemen haben wir bei steigender Clientanzahl eine allmähliche Abnahme der Abfragegeschwindigkeit feststellen können. Im Zuge der Lösung dieses Problems haben wir von einem unserer Benutzer einen Kernel-Patch erhalten, der seinen Angaben zufolge auf seiner Site geholfen haben soll. Dieser Patch ist unter http://dev.mysql.com/Downloads/Patches/linux-fork.patch verfügbar. Wir haben den Patch sowohl in Entwicklungs- als auch in Produktionssystemen umfassend getestet und festgestellt, dass sich die MySQL-Performance hierdurch erheblich verbessert, ohne dass es zu Problemen kommt. Deswegen empfehlen wir Benutzern, die hoch beanspruchte Server mit Kernel-Version 2.2 betreiben, seine Anwendung.

In der Kernel-Version 2.4 wurde das Problem behoben; wenn Sie also nicht mit der aktuellen Leistung Ihres System zufrieden sind, ist es unter Umständen einfacher, ein Upgrade auf Version 2.4 durchzuführen, statt Ihren 2.2-Kernel zu patchen. Auf SMP-Systemen erhalten Sie neben der Problembehandlung zusätzlich noch eine beträchtliche SMP-Steigerung.

Wir haben MySQL mit dem Kernel 2.4 auf einem System mit zwei Prozessoren getestet und festgestellt, dass sich MySQL wesentlich besser skalieren lässt. Es gab im gesamten Testbereich bis 1000 Clients praktisch keine Verringerung des Abfragedurchsatzes, und der MySQL-Skalierungsfaktor (berechnet als Verhältnis des maximalen Durchsatzes zum Durchsatz pro Client) lag bei 180 %. Ähnliche Ergebnisse konnten wir auf einem System mit vier CPUs beobachten: praktisch keine Verlangsamung, während die Anzahl der Clients auf bis zu 1000 erhöht wurde, und dazu ein Skalierungsfaktor von 300 %. Basierend auf diesen Ergebnissen empfehlen wir für hoch beanspruchte SMP-Server mit dem Kernel 2.2 derzeit in jedem Fall eine Aktualisierung auf Kernel 2.4.

Unseren Beobachtungen zufolge ist es unumgänglich, den Prozess mysqld unter dem Kernel 2.4 mit höchstmöglicher Priorität auszuführen, um maximale Leistung zu erzielen. Dies ist möglich, indem der Befehl renice -20 $$ zu mysqld_safe hinzugefügt wird. Bei unseren Tests mit einem 4-CPU-Rechner haben wir eine 60-prozentige Durchsatzsteigerung bei 400 Clients erzielt.

Ferner versuchen wir derzeit auch, weitere Informationen dazu zu sammeln, wie gut MySQL mit dem Kernel 2.4 auf 4-Wege- und 8-Wege-Systemen funktioniert. Wenn Sie Zugang zu einem solchen System haben und einige Benchmarks erstellt haben, möchten wir Sie bitten, eine E-Mail mit den Ergebnissen an zu senden. Wir werden diese prüfen und ggf. in das Handbuch aufnehmen.

Wenn Sie einen abgestürzten mysqld-Serverprozess mit ps erkennen, dann weist dies normalerweise darauf hin, dass Sie einen Bug in MySQL entdeckt haben oder eine Tabelle beschädigt ist. Siehe auch What to Do If MySQL Keeps Crashing.

Um, wenn mysqld mit einem SIGSEGV-Signal abstürzt, unter Linux einen Speicherauszug zu erhalten, können Sie mysqld mit der Option --core-file starten. Beachten Sie, dass Sie wahrscheinlich auch die Größe der Speicherauszugsdatei erhöhen müssen, indem Sie ulimit -c 1000000 zu mysqld_safe hinzufügen oder mysqld_safe mit --core-file-size=1000000 starten. Siehe auch mysqld_safe.

2.13.1.5. Anmerkungen zu Linux x86

MySQL erfordert libc 5.4.12 oder höher. Bekanntermaßen funktioniert es mit libc 5.4.46. glibc 2.0.6 und höher sollten ebenfalls keine Probleme bereiten. Es hat in der Vergangenheit einige Probleme mit den glibc-RPMs von Red Hat gegeben. Prüfen Sie also bei Auftreten von Problemen, ob Updates vorhanden sind. Die glibc-RPMs 2.0.7-19 und 2.0.7-29 RPMs funktionieren ebenfalls einwandfrei.

Wenn Sie Red Hat 8.0 oder eine neue glibc 2.2.x-Bibliothek verwenden, werden Sie unter Umständen feststellen, dass sich mysqld in gethostbyaddr() aufhängt. Dies geschieht, weil die neue glibc-Bibliothek eine Stapelgröße von mehr als 128 Kbyte für diesen Aufruf benötigt. Um das Problem zu beheben, starten Sie mysqld mit der Option --thread-stack=192K. (Verwenden Sie -O thread_stack=192K bei MySQL vor Version 4.) Diese Stapelgröße ist bei MySQL 4.0.10 und höher voreingestellt, weswegen das Problem bei diesen Versionen nicht auftreten sollte.

Wenn Sie zur Kompilierung von MySQL gcc 3.0 und höher verwenden, müssen Sie die Bibliothek libstdc++v3 vor der MySQL-Kompilierung installieren, da Sie anderenfalls bei der Verknüpfung eine Fehlermeldung zu einem fehlenden __cxa_pure_virtual-Symbol erhalten.

Bei einigen älteren Linux-Distributionen erzeugt configure unter Umständen einen Fehler wie den folgenden:

Syntax error in sched.h. Change _P to __P in the
/usr/include/sched.h file.
See the Installation chapter in the Reference Manual.

Tun Sie einfach, was die Fehlermeldung vorschlägt: Ergänzen Sie den Makronamen _P, der nur einen Unterstrich aufweist, um einen weiteren Unterstrich und probieren Sie es dann erneut.

Bei der Kompilierung werden unter Umständen Warnungen angezeigt. Die folgenden können dabei ignoriert werden:

mysqld.cc -o objs-thread/mysqld.o
mysqld.cc: In function `void init_signals()':
mysqld.cc:315: warning: assignment of negative value `-1' to
`long unsigned int'
mysqld.cc: In function `void * signal_hand(void *)':
mysqld.cc:346: warning: assignment of negative value `-1' to
`long unsigned int'

Wenn mysqld beim Start immer einen Speicherauszug erzeugt, kann dies möglicherweise durch eine veraltete /lib/libc.a verursacht worden sein. Versuchen Sie sie umzubenennen, entfernen Sie sql/mysqld, führen Sie ein neues make install durch und probieren Sie es dann erneut. Dieses Problem wurde für einige Slackware-Installationen gemeldet.

Wenn Sie die folgende Fehlermeldung beim Verknüpfen von mysqld erhalten, ist Ihre libg++.a nicht korrekt installiert:

/usr/lib/libc.a(putc.o): In function `_IO_putc':
putc.o(.text+0x0): multiple definition of `_IO_putc'

Sie können die Verwendung von libg++.a vermeiden, indem Sie configure wie folgt ausführen:

shell> CXX=gcc ./configure

2.13.1.6. Anmerkungen zu Linux SPARC

Bei einigen Implementierungen ist readdir_r() fehlerhaft. Das Symptom besteht darin, dass die SHOW DATABASES-Anweisung immer eine leere Menge zurückgibt. Dies lässt sich durch Entfernen von HAVE_READDIR_R aus der Datei config.h nach der Konfiguration, aber vor der Kompilierung durchführen.

2.13.1.7. Anmerkungen zu Linux Alpha

Wir haben MySQL 5.1 unter Linux Alpha mit unseren Benchmarks und unserer Testsuite getestet, und es scheint gut zu funktionieren.

Derzeit erstellen wir die MySQL-Binärpakete unter SuSE Linux 7.0 für AXP, Kernel 2.4.4-SMP, Compaq C-Compiler (V6.2-505) und Compaq C++-Compiler (V6.3-006) auf einem Compaq DS20-Computer mit einem Alpha EV6-Prozessor.

Sie finden die genannten Compiler unter http://www.support.compaq.com/alpha-tools/. Durch Verwendung dieser Compiler anstelle von gcc erhalten wir eine um ca. 9 bis 14 % bessere Leistung von MySQL.

Bei MySQL unter Alpha verwenden wir das Flag -arch generic für unsere Kompilierungsoptionen. Hierdurch ist sichergestellt, dass die Binärdatei auf allen Alpha-Prozessoren läuft. Wir kompilieren auch statisch, um Probleme mit Bibliotheken zu vermeiden. Der configure-Befehl sieht wie folgt aus:

CC=ccc CFLAGS="-fast -arch generic" CXX=cxx \
CXXFLAGS="-fast -arch generic -noexceptions -nortti" \
./configure --prefix=/usr/local/mysql --disable-shared \
    --with-extra-charsets=complex --enable-thread-safe-client \
    --with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shared

Es gibt ein paar bekannte Probleme bei der Ausführung von MySQL unter Linux-Alpha:

  • Das Debugging von Thread-basierten Anwendungen wie MySQL funktioniert mit gdb 4.18 nicht. Verwenden Sie stattdessen gdb 5.1.

  • Wenn Sie versuchen, mysqld bei der Verwendung von gcc statisch zu verknüpfen, dann tritt beim Start des resultierenden Images ein Speicherauszug auf. Anders gesagt: Verwenden Sie keinesfalls --with-mysqld-ldflags=-all-static mit gcc.

2.13.1.8. Anmerkungen zu Linux PowerPC

MySQL sollte auf MkLinux mit dem neuesten glibc-Paket funktionieren (getestet mit glibc 2.0.7).

2.13.1.9. Anmerkungen zu Linux MIPS

Um MySQL auf Qube2 (Linux Mips) zum Laufen zu bringen, benötigen Sie die neuesten glibc-Bibliotheken. glibc-2.0.7-29C2 funktioniert bekanntermaßen. Sie müssen ferner gcc 2.95.2 oder höher verwenden.

2.13.1.10. Anmerkungen zu Linux IA-64

Um MySQL unter Linux IA-64 kompilieren zu können, verwenden wir den folgenden configure-Befehl zur Erstellung mit gcc 2.96:

CC=gcc \
CFLAGS="-O3 -fno-omit-frame-pointer" \
CXX=gcc \
CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors \
    -fno-exceptions -fno-rtti" \
    ./configure --prefix=/usr/local/mysql \
    "--with-comment=Official MySQL binary" \
    --with-extra-charsets=complex

Unter IA-64 verwenden die MySQL-Clientbinärdateien gemeinsame Bibliotheken. Das bedeutet, dass Sie, wenn Sie unsere Binärdistribution in einem anderen Verzeichnis als /usr/local/mysql installieren, den Pfad des Verzeichnisses, in dem libmysqlclient.so installiert ist, entweder der Datei /etc/ld.so.conf oder dem Wert der Umgebungsvariablen LD_LIBRARY_PATH hinzufügen müssen.

Siehe auch Problems Linking to the MySQL Client Library.

2.13.1.11. Anmerkungen zu SELinux

RHEL4 verfügt über SELinux, das eine strengere Zugriffskontrolle für Prozesse unterstützt. Wenn SELinux aktiviert ist (SELINUX wurde in /etc/selinux/config auf enforcing gesetzt, SELINUXTYPE wurde entweder auf targeted oder strict gesetzt), können Probleme bei der Installation von PRM-Paketen von Sun Microsystems, Inc. auftreten.

Für Red Hat gibt es ein Update, das dieses Problem behebt. Dabei handelt es sich um ein Update der „security policy“-Spezifikation für die Verarbeitung der Installationsstruktur der von Sun Microsystems, Inc. bereitgestellten RPMs. Weitere Informationen finden Sie unter https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=167551 und http://rhn.redhat.com/errata/RHBA-2006-0049.html.

Die obige Diskussion bezieht sich ausschließlich auf RHEL4. Bei RHEL5 ist der Patch nicht notwendig.

2.13.2. Anmerkungen zu Mac OS X

Unter Mac OS X kann tar lange Dateinamen nicht verarbeiten. Wenn Sie eine .tar.gz-Distribution entpacken müssen, verwenden Sie stattdessen gnutar. Mac OS X 10.x (Darwin)

2.13.2.1. Mac OS X 10.x (Darwin)

MySQL sollte unter Mac OS X 10.x (Darwin) ohne größere Probleme funktionieren.

Die folgenden Probleme sind bekannt:

  • Sollten Leistungsprobleme unter starker Belastung auftreten, dann probieren Sie die Option --skip-thread-priority für mysqld. Hierdurch werden alle Threads mit derselben Priorität ausgeführt. Unter Mac OS X können Sie auf diese Weise die Leistung verbessern – zumindest so lange, bis Apple den Thread-Scheduler in Ordnung bringt.

  • Die Verbindungszeiten (wait_timeout, interactive_timeout und net_read_timeout) werden nicht beachtet.

    Dies ist wahrscheinlich ein Signalverwaltungsproblem in der Thread-Bibliothek, wo das Signal eine anhängige Leseoperation nicht unterbricht. Wir hoffen, dass ein künftiges Update der Thread-Bibliotheken dieses Problem beheben wird.

Unsere Binärdatei für Mac OS X wird unter Darwin 6.3 mit der folgenden configure-Zeile kompiliert:

CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc \
CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors \
    -fno-exceptions -fno-rtti" \
    ./configure --prefix=/usr/local/mysql \
    --with-extra-charsets=complex --enable-thread-safe-client \
    --enable-local-infile --disable-shared

Siehe auch Abschnitt 2.5, „Installieren von MySQL unter Mac OS X“.

2.13.2.2. Mac OS X Server 1.2 (Rhapsody)

Bei aktuellen Versionen von Mac OS X Server sind vor der Kompilierung keine Betriebssystemänderungen erforderlich. Die Kompilierung für die Serverplattform ist mit der für die Clientversion von Mac OS X identisch.

Bei älteren Versionen (Mac OS X Server 1.2, auch bekannt als ?Rhapsody“) müssen Sie zunächst ein pthread-Paket installieren, bevor Sie MySQL konfigurieren können.

Siehe auch Abschnitt 2.5, „Installieren von MySQL unter Mac OS X“.

2.13.3. Anmerkungen zu Solaris

Informationen zur Installation von MySQL unter Solaris mithilfe von PKG-Distributionen finden Sie in Abschnitt 2.6, „Installieren von MySQL unter Solaris“.

Unter Solaris haben Sie möglicherweise schon die ersten Probleme, bevor Sie die MySQL-Distribution überhaupt entpacken können, denn tar unter Solaris kann mit langen Dateinamen nicht umgehen. Dies bedeutet, dass Ihnen unter Umständen Fehler angezeigt werden, wenn Sie MySQL entpacken.

In diesem Fall müssen Sie GNU tar (gtar) zum Entpacken der Distribution verwenden.

Native Sun-Threads funktionieren erst ab Solaris 2.5. Bis Solaris 2.4 verwendet MySQL automatisch MIT-pthreads. Siehe auch Abschnitt 2.10.5, „Anmerkungen zu MIT-pthreads“.

Wenn die folgende Fehlermeldung bei Ausführung von configure angezeigt wird, stimmt etwas mit Ihrer Compiler-Installation nicht:

checking for restartable system calls... configure: error can not
run test programs while cross compiling

In diesem Fall sollten Sie den Compiler auf eine neuere Version aktualisieren. Sie können das Problem möglicherweise auch beheben, indem Sie die folgende Zeile in die Datei config.cache einfügen:

ac_cv_sys_restartable_syscalls=${ac_cv_sys_restartable_syscalls='no'}

Wenn Sie Solaris auf einem SPARC-System verwenden, wird gcc 2.95.2 oder 3.2 als Compiler empfohlen. Sie finden ihn unter http://gcc.gnu.org/. Beachten Sie, dass gcc 2.8.1 auf SPARC nicht zuverlässig arbeitet.

Die empfohlene configure-Zeile sieht bei Verwendung von gcc 2.95.2 wie folgt aus:

CC=gcc CFLAGS="-O3" \
CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti" \
./configure --prefix=/usr/local/mysql --with-low-memory \
    --enable-assembler

Bei Verwendung eines UltraSPARC-Systems erhalten Sie eine um 4 % bessere Leistung, wenn Sie -mcpu=v8 -Wa,-xarch=v8plusa zu den Umgebungsvariablen CFLAGS und CXXFLAGS hinzufügen.

Wenn Sie den Forte-Compiler 5.0 oder höher von Sun einsetzen, können Sie configure wie folgt ausführen:

CC=cc CFLAGS="-Xa -fast -native -xstrconst -mt" \
CXX=CC CXXFLAGS="-noex -mt" \
./configure --prefix=/usr/local/mysql --enable-assembler

Um eine 64-Bit-Binärdatei mit Sun Forte zu erstellen, verwenden Sie die folgenden Konfigurationsoptionen:

CC=cc CFLAGS="-Xa -fast -native -xstrconst -mt -xarch=v9" \
CXX=CC CXXFLAGS="-noex -mt -xarch=v9" ASFLAGS="-xarch=v9" \
./configure --prefix=/usr/local/mysql --enable-assembler

Wenn Sie eine 64-Bit-Solaris-Binärdatei mit gcc erstellen wollen, ergänzen Sie -m64 in CFLAGS und CXXFLAGS und entfernen Sie --enable-assembler aus der configure-Zeile.

In den MySQL-Benchmarks erhielten wir auf UltraSPARC bei der Verwendung von Forte 5.0 im 32-Bit-Modus im Vergleich zu gcc 3.2 mit dem Flag -mcpu einen Geschwindigkeitszuwachs von 4 Prozent.

Wenn Sie eine 64-Bit-mysqld-Binärdatei erstellen, ist diese um 4 Prozent langsamer als die 32-Bit-Binärdatei, kann aber mehr Threads und Speicher verwalten.

Wenn Sie Solaris 10 für x86_64 einsetzen, sollten Sie alle Dateisysteme einbinden, auf denen Sie InnoDB-Dateien mit der Option forcedirectio speichern wollen. (Standardmäßig erfolgt die Einbindung ohne diese Option.) Andernfalls entsteht ein erheblicher Leistungseinbruch, wenn die InnoDB-Speicher-Engine auf dieser Plattform verwendet wird.

Wenn Sie auf ein Problem mit fdatasync oder sched_yield stoßen, können Sie es beheben, indem Sie LIBS=-lrt zur configure-Zeile hinzufügen.

Bei Versionen des WorkShop-Compilers vor 5.3 müssen Sie eventuell das Skript configure bearbeiten. Die Zeile

#if !defined(__STDC__) || __STDC__ != 1

ändern Sie wie folgt:

#if !defined(__STDC__)

Wenn Sie __STDC__ mit der Option -Xc aktivieren, kann der Sun-Compiler keine Kompilierung mit der pthread.h-Header-Datei von Solaris durchführen. Dies ist ein Sun-spezifischer Bug (beschädigter Compiler oder beschädigte Include-Datei).

Wenn mysqld die folgende Fehlermeldung bei der Ausführung ausgibt, haben Sie versucht, MySQL mit dem Sun-Compiler zu kompilieren, ohne die Multithread-Option -mt zu aktivieren:

libc internal error: _rmutex_unlock: rmutex not held

Fügen Sie -mt zu CFLAGS und CXXFLAGS hinzu und kompilieren Sie neu.

Wenn Sie die SFW-Version von gcc verwenden (in Solaris 8 enthalten), dann müssen Sie /opt/sfw/lib zur Umgebungsvariablen LD_LIBRARY_PATH hinzufügen, bevor Sie configure ausführen.

Verwenden Sie das auf sunfreeware.com verfügbare gcc, dann werden Sie eine Menge Probleme haben. Um dies zu vermeiden, sollten Sie gcc und GNU binutils auf dem Computer kompilieren, auf dem sie auch ausgeführt werden sollen.

Wenn Sie bei der Kompilierung von MySQL mit gcc folgende Fehlermeldung erhalten, ist Ihr gcc nicht für Ihre Solaris-Version konfiguriert:

shell> gcc -O3 -g -O2 -DDBUG_OFF  -o thr_alarm ...
./thr_alarm.c: In function `signal_hand':
./thr_alarm.c:556: too many arguments to function `sigwait'

In diesem Fall besteht die richtige Lösung einzig und allein darin, sich die neueste Version von gcc zu besorgen und sie mit Ihrem aktuellen gcc-Compiler zu kompilieren. Zumindest bei Solaris 2.5 enthalten praktisch alle Binärversionen von gcc alte, unbrauchbare Include-Dateien, die Thread-basierte (und wohl auch weitere) Programme beschädigen.

Solaris bietet keine statischen Versionen aller Systembibliotheken (libpthreads und libdl) an, d. h., Sie können MySQL nicht mit --static kompilieren. Wenn Sie es dennoch versuchen, erhalten Sie eine der folgenden Fehlermeldungen:

ld: fatal: library -ldl: not found
undefined reference to `dlopen'
cannot find -lrt

Wenn Sie eigene MySQL-Clientprogramme verknüpfen, dann wird unter Umständen die folgende Fehlermeldung zur Laufzeit angezeigt:

ld.so.1: fatal: libmysqlclient.so.#:
open failed: No such file or directory

Dieses Problem lässt sich auf eine der folgenden Weisen lösen:

  • Verknüpfen Sie die Clients mit dem Flag -Wl,r/full/path/to/libmysqlclient.so statt mit -Lpath.

  • Kopieren Sie libmysqclient.so nach /usr/lib.

  • Fügen Sie den Pfadnamen des Verzeichnisses, in dem sich libmysqlclient.so befindet, der Umgebungsvariablen LD_RUN_PATH hinzu, bevor Sie Ihren Client ausführen.

Wenn Sie Probleme haben, configure mit -lz zu verknüpfen, weil zlib nicht installiert ist, dann haben Sie zwei Möglichkeiten:

  • Wenn Sie das komprimierte Kommunikationsprotokoll einsetzen können wollen, müssen Sie zlib bei ftp.gnu.org herunterladen und installieren.

  • Sie führen configure mit der Option --with-named-z-libs=no aus, wenn Sie MySQL erstellen.

Wenn Sie gcc verwenden und Probleme beim Einladen von UDFs (User-Defined Functions, benutzerdefinierte Funktionen) in MySQL haben, ergänzen Sie die Verknüpfungszeile für die UDF um -lgcc.

Wollen Sie, dass MySQL automatisch startet, dann können Sie support-files/mysql.server in das Verzeichnis /etc/init.d kopieren und eine symbolische Verknüpfung namens /etc/rc3.d/S99mysql.server zu ihr erstellen.

Wenn zu viele Prozesse innerhalb kurzer Zeit eine Verbindung mit mysqld herstellen wollen, werden Sie die folgende Fehlermeldung im MySQL-Log finden:

Error in accept: Protocol error

Dieses Problem können Sie unter Umständen beheben, indem Sie den Server mit der Option --back_log=50 starten. (Bei MySQL vor Version 4 verwenden Sie -O back_log=50.)

Solaris unterstützt Core-Dateien für setuid()-Anwendungen nicht, d. h., Sie können keine Core-Datei von mysqld erhalten, wenn Sie die Option --user verwenden.

2.13.3.1. Anmerkungen zu Solaris 2.7/2.8

Normalerweise können Sie eine Binärdatei für Solaris 2.6 auch unter Solaris 2.7 und 2.8 verwenden. Auch betreffen Probleme, die für Solaris 2.6 gelistet sind, meist ebenfalls Solaris 2.7 und 2.8.

MySQL sollte neue Versionen von Solaris automatisch erkennen können und für die im Folgenden beschriebenen Probleme Workarounds aktivieren.

Solaris 2.7 und 2.8 haben einige Bugs bei den Include-Dateien. Bei Verwendung von gcc erhalten Sie unter Umständen folgende Fehlermeldung:

/usr/include/widec.h:42: warning: `getwc' redefined
/usr/include/wchar.h:326: warning: this is the location of the previous
definition

In diesem Fall können Sie das Problem beheben, indem Sie /usr/include/widec.h nach .../lib/gcc-lib/os/gcc-version/include kopieren. Die Zeile 41

#if     !defined(lint) && !defined(__lint)

ändern Sie wie folgt:

#if     !defined(lint) && !defined(__lint) && !defined(getwc)

Alternativ können Sie /usr/include/widec.h auch direkt editieren. Wenn Sie das Problem auf eine der beschriebenen Weisen behoben haben, sollten Sie config.cache entfernen und configure erneut ausführen.

Wenn Sie bei der Ausführung von make die folgenden Fehlermeldungen erhalten, liegt das daran, dass configure die Datei curses.h nicht erkannt hat (wahrscheinlich aufgrund des Fehlers in /usr/include/widec.h):

In file included from mysql.cc:50:
/usr/include/term.h:1060: syntax error before `,'
/usr/include/term.h:1081: syntax error before `;'

Dieses Problem lässt sich auf mehreren Wegen lösen:

  1. Konfigurieren Sie mit CFLAGS=-DHAVE_CURSES_H CXXFLAGS=-DHAVE_CURSES_H ./configure.

  2. Bearbeiten Sie /usr/include/widec.h wie im vorherigen Abschnitt beschrieben und führen Sie configure erneut aus.

  3. Entfernen Sie die Zeile #define HAVE_TERM aus der Datei config.h und führen Sie make erneut aus.

Wenn Ihr Linker beim Verknüpfen von Clientprogrammen -lz nicht finden kann, besteht das Problem wahrscheinlich darin, dass Ihre Datei libz.so in /usr/local/lib installiert ist. Dieses Problem lässt sich auf eine der folgenden Weisen lösen:

  • Fügen Sie /usr/local/lib zu LD_LIBRARY_PATH hinzu.

  • Fügen Sie von /lib aus eine Verknüpfung zu libz.so hinzu.

  • Wenn Sie Solaris 8 verwenden, können Sie die optionale zlib von Ihrer Solaris 8-Distributions-CD installieren.

  • Sie führen configure mit der Option --with-named-z-libs=no aus, wenn Sie MySQL erstellen.

2.13.3.2. Anmerkungen zu Solaris x86

Unter Solaris 8 auf x86 erzeugt mysqld einen Speicherauszug, wenn Sie die Debugsymbole mithilfe von strip entfernen.

Wenn Sie gcc unter Solaris x86 verwenden und bei hoher Belastung Probleme mit Speicherauszügen haben, sollten Sie folgenden configure-Befehl verwenden:

CC=gcc CFLAGS="-O3 -fomit-frame-pointer -DHAVE_CURSES_H" \
CXX=gcc \
CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors \
    -fno-exceptions -fno-rtti -DHAVE_CURSES_H" \
./configure --prefix=/usr/local/mysql

Hierdurch vermeiden Sie Probleme mit der Bibliothek libstdc++ und mit C++-Ausnahmefehlern.

Sollte dies nicht helfen, dann sollten Sie eine Debugversion kompilieren und diese mit einer Trace-Datei oder unter gdb ausführen. Siehe auch MySQL Internals: Porting.

2.13.4. Anmerkungen zu BSD

In diesem Abschnitt erhalten Sie Informationen zur Verwendung von MySQL unter Varianten von BSD Unix.

2.13.4.1. Anmerkungen zu FreeBSD

Anmerkungen zu FreeBSD FreeBSD 4.x oder neuer wird für die Ausführung von MySQL empfohlen, da das Thread-Paket wesentlich besser integriert ist. Um ein sicheres und stabiles System zu erhalten, sollten Sie nur FreeBSD-Kernels verwenden, die mit -RELEASE gekennzeichnet sind.

Die einfachste (und deshalb empfohlene) Vorgehensweise zur Installation von MySQL besteht in der Verwendung der Ports mysql-server und mysql-client, die unter http://www.freebsd.org/ verfügbar sind. Die Verwendung dieser Ports hat die folgenden Vorteile:

  • Sie erhalten ein funktionsfähiges MySQL, bei dem alle Optimierungen, die unter Ihrer FreeBSD-Version bekanntermaßen funktionieren, bereits aktiviert sind.

  • Konfiguration und Erstellung werden automatisch durchgeführt.

  • Startskripten sind in /usr/local/etc/rc.d installiert.

  • Sie können mit pkg_info -L überprüfen, welche Dateien installiert sind.

  • Sie können ferner mit pkg_delete MySQL entfernen, wenn Sie es auf Ihrem Rechner nicht mehr benötigen.

Wir empfehlen die Verwendung von MIT-pthreads unter FreeBSD 2.x und von nativen Threads unter FreeBSD 3 und höher. Zwar können auch spätere Versionen von Release 2.2.x mit nativen Threads betrieben werden, aber dann kann es zu Problemen beim Herunterfahren von mysqld kommen.

Leider sind bestimmte Funktionsaufrufe unter FreeBSD noch nicht vollständig Thread-sicher. Dies betrifft vor allem die Funktion gethostbyname(), die von MySQL zur Umwandlung von Hostnamen in IP-Adressen verwendet wird. Unter bestimmten Umständen verursacht der Prozess mysqld unvermittelt eine Prozessorauslastung von 100 Prozent und reagiert nicht mehr. Wenn dieses Problem auftritt, versuchen Sie MySQL mit der Option --skip-name-resolve zu starten.

Alternativ können Sie MySQL unter FreeBSD 4.x mit der LinuxThreads-Bibliothek verknüpfen, wodurch einige der Probleme vermieden werden, die die native Thread-Implementierung von FreeBSD hat. Einen sehr guten Vergleich von LinuxThreads und nativen Threads finden Sie in Jeremy Zawodnys Artikel FreeBSD or Linux for your MySQL Server? unter http://jeremy.zawodny.com/blog/archives/000697.html.

Es gibt ein bekanntes Problem bei der Verwendung von LinuxThreads unter FreeBSD:

  • Die Verbindungszeiten (wait_timeout, interactive_timeout und net_read_timeout) werden nicht beachtet. Auffälliges Symptom ist, dass Permanentverbindungen für eine sehr lange Zeit hängen, ohne abgebaut zu werden, und dass eine Terminierung des Threads erst Erfolg hat, wenn der Thread einem neuen Befehl zugeordnet wird.

    Dies ist wahrscheinlich ein Signalverwaltungsproblem in der Thread-Bibliothek, wo das Signal eine anhängige Leseoperation nicht unterbricht. Das Problem wird voraussichtlich in FreeBSD 5.0 behoben.

Damit der MySQL-Erstellungsprozess funktioniert, ist GNU make (gmake) erforderlich. Wenn GNU make nicht vorhanden ist, müssen Sie es vor der Kompilierung von MySQL installieren.

Die empfohlene Vorgehensweise zur Kompilierung und Installation von MySQL unter FreeBSD mit gcc (2.95.2 und höher) ist die folgende:

CC=gcc CFLAGS="-O2 -fno-strength-reduce" \
    CXX=gcc CXXFLAGS="-O2 -fno-rtti -fno-exceptions \
    -felide-constructors -fno-strength-reduce" \
    ./configure --prefix=/usr/local/mysql --enable-assembler
gmake
gmake install
cd /usr/local/mysql
bin/mysql_install_db --user=mysql
bin/mysqld_safe &

Wenn Sie feststellen, dass configure MIT-pthreads verwendet, lesen Sie die Anmerkungen zu MIT-pthreads. Siehe auch Abschnitt 2.10.5, „Anmerkungen zu MIT-pthreads“.

Wenn make install die Fehlermeldung ausgibt, dass es /usr/include/pthreads nicht finden kann, dann hat configure nicht erkannt, dass Sie MIT-pthreads benötigen. Um dieses Problem zu beheben, entfernen Sie config.cache und führen configure dann erneut mit der Option --with-mit-threads aus.

Achten Sie darauf, dass Ihre Namensauflösung korrekt ist. Andernfalls werden Verzögerungen oder Fehler bei der Auflösung auftreten, wenn Sie die Verbindung mit mysqld herzustellen versuchen. Ferner müssen Sie sicherstellen, dass der Eintrag localhost in der Datei /etc/hosts korrekt ist. Am Anfang der Datei sollte eine Zeile ähnlich der folgenden stehen:

127.0.0.1       localhost localhost.your.domain

FreeBSD hat bekanntermaßen einen sehr niedrigen Standardwert für Datei-Handles. So bietet etwa die C-API eine Anzahl von Funktionsaufrufen, die eine API für vorbereitete Anweisungen darstellen. Siehe auch 'File' Not Found and Similar Errors. Starten Sie den Server unter Verwendung der Option --open-files-limit für mysqld_safe oder heben Sie den Wert für den Benutzer mysqld in /etc/login.conf an und erstellen Sie die Datei dann mit cap_mkdb /etc/login.conf neu. Achten Sie außerdem darauf, die passende Klasse für diesen Benutzer in der Passwortdatei zu konfigurieren, sofern Sie die Vorgabe nicht verwenden (benutzen Sie chpass mysqld-user-name). Siehe auch mysqld_safe.

FreeBSD beschränkt die Größe eines Prozesses auch dann auf 512 Mbyte, wenn auf Ihrem System wesentlich mehr Arbeitsspeicher vorhanden ist. Insofern kann ein Fehler wie der folgende auftreten:

Out of memory (Needed 16391 bytes)

Bei den aktuellen Versionen von FreeBSD (mindestens seit 4.x) können Sie den Grenzwert auch anheben, indem Sie die folgenden Einträge in der Datei /boot/loader.conf hinzufügen und den Computer neu starten (diese Einstellungen lassen sich nicht zur Laufzeit mit dem Befehl sysctl ändern):

kern.maxdsiz="1073741824" # 1GB
kern.dfldsiz="1073741824" # 1GB
kern.maxssiz="134217728" # 128MB

Bei älteren FreeBSD-Versionen müssen Sie Ihren Kernel neu kompilieren, um die maximale Datensegmentgröße für einen Prozess zu ändern. In diesem Fall sollten Sie sich die Option MAXDSIZ in der Konfigurationsdatei LINT näher ansehen, um weitere Informationen zu erhalten.

Wenn es Probleme mit dem aktuellen Daten in MySQL gibt, sollte eine Einstellung der Variablen TZ Abhilfe leisten können. Siehe auch Abschnitt 2.14, „Umgebungsvariablen“.

2.13.4.2. Anmerkungen zu NetBSD

Zur Kompilierung unter NetBSD benötigen Sie GNU make. Andernfalls schlägt der Erstellungsprozess fehl, wenn make versucht, lint für C++-Dateien auszuführen. Anmerkungen zu OpenBSD

2.13.4.3. Anmerkungen zu OpenBSD 2.5

Unter OpenBSD 2.5 können Sie MySQL mit nativen Threads kompilieren. Hierzu verwenden Sie die folgenden Optionen:

CFLAGS=-pthread CXXFLAGS=-pthread ./configure --with-mit-threads=no

2.13.4.4. Anmerkungen zu BSD/OS Version 2.x

Anmerkungen zu BSD/OS Wenn Sie die folgende Fehlermeldung bei der Kompilierung von MySQL erhalten, ist der Wert ulimit für den virtuellen Speicher auf Ihrem System zu niedrig:

item_func.h: In method
`Item_func_ge::Item_func_ge(const Item_func_ge &)':
item_func.h:28: virtual memory exhausted
make[2]: *** [item_func.o] Error 1

Verwenden Sie beispielsweise ulimit -v 80000 und führen Sie make erneut aus. Funktioniert dies nicht und Sie verwenden bash, dann probieren Sie stattdessen csh oder sh aus. Einige BSDI-Benutzer haben Probleme mit bash und ulimit gemeldet.

Wenn Sie gcc einsetzen, müssen Sie unter Umständen auch das Flag --with-low-memory verwenden, damit configure sql_yacc.cc kompilieren kann.

Wenn es Probleme mit dem aktuellen Daten in MySQL gibt, sollte eine Einstellung der Variablen TZ Abhilfe leisten können. Siehe auch Abschnitt 2.14, „Umgebungsvariablen“.

2.13.4.5. Anmerkungen zu BSD/OS Version 3.x

Aktualisieren Sie auf BSD/OS 3.1. Sollte dies nicht möglich sein, dann installieren Sie BSDIpatch M300-038.

Verwenden Sie den folgenden Befehl zur Konfiguration von MySQL:

env CXX=shlicc++ CC=shlicc2 \
./configure \
    --prefix=/usr/local/mysql \
    --localstatedir=/var/mysql \
    --without-perl \
    --with-unix-socket-path=/var/mysql/mysql.sock

Auch die folgende Variante funktioniert bekanntermaßen:

env CC=gcc CXX=gcc CXXFLAGS=-O3 \
./configure \
    --prefix=/usr/local/mysql \
    --with-unix-socket-path=/var/mysql/mysql.sock

Sie können die Verzeichnispositionen auf Wunsch ändern oder die Voreinstellungen übernehmen (hierzu geben Sie einfach keine Positionen an).

Sollten Leistungsprobleme unter starker Belastung auftreten, dann probieren Sie die Option --skip-thread-priority für mysqld. Hierdurch werden alle Threads mit derselben Priorität ausgeführt. Unter BSDI 3.1 können Sie auf diese Weise die Leistung verbessern – zumindest so lange, bis BSDI den Thread-Scheduler in Ordnung bringt.

Wird bei der Kompilierung die Fehlermeldung virtual memory exhausted angezeigt, dann sollten Sie ulimit -v 80000 ausprobieren und make erneut ausführen. Funktioniert dies nicht und Sie verwenden bash, dann probieren Sie stattdessen csh oder sh aus. Einige BSDI-Benutzer haben Probleme mit bash und ulimit gemeldet.

2.13.4.6. Anmerkungen zu BSD/OS Version 4.x

BSDI 4.x weist einige Bugs in Bezug auf Threads auf. Wenn Sie MySQL hierunter verwenden wollen, sollten Sie alle Thread-spezifischen Patches installieren. Es sollte mindestens M400-023 installiert werden.

Auf einigen BSDI 4.x-Systemen treten Probleme mit gemeinsamen Bibliotheken auf. Sie erkennen dies daran, dass Sie keine Clientprogramme wie etwa mysqladmin ausführen können. In diesem Fall müssen Sie das System so umkonfigurieren, dass es keine gemeinsamen Bibliotheken verwendet; dies tun Sie mit der Option --disable-shared für configure.

Ferner haben Kunden Probleme unter BSDI 4.0.1 damit gehabt, dass die Binärdatei mysqld nach einer Weile keine Tabellen mehr öffnen konnte. Ursache hierfür ist ein bibliotheks- oder systembezogener Bug, aufgrund dessen mysqld das aktuelle Verzeichnis wechselt, ohne hierfür zuvor eine Bestätigung angefordert zu haben.

Sie beseitigen das Problem, indem Sie entweder MySQL auf Version 3.23.34 oder höher aktualisieren oder nach der Ausführung von configure die Zeile #define HAVE_REALPATH aus der Datei config.h entfernen, bevor Sie make starten.

Beachten Sie, dass dies bedeutet, dass Sie in diesem Fall unter BSDI keine symbolischen Verknüpfungen zwischen Datenbankverzeichnissen oder von einer Tabelle zu einer anderen Datenbank erstellen können. (Symbolische Verknüpfungen zu anderen Festplatten hingegen sind unproblematisch.)

2.13.5. Anmerkungen zu anderen unixartigen Systemen

2.13.5.1. Anmerkungen zu HP-UX Version 10.20

Bei der Installation einer tar-Binärdistribution unter HP-UX haben Sie möglicherweise schon die ersten Probleme, bevor Sie die MySQL-Distribution überhaupt entpacken können, denn tar kann unter HP-UX nicht mit langen Dateinamen umgehen. Dies bedeutet, dass Ihnen unter Umständen Fehler angezeigt werden, wenn Sie MySQL entpacken.

In diesem Fall müssen Sie GNU tar (gtar) zum Entpacken der Distribution verwenden.

Anmerkungen zu HP-UX Version 10.20 Wenn Sie MySQL unter HP-UX kompilieren, gibt es ein paar kleinere Probleme. Verwenden Sie gcc anstelle des nativen Compilers von HP-UX, da gcc einen besseren Code erzeugt.

Verwenden Sie unter HP-UX am besten gcc 2.95. Verwenden Sie keine Hochoptimierungsflags (wie etwa -O6), da dies unter Umständen unter HP-UX nicht sicher ist.

Der folgende configure-Befehl sollte für gcc 2.95 funktionieren:

CFLAGS="-I/opt/dce/include -fpic" \
CXXFLAGS="-I/opt/dce/include -felide-constructors -fno-exceptions \
-fno-rtti" \
CXX=gcc \
./configure --with-pthread \
    --with-named-thread-libs='-ldce' \
    --prefix=/usr/local/mysql --disable-shared

Der folgende configure-Befehl sollte für gcc 3.1 funktionieren:

CFLAGS="-DHPUX -I/opt/dce/include -O3 -fPIC" CXX=gcc \
CXXFLAGS="-DHPUX -I/opt/dce/include -felide-constructors \
    -fno-exceptions -fno-rtti -O3 -fPIC" \
./configure --prefix=/usr/local/mysql \
    --with-extra-charsets=complex --enable-thread-safe-client \
    --enable-local-infile  --with-pthread \
    --with-named-thread-libs=-ldce --with-lib-ccflags=-fPIC
    --disable-shared

2.13.5.2. Anmerkungen zu HP-UX Version 11.x

Bei der Installation einer tar-Binärdistribution unter HP-UX haben Sie möglicherweise schon die ersten Probleme, bevor Sie die MySQL-Distribution überhaupt entpacken können, denn tar kann unter HP-UX nicht mit langen Dateinamen umgehen. Dies bedeutet, dass Ihnen unter Umständen Fehler angezeigt werden, wenn Sie MySQL entpacken.

In diesem Fall müssen Sie GNU tar (gtar) zum Entpacken der Distribution verwenden.

Aufgrund einiger kritischer Bugs in den HP-UX-Standardbibliotheken sollten Sie die folgenden Patches installieren, bevor Sie MySQL unter HP-UX 11.0 ausführen:

PHKL_22840 Streams cumulative
PHNE_22397 ARPA cumulative

Hierdurch können Sie das Problem beheben, EWOULDBLOCK aus recv() und EBADF aus accept() in thread-basierten Anwendungen zu erhalten.

Wenn Sie gcc 2.95.1 auf einem nicht gepatchten HP-UX 11.x-System einsetzen, wird unter Umständen die folgende Fehlermeldung angezeigt:

In file included from /usr/include/unistd.h:11,
                 from ../include/global.h:125,
                 from mysql_priv.h:15,
                 from item.cc:19:
/usr/include/sys/unistd.h:184: declaration of C function ...
/usr/include/sys/pthread.h:440: previous declaration ...
In file included from item.h:306,
                 from mysql_priv.h:158,
                 from item.cc:19:

Das Problem besteht darin, dass HP-UX pthreads_atfork() nicht konsistent definiert. Es liegt ein Prototypkonflikt in /usr/include/sys/unistd.h:184 und /usr/include/sys/pthread.h:440 vor.

Eine Lösung besteht darin, /usr/include/sys/unistd.h nach mysql/include zu kopieren und unistd.h so zu editieren, dass es zur Definition in pthread.h passt. Suchen Sie nach der folgenden Zeile:

extern int pthread_atfork(void (*prepare)(), void (*parent)(),
                                          void (*child)());

Ändern Sie sie wie folgt ab:

extern int pthread_atfork(void (*prepare)(void), void (*parent)(void),
                                          void (*child)(void));

Wenn Sie die Änderung vorgenommen haben, sollte die folgende configure-Zeile funktionieren:

CFLAGS="-fomit-frame-pointer -O3 -fpic" CXX=gcc \
CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti -O3" \
./configure --prefix=/usr/local/mysql --disable-shared

Verwenden Sie den HP-UX-Compiler, dann können Sie den folgenden Befehl verwenden (dieser wurde mit cc B.11.11.04 getestet):

CC=cc CXX=aCC CFLAGS=+DD64 CXXFLAGS=+DD64 ./configure \
    --with-extra-character-set=complex

Sie können alle Fehler des folgenden Typs ignorieren:

aCC: warning 901: unknown option: `-3': use +help for online
documentation

Wenn die folgende Fehlermeldung von configure ausgegeben wird, dann stellen Sie sicher, dass der Pfad zum K&R-Compiler nicht vor dem Pfad zum HP-UX-C- und C++-Compiler steht:

checking for cc option to accept ANSI C... no
configure: error: MySQL requires an ANSI C compiler (and a C++ compiler).
Try gcc. See the Installation chapter in the Reference Manual.

Ein anderer Grund dafür, dass eine Kompilierung nicht möglich ist, besteht darin, dass Sie die +DD64-Flags nicht wie eben beschrieben definiert haben.

Eine andere Möglichkeit für HP-UX 11 besteht darin, die unter http://dev.mysql.com/downloads/ verfügbaren MySQL-Binärdateien zu verwenden, die wir selbst erstellt und getestet haben. Ferner wurde uns mitgeteilt, dass die von MySQL angebotenen Binärdateien für HP-UX 10.20 auch unter HP-UX 11 erfolgreich ausgeführt werden können. Wenn Sie hierbei auf Probleme treffen, sollten Sie Ihren HP-UX-Patchstand prüfen.

2.13.5.3. Anmerkungen zu IBM-AIX

Die automatische Erkennung von xlC fehlt bei Autoconf. Aus diesem Grund muss eine Reihe von Variablen eingestellt werden, bevor configure ausgeführt wird. Das folgende Beispiel verwendet den IBM-Compiler:

export CC="xlc_r -ma -O3 -qstrict -qoptimize=3 -qmaxmem=8192 "
export CXX="xlC_r -ma -O3 -qstrict -qoptimize=3 -qmaxmem=8192"
export CFLAGS="-I /usr/local/include"
export LDFLAGS="-L /usr/local/lib"
export CPPFLAGS=$CFLAGS
export CXXFLAGS=$CFLAGS
./configure --prefix=/usr/local \
                --localstatedir=/var/mysql \
                --sbindir='/usr/local/bin' \
                --libexecdir='/usr/local/bin' \
                --enable-thread-safe-client \
                --enable-large-files

Obige Optionen werden zur Kompilierung der MySQL-Distribution verwendet, die unter http://www-frec.bull.com/ verfügbar ist.

Wenn Sie in obiger configure-Zeile die Option -O3 auf -O2 setzen, müssen Sie auch die Option -qstrict entfernen. Dies ist eine Einschränkung des C-Compilers von IBM.

Wenn Sie gcc zur Kompilierung von MySQL verwenden, müssen Sie das Flag -fno-exceptions benutzen, weil die Fehlerbehandlung in gcc nicht threadsicher ist! Es gibt ferner einige bekannte Probleme mit dem IBM-Assembler, die in Verbindung mit gcc zu fehlerhaftem Code führen können.

Verwenden Sie die folgende configure-Zeile bei gcc 2.95 unter AIX:

CC="gcc -pipe -mcpu=power -Wa,-many" \
CXX="gcc -pipe -mcpu=power -Wa,-many" \
CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti" \
./configure --prefix=/usr/local/mysql --with-low-memory

Die Option -Wa,-many ist erforderlich, damit die Kompilierung erfolgreich verläuft. Bei IBM ist dieses Problem bekannt, man sieht sich aber mit der Behebung nicht unter Zeitdruck, da ein Workaround verfügbar ist. Wir wissen nicht, ob -fno-exceptions bei gcc 2.95 erforderlich ist, aber weil MySQL keine Ausnahmen verwendet und die Option einen schnelleren Code erzeugt, empfehlen wir ihre generelle Verwendung bei gcc.

Wenn ein Problem mit dem Assemblercode auftritt, versuchen Sie die Option -mcpu=xxx so zu ändern, dass sie zu Ihrer CPU passt. Normalerweise müssen power2, power oder powerpc verwendet werden. Möglicherweise müssen Sie aber auch 604 oder 604e einsetzen. Wir wissen es nicht genau, nehmen aber an, dass power mit hoher Wahrscheinlichkeit in den meisten Fällen sicher ist (und zwar auch auf power2-Systemen).

Wenn Sie nicht wissen, welchen Prozessor Sie haben, führen Sie den Befehl uname -m aus. Er erzeugt einen String, der etwa so aussieht: 000514676700. Das Format ist xxyyyyyymmss, wobei xx und ss immer 00, yyyyyy eine eindeutige Systemkennung und mm die Kennung des CPU-Planars sind. Eine Übersicht über diese Werte finden Sie unter http://www16.boulder.ibm.com/pseries/en_US/cmds/aixcmds5/uname.htm.

Dort erhalten Sie Angaben zu Rechnertyp und -modell, auf deren Basis Sie die CPU in Ihrem Rechner ermitteln können.

Wenn Sie Probleme mit Threads unter AIX 5.3 haben, sollten Sie AIX 5.3 auf Technology Level 7 aktualisieren (5300-07).

Wenn Sie Probleme mit Signalen haben (weil sich MySQL unter hoher Belastung unerwartet aufhängt), haben Sie unter Umständen einen Betriebssystembug bei den Threads oder Signalen gefunden. In diesem Fall können Sie MySQL wie folgt anweisen, Signale nicht zu verwenden:

CFLAGS=-DDONT_USE_THR_ALARM CXX=gcc \
CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti \
-DDONT_USE_THR_ALARM" \
./configure --prefix=/usr/local/mysql --with-debug \
    --with-low-memory

Hierdurch wird die Leistung von MySQL nicht beeinträchtigt; ein Nebeneffekt besteht aber darin, dass Sie Clients, die an einer Verbindung „schlafen“, mit mysqladmin kill oder mysqladmin shutdown nicht terminieren können. Stattdessen hängt sich der Client auf, wenn er den nächsten Befehl absetzt.

Bei einigen Versionen von AIX führt eine Verknüpfung mit libbind.a bei getservbyname() zu einem Speicherauszug. Dies ist ein AIX-Bug, der IBM gemeldet werden sollte.

Bei AIX 4.2.1 und gcc müssen Sie die folgenden Änderungen vornehmen.

Bearbeiten Sie nach der Konfiguration config.h und include/my_config.h. Die Zeile

#define HAVE_SNPRINTF 1

ändern Sie wie folgt:

#undef HAVE_SNPRINTF

Schließlich müssen Sie in mysqld.cc noch einen Prototyp für initgroups() hinzufügen.

#ifdef _AIX41
extern "C" int initgroups(const char *,int);
#endif

Wenn Sie dem Prozess mysqld bei 32-Bit-Binärdateien viel Speicher zuweisen müssen, reicht es nicht aus, einfach ulimit -d unlimited zu verwenden. Sie müssen vielmehr auch mysqld_safe mit einer Zeile wie der folgenden ergänzen:

export LDR_CNTRL='MAXDATA=0x80000000'

Weitere Informationen zur Verwendung einer großen Menge Speicher finden Sie unter http://publib16.boulder.ibm.com/pseries/en_US/aixprggd/genprogc/lrg_prg_support.htm.

Benutzer von AIX 4.3 sollten gmake statt des in AIX enthaltenen make-Hilfsprogramms verwenden.

Ab AIX 4.1 ist der C-Compiler getrennt von AIX als separates Produkt verfügbar. gcc 3.3.2 erhalten Sie hier: ftp://ftp.software.ibm.com/aix/freeSoftware/aixtoolbox/RPMS/ppc/gcc/

Die Schritte zur Kompilierung von MySQL unter AIX mit gcc 3.3.2 ähneln denen bei der Verwendung von gcc 2.95 (insbesondere bezüglich der notwendigen Bearbeitung von config.h und my_config.h nach dem Ausführen von configure). Bevor Sie jedoch configure ausführen, sollten Sie auch die Datei curses.h wie folgt patchen:

/opt/freeware/lib/gcc-lib/powerpc-ibm-aix5.2.0.0/3.3.2/include/curses.h.ORIG
       Mon Dec 26 02:17:28 2005
--- /opt/freeware/lib/gcc-lib/powerpc-ibm-aix5.2.0.0/3.3.2/include/curses.h
Mon Dec 26 02:40:13 2005
***************
*** 2023,2029 ****
  #endif /* _AIX32_CURSES */
! #if defined(__USE_FIXED_PROTOTYPES__) || defined(__cplusplus) || defined
(__STRICT_ANSI__)
  extern int delwin (WINDOW *);
  extern int endwin (void);
  extern int getcurx (WINDOW *);
--- 2023,2029 ----
  #endif /* _AIX32_CURSES */
! #if 0 && (defined(__USE_FIXED_PROTOTYPES__) || defined(__cplusplus)
|| defined
(__STRICT_ANSI__))
  extern int delwin (WINDOW *);
  extern int endwin (void);
  extern int getcurx (WINDOW *);

2.13.5.4. Anmerkungen zu SunOS 4

Unter SunOS 4 ist MIT-pthreads zur Kompilierung von MySQL erforderlich. Das wiederum bedeutet, dass Sie GNU make benötigen.

Einige SunOS 4-Systeme haben Probleme mit dynamischen Bibliotheken und libtool. Dieses Problem können Sie mit der folgenden configure-Zeile beheben:

./configure --disable-shared --with-mysqld-ldflags=-all-static

Wenn Sie readline kompilieren, erhalten Sie unter Umständen Warnungen zu Doppeldefinitionen. Diese können Sie getrost ignorieren.

Wenn Sie mysqld kompilieren, erscheinen einige Warnungen des Typs implicit declaration of function. Diese können Sie getrost ignorieren.

2.13.5.5. Anmerkungen zu Alpha-DEC-UNIX (Tru64)

Wenn Sie egcs 1.1.2 unter Digital Unix verwenden, sollten Sie auf gcc 2.95.2 aktualisieren, weil egcs unter DEC einige schwerwiegende Bugs aufweist!

Wenn Sie thread-basierte Programme unter Digital Unix kompilieren, empfiehlt die Dokumentation die Verwendung der Option -pthread für cc und cxx und die -lmach -lexc-Bibliotheken (zusätzlich zu -lpthread). Sie sollten configure etwa wie folgt ausführen:

CC="cc -pthread" CXX="cxx -pthread -O" \
./configure --with-named-thread-libs="-lpthread -lmach -lexc -lc"

Wenn Sie mysqld kompilieren, werden unter Umständen einige Warnungen wie die folgenden angezeigt:

mysqld.cc: In function void handle_connections()':
mysqld.cc:626: passing long unsigned int *' as argument 3 of
accept(int,sockadddr *, int *)'

Diese können Sie getrost ignorieren. Sie erscheinen, weil configure nur Fehler, nicht jedoch Warnungen erkennen kann.

Wenn Sie den Server direkt über die Befehlszeile starten, kann es bei der Abmeldung zu Abstürzen kommen. (Wenn Sie sich abmelden, erhalten Ihre ausstehenden Prozesse ein SIGHUP-Signal.) Versuchen Sie, den Server wie folgt zu starten:

nohup mysqld [options] &

nohup sorgt dafür, dass der Befehl, der darauf folgt, alle ggf. vom Terminal gesendeten SIGHUP-Signale ignoriert. Alternativ starten Sie den Server durch Ausführung von mysqld_safe. Hierdurch wird mysqld unter Verwendung von nohup für Sie aufgerufen. Siehe auch mysqld_safe.

Wenn ein Problem bei der Kompilierung von mysys/get_opt.c auftritt, entfernen Sie einfach die Zeile #define _NO_PROTO am Anfang dieser Datei.

Wenn Sie den CC-Compiler von Compaq einsetzen, sollte die folgende configure-Zeile problemlos funktionieren:

CC="cc -pthread"
CFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed \
        -speculate all -arch host"
CXX="cxx -pthread"
CXXFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed \
          -speculate all -arch host -noexceptions -nortti"
export CC CFLAGS CXX CXXFLAGS
./configure \
    --prefix=/usr/local/mysql \
    --with-low-memory \
    --enable-large-files \
    --enable-shared=yes \
    --with-named-thread-libs="-lpthread -lmach -lexc -lc"
gnumake

Tritt ein Problem mit libtool auf, wenn Sie wie gerade gezeigt mit gemeinsamen Bibliotheken kompilieren und mysql verknüpfen, sollten Sie dieses durch Absetzen der folgenden Befehle umgehen können:

cd mysql
/bin/sh ../libtool --mode=link cxx -pthread  -O3 -DDBUG_OFF \
    -O4 -ansi_alias -ansi_args -fast -inline speed \
    -speculate all \ -arch host  -DUNDEF_HAVE_GETHOSTBYNAME_R \
    -o mysql  mysql.o readline.o sql_string.o completion_hash.o \
    ../readline/libreadline.a -lcurses \
    ../libmysql/.libs/libmysqlclient.so  -lm
cd ..
gnumake
gnumake install
scripts/mysql_install_db

2.13.5.6. Anmerkungen zu Alpha-DEC-OSF/1

Wenn Sie Probleme beim Kompilieren haben und DEC CC und gcc installiert sind, probieren Sie einmal, configure wie folgt auszuführen:

CC=cc CFLAGS=-O CXX=gcc CXXFLAGS=-O3 \
./configure --prefix=/usr/local/mysql

Treten Probleme in Verbindung mit der Datei c_asm.h auf, dann können Sie wie folgt eine Dummyversion von c_asm.h erstellen:

touch include/c_asm.h
CC=gcc CFLAGS=-I./include \
CXX=gcc CXXFLAGS=-O3 \
./configure --prefix=/usr/local/mysql

Beachten Sie, dass die folgenden Probleme beim Programm ld sich durch den Download des aktuellen DEC-(Compaq-)Patch-Kits beheben lassen. Dieses finden Sie unter http://ftp.support.compaq.com/public/unix/.

Unter OSF/1 V4.0D tritt bei Verwendung des Compilers "DEC C V5.6-071 on Digital Unix V4.0 (Rev. 878)" ein seltsames Verhalten auf (undefinierte asm-Symbole). /bin/ld scheint ebenfalls beschädigt zu sein (Probleme mit _exit undefined-Fehlern, die beim Verknüpfen von mysqld auftreten). Es ist uns gelungen, MySQL auf diesem System mit der folgenden configure-Zeile zu kompilieren, nachdem wir /bin/ld durch die Version aus OSF 4.0C ersetzt haben:

CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql

Beim Digital-Compiler "C++ V6.1-029" sollte Folgendes funktionieren:

CC=cc -pthread
CFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed \
       -speculate all -arch host
CXX=cxx -pthread
CXXFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed \
         -speculate all -arch host -noexceptions -nortti
export CC CFLAGS CXX CXXFLAGS
./configure --prefix=/usr/mysql/mysql \
            --with-mysqld-ldflags=-all-static --disable-shared \
            --with-named-thread-libs="-lmach -lexc -lc"

Bei einigen Versionen von OSF/1 ist die Funktion alloca() beschädigt. Dieses Problem können Sie beheben, indem Sie die Zeile in config.h entfernen, die 'HAVE_ALLOCA' definiert.

Die Funktion alloca() weist unter Umständen auch einen falschen Prototyp in /usr/include/alloca.h auf. Sich hierauf beziehende Warnmeldungen können Sie ignorieren.

configure verwendet die folgenden Thread-Bibliotheken automatisch: --with-named-thread-libs="-lpthread -lmach -lexc -lc".

Wenn Sie gcc verwenden, können Sie auch versuchen, configure wie folgt auszuführen:

CFLAGS=-D_PTHREAD_USE_D4 CXX=gcc CXXFLAGS=-O3 ./configure ...

Wenn Sie Probleme mit Signalen haben (weil sich MySQL unter hoher Belastung unerwartet aufhängt), haben Sie unter Umständen einen Betriebssystembug bei den Threads oder Signalen gefunden. In diesem Fall können Sie MySQL wie folgt anweisen, Signale nicht zu verwenden:

CFLAGS=-DDONT_USE_THR_ALARM \
CXXFLAGS=-DDONT_USE_THR_ALARM \
./configure ...

Hierdurch wird die Leistung von MySQL nicht beeinträchtigt; ein Nebeneffekt besteht aber darin, dass Sie Clients, die an einer Verbindung „schlafen“, mit mysqladmin kill oder mysqladmin shutdown nicht terminieren können. Stattdessen hängt sich der Client auf, wenn er den nächsten Befehl absetzt.

Bei gcc 2.95.2 erhalten Sie möglicherweise den folgenden Kompilierungsfehler:

sql_acl.cc:1456: Internal compiler error in `scan_region',
at except.c:2566
Please submit a full bug report.

Um dies zu beheben, sollten Sie in das Verzeichnis sql wechseln und dort die letzte gcc-Zeile ausschneiden und einfügen, die Option -O3 dabei jedoch zu -O0 ändern (oder -O0 direkt nach gcc hinzufügen, wenn Ihre compile-Zeile gar keine -O-Option enthält). Danach können Sie wieder zum obersten Verzeichnis wechseln und make erneut ausführen. Anmerkungen zu SGI Irix

2.13.5.7. Anmerkungen zu SGI Irix

Ab MySQL 5.0 stellen wir für Irix keine Binärdateien mehr zur Verfügung.

Wenn Sie Irix 6.5.3 oder höher verwenden, kann mysqld Threads nur dann erstellen, wenn Sie es als Benutzer mit CAP_SCHED_MGT-Berechtigungen (z. B. als root) ausführen oder dem Server mysqld diese Berechtigung mit dem folgenden Shell-Befehl zuweisen:

chcap "CAP_SCHED_MGT+epi" /opt/mysql/libexec/mysqld

Unter Umständen müssen Sie die Definitionen einiger Symbole in config.h nach der Ausführung von configure, aber vor der Kompilierung aufheben.

Bei einigen Irix-Implementierungen ist die Funktion alloca() beschädigt. Wenn der mysqld-Server sich bei einigen SELECT-Anweisungen aufhängt, entfernen Sie die Zeilen aus config.h, die HAVE_ALLOC und HAVE_ALLOCA_H definieren. Funktioniert mysqladmin create nicht, dann entfernen Sie die Zeile aus config.h, die HAVE_READDIR_R definiert. Möglicherweise müssen Sie auch die Zeile HAVE_TERM_H entfernen.

SGI empfiehlt, alle Patches auf der folgenden Seite auf einmal zu installieren: http://support.sgi.com/surfzone/patches/patchset/6.2_indigo.rps.html

Sie sollten zumindest das jeweils letzte Kernel-, rld- und libc-Rollup installieren.

Für die pthreads-Unterstützung benötigen Sie in jedem Fall alle POSIX-Patches auf der folgenden Seite:

http://support.sgi.com/surfzone/patches/patchset/6.2_posix.rps.html

Möglicherweise erhalten Sie bei der Kompilierung von mysql.cc eine Fehlermeldung ähnlich der folgenden:

"/usr/include/curses.h", line 82: error(1084):
invalid combination of type

Geben Sie in diesem Fall Folgendes im obersten Verzeichnis Ihres MySQL-Source-Trees ein:

extra/replace bool curses_bool < /usr/include/curses.h > include/curses.h
make

Gemeldet wurden ferner Zeitplanungsprobleme. Wird nur ein Thread ausgeführt, dann ist die Performance schwach. Dies können Sie vermeiden, indem Sie einen anderen Client starten. Dies hat unter Umständen eine zwei- bis zehnfache Steigerung der Ausführungsgeschwindigkeit für den anderen Thread zur Folge. Dieses Problem mit Irix-Threads ist schlecht nachvollziehbar: Bis es behoben ist, müssen Sie wohl improvisieren, um geeignete Lösungen zu finden.

Wenn Sie mit gcc kompilieren, können Sie den folgenden configure-Befehl verwenden:

CC=gcc CXX=gcc CXXFLAGS=-O3 \
./configure --prefix=/usr/local/mysql --enable-thread-safe-client \
    --with-named-thread-libs=-lpthread

Unter Irix 6.5.11 mit nativen Irix-C- und -C++-Compilern der Version 7.3.1.2 funktioniert Angaben zufolge auch Folgendes:

CC=cc CXX=CC CFLAGS='-O3 -n32 -TARG:platform=IP22 -I/usr/local/include \
-L/usr/local/lib' CXXFLAGS='-O3 -n32 -TARG:platform=IP22 \
-I/usr/local/include -L/usr/local/lib' \
./configure --prefix=/usr/local/mysql --with-innodb \
    --with-libwrap=/usr/local \
    --with-named-curses-libs=/usr/local/lib/libncurses.a

2.13.5.8. Anmerkungen zu SCO UNIX and OpenServer 5.0.x

Die aktuelle Portierung wird nur auf Systemen unter sco3.2v5.0.5, sco3.2v5.0.6 und sco3.2v5.0.7 getestet. Die Portierung auf sco3.2v4.2 ist ebenfalls weit fortgeschritten. Open Server 5.0.8 (Legend) bietet native Threads und unterstützt Dateien, die größer sind als 2 GB. Das aktuelle Limit bei der Dateigröße liegt bei 2 Gbyte.

Wir konnten MySQL mit dem folgenden configure-Befehl unter OpenServer mit gcc 2.95.3 kompilieren.

CC=gcc CFLAGS="-D_FILE_OFFSET_BITS=64 -O3" \
CXX=gcc CXXFLAGS="-D_FILE_OFFSET_BITS=64 -O3" \
./configure --prefix=/usr/local/mysql \
    --enable-thread-safe-client --with-innodb \
    --with-openssl --with-vio --with-extra-charsets=complex

gcc erhalten Sie unter ftp://ftp.sco.com/pub/openserver5/opensrc/gnutools-5.0.7Kj.

Dieses Entwicklungssystem erfordert das OpenServer Execution Environment Supplement oss646B unter OpenServer 5.0.6 und oss656B und die in gwxlibs enthaltenen OpenSource-Bibliotheken. Alle OpenSource-Tools befinden sich im Verzeichnis opensrc. Sie finden sie unter ftp://ftp.sco.com/pub/openserver5/opensrc/.

Verwenden Sie das aktuelle Produktions-Release von MySQL.

SCO stellt Betriebssystem-Patches unter ftp://ftp.sco.com/pub/openserver5 für OpenServer 5.0.[0-6] und unter ftp://ftp.sco.com/pub/openserverv5/507 für OpenServer 5.0.7 bereit.

Informationen zu behobenen Sicherheitslücken bietet SCO unter ftp://ftp.sco.com/pub/security/OpenServer für OpenServer 5.0.x an.

Die maximale Dateigröße auf einem OpenServer 5.0.x-System beträgt 2 GB.

Die Gesamtmenge an Speicher, der für Stream-Puffer, CLISTs und Sperrdatensätze zugewiesen wird, darf unter OpenServer 5.0.x einen Wert von 60 Mbyte nicht überschreiten.

Stream-Puffer werden in Einheiten von 4096 Byte großen Seiten zugewiesen, CLISTs haben jeweils 70 Byte, und Sperrdatensätze sind je 64 Byte groß. Hieraus ergibt sich:

(NSTRPAGES × 4096) + (NCLIST × 70) + (MAX_FLCKREC × 64) <= 62914560

Gehen Sie wie folgt vor, um die Option ?Database Services“ zu konfigurieren. Wenn Sie nicht genau wissen, ob eine Anwendung dies erfordert, schlagen Sie in der Dokumentation dieser Anwendung nach.

  1. Melden Sie sich als root an.

  2. Aktivieren Sie den SUDS-Treiber, indem Sie die Datei /etc/conf/sdevice.d/suds bearbeiten. Ändern Sie das N im zweiten Feld zu Y.

  3. Aktivieren Sie mithilfe von mkdev aio oder des Hardware/Kernel-Managers die Unterstützung für asynchrone Eingabe/Ausgabe und verknüpfen Sie den Kernel neu. Damit Benutzer Speicher für die Verwendung mit diesem E/A-Typ verriegeln können, aktualisieren Sie die Datei aiomemlock(F). Diese Datei sollte mit den Namen der Benutzer, die AIO verwenden dürfen, und der maximalen Speichermenge aktualisiert werden, die diese Benutzer sperren dürfen.

  4. Viele Anwendungen verwenden setuid-Binärdateien, d. h., Sie müssen nur einen Benutzer angeben. Konsultieren Sie die Dokumentation zur fraglichen Anwendung, um zu ermitteln, ob dies bei dieser Anwendung der Fall ist.

Nachdem Sie den Vorgang abgeschlossen haben, starten Sie das System neu, um einen neuen Kernel zu erstellen, der diese Änderungen beinhaltet.

Standardmäßig haben die Einträge in /etc/conf/cf.d/mtune folgende Einstellungen:

Value           Default         Min             Max
-----           -------         ---             ---
NBUF            0               24              450000
NHBUF           0               32              524288
NMPBUF          0               12              512
MAX_INODE       0               100             64000
MAX_FILE        0               100             64000
CTBUFSIZE       128             0               256
MAX_PROC        0               50              16000
MAX_REGION      0               500             160000
NCLIST          170             120             16640
MAXUP           100             15              16000
NOFILES         110             60              11000
NHINODE         128             64              8192
NAUTOUP         10              0               60
NGROUPS         8               0               128
BDFLUSHR        30              1               300
MAX_FLCKREC     0               50              16000
PUTBUFSZ        8000            2000            20000
MAXSLICE        100             25              100
ULIMIT          4194303         2048            4194303
* Streams Parameters
NSTREAM         64              1               32768
NSTRPUSH        9               9               9
NMUXLINK        192             1               4096
STRMSGSZ        16384           4096            524288
STRCTLSZ        1024            1024            1024
STRMAXBLK       524288          4096            524288
NSTRPAGES       500             0               8000
STRSPLITFRAC    80              50              100
NLOG            3               3               3
NUMSP           64              1               256
NUMTIM          16              1               8192
NUMTRW          16              1               8192
* Semaphore Parameters
SEMMAP          10              10              8192
SEMMNI          10              10              8192
SEMMNS          60              60              8192
SEMMNU          30              10              8192
SEMMSL          25              25              150
SEMOPM          10              10              1024
SEMUME          10              10              25
SEMVMX          32767           32767           32767
SEMAEM          16384           16384           16384
* Shared Memory Parameters
SHMMAX          524288          131072          2147483647
SHMMIN          1               1               1
SHMMNI          100             100             2000
FILE            0               100             64000
NMOUNT          0               4               256
NPROC           0               50              16000
NREGION         0               500             160000

Stellen Sie folgende Werte ein:

  • NOFILES sollte 4096 oder 2048 sein.

  • MAXUP sollte 2048 sein.

Um Änderungen am Kernel vorzunehmen, verwenden sie den Befehl idtune name parameter. idtune ändert die Datei /etc/conf/cf.d/stune für Sie. Um beispielsweise SEMMS auf 200 zu setzen, führen Sie folgenden Befehl als root aus:

# /etc/conf/bin/idtune SEMMNS 200

Erstellen Sie den Kernel anschließend neu und booten Sie ihn mit dem folgenden Befehl:

# /etc/conf/bin/idbuild -B && init 6

Welche Parameterwerte für die Optimierung des Systems geeignet sind, hängt von der Anzahl der Benutzer, die auf die Anwendung oder Datenbank zugreifen, und von der Größe der Datenbank selbst (d. h. dem verwendeten Pufferpool) ab. Die folgenden Kernel-Parameter können mit idtune eingestellt werden:

  • SHMMAX (empfohlene Einstellung: 128 MB) und SHMSEG (empfohlene Einstellung: 15). Diese Parameter beeinflussen die MySQL-Datenbank-Engine bei der Erstellung der Benutzerpufferpools.

  • NOFILES und MAXUP sollten auf mindestens 2048 gesetzt werden.

  • MAXPROC sollte (abhängig von der Anzahl der Benutzer) auf mindestens 3000/4000 gesetzt werden.

  • Ferner wird die Verwendung der folgenden Formeln zur Berechnung der Werte für SEMMSL, SEMMNS und SEMMNU empfohlen:

    SEMMSL = 13
    

    13 hat sich als optimaler Wert sowohl für Progress als auch für MySQL erwiesen.

    SEMMNS = SEMMSL × number of db servers to be run on the system
    

    Setzen Sie SEMMNS auf den Wert von SEMMSL multipliziert mit der maximalen Anzahl der Datenbankserver, die gleichzeitig auf Ihrem System ausgeführt werden.

    SEMMNU = SEMMNS
    

    SEMMNU setzen Sie dann auf den gleichen Wert wie SEMMNS. Wahrscheinlich würde hier auch ein Wert von 75 Prozent von SEMMNS ausreichen, aber dies ist eine konservative Schätzung.

Sie müssen zumindest die ?SCO OpenServer Linker and Application Development Libraries“ oder das OpenServer Development System installieren, um gcc verwenden zu können. Das GCC Dev-System können Sie nicht nutzen, ohne mindestens eine dieser Komponenten zu installieren.

Zunächst sollten Sie sich jedoch das FSU-Pthreads-Paket beschaffen und es installieren. Dieses finden Sie unter http://moss.csc.ncsu.edu/~mueller/ftp/pub/PART/pthreads.tar.gz. Eine vorkompilierte Fassung finden Sie unter ftp://ftp.zenez.com/pub/zenez/prgms/FSU-threads-3.14.tar.gz.

FSU-Pthreads kann mit SCO Unix 4.2 mit tcpip oder aber mithilfe von OpenServer 3.0 oder Open Desktop 3.0 (OS 3.0 ODT 3.0) mit installiertem SCO Development System kompiliert werden, wobei eine gute Portierung von GCC 2.5.x zum Einsatz kommen sollte. Für ODT oder OS 3.0 benötigen Sie eine gute Portierung von GCC 2.5.x. Ohne eine solche gute Portierung können eine Menge Probleme entstehen. Die Portierung für dieses Produkt erfordert das SCO Unix Development-System. Ohne dieses fehlen Ihnen die Bibliotheken und der erforderliche Linker. Ferner benötigen Sie SCO-3.2v4.2-includes.tar.gz. Diese Datei enthält die Änderungen an den Include-Dateien des SCO Development Systems, die für die Erstellung von MySQL benötigt werden. Sie müssen die vorhandenen System-Include-Dateien durch diese modifizierten Header-Dateien ersetzen. Diese erhalten Sie unter ftp://ftp.zenez.com/pub/zenez/prgms/SCO-3.2v4.2-includes.tar.gz.

Um FSU-Pthreads auf Ihrem System zu erstellen, sollten Sie nichts weiteres tun müssen, als GNU make auszuführen. Das Makefile in FSU-threads-3.14.tar.gz ist so konfiguriert, dass es FSU-threads erstellt.

Sie können ./configure im Verzeichnis threads/src ausführen und die Option SCO OpenServer auswählen. Dieser Befehl kopiert Makefile.SCO5 nach Makefile. Danach führen Sie make aus.

Zur Installation in das Standardverzeichnis /usr/include melden Sie sich als root an. Wechseln (cd) Sie dann in das Verzeichnis thread/src und führen Sie dort make install aus.

Denken Sie daran, GNU make zur Erstellung von MySQL zu verwenden.

Anmerkung

Wenn Sie mysqld_safe nicht als root starten, erhalten Sie nur die standardmäßig vorgesehenen 110 offenen Dateien pro Prozess. mysqld schreibt eine entsprechende Anmerkung in die Logdatei.

Bei SCO 3.2V4.2 sollten Sie FSU-Pthreads Version 3.14 oder höher verwenden. Der folgende configure-Befehl sollte funktionieren:

CFLAGS="-D_XOPEN_XPG4" CXX=gcc CXXFLAGS="-D_XOPEN_XPG4" \
./configure \
    --prefix=/usr/local/mysql \
    --with-named-thread-libs="-lgthreads -lsocket -lgen -lgthreads" \
    --with-named-curses-libs="-lcurses"

Unter Umständen treten Probleme mit einigen Include-Dateien auf. In diesem Fall finden Sie neue SCO-spezifische Include-Dateien unter ftp://ftp.zenez.com/pub/zenez/prgms/SCO-3.2v4.2-includes.tar.gz.

Sie sollten diese Datei in das Verzeichnis include Ihres MySQL-Source-Trees entpacken.

Anmerkungen zur SCO-Entwicklung:

  • MySQL sollte FSU-Pthreads automatisch erkennen und mysqld mit -lgthreads -lsocket -lgthreads verknüpfen.

  • Die SCO-Entwicklungsbibliotheken sind in FSU-Pthreads mehrfach aufrufbar. SCO behauptet, dass seine Bibliothek mehrfach aufrufbar ist, mithin muss sie also auch bei FSU-Pthreads mehrfach aufrufbar sein. FSU-Pthreads unter OpenServer versucht, mithilfe des SCO-Schemas mehrfach aufrufbare Bibliotheken zu erstellen.

  • FSU-Pthreads wird mit GNU malloc verknüpft ausgeliefert (zumindest gilt dies für die Version unter ftp://ftp.zenez.com). Wenn Probleme mit der Speichernutzung auftreten, vergewissern Sie sich, dass gmalloc.o in libgthreads.a und libgthreads.so enthalten ist.

  • In FSU-Pthreads erkennen die folgenden Systemaufrufe das Vorhandensein von Pthreads: read(), write(), getmsg(), connect(), accept(), select() und wait().

  • Der Patch CSSA-2001-SCO.35.2, der üblicherweise als Sicherheits-Patch erg711905-dscr_remap (version 2.0.0) gelistet ist, beschädigt FSU-Threads und macht mysqld instabil. Wenn Sie mysqld auf einem System unter OpenServer 5.0.6 verwenden wollen, müssen Sie diesen Patch entfernen.

  • Setzen Sie SCO OpenServer 5 ein, dann müssen Sie unter Umständen FSU-Pthreads mit -DDRAFT7 in CFLAGS neu kompilieren. Andernfalls hängt sich InnoDB beim Start von mysqld auf.

  • SCO bietet Betriebssystem-Patches unter ftp://ftp.sco.com/pub/openserver5 für OpenServer 5.0.x an.

  • Fehlerbehebungen für Sicherheitslücken und libsocket.so.2 bietet SCO unter ftp://ftp.sco.com/pub/security/OpenServer und ftp://ftp.sco.com/pub/security/sse für OpenServer 5.0.x an.

  • Sicherheitsrelevante Fehlerbehebungen für Systeme vor OSR506 sowie den Bugfix für telnetd finden Sie unter ftp://stage.caldera.com/pub/security/openserver/ oder ftp://stage.caldera.com/pub/security/openserver/CSSA-2001-SCO.10/ als libsocket.so.2 und libresolv.so.1 mit Anweisungen zur Installation auf Systemen vor OSR506.

    Es empfiehlt sich wohl, diese Patches vor der Kompilierung und Verwendung von MySQL zu installieren.

Ab Legend/OpenServer 6.0.0 gibt es native Threads, und die Beschränkung der Dateigröße auf 2 Gbyte entfällt. Anmerkungen zu SCO OpenServer 6.0.x

2.13.5.9. Anmerkungen zu SCO OpenServer 6.0.x

OpenServer 6 enthält die folgenden wesentlichen Verbesserungen:

  • Unterstützung für Dateien bis zu 1 Tbyte

  • Multiprozessorunterstützung für bis zu 32 Prozessoren

  • verbesserte Speicherunterstützung für bis zu 64 Gbyte

  • Leistungserweiterung von UnixWare auf OpenServer 6

  • drastische Leistungssteigerungen

OpenServer 6.0.0-Befehle sind wie folgt organisiert:

  • /bin ist für Befehle vorgesehen, die sich exakt so verhalten wie unter OpenServer 5.0.x.

  • /u95/bin ist für Befehle vorgesehen, die eine erhöhte Standardkonformität aufweisen. Hierzu gehört z. B. die LFS-Unterstützung (Large File System).

  • /udk/bin ist für Befehle vorgesehen, die sich exakt so verhalten wie unter UnixWare 7.1.4. Standardmäßig wird LFS unterstützt.

Nachfolgend erhalten Sie eine Anleitung zur Einstellung von PATH unter OpenServer 6. Wenn der Benutzer das traditionelle Verhalten von OpenServer 5.0.x wünscht, sollte PATH zunächst /bin sein. Wünscht der Benutzer LFS-Unterstützung, dann sollte der Pfad /u95/bin:/bin sein. Benötigt der Benutzer zunächst UnixWare 7-Unterstützung, dann wäre der korrekte Pfad /udk/bin:/u95/bin:/bin:.

Verwenden Sie das aktuelle Produktions-Release von MySQL. Sollten Sie sich für ein älteres MySQL-Release unter OpenServer 6.0.x entscheiden, müssen Sie mindestens die MySQL-Version 3.22.13 verwenden, um Korrekturen für einige Portabilitäts- und betriebssystembezogene Probleme zu erhalten.

MySQL-Distributionsdateien mit Namen der folgenden Form sind tar-Archive von Medien-Images, die für die Installation mit dem SCO Software Manager (/etc/custom) unter SCO OpenServer 6 geeignet sind:

mysql-PRODUCT-5.1.54-sco-osr6-i686.VOLS.tar

Eine Distribution, bei der PRODUCT pro-cert ist, ist der kommerziell lizenzierte MySQL Pro Certified Server. Eine Distribution, bei der PRODUCT pro-gpl-cert ist, ist der nach der General Public License (GPL) lizenzierte MySQL Pro Certified Server.

Wählen Sie die gewünschte Distribution aus und extrahieren Sie nach dem Herunterladen das tar-Archive in ein leeres Verzeichnis. Ein Beispiel:

shell> mkdir /tmp/mysql-pro
shell> cd /tmp/mysql-pro
shell> tar xf /tmp/mysql-pro-cert-5.1.54-sco-osr6-i686.VOLS.tar

Sichern Sie vor der Installation Ihre Daten entsprechend der in Abschnitt 2.12.1, „Upgrade von MySQL“ beschriebenen Vorgehensweise.

Entfernen Sie bereits installierte pkgadd-Versionen von MySQL:

shell> pkginfo mysql 2>&1 > /dev/null && pkgrm mysql

Installieren Sie MySQL Pro mithilfe des SCO Software Managers von den Medien-Images:

shell> /etc/custom -p SCO:MySQL -i -z /tmp/mysql-pro

Alternativ kann der SCO Software Manager grafisch angezeigt werden, indem Sie auf dem Desktop auf das Symbol Software Manager klicken und Software -> Install New, den Host sowie Media Images für das Media Device auswählen und /tmp/mysql-pro als Imageverzeichnis eingeben.

Führen Sie nach der Installation mkdev mysql als Benutzer root aus, um Ihren neu installierten MySQL Pro Certified Server zu konfigurieren.

Anmerkung

Beim Installationsverfahren für VOLS-Pakete werden der Benutzer und die Gruppe mysql, die das Paket standardmäßig verwendet, nicht generiert. Erstellen Sie deshalb den Benutzer und die Gruppe mysql selbst oder wählen Sie über eine Option aus mkdev mysql einen anderen Benutzer und eine andere Gruppe aus.

Wenn Sie Ihren MySQL Pro Server für PHP-Schnittstellen mit dem Apache Web Server konfigurieren wollen, laden Sie das PHP-Update von SCO unter ftp://ftp.sco.com/pub/updates/OpenServer/SCOSA-2006.17/ herunter und installieren Sie es.

Wir konnten MySQL mit dem folgenden configure-Befehl unter OpenServer 6.0.x kompilieren.

CC=cc CFLAGS="-D_FILE_OFFSET_BITS=64 -O3" \
CXX=CC CXXFLAGS="-D_FILE_OFFSET_BITS=64 -O3" \
./configure --prefix=/usr/local/mysql \
    --enable-thread-safe-client  \
    --with-extra-charsets=complex \
    --build=i686-unknown-sysv5SCO_SV6.0.0

Wenn Sie gcc verwenden, müssen Sie gcc 2.95.3 oder höher einsetzen.

CC=gcc CXX=g++ ... ./configure ...

SCO stellt Betriebssystem-Patches für OpenServer 6 unter ftp://ftp.sco.com/pub/openserver6 bereit.

Informationen zu behobenen Sicherheitslücken bietet SCO unter ftp://ftp.sco.com/pub/security/OpenServer an.

Standardmäßig beträgt die maximale Dateigröße auf einem OpenServer 6.0.0-System 1 TB. Einige Betriebssystem-Hilfsprogramme weisen eine Beschränkung auf 2 GB auf. Die maximale Dateigröße unter UnixWare 7 beträgt 1 TB mit VXFS oder HTFS.

OpenServer 6 kann durch die Optimierung des UNIX-Kernels für die Unterstützung großer Dateien (Dateigrößen über 2 GB) konfiguriert werden.

Standardmäßig haben die Einträge in /etc/conf/cf.d/mtune folgende Einstellungen:

Value           Default         Min             Max
-----           -------         ---             ---
SVMMLIM         0x9000000       0x1000000       0x7FFFFFFF
HVMMLIM         0x9000000       0x1000000       0x7FFFFFFF

Um Änderungen am Kernel vorzunehmen, verwenden sie den Befehl idtune name parameter. idtune ändert die Datei /etc/conf/cf.d/stune für Sie. Zur Einstellung der Kernel-Werte führen Sie die folgenden Befehle als root aus:

# /etc/conf/bin/idtune SDATLIM 0x7FFFFFFF
# /etc/conf/bin/idtune HDATLIM 0x7FFFFFFF
# /etc/conf/bin/idtune SVMMLIM 0x7FFFFFFF
# /etc/conf/bin/idtune HVMMLIM 0x7FFFFFFF
# /etc/conf/bin/idtune SFNOLIM 2048
# /etc/conf/bin/idtune HFNOLIM 2048

Erstellen Sie den Kernel anschließend neu und booten Sie ihn mit dem folgenden Befehl:

# /etc/conf/bin/idbuild -B && init 6

Welche Parameterwerte für die Optimierung des Systems geeignet sind, hängt von der Anzahl der Benutzer, die auf die Anwendung oder Datenbank zugreifen, und von der Größe der Datenbank selbst (d. h. dem verwendeten Pufferpool) ab. Die folgenden Kernel-Parameter können mit idtune eingestellt werden:

  • SHMMAX (empfohlene Einstellung: 128 MB) und SHMSEG (empfohlene Einstellung: 15). Diese Parameter beeinflussen die MySQL-Datenbank-Engine bei der Erstellung der Benutzerpufferpools.

  • SFNOLIM und HFNOLIM sollten auf maximal 2048 gesetzt werden.

  • NPROC sollte (abhängig von der Anzahl der Benutzer) auf mindestens 3000/4000 gesetzt werden.

  • Ferner wird die Verwendung der folgenden Formeln zur Berechnung der Werte für SEMMSL, SEMMNS und SEMMNU empfohlen:

    SEMMSL = 13
    

    13 hat sich als optimaler Wert sowohl für Progress als auch für MySQL erwiesen.

    SEMMNS = SEMMSL × number of db servers to be run on the system
    

    Setzen Sie SEMMNS auf den Wert von SEMMSL multipliziert mit der maximalen Anzahl der Datenbankserver, die gleichzeitig auf Ihrem System ausgeführt werden.

    SEMMNU = SEMMNS
    

    SEMMNU setzen Sie dann auf den gleichen Wert wie SEMMNS. Wahrscheinlich würde hier auch ein Wert von 75 Prozent von SEMMNS ausreichen, aber dies ist eine konservative Schätzung.

2.13.5.10. Anmerkungen zu SCO UnixWare 7.1.x und OpenUNIX 8.0.0

Verwenden Sie das aktuelle Produktions-Release von MySQL. Sollten Sie sich für ein älteres MySQL-Release unter UnixWare 7.1.x entscheiden, müssen Sie mindestens die MySQL-Version 3.22.13 verwenden, um Korrekturen für einige Portabilitäts- und betriebssystembezogene Probleme zu erhalten.

Wir konnten MySQL mit dem folgenden configure-Befehl unter UnixWare 7.1.x kompilieren.

CC="cc" CFLAGS="-I/usr/local/include" \
CXX="CC" CXXFLAGS="-I/usr/local/include" \
./configure --prefix=/usr/local/mysql \
    --enable-thread-safe-client \
    --with-innodb --with-openssl --with-extra-charsets=complex

Wenn Sie gcc verwenden wollen, müssen Sie gcc 2.95.3 oder höher einsetzen.

CC=gcc CXX=g++ ... ./configure ...

SCO bietet Betriebssystem-Patches unter ftp://ftp.sco.com/pub/unixware7 für UnixWare 7.1.1, ftp://ftp.sco.com/pub/unixware7/713/ für UnixWare 7.1.3, ftp://ftp.sco.com/pub/unixware7/714/ für UnixWare 7.1.4 und ftp://ftp.sco.com/pub/openunix8 für OpenUNIX 8.0.0 an.

Informationen zu behobenen Sicherheitslücken bietet SCO unter ftp://ftp.sco.com/pub/security/OpenUNIX für OpenUNIX und ftp://ftp.sco.com/pub/security/UnixWare für UnixWare an.

Die maximale Dateigröße unter UnixWare 7 beträgt 1 TB mit VXFS. Einige Betriebssystem-Hilfsprogramme weisen eine Beschränkung auf 2 GB auf.

Unter UnixWare 7.1.4 müssen Sie nichts tun, um in den Genuss der Unterstützung großer Dateien zu kommen. Bei Versionen vor UnixWare 7.1.x müssen Sie zu diesem Zweck fsadm ausführen.

# fsadm -Fvxfs -o largefiles /
# fsadm /         * Note
# ulimit unlimited
# /etc/conf/bin/idtune SFSZLIM 0x7FFFFFFF     ** Note
# /etc/conf/bin/idtune HFSZLIM 0x7FFFFFFF     ** Note
# /etc/conf/bin/idbuild -B
* This should report "largefiles".
** 0x7FFFFFFF represents infinity for these values.

Starten Sie das System mit shutdown neu.

Standardmäßig haben die Einträge in /etc/conf/cf.d/mtune folgende Einstellungen:

Value           Default         Min             Max
-----           -------         ---             ---
SVMMLIM         0x9000000       0x1000000       0x7FFFFFFF
HVMMLIM         0x9000000       0x1000000       0x7FFFFFFF

Um Änderungen am Kernel vorzunehmen, verwenden sie den Befehl idtune name parameter. idtune ändert die Datei /etc/conf/cf.d/stune für Sie. Zur Einstellung der Kernel-Werte führen Sie die folgenden Befehle als root aus:

# /etc/conf/bin/idtune SDATLIM 0x7FFFFFFF
# /etc/conf/bin/idtune HDATLIM 0x7FFFFFFF
# /etc/conf/bin/idtune SVMMLIM 0x7FFFFFFF
# /etc/conf/bin/idtune HVMMLIM 0x7FFFFFFF
# /etc/conf/bin/idtune SFNOLIM 2048
# /etc/conf/bin/idtune HFNOLIM 2048

Erstellen Sie den Kernel anschließend neu und booten Sie ihn mit dem folgenden Befehl:

# /etc/conf/bin/idbuild -B && init 6

Welche Parameterwerte für die Optimierung des Systems geeignet sind, hängt von der Anzahl der Benutzer, die auf die Anwendung oder Datenbank zugreifen, und von der Größe der Datenbank selbst (d. h. dem verwendeten Pufferpool) ab. Die folgenden Kernel-Parameter können mit idtune eingestellt werden:

  • SHMMAX (empfohlene Einstellung: 128 MB) und SHMSEG (empfohlene Einstellung: 15). Diese Parameter beeinflussen die MySQL-Datenbank-Engine bei der Erstellung der Benutzerpufferpools.

  • SFNOLIM und HFNOLIM sollten auf maximal 2048 gesetzt werden.

  • NPROC sollte (abhängig von der Anzahl der Benutzer) auf mindestens 3000/4000 gesetzt werden.

  • Ferner wird die Verwendung der folgenden Formeln zur Berechnung der Werte für SEMMSL, SEMMNS und SEMMNU empfohlen:

    SEMMSL = 13
    

    13 hat sich als optimaler Wert sowohl für Progress als auch für MySQL erwiesen.

    SEMMNS = SEMMSL × number of db servers to be run on the system
    

    Setzen Sie SEMMNS auf den Wert von SEMMSL multipliziert mit der maximalen Anzahl der Datenbankserver, die gleichzeitig auf Ihrem System ausgeführt werden.

    SEMMNU = SEMMNS
    

    SEMMNU setzen Sie dann auf den gleichen Wert wie SEMMNS. Wahrscheinlich würde hier auch ein Wert von 75 Prozent von SEMMNS ausreichen, aber dies ist eine konservative Schätzung.

2.14. Umgebungsvariablen

Dieser Abschnitt listet alle Umgebungsvariablen auf, die direkt oder indirekt von MySQL verwendet werden. Die meisten davon sind auch an anderer Stelle in diesem Handbuch zu finden.

Beachten Sie, dass Optionen in der Befehlszeile Vorrang gegenüber in den Optionsdateien und Umgebungsvariablen angegebenen Werten haben, Werte in Optionsdateien wiederum haben Vorrang gegenüber Werten in Umgebungsvariablen.

Häufig ist es besser, anstelle von Umgebungsvariablen eine Optionsdatei zu verwenden, um das Verhalten von MySQL zu ändern. Siehe auch Using Option Files.

VariableBeschreibung
CXXDer Name Ihres C++-Compilers (für die Ausführung von configure).
CCDer Name Ihres C-Compilers (für die Ausführung von configure).
CFLAGSFlags für Ihren C-Compiler (für die Ausführung von configure).
CXXFLAGSFlags für Ihren C++-Compiler (für die Ausführung von configure).
DBI_USERDer Standardbenutzername für Perl DBI.
DBI_TRACETrace-Optionen für Perl DBI.
HOMEDer Standardpfad für die mysql-Verlaufsdatei ist $HOME/.mysql_history.
LD_RUN_PATHGibt den Speicherort von libmysqlclient.so an.
MYSQL_DEBUGGibt Trace-Optionen für das Debuggen an.
MYSQL_GROUP_SUFFIXSuffixwert für Optionsgruppen (wie die Angabe --defaults-group-suffix).
MYSQL_HISTFILEDer Pfad zur mysql-Verlaufsdatei. Wenn diese Variable gesetzt ist, hat ihr Wert Vorrang gegenüber dem Standard für $HOME/.mysql_history.
MYSQL_HOMEDer Pfad zu dem Verzeichnis, in dem die serverspezifische Datei my.cnf liegt (ab MySQL 5.0.3).
MYSQL_HOSTDer vom mysql-Befehlszeilen-Client verwendete Standard-Hostname.
MYSQL_PS1Der im mysql-Befehlszeilen-Client zu verwendende Befehls-Prompt.
MYSQL_PWDDas Standardkennwort für Verbindungen mit mysqld. Beachten Sie, dass seine Verwendung unsicher ist. Siehe auch End-User Guidelines for Password Security.
MYSQL_TCP_PORTDie Standardnummer des TCP/IP-Ports.
MYSQL_UNIX_PORTDer Name der Standard-Unix-Socketdatei. Sie wird für Verbindungen mit localhost verwendet.
PATHWird von der Shell verwendet, um MySQL-Programme zu finden.
TMPDIRDas Verzeichnis, in dem Temporärdateien eingerichtet werden.
TZHier sollte Ihre lokale Zeitzone eingestellt sein. Siehe auch Time Zone Problems.
UMASKBei der Dateierstellung verwendeter Modus für das Erstellen von Benutzerdateien. Siehe Anmerkung nach dieser Tabelle.
UMASK_DIRBei der Verzeichniserstellung verwendeter Modus für das Erstellen von Benutzerverzeichnissen. Siehe Anmerkung nach dieser Tabelle.
USERDer Standardbenutzername unter Windows und NetWare, der für die Verbindungsherstellung mit mysqld verwendet wird.

Die Variablen UMASK und UMASK_DIR werden trotz ihrer Namen nicht als Masken, sondern als Modi verwendet:

  • Wenn UMASK gesetzt ist, verwendet mysqld ($UMASK | 0600) als Modus für die Dateierstellung, sodass neu eingerichtete Dateien einen Modus im Bereich zwischen 0600 und 0666 haben (alle Werte oktal).

  • Wenn UMASK_DIR gesetzt ist, verwendet mysqld ($UMASK_DIR | 0700) als Basismodus für die Verzeichniserstellung, der dann mit ~(~$UMASK & 0666) durch AND verknüpft wird, sodass neu eingerichtete Verzeichnisse einen Modus im Bereich zwischen 0700 und 0777 haben (alle Werte oktal). Die AND-Operation kann Lese- und Schreibberechtigungen aus dem Verzeichnismodus entfernen, allerdings keine Berechtigungen ausführen.

MySQL geht davon aus, dass der Wert für UMASK oder UMASK_DIR ein Oktalwert ist, wenn er mit einer Null beginnt.

2.15. Anmerkungen zur Perl-Installation

Die Perl-Unterstützung für MySQL erfolgt mithilfe der DBI-/DBD-Clientschnittstelle. Die Schnittstelle erfordert Perl 5.6.0, wobei 5.6.1 und höher bevorzugt wird. DBI funktioniert nicht, wenn Sie eine ältere Perl-Version haben.

Wenn Sie Transaktionen mit Perl DBI verwenden wollen, benötigen Sie DBD::mysql 2.0900. Sofern Sie MySQL 4.1 oder eine neuere Clientbibliothek verwenden, müssen Sie DBD::mysql 2.9003 oder höher einsetzen. Für die Unterstützung serverseitig vorbereiteter Anweisungen ist DBD::mysql 3.0009 oder höher erforderlich.

Die Perl-Unterstützung ist nicht in den MySQL-Distributionen enthalten. Die erforderlichen Module erhalten Sie unter http://search.cpan.org für Unix bzw. durch Verwendung des ActiveState-Programms ppm unter Windows. Die folgenden Abschnitte beschreiben die erforderlichen Abläufe.

Wenn Sie die MySQL-Benchmark-Skripten ausführen wollen, muss die Perl-Unterstützung für MySQL installiert sein (siehe auch Abschnitt 4.1.4, „Die MySQL-Benchmark-Suite“). Sie ist auch für das MySQL Cluster-Hilfsprogramm ndb_size.pl notwendig. Siehe auch ndb_size.pl.

2.15.1. Installieren von Perl unter Unix

Die Perl-Unterstützung durch MySQL setzt voraus, dass Sie die Unterstützung für die MySQL-Clientprogrammierung (Bibliotheken und Header-Dateien) installiert haben. Bei den meisten Installationsmethoden werden die notwendigen Dateien installiert. Haben Sie MySQL allerdings aus RPM-Dateien für Linux installiert, dann vergewissern Sie sich, dass Sie das Entwickler-RPM zur Installation verwendet haben. Die Clientprogramme befinden sich im Client-RPM, die Unterstützung für die Clientprogrammierung jedoch im Entwickler-RPM.

Wenn Sie die Perl-Unterstützung installieren wollen, erhalten Sie die erforderlichen Dateien beim CPAN (Comprehensive Perl Archive Network) unter http://search.cpan.org.

Die einfachste Möglichkeit, Perl-Module unter Unix zu installieren, besteht in der Verwendung des CPAN-Moduls. Ein Beispiel:

shell> perl -MCPAN -e shell
cpan> install DBI
cpan> install DBD::mysql

Die DBD::mysql-Installation führt eine Anzahl von Tests durch. Bei diesen Tests wird versucht, unter Angabe der Standardwerte für Benutzername und Kennwort eine Verbindung zum lokalen MySQL Server herzustellen. (Der Standardbenutzername ist unter Unix Ihr Anmeldename und unter Windows ODBC. Das Standardpasswort heißt „no password“.) Wenn Sie mit diesen Einstellungen keine Verbindung zum Server herstellen können, weil beispielsweise Ihr Konto ein Passwort hat, dann schlagen die Tests fehl. Sie können force install DBD::mysql verwenden, um fehlgeschlagene Tests zu ignorieren.

DBI benötigt das Modul Data::Dumper. Dieses ist unter Umständen bereits installiert, andernfalls sollten Sie es vor der Installation von DBI installieren.

Es ist auch möglich, die Moduldistributionen in Form komprimierter tar-Archive herunterzuladen und die Module manuell zu erstellen. Um beispielsweise eine DBI-Distribution zu entpacken und zu erstellen, verwenden Sie folgende Vorgehensweise:

  1. Entpacken Sie die Distribution in das aktuelle Verzeichnis:

    shell> gunzip < DBI-VERSION.tar.gz | tar xvf -
    

    Dieser Befehl erstellt ein Verzeichnis namens DBI-VERSION.

  2. Wechseln Sie nun in das Stammverzeichnis der entpackten Distribution:

    shell> cd DBI-VERSION
    
  3. Erstellen Sie die Distribution und kompilieren Sie alles:

    shell> perl Makefile.PL
    shell> make
    shell> make test
    shell> make install
    

Der Befehl make test ist wichtig, da mit ihm die Funktionsfähigkeit des Moduls verifiziert wird. Beachten Sie, dass der MySQL Server laufen muss, wenn Sie diesen Befehl während der DBD::mysql-Installation absetzen, um den Schnittstellencode auszuführen; andernfalls schlägt der Test fehl.

Sie sollten die DBD::mysql-Distribution bei jeder Installation eines neuen MySQL-Releases neu erstellen und installieren. Dies gilt insbesondere, wenn Sie beispielsweise feststellen, dass all Ihre DBI-Skripten nach der Aktualisierung von MySQL nicht mehr funktionieren.

Wenn Sie nicht die erforderlichen Berechtigungen zur Installation von Perl-Modulen im Systemverzeichnis haben oder lokale Perl-Module installieren wollen, ist die folgende Referenz für Ihre Belange vielleicht recht nützlich: http://servers.digitaldaze.com/extensions/perl/modules.html#modules.

Lesen Sie dort das Kapitel „Installing New Modules that Require Locally Installed Modules“. Installation von ActiveState-Perl unter Windows

2.15.2. Installieren von ActiveState Perl unter Windows

Unter Windows müssen Sie Folgendes tun, um das DBD-Modul mit ActiveState-Perl zu installieren:

  1. Beschaffen Sie ActiveState Perl unter http://www.activestate.com/Products/ActivePerl/ und installieren Sie es.

  2. Öffnen Sie ein Konsolenfenster (ein „DOS-Fenster“).

  3. Stellen Sie ggf. die Variable HTTP_proxy ein. So kann etwa folgende Einstellung erforderlich sein:

    set HTTP_proxy=my.proxy.com:3128
    
  4. Starten Sie das PPM-Programm:

    C:\> C:\perl\bin\ppm.pl
    
  5. Installieren Sie DBI, sofern Sie dies nicht bereits getan haben:

    ppm> install DBI
    
  6. Führen Sie, wenn alles geklappt hat, folgenden Befehl aus:

    ppm> install DBD-mysql
    

Diese Vorgehensweise sollte bei ActiveState Perl 5.6 oder höher funktionieren.

Klappt dies nicht, dann sollten Sie stattdessen den MyODBC-Treiber installieren und über ODBC eine Verbindung zum MySQL Server herstellen:

use DBI;
$dbh= DBI->connect("DBI:ODBC:$dsn",$user,$password) ||
  die "Got error $DBI::errstr when connecting to $dsn\n";

2.15.3. Probleme bei der Benutzung der DBI/DBD-Schnittstelle von Perl

Wenn Perl meldet, dass das Modul ../mysql/mysql.so nicht gefunden werden kann, dann liegt das wahrscheinlich daran, dass Perl die gemeinsame Bibliothek libmysqlclient.so nicht findet. Sie sollten dieses Problem auf eine der folgenden Weisen lösen können:

  • Kompilieren Sie die Distribution DBD::mysql mit perl Makefile.PL -static -config statt mit perl Makefile.PL.

  • Kopieren Sie libmysqlclient.so in das Verzeichnis, in dem sich Ihre anderen gemeinsamen Bibliotheken befinden (dies ist wahrscheinlich /usr/lib oder /lib).

  • Ändern Sie die -L-Optionen zur Kompilierung von DBD::mysql so ab, dass die tatsächliche Position von libmysqlclient.so berücksichtigt wird.

  • Unter Linux können Sie den Pfadnamen des Verzeichnisses, in dem sich libmysqlclient.so befindet, zur Datei /etc/ld.so.conf hinzufügen.

  • Fügen Sie den Pfad des Verzeichnisses, in dem sich libmysqlclient.so befindet, der Umgebungsvariablen LD_RUN_PATH hinzu. Einige Systeme verwenden stattdessen LD_LIBRARY_PATH.

Beachten Sie, dass Sie möglicherweise auch die -L-Optionen ändern müssen, wenn auch andere Bibliotheken vom Linker nicht gefunden werden. Kann der Linker beispielsweise libc nicht finden, weil sich die Datei in /lib befindet, der Verknüpfungsbefehl aber -L/usr/lib angibt, dann ändern Sie die Option -L zu -L/lib oder fügen -L/lib zum vorhandenen Verknüpfungsbefehl hinzu.

Wenn Sie die folgenden Fehler von DBD::mysql erhalten, verwenden Sie wahrscheinlich gcc (oder eine alte Binärdatei, die mit gcc kompiliert wurde):

/usr/bin/perl: can't resolve symbol '__moddi3'
/usr/bin/perl: can't resolve symbol '__divdi3'

Fügen Sie -L/usr/lib/gcc-lib/...-lgcc zum Verknüpfungsbefehl hinzu, wenn die Bibliothek mysql.so erstellt wird (überprüfen Sie die Ausgabe von make bezüglich mysql.so, wenn Sie den Perl-Client kompilieren). Die -L-Option sollte den Pfadnamen des Verzeichnisses angeben, in dem libgcc.a auf Ihrem System gespeichert ist.

Eine andere Ursache dieses Problems könnte sein, dass nicht sowohl Perl als auch MySQL mit gcc kompiliert wurden. In diesem Fall können Sie die Nichtübereinstimmung beheben, indem Sie beide mit gcc kompilieren.

Wenn Sie die Tests ausführen, gibt DBD::mysql unter Umständen die folgende Fehlermeldung aus:

t/00base............install_driver(mysql) failed:
Can't load '../blib/arch/auto/DBD/mysql/mysql.so' for module DBD::mysql:
../blib/arch/auto/DBD/mysql/mysql.so: undefined symbol:
uncompress at /usr/lib/perl5/5.00503/i586-linux/DynaLoader.pm line 169.

Dies bedeutet, dass Sie die Komprimierungsbibliothek -lz in der Verknüpfungszeile hinzufügen müssen. Dies können Sie tun, indem Sie in der Datei lib/DBD/mysql/Install.pm die Zeile

$sysliblist .= " -lm";

wie folgt ändern:

$sysliblist .= " -lm -lz";

Danach müssen Sie make realclean ausführen und nachfolgend von vorne mit der Installation beginnen.

Wenn Sie DBI unter SCO installieren wollen, müssen Sie Makefile in DBI-xxx und allen Unterverzeichnissen bearbeiten. Beachten Sie, dass das Folgende gcc 2.95.2 oder höher voraussetzt:

OLD:                                  NEW:
CC = cc                               CC = gcc
CCCDLFLAGS = -KPIC -W1,-Bexport       CCCDLFLAGS = -fpic
CCDLFLAGS = -wl,-Bexport              CCDLFLAGS =
LD = ld                               LD = gcc -G -fpic
LDDLFLAGS = -G -L/usr/local/lib       LDDLFLAGS = -L/usr/local/lib
LDFLAGS = -belf -L/usr/local/lib      LDFLAGS = -L/usr/local/lib
LD = ld                               LD = gcc -G -fpic
OPTIMISE = -Od                        OPTIMISE = -O1
OLD:
CCCFLAGS = -belf -dy -w0 -U M_XENIX -DPERL_SCO5 -I/usr/local/include
NEW:
CCFLAGS = -U M_XENIX -DPERL_SCO5 -I/usr/local/include

Diese Änderungen sind erforderlich, weil der Perl-Dynaloader die DBI-Module nicht lädt, wenn diese mit icc oder cc kompiliert wurden.

Wollen Sie das Perl-Modul auf einem System verwenden, das keine dynamischen Verknüpfungen unterstützt (wie z. B. SCO), dann können Sie eine statische Perl-Version erzeugen, die DBI und DBD::mysql enthält. Dies funktioniert so, dass Sie eine Perl-Version mit verknüpftem DBI-Code erzeugen und diese über Ihre aktuelle Perl-Installation installieren. Dieses verwenden Sie dann zur Erstellung einer Perl-Version, die zusätzlich den verknüpften DBD-Code beinhaltet und die Sie dann installieren.

Unter SCO müssen Sie zuvor die folgenden Umgebungsvariablen einstellen:

LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib:/usr/progressive/lib

Oder:

LD_LIBRARY_PATH=/usr/lib:/lib:/usr/local/lib:/usr/ccs/lib:\
    /usr/progressive/lib:/usr/skunk/lib
LIBPATH=/usr/lib:/lib:/usr/local/lib:/usr/ccs/lib:\
    /usr/progressive/lib:/usr/skunk/lib
MANPATH=scohelp:/usr/man:/usr/local1/man:/usr/local/man:\
    /usr/skunk/man:

Sie erstellen zunächst eine Perl-Version, die ein statisch verknüpftes DBI-Modul enthält. Dies tun Sie durch Ausführen der folgenden Befehle in dem Verzeichnis, in dem Ihre DBI-Distribution gespeichert ist:

shell> perl Makefile.PL -static -config
shell> make
shell> make install
shell> make perl

Danach müssen Sie das neue Perl installieren. Die Ausgabe von make perl gibt den exakten make-Befehl an, den Sie ausführen müssen, um die Installation durchzuführen. Unter SCO heißt der Befehl make -f Makefile.aperl inst_perl MAP_TARGET=perl.

Als Nächstes verwenden Sie das gerade erstellte Perl zur Erstellung eines anderen Perl, welches auch ein statisch verknüpftes DBD::mysql enthält. Hierzu führen Sie die folgenden Befehle in dem Verzeichnis aus, in dem sich Ihre DBD::mysql-Distribution befindet:

shell> perl Makefile.PL -static -config
shell> make
shell> make install
shell> make perl

Abschließend sollten Sie dieses neue Perl installieren. Auch hier zeigt die Ausgabe von make perl den zu verwendenden Befehl an.

Kapitel 3. MySQL-Client-Programme

In diesem Abschnitt werden Client-Programme beschrieben, die eine Verbindung zum MySQL-Server herstellen.

3.1. mysql — Das MySQL Command-Line Tool

mysql ist eine einfache SQL-Shell (mit GNU-readline-Fähigkeiten). Sie unterstützt die interaktive und nichtinteraktive Nutzung. Bei interaktiver Nutzung werden die Abfrageergebnisse im ASCII-Tabellenformat angezeigt. Wird sie hingegen nichtinteraktiv verwendet (z. B. als Filter), dann wird das Ergebnis durch Tabulatoren getrennt aufgelistet. Das Ausgabeformat kann mit den folgenden Befehlsoptionen beeinflusst werden.

Wenn Sie bei großen Ergebnismengen Probleme aufgrund mangelnden Speichers haben, verwenden Sie die Option --quick. Hierdurch wird mysql gezwungen, die Ergebnisse datensatzweise vom Server abzurufen, statt vor der Anzeige die gesamte Ergebnismenge zu holen und sie temporär im Speicher abzulegen. Dies wird durch Rückgabe der Ergebnismenge mithilfe der C-API-Funktion mysql_use_result() in der Client/Server-Bibliothek statt mit mysql_store_result() ermöglicht.

Die Verwendung von mysql ist ganz leicht. Rufen Sie es einfach wie folgt über die Eingabeaufforderung Ihres Befehls-Interpreters auf:

shell> mysql db_name

Oder:

shell> mysql --user=user_name --password=your_password db_name

Geben Sie dann eine SQL-Anweisung ein, die auf „;“, \g oder \G endet, und betätigen Sie die Eingabetaste.

Ab MySQL 5.1.10 führt Strg-C dazu, dass mysql versucht, die aktuelle Anweisung abzubrechen. Wenn dies nicht ausgeführt werden kann oder nochmals Strg-C gedrückt wird, bevor die Anweisung abgebrochen wird, wird mysql beendet. Früher führte Strg-C dazu, dass mysql in allen Fällen beendet wurde.

Sie können SQL-Anweisungen wie folgt in einer Skriptdatei (Stapelverarbeitungsdatei) ausführen:

shell> mysql db_name < script.sql > output.tab

3.1.1. mysql Optionen

mysql unterstützt die Optionen in der folgenden Liste. Es liest auch Optionsdateien und unterstützt die beschriebenen Optionen für deren Verarbeitung (siehe Command-Line Options that Affect Option-File Handling).

  • --help, -?

    Zeigt eine Hilfsmeldung an und wird dann beendet.

  • --auto-rehash

    Automatisches Rehashing aktivieren. Diese Option ist standardmäßig aktiviert, wodurch eine Autovervollständigung von Datenbank-, Tabellen- und Spaltennamen ermöglicht wird. Verwenden Sie --disable-auto-rehash, um Rehashing zu deaktivieren. Dies sorgt zwar für einen schnelleren Start von mysql, aber Sie müssen den Befehl rehash absetzen, wenn Sie die Vervollständigung von Namen verwenden wollen.

    Um einen Namen zu vervollständigen, geben Sie den ersten Teil ein, und drücken Sie die Tab-Taste. Wenn der Name unzweideutig ist, vervollständigt mysql ihn. Ansonsten können Sie Tab drücken, um nochmals die möglichen Namen zu sehen, die mit den Buchstaben anfangen, die Sie bisher eingegeben haben. Die Vervollständigung erfolgt nicht, wenn es keine Standarddatenbank gibt.

  • --batch, -B

    Gibt die Ergebnisse mit einem Tabulator als Spaltentrennzeichen aus. Jeder Datensatz beginnt in einer neuen Zeile. Bei dieser Option verwendet mysql die Verlaufsdatei nicht.

    Der Stapelbetrieb führt zu einem nichttabellarischen Ausgabeformat und einem Escapen von Sonderzeichen. Das Escapen kann unter Verwendung des raw-Modus deaktiviert werden; Details dazu in der Beschreibung für die --raw-Option.

  • --character-sets-dir=path

    Das Verzeichnis, in dem Zeichensätze installiert sind. Siehe auch Character Set Configuration.

  • --column-names

    Spaltennamen in Ergebnissen schreiben.

  • --column-type-info, -m

    Ergebnismengen-Metadaten anzeigen. Diese Option wurde in MySQL 5.1.14 hinzugefügt. (Davor wurde --debug-info verwendet.) Die Kurzform der Option -m wurde in MySQL 5.1.21 hinzugefügt.

  • --comments, -c

    Bestimmt, ob Kommentare in Anweisungen, die an den Server geschickt werden, beibehalten werden. Die Voreinstellung ist --skip-comments (Kommentare verwerfen), --comments aktiviert Kommentare (behält Kommentare bei). Diese Option wurde in MySQL 5.1.23 hinzugefügt.

  • --compress, -C

    Komprimiert alle Daten, die zwischen Client und Server ausgetauscht werden, sofern beide die Komprimierung unterstützen.

  • --database=db_name, -D db_name

    Die zu verwendende Datenbank. Diese Option ist in erster Linie für Optionsdateien gedacht.

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

    Schreibt ein Debuglog. Der String debug_options heißt häufig 'd:t:o,file_name'. Standardwert ist 'd:t:o,/tmp/mysql.trace'.

  • --debug-check

    Gibt einige Debuginformationen aus, wenn das Programm beendet wird. Diese Option wurde in MySQL 5.1.21 hinzugefügt.

  • --debug-info, -T

    Vor MySQL 5.1.14 druckt diese Option Debuginformationen sowie Speicher- und CPU-Nutzungsstatistiken beim Beenden des Programms und zeigt Ergebnismengen-Metadaten während der Ausführung an. Verwenden Sie ab MySQL 5.1.14 --column-type-info, um Ergebnismengen-Metadaten anzuzeigen.

  • --default-character-set=charset_name

    Verwendet charset_name als Standardzeichensatz. Siehe auch Character Set Configuration.

  • --delimiter=str

    Setzt den Anweisungsbegrenzer. Die Voreinstellung ist das Semikolonzeichen („;“).

  • --disable-named-commands

    Deaktiviert benannte Befehle. Verwenden Sie ausschließlich die Form \* oder benannte Befehle nur am Anfang einer Zeile, die mit einem Semikolon („;“) endet. mysql startet mit dieser standardmäßig aktivierten Option. Allerdings funktionieren Befehle im langen Format auch bei dieser Option noch in der ersten Zeile. Siehe auch Abschnitt 3.1.2, „mysql-Befehle“.

  • --execute=statement, -e statement

    Führt die Anweisung aus und wird dann beendet. Das Standardausgabeformat entspricht dem mit --batch erzeugten. Einige Beispiele finden Sie in Using Options on the Command Line.

  • --force, -f

    Das Programm wird auch dann fortgesetzt, wenn ein SQL-Fehler auftritt.

  • --host=host_name, -h host_name

    Stellt eine Verbindung zum MySQL Server auf dem angegebenen Host her.

  • --html, -H

    Erzeugt eine HTML-formatierte Ausgabe.

  • --ignore-spaces, -i

    Ignoriert Leerzeichen nach Funktionsnamen. Die Auswirkung dieser Option wird in der Erläuterung zum IGNORE_SPACE-SQL-Modus in Server SQL Modes beschrieben.

  • --line-numbers

    Schreibt Zeilennummern für Fehler. Deaktivieren Sie diese Option mit --skip-line-numbers.

  • --local-infile[={0|1}]

    Aktiviert oder deaktiviert die LOCAL-Funktionalität für LOAD DATA INFILE. Ohne angegebenen Wert aktiviert die Option LOCAL. Die Option kann als --local-infile=0 oder als --local-infile=1 angegeben werden, wenn LOCAL ausdrücklich deaktiviert bzw. aktiviert werden soll. Die Aktivierung von LOCAL wirkt sich nicht aus, wenn die Unterstützung durch den Server fehlt.

  • --named-commands, -G

    Aktiviert benannte mysql-Befehle. Neben Befehlen im Kurzformat sind auch solche mit langen Namen zulässig. Beispielsweise werden sowohl quit als auch \q akzeptiert. Verwenden Sie --skip-named-commands, um benannte Befehle zu deaktivieren. Siehe auch Abschnitt 3.1.2, „mysql-Befehle“.

  • --no-auto-rehash, -A

    Veraltete Form von -skip-auto-rehash. Verwenden Sie stattdessen --disable-auto-rehash. Siehe Beschreibung zu --auto-rehash.

  • --no-beep, -b

    Unterbindet die Ausgabe eines Warntons bei Auftreten eines Fehlers.

  • --no-named-commands, -g

    Veraltet, verwenden Sie stattdessen --disable-named-commands.

  • --no-pager

    Veraltete Form von --skip-pager. Siehe --pager-Option.

  • --no-tee

    Unterbindet das Kopieren der Ausgabe in einer Datei. Abschnitt 3.1.2, „mysql-Befehle“, enthält eine eingehendere Beschreibung von Tee-Dateien.

  • --one-database, -o

    Ignoriert alle Anweisungen mit Ausnahme derjenigen, die an die auf der Befehlszeile benannte Standarddatenbank gerichtet sind. Dies ist nützlich, um Aktualisierungen anderer Datenbanken im Binärlog zu übergehen.

  • --pager[=command]

    Verwendet den angegebenen Befehl zur Anzeige der Abfrageausgabe Seite für Seite. Wird der Befehl weggelassen, dann wird der Standardpager verwendet, der in Ihrer Umgebungsvariable PAGER gespeichert ist. Zulässige Pager sind less more cat [> filename] und so weiter. Diese Option funktioniert nur unter Unix. Im Stapelbetrieb funktioniert sie nicht. Um Seitenwechsel zu deaktivieren, verwenden Sie --skip-pager. Abschnitt 3.1.2, „mysql-Befehle“, enthält eine eingehendere Beschreibung zum Pager.

  • --password[=password], -p[password]

    Verwendet das angegebene Passwort zur Verbindung mit dem Server. Wenn Sie die Kurzform der Option (-p) verwenden, dürfen Sie kein Leerzeichen zwischen Option und Passwort setzen. Lassen Sie den Wert password auf die Option --password bzw. -p folgend weg, dann werden Sie zur Eingabe des Passworts aufgefordert.

    Die Angabe eines Passworts direkt auf der Befehlszeile ist als nicht sicher einzuordnen. Siehe auch End-User Guidelines for Password Security.

  • --pipe, -W

    Stellt unter Windows eine Verbindung mit dem Server über eine Named Pipe her. Diese Option gilt nur für Verbindungen zu einem lokalen Server und nur wenn der Server Named-Pipe-Verbindungen unterstützt.

  • --port=port_num, -P port_num

    Die TCP/IP-Portnummer, die für die Verbindung verwendet werden soll.

  • --prompt=format_str

    Setzt die Eingabeaufforderung auf das angegebene Format. Standardwert ist mysql>. Die Sondersequenzen, die die Eingabeaufforderung enthalten kann, sind unter Abschnitt 3.1.2, „mysql-Befehle“, beschrieben.

  • --protocol={TCP|SOCKET|PIPE|MEMORY}

    Das Verbindungsprotokoll, das für die Verbindung mit dem Server verwendet wird. Es ist nützlich, wenn die anderen Verbindungsparameter normalerweise dazu führen würden, dass ein anderes Protokoll verwendet wird als dasjenige, das Sie wollen. Details zu den zulässigen Werten finden Sie unter Connecting to the MySQL Server.

  • --quick, -q

    Unterbindet die Zwischenspeicherung der einzelnen Abfrageergebnisse (d. h., jeder Datensatz wird direkt beim Empfang angezeigt). Hierdurch kann der Server verlangsamt werden, wenn die Ausgabe aussetzt. Bei dieser Option verwendet mysql die Verlaufsdatei nicht.

  • --raw, -r

    Für die tabellarische Ausgabe aktiviert diese Option „Rahmen“ um Spalten, damit Spaltenwerte von anderen unterschieden werden können. Für die nichttabellarische Ausgabe (im Stapelmodus oder bei Angabe der Option --batch oder --silent) werden Sonderzeichen in der Ausgabe mit Escape-Zeichen umgangen, so dass sie leicht identifiziert werden können. Neue Zeile, Tabulator, NUL und Backslash werden als \n, \t, \0 und \\ geschrieben. Die -- raw-Option deaktiviert dieses Escaping von Zeichen.

    Das folgende Beispiel zeigt eine tabellarische und eine nichttabellarische Ausgabe und die Verwendung des raw-Modus, um Escaping zu deaktivieren:

    % mysql
    mysql> SELECT CHAR(92);
    +----------+
    | CHAR(92) |
    +----------+
    | \        |
    +----------+
    % mysql -s
    mysql> SELECT CHAR(92);
    CHAR(92)
    \\
    % mysql -s -r
    mysql> SELECT CHAR(92);
    CHAR(92)
    \
    
  • --reconnect

    Wenn die Verbindung zum Server abbricht, wird automatisch eine Wiederverbindung versucht. Bei jedem Verbindungsabbruch wird genau ein Wiederverbindungsversuch unternommen. Um diese Versuche zu unterbinden, verwenden Sie --skip-reconnect.

  • --safe-updates, --i-am-a-dummy, -U

    Gestattet nur diejenigen UPDATE- und DELETE-Anweisungen, die über Schlüsselwerte angeben, welche Datensätze zu ändern sind. Wenn Sie diese Option in einer Optionsdatei angegeben haben, können Sie sie mithilfe von --safe-updates auf der Befehlszeile außer Kraft setzen. Weitere Informationen zu dieser Option finden Sie in Abschnitt 3.1.5, „mysql-Tipps“.

  • --secure-auth

    Sendet kein Passwort im alten (d. h. vor MySQL 4.1.1 gültigen) Format an den Server. Hierdurch werden Verbindungen auf solche Server beschränkt, die das neue Passwortformat verwenden.

  • --show-warnings

    Sorgt dafür, dass – sofern erforderlich – nach jeder Anweisung Warnungen angezeigt werden. Diese Option gilt für den interaktiven und den Stapelbetrieb.

  • --sigint-ignore

    Ignoriert SIGINT-Signale (diese werden normalerweise durch Eingabe von Strg+C abgesetzt).

  • --silent, -s

    Stummer Modus. Erzeugt weniger Ausgabedaten. Diese Option kann mehrfach angegeben werden, um den Umfang der Ausgabe kontinuierlich zu verringern.

    Diese Option führt zu einem nichttabellarischen Ausgabeformat und einem Escapen von Sonderzeichen. Das Escapen kann unter Verwendung des raw-Modus deaktiviert werden; Details dazu in der Beschreibung für die --raw-Option.

  • --skip-column-names, -N

    Schreibt keine Spaltennamen in die Ergebnisse. Das kurze Format -N ist veraltet, verwenden Sie stattdessen das lange Format.

  • --skip-line-numbers, -L

    Schreibt keine Zeilennummern für Fehler. Dies ist praktisch, wenn Sie Ergebnisdateien vergleichen wollen, die Fehlermeldungen enthalten. Das kurze Format -L ist veraltet, verwenden Sie stattdessen das lange Format.

  • --socket=path, -S path

    Bei Verbindungen mit localhost ist dies die zu verwendende Unix-Socketdatei bzw. (unter Windows) der Name der zu verwendenden Named Pipe.

  • --ssl*

    Optionen, die mit --ssl anfangen, geben an, ob Sie eine Serververbindung über SSL herstellen und wo Sie SSL-Schlüssel und Zertifikate finden. Siehe auch SSL Command Options.

  • --table, -t

    Zeigt die Ausgabe im Tabellenformat an. Dies ist das Standardverhalten bei interaktivem Betrieb und kann zudem für die Ausgabe im Stapelbetrieb verwendet werden.

  • --tee=file_name

    Hängt eine Kopie der Ausgabe an die angegebene Datei an. Diese Option funktioniert nicht im Stapelbetrieb. Abschnitt 3.1.2, „mysql-Befehle“, enthält eine eingehendere Beschreibung von Tee-Dateien.

  • --unbuffered, -n

    Synchronisiert den Puffer nach jeder Abfrage.

  • --user=user_name, -u user_name

    Verwendet den angegebenen MySQL-Benutzernamen zur Verbindung mit dem Server.

  • --verbose, -v

    Ausführlicher Modus. Es werden zusätzliche Angaben zu den Aktivitäten des Programms erzeugt. Diese Option kann mehrfach angegeben werden, um den Umfang der Ausgabe kontinuierlich zu erhöhen. (Beispielsweise erzeugt -v -v -v auch im Stapelbetrieb eine Ausgabe im Tabellenformat.)

  • --version, -V

    Zeigt die Versionsinformation an und wird dann beendet.

  • --vertical, -E

    Gibt die Abfrageausgabe vertikal angeordnet aus (d. h. eine Zeile pro Spaltenwert). Ohne diese Option können Sie die vertikale Ausgabe für einzelne Anweisungen festlegen, indem Sie sie mit \G abschließen.

  • --wait, -w

    Wenn die Verbindung nicht hergestellt werden kann, erfolgt anstelle eines Abbruchs nach einer Wartezeit ein neuer Verbindungsversuch.

  • --xml, -X

    Erzeugt eine XML-formatierte Ausgabe.

    Anmerkung

    Vor MySQL 5.1.12 gab es keine Differenzierung in der Ausgabe, wenn Sie diese Option zwischen den NULL-Wert enthaltenden Spalten und das String-Literal 'NULL' enthaltenden Spalten verwendet haben; beide wurden so dargestellt:

    <field name="column_name">NULL</field>
    

    Ab MySQL 5.1.12 wird die Ausgabe verwendet, wenn --xml mit mysql der von mysqldump --xml übereinstimmt. Einzelheiten siehe Abschnitt 3.4, „mysqldump — ein Datenbanksicherungsprogramm“.

    Ab MySQL 5.1.18 verwendet die XML-Ausgabe auch einen XML-Namensraum, wie hier gezeigt:

    shell> mysql --xml -uroot -e "SHOW VARIABLES LIKE 'version%'"
    <?xml version="1.0"?>
    <resultset statement="SHOW VARIABLES LIKE 'version%'" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <row>
    <field name="Variable_name">version</field>
    <field name="Value">5.0.40-debug</field>
    </row>
    <row>
    <field name="Variable_name">version_comment</field>
    <field name="Value">Source distribution</field>
    </row>
    <row>
    <field name="Variable_name">version_compile_machine</field>
    <field name="Value">i686</field>
    </row>
    <row>
    <field name="Variable_name">version_compile_os</field>
    <field name="Value">suse-linux-gnu</field>
    </row>
    </resultset>
    

    (Siehe Bug#25946.)

Sie können mit der Option --var_name=value auch die folgenden Variablen einstellen: Das --set-variable-Format ist veraltet.

  • connect_timeout

    Anzahl der Sekunden bis zur Zeitüberschreitung der Verbindung. (Der Vorgabewert ist 0.)

  • max_allowed_packet

    Maximaler Umfang der vom Server gesendeten oder empfangenen Pakete. (Der Vorgabewert ist 16 Mbyte.)

  • max_join_size

    Das automatische Limit für Datensätze in einem Join bei Verwendung von --safe-updates. (Der Vorgabewert beträgt 1.000.000.)

  • net_buffer_length

    Puffergröße für die TCP/IP- und Socketkommunikation. (Der Vorgabewert ist 16 Kbyte.)

  • select_limit

    Automatisches Limit für SELECT-Anweisungen bei Verwendung von --safe-updates. (Der Vorgabewert beträgt 1,000.)

Unter Unix schreibt der mysql-Client einen Eintrag mit ausgeführten Anweisungen in eine Verlaufsdatei. Standardmäßig heißt diese Datei .mysql_history und wird im Stammverzeichnis erstellt. Durch Einstellen der Umgebungsvariablen MYSQL_HISTFILE können Sie eine andere Datei angeben.

Das .mysql_history sollte mit einem einschränkenden Zugriffsmodus geschützt werden, weil sensitive Informationen hinein geschrieben werden könnten, z. B. der Text von SQL-Anweisungen, die Kennwörter enthalten. Siehe auch End-User Guidelines for Password Security.

Wenn Sie keine Verlaufsdatei führen wollen, entfernen Sie zunächst .mysql_history (sofern vorhanden) und verwenden daraufhin eine der folgenden Methoden:

  • Setzen Sie die Variable MYSQL_HISTFILE auf /dev/null. Damit diese Einstellung bei jeder Anmeldung angewendet wird, müssen Sie sie in eine der Startdateien Ihrer Shell schreiben.

  • Erstellen Sie .mysql_history als symbolische Verknüpfung auf /dev/null:

    shell> ln -s /dev/null $HOME/.mysql_history
    

    Dies müssen Sie nur einmal tun.

3.1.2. mysql-Befehle

mysql sendet jede von Ihnen abgesetzte SQL-Anweisung zur Ausführung an den Server. Es gibt aber auch eine Reihe von Befehlen, die mysql selbst interpretiert. Eine Liste dieser Befehle erhalten Sie, indem Sie help oder \h an der Eingabeaufforderung mysql> eingeben:

mysql> help
List of all MySQL commands:
Note that all text commands must be first on line and end with ';'
?         (\?) Synonym for `help'.
clear     (\c) Clear command.
connect   (\r) Reconnect to the server. Optional arguments are db and host.
delimiter (\d) Set statement delimiter.
edit      (\e) Edit command with $EDITOR.
ego       (\G) Send command to mysql server, display result vertically.
exit      (\q) Exit mysql. Same as quit.
go        (\g) Send command to mysql server.
help      (\h) Display this help.
nopager   (\n) Disable pager, print to stdout.
notee     (\t) Don't write into outfile.
pager     (\P) Set PAGER [to_pager]. Print the query results via PAGER.
print     (\p) Print current command.
prompt    (\R) Change your mysql prompt.
quit      (\q) Quit mysql.
rehash    (\#) Rebuild completion hash.
source    (\.) Execute an SQL script file. Takes a file name as an argument.
status    (\s) Get status information from the server.
system    (\!) Execute a system shell command.
tee       (\T) Set outfile [to_outfile]. Append everything into given
               outfile.
use       (\u) Use another database. Takes database name as argument.
charset   (\C) Switch to another charset. Might be needed for processing
               binlog with multi-byte charsets.
warnings  (\W) Show warnings after every statement.
nowarning (\w) Don't show warnings after every statement.
For server side help, type 'help contents'

Für jeden Befehl gibt es eine Lang- und eine Kurzform. Anders als bei der Langform wird die Groß-/Kleinschreibung bei der Kurzform unterschieden. Der Langform eines Befehls kann optional ein Semikolon als Trennzeichen folgen; dieses sollte bei der Kurzform weggelassen werden.

Die Verwendung der Kurzform von Befehlen in mehrzeiligen /* ... */-Kommentaren wird nicht unterstützt.

  • help [arg], \h [arg], \? [arg], ? [arg]

    Zeigt eine Hilfemeldung an, die die verfügbaren mysql-Befehle aufführt.

    Wenn Sie ein Argument zum help-Befehl angeben, verwendet mysql es als einen Suchstring, um auf serverseitige Hilfe aus dem Inhalt des MySQL-Handbuchs zuzugreifen. Weitere Informationen siehe Abschnitt 3.1.3, „Serverseitige mysql-Hilfe“.

  • charset charset_name, \C charset_name

    Ändert den Standardzeichensatz und gibt eine SET NAMES-Anweisung aus. So kann der Zeichensatz auf dem Client und dem Server synchronisiert bleiben, wenn mysql mit aktivierter Option auto-reconnect ausgeführt wird (nicht empfohlen), weil der angegebene Zeichensatz für erneute Verbindungen verwendet wird. Dieser Befehl wurde in MySQL 5.1.7 hinzugefügt.

  • clear, \c

    Löscht die aktuelle Eingabe. Verwenden Sie diesen Befehl, wenn Sie sich dazu entschließen, die Anweisung doch nicht auszuführen, die Sie gerade eingeben.

  • connect [db_name host_name]], \r [db_name host_name]]

    Stellt eine erneute Verbindung zum Server her. Der optionale Datenbankname und Hostnamensargumente können angegeben werden, um die Standarddatenbank oder den Host anzugeben, auf dem der Server ausgeführt wird. Falls sie weggelassen werden, werden die aktuellen Werte verwendet.

  • delimiter str, \d str

    Ändert den String, den mysql als Trennzeichen zwischen SQL-Anweisungen interpretiert. Die Voreinstellung ist das Semikolonzeichen („;“).

    Der Begrenzer kann als ein Argument in Anführungszeichen oder ohne Anführungszeichen angegeben werden. Das Einschließen in Anführungszeichen kann mit einfachen Anführungszeichen (') oder mit doppelten (") Anführungszeichen erfolgen. Um ein Anführungszeichen innerhalb eines in Anführungszeichen gesetzten Strings anzugeben, schließen Sie entweder den String in die anderen Anführungszeichen ein oder escapen das Anführungszeichen mit einem Backslash („\“). Der Backslash sollte außerhalb von in Anführungszeichen gesetzten Strings vermieden werden, weil es das Escape-Zeichen für MySQL ist. Für ein nicht in Anführungszeichen gesetztes Argument ist der Begrenzer, bis zum ersten Leerzeichen oder bis zum Zeilenende zu lesen. Für ein in Anführungszeichen gesetztes Argument ist der Begrenzer bis zum entsprechenden Anführungszeichen in der Zeile zu lesen.

    Wenn der von mysql erkannte Begrenzer auf eine andere Einstellung als die Voreinstellung („;“) gesetzt ist, werden Instanzen dieses Zeichens dem Server ohne Interpretation geschickt. Allerdings interpretiert der Server selbst „;“ noch als Anweisungsbegrenzer und verarbeitet die Anweisungen dementsprechend. Dieses Verhalten auf der Serverseite tritt für Mehrfachanweisungsausführung (siehe C API Support for Multiple Statement Execution) und für die Analyse des Hauptteils von Stored Procedures und Funktionen, Triggern und Ereignissen (siehe Defining Stored Programs) in Aktion.

  • edit, \e

    Editiert die aktuell eingegebene Anweisung. mysql überprüft die Werte der EDITOR- und VISUAL-Umgebungsvariablen, um zu entscheiden, welchen Editor es verwenden soll. Der Standardeditor ist vi, wenn keine Variable gesetzt wurde.

    Der Befehl edit funktioniert nur in Unix.

  • ego, \G

    Schickt die aktuelle Anweisung an den ausführenden Server und zeigt das Ergebnis in vertikalem Format an.

  • exit, \q

    Beendet mysql.

  • go, \g

    Schickt die aktuelle Anweisung an den ausführenden Server.

  • nopager, \n

    Deaktiviert Ausgabeseitenwechsel. Siehe Beschreibung zu pager.

    Der Befehl nopager funktioniert nur in Unix.

  • notee, \t

    Deaktiviert die Ausgabekopierung in die Tee-Datei. Siehe Beschreibung zu tee.

  • nowarning, \w

    Aktiviert die Anzeige von Warnungen nach jeder Anweisung.

  • pager [command], \P [command]

    Aktiviert Ausgabeseitenwechsel. Wenn Sie die Option --pager unter mysql aufrufen, ist es möglich, sich Abfrageergebnisse anzuschauen oder in interaktivem Modus mit Unix-Programmen wie less, more oder ähnlichen Programmen zu durchsuchen. Wenn Sie keinen Wert für die Option angeben, überprüft mysql den Wert der PAGER-Umgebungsvariablen und setzt den Pager auf diesen Wert.

    Interaktiv lässt sich das Paging mithilfe des Befehls pager aktivieren und mit nopager deaktivieren. Der Befehl nimmt ein optionales Argument entgegen; ist es vorhanden, dann wird das entsprechende Pager-Programm ausgewählt. Ohne Argumentangabe wird der Pager, der über die Befehlszeile angegeben wurde, oder stdout ausgewählt (sofern überhaupt kein Pager festgelegt wurde).

    Die seitenweise Ausgabe funktioniert nur unter Unix, da sie die Funktion popen() verwendet, die unter Windows nicht existiert. Unter Windows kann stattdessen die Option tee zur Speicherung der Abfrageausgabe verwendet werden, auch wenn sie in bestimmten Situationen zum Durchsuchen der Ausgabe nicht so praktisch ist wie pager.

  • print, \p

    Druckt die aktuelle eingegebene Anweisung, ohne sie auszuführen.

  • prompt [str], \R [str]

    Rekonfiguriert die mysql-Eingabeaufforderung in den angegebenen String. Die Sonderzeichensequenzen, die in der Eingabeaufforderung verwendet werden können, werden später in diesem Abschnitt beschrieben.

    Wenn Sie den Befehl prompt ohne Argument eingeben, setzt mysql die Eingabeaufforderung auf die Standardform (mysql>) zurück.

  • quit, \q

    Beendet mysql.

  • rehash, \#

    Baut den Vervollständigungs-Hash wieder auf, der die Datenbank-, Tabellen- und Spaltennamensvervollständigung aktiviert, während Sie Anweisungen eingeben. (Siehe Beschreibung zu --auto-rehash.)

  • source file_name, \. file_name

    Liest die benannte Datei und führt die darin enthaltenen Anweisungen aus. Unter Windows können Sie Pfadnamenstrennzeichen wie / oder \\ angeben.

  • status, \s

    Liefert Statusinformationen über die Verbindung und den Server, den Sie verwenden. Wenn der Client mit --safe-updates gestartet wurde, gibt status auch die Werte für die mysql-Variablen aus, die sich auf Ihre Abfragen auswirken.

  • system command, \! command

    Führt den bestimmten Befehl mit dem Standardbefehlsinterpreter aus.

    Der Befehl system funktioniert nur in Unix.

  • tee [file_name], \T [file_name]

    Indem Sie die Option --tee beim Aufruf von mysql verwenden, können Sie Anweisungen und ihre Ausgabe protokollieren. Alle auf dem Bildschirm angezeigten Daten werden an eine angegebene Datei angehängt. Dies kann auch zu Debugzwecken sehr praktisch sein. mysql leert Ergebnisse in die Datei nach jeder Anweisung, gerade bevor es seine nächste Eingabeaufforderung druckt.

    Sie können diese Funktion interaktiv mit dem Befehl tee aktivieren. Wird kein Parameter angegeben, dann wird die vorherige Datei verwendet. Die Datei tee kann mit dem Befehl notee deaktiviert werden. Die erneute Ausführung von tee reaktiviert das Loggen wieder.

  • use db_name, \u db_name

    Verwendet db_name als Standarddatenbank.

  • warnings, \W

    Aktiviert die Anzeige von Warnungen nach jeder Anweisung (wenn es welche gibt).

Es folgen ein paar Tipps zum Befehl pager:

  • Sie können damit in eine Datei schreiben, und die Ergebnisse landen dann auch nur in dieser Datei:

    mysql> pager cat > /tmp/log.txt
    

    Sie können auch Optionen für das Programm übergeben, das Sie als Pager verwenden wollen:

    mysql> pager less -n -i -S
    
  • Beachten Sie die Option -S im obigen Beispiel. Sie kann zum Durchblättern sehr breiter Abfrageergebnisse recht praktisch sein. Manchmal sind sehr breite Ergebnismengen auf dem Bildschirm schlecht zu lesen. Die Option -S für den Befehl less kann die Lesbarkeit der Ergebnisse erheblich steigern, denn sie erlaubt das horizontale Scrolling mit den Pfeiltasten auf der Computertastatur. Sie können die Option -S auch interaktiv innerhalb von less verwenden, um das horizontale Scrolling nach Belieben ein- und auszuschalten. Weitere Informationen finden Sie auf der Manpage zu less:

    shell> man less
    
  • Die Optionen -F und -X können mit less verwendet werden, damit das Programm beendet wird, wenn die Ausgabe auf einen Bildschirm passt. Dies ist günstig, wenn kein Scrollen erforderlich ist:

    mysql> pager less -n -i -S -F -X
    
  • Sie können zur Verarbeitung der Ausgabe sehr komplexe Pager-Befehle angeben:

    mysql> pager cat | tee /dr1/tmp/res.txt \
              | tee /dr2/tmp/res2.txt | less -n -i -S
    

    In diesem Beispiel würde der Befehl die Abfrageergebnisse an zwei Dateien in zwei verschiedenen Verzeichnissen auf zwei separaten Dateisystemen senden, die als /dr1 und /dr2 eingebunden sind. Via less werden die Ergebnisse aber auch auf dem Bildschirm angezeigt.

Sie können die Funktionen von tee und pager auch kombinieren. Wenn Sie eine tee-Datei aktivieren und pager auf less setzen, können Sie die Ergebnisse mit dem Programm less durchsuchen und gleichzeitig alles an eine Datei anhängen. Der Unterschied zwischen tee unter Unix, wenn es mit dem pager-Befehl verwendet wird, und dem in mysql integrierten tee-Befehl besteht darin, dass das integrierte tee auch dann funktioniert, wenn der Unix-Befehl tee nicht vorhanden ist. Außerdem loggt das integrierte tee alles, was auf dem Bildschirm ausgegeben wird; im Gegensatz dazu wird von dem unter Unix mit pager verwendeten tee nicht so viel protokolliert. Zudem lässt sich das tee-Dateiloggen interaktiv von mysql aus ein- und ausschalten. Dies ist nützlich, wenn Sie nur einige, nicht aber alle Abfragen in einer Datei loggen wollen.

Der Befehl prompt konfiguriert die vorgabemäßige mysql>-Eingabeaufforderung neu. Der String zur Definition der Eingabeaufforderung kann die folgenden Spezialsequenzen enthalten.

OptionBeschreibung
\cZähler, der bei jeder von Ihnen abgesetzten Anweisung hochgezählt wird
\Daktuelles vollständiges Datum
\dStandarddatenbank
\hServerhost
\laktueller Begrenzer (neu in 5.1.12)
\mMinuten der aktuellen Uhrzeit
\nZeilenwechselzeichen
\Oaktueller Monat, angegeben mit drei Buchstaben (Jan, Feb usw.)
\oaktueller Monat im numerischen Format
\PAM/PM
\paktuelle TCP/IP-Port bzw. aktuelle Socketdatei
\Raktuelle Uhrzeit im 24-Stunden-Format (0 - 23)
\raktuelle Uhrzeit im 12-Stunden-Format (1 - 12)
\SSemikolon
\sSekunden der aktuellen Uhrzeit
\tTabulatorzeichen
\U

Ihr vollständiger user_name@host_name-Kontenname

\uIhr Benutzername
\vServerversion
\waktueller Wochentag, angegeben mit drei Buchstaben (Mon, Tue usw.)
\Yaktuelles Jahr (vierstellig)
\yaktuelles Jahr (zweistellig)
\_Leerzeichen
Leerzeichen (folgt dem Backslash)
\'einfaches Anführungszeichen
\"doppeltes Anführungszeichen
\\literales „\“-Backslash-Zeichen
\x

x, steht für jedes nicht oben aufgeführte „x

Sie können die Eingabeaufforderung auf verschiedene Weise einstellen:

  • Verwenden Sie eine Umgebungsvariable. Sie können der Umgebungsvariablen MYSQL_PS1 als Wert einen Eingabeaufforderungs-String zuweisen. Ein Beispiel:

    shell> export MYSQL_PS1="(\u@\h) [\d]> "
    
  • Verwenden Sie eine Befehlszeilenoption. Sie können für mysql die Option --prompt auf der Befehlszeile angeben. Ein Beispiel:

    shell> mysql --prompt="(\u@\h) [\d]> "
    (user@host) [database]>
    
  • Verwenden Sie eine Optionsdatei. Sie können die Option prompt im Abschnitt [mysql] einer beliebigen MySQL-Optionsdatei (z. B. /etc/my.cnf oder .my.cnf) in Ihrem Stammverzeichnis angeben. Ein Beispiel:

    [mysql]
    prompt=(\\u@\\h) [\\d]>\\_
    

    Beachten Sie in diesem Beispiel die doppelten Backslashs. Wenn Sie die Eingabeaufforderung mit der Option prompt in einer Optionsdatei einstellen, sollten Sie die Backslashes verdoppeln, wenn Sie bestimmte Optionen für die Eingabeaufforderung angeben. Es gibt eine Reihe von Überschneidungen zwischen den zulässigen Optionen für die Eingabeaufforderung und den speziellen Escape-Sequenzen, die in Optionsdateien erkannt werden. (Diese Sequenzen sind in Using Option Files, aufgelistet.) Diese Überschneidungen können bei Verwendung einzelner Backslashs Probleme verursachen. So wird etwa \s als Leerzeichen statt als aktueller Sekundenwert interpretiert. Das folgende Beispiel zeigt, wie Sie eine Eingabeaufforderung in einer Optionsdatei so definieren, dass die aktuelle Uhrzeit im Format HH:MM:SS> enthalten ist:

    [mysql]
    prompt="\\r:\\m:\\s> "
    
  • Stellen Sie die Eingabeaufforderung interaktiv ein. Sie können Ihre Eingabeaufforderung auch interaktiv mithilfe des Befehls prompt (oder \R) einstellen. Ein Beispiel:

    mysql> prompt (\u@\h) [\d]>\_
    PROMPT set to '(\u@\h) [\d]>\_'
    (user@host) [database]>
    (user@host) [database]> prompt
    Returning to default PROMPT of mysql>
    mysql>
    

3.1.3. Serverseitige mysql-Hilfe

mysql> help search_string

Wenn Sie ein Argument zum help-Befehl angeben, verwendet mysql es als einen Suchstring, um auf serverseitige Hilfe aus dem Inhalt des MySQL-Handbuchs zuzugreifen. Die richtige Operation dieses Befehls erfordert, dass die Hilfetabellen in der mysql-Datenbank mit Hilfethemeninformationen initialisiert werden (siehe Server-Side Help).

Wenn es keine Übereinstimmung für den Suchstring gibt, schlägt die Suche fehl:

mysql> help me
Nothing found
Please try to run 'help contents' for a list of all accessible topics

Verwenden Sie den Hilfeinhalt, um eine Liste der Hilfekategorien zu sehen:

mysql> help contents
You asked for help about help category: "Contents"
For more information, type 'help <item>', where <item> is one of the
following categories:
   Account Management
   Administration
   Data Definition
   Data Manipulation
   Data Types
   Functions
   Functions and Modifiers for Use with GROUP BY
   Geographic Features
   Language Structure
   Plugins
   Storage Engines
   Stored Routines
   Table Maintenance
   Transactions
   Triggers

Wenn der Suchstring zu mehreren Elementen passt, zeigt mysql eine Liste von übereinstimmenden Hilfethemen an:

mysql> help logs
Many help items for your request exist.
To make a more specific request, please type 'help <item>',
where <item> is one of the following topics:
   SHOW
   SHOW BINARY LOGS
   SHOW ENGINE
   SHOW LOGS

Verwenden Sie ein Hilfethema als Suchstring, um den Hilfeeintrag für dieses Thema zu sehen:

mysql> help show binary logs
Name: 'SHOW BINARY LOGS'
Description:
Syntax:
SHOW BINARY LOGS
SHOW MASTER LOGS
Lists the binary log files on the server. This statement is used as
part of the procedure described in [purge-binary-logs], that shows how
to determine which logs can be purged.
mysql> SHOW BINARY LOGS;
+---------------+-----------+
| Log_name      | File_size |
+---------------+-----------+
| binlog.000015 |    724935 |
| binlog.000016 |    733481 |
+---------------+-----------+

3.1.4. Ausführen von SQL-Anweisungen aus einer Textdatei

Der Client mysql wird normalerweise interaktiv verwendet. Das sieht etwa so aus:

shell> mysql db_name

Es ist allerdings auch möglich, SQL-Anweisungen in einer Datei abzulegen und mysql dann anzuweisen, seine Eingabe aus dieser Datei auszulesen. Zu diesem Zweck erstellen Sie eine Textdatei text_file, die die Anweisungen enthält, die Sie ausführen wollen. Danach rufen Sie mysql wie folgt auf:

shell> mysql db_name < text_file

Wenn Sie als Erstes eine USE db_name-Anweisung in die Datei setzen, müssen Sie den Datenbanknamen nicht mehr auf der Befehlszeile angeben:

shell> mysql < text_file

Wird mysql bereits ausgeführt, dann können Sie eine SQL-Skriptdatei mithilfe des Befehls source oder \. ausführen:

mysql> source file_name
mysql> \. file_name

In bestimmten Fällen kann es sinnvoll sein, ein Skript Fortschrittsinformationen für den Benutzer anzeigen zu lassen. Hierzu können Sie Anweisungen wie die folgende einfügen:

SELECT '<info_to_display>' AS ' ';

Die gezeigte Anweisung gibt <info_to_display> aus.

Sie können mysql auch mit der --verbose-Option aufrufen, die dazu führt, dass jede Anweisung vor dem Ergebnis gezeigt wird, das sie erzeugt.

Ab MySQL 5.1.23 ignoriert mysql Unicode-Bytereihenfolge (BOM)-Zeichen am Anfang von Eingabedateien. Früher las mysql diese und schickte sie an den Server, was in einem Syntaxfehler resultierte. Das Vorhandensein eines BOM-Zeichens führt nicht dazu, dass mysql seinen Standardzeichensatz ändert. Dazu rufen Sie mysql mit einer Option wie --default-character-set=utf8 auf.

Weitere Informationen zum Stapelbetrieb finden Sie in Abschnitt 1.5, „Verwenden von mysql im Stapelmodus“.

3.1.5. mysql-Tipps

Dieser Abschnitt beschreibt einige Methoden, mit deren Hilfe Sie mysql effizienter benutzen können.

3.1.5.1. Vertikales Anzeigen von Abfrageergebnissen

Die Lesbarkeit bestimmter Abfrageergebnisse wird erhöht, wenn diese nicht in einem horizontalen, sondern einem vertikalen Tabellenformat angezeigt werden. Die Abfrage wird vertikal angezeigt, indem sie mit \G statt mit einem Semikolon abgeschlossen wird. So lassen sich etwa längere Textwerte mit Zeilenumbrüchen häufig besser lesen, wenn sie vertikal ausgegeben werden:

mysql> SELECT * FROM mails WHERE LENGTH(txt) < 300 LIMIT 300,1\G
*************************** 1. row ***************************
  msg_nro: 3068
     date: 2000-03-01 23:29:50
time_zone: +0200
mail_from: Monty
    reply: monty@no.spam.com
  mail_to: "Thimble Smith" <tim@no.spam.com>
      sbj: UTF-8
      txt: >>>>> "Thimble" == Thimble Smith writes:
Thimble> Hi.  I think this is a good idea.  Is anyone familiar
Thimble> with UTF-8 or Unicode? Otherwise, I'll put this on my
Thimble> TODO list and see what happens.
Yes, please do that.
Regards,
Monty
     file: inbox-jani-1
     hash: 190402944
1 row in set (0.09 sec)

3.1.5.2. Verwenden der --safe-updates-Option

Für MySQL-Neulinge kann die Startoption --safe-updates (bzw. --i-am-a-dummy, was den gleichen Effekt hat) ausgesprochen nützlich sein. Sie hilft in Fällen, in denen Sie eine DELETE FROM tbl_name-Anweisung abgesetzt, aber die WHERE-Klausel vergessen haben. Normalerweise werden durch eine solche Anweisung nämlich alle Datensätze in der Tabelle gelöscht. Mit --safe-updates können Sie Datensätze nur dann löschen, wenn die Schlüsselwerte angegeben sind, mit denen sie identifiziert werden. Auf diese Weise werden Unfälle verhindert.

Wenn Sie die Option --safe-updates benutzen, setzt mysql beim Herstellen der Verbindung zum MySQL Server die folgende Anweisung ab:

SET sql_safe_updates=1, sql_select_limit=1000, sql_max_join_size=1000000;

Siehe auch Server System Variables.

Die Anweisung SET hat die folgenden Auswirkungen:

  • Sie dürfen eine UPDATE- oder DELETE-Anweisung nur dann ausführen, wenn Sie einen Schlüssel-Constraint in der WHERE-Klausel spezifiziert oder eine LIMIT-Klausel angegeben haben (oder beides). Ein Beispiel:

    UPDATE tbl_name SET not_key_column=val WHERE key_column=val;
    UPDATE tbl_name SET not_key_column=val LIMIT 1;
    
  • Der Server beschränkt alle umfangreichen SELECT-Ergebnisse auf 1.000 Datensätze, sofern die Anweisung keine LIMIT-Klausel enthält.

  • Der Server bricht tabellenübergreifende SELECT-Anweisungen ab, bei denen voraussichtlich mehr als 1.000.000 Datensatzkombinationen untersucht werden müssten.

Um andere Grenzen als 1.000 und 1.000.000 anzugeben, können Sie die Vorgaben mithilfe der Optionen --select_limit und --max_join_size außer Kraft setzen:

shell> mysql --safe-updates --select_limit=500 --max_join_size=10000

3.1.5.3. Deaktivieren des mysql-Auto-Reconnects

Wenn die Verbindung zwischen dem mysql-Client und dem Server während des Versands einer Anweisung abbricht, dann versucht der Client, die Verbindung sofort und automatisch wiederherzustellen, und sendet die Anweisung dann erneut. Auch wenn mysql ein Wiederverbinden gelingt, wurde allerdings Ihre erste Verbindung beendet und all Ihre bisherigen Sitzungsobjekte und Einstellungen gehen verloren: temporäre Tabellen, der Autocommit-Modus, benutzerdefinierte Variablen und Sitzungsvariablen. Außerdem wird für alle aktuellen Transaktionen ein Rollback durchgeführt. Dieses Verhalten kann für Sie gefährlich sein. Beachten Sie das folgende Beispiel, in dem der Server zwischen der ersten und der zweiten Anweisung heruntergefahren und neu gestartet wurde, ohne dass Sie davon erfahren haben:

mysql> SET @a=1;
Query OK, 0 rows affected (0.05 sec)
mysql> INSERT INTO t VALUES(@a);
ERROR 2006: MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    1
Current database: test
Query OK, 1 row affected (1.30 sec)
mysql> SELECT * FROM t;
+------+
| a    |
+------+
| NULL |
+------+
1 row in set (0.05 sec)

Die Benutzervariable @a ist mit der Verbindung verloren gegangen und nach der Neuverbindung undefiniert. Wenn wichtig ist, dass mysql in dem Fall, dass die Verbindung abreißt, mit einem Fehler beendet wird, dann können Sie den mysql-Client mit der Option --skip-reconnect starten.

Weitere Informationen über Auto-Reconnect und seine Wirkung auf Statusinformationen, wenn ein Wiederverbinden erfolgt, finden Sie unter Controlling Automatic Reconnection Behavior.

3.2. mysqladmin — Client zum Verwalten eines MySQL-Servers

mysqladmin ist ein Client zur Durchführung administrativer Aufgaben. Sie können damit Konfiguration und aktuellen Status des Servers überprüfen, Datenbanken erstellen und löschen und vieles mehr.

Rufen Sie mysqladmin wie folgt auf:

shell> mysqladmin [options] command [command-arg] [command [command-arg]] ...

mysqladmin unterstützt die in der folgenden Liste beschriebenen Befehle. Einige Befehle nehmen auf den Befehlsnamen folgend ein Argument entgegen.

  • create db_name

    Erstellt eine neue Datenbank namens db_name.

  • debug

    Weist den Server an, Debuginformationen in das Fehlerlog zu schreiben.

    Ab MySQL 5.1.12 schließt dies Informationen über den Ereignisplaner ein. Siehe auch Event Scheduler Status.

  • drop db_name

    Löscht die Datenbank namens db_name und alle in ihr enthaltenen Tabellen.

  • extended-status

    Zeigt die Serverstatusvariablen und ihre jeweiligen Werte an.

  • flush-hosts

    Synchronisiert alle Daten in den Host-Cache.

  • flush-logs

    Schreibt alle Logs auf Festplatte.

  • flush-privileges

    Lädt die Grant-Tabellen neu (wie reload).

  • flush-status

    Löscht die Statusvariablen.

  • flush-tables

    Synchronisiert alle Tabellen auf Festplatte.

  • flush-threads

    Synchronisiert den Thread-Cache.

  • kill id,id,...

    Terminiert Server-Threads. Werden mehrere Thread-Kennungswerte übergeben, dann dürfen in der Liste keine Leerzeichen enthalten sein.

  • old-password new-password

    Entspricht dem Befehl password, speichert das Passwort aber im alten (vor MySQL 4.1 verwendeten) Hashing-Format. (Siehe auch Password Hashing in MySQL.)

  • password new-password

    Legt ein neues Passwort fest. Hierdurch wird das Passwort des Kontos, das Sie bei mysqladmin zur Verbindung mit dem Server verwenden, auf new-password gesetzt. Wenn Sie also beim nächsten Mal mysqladmin (oder ein anderes Clientprogramm) über dieses Konto aufrufen, müssen Sie das neue Passwort angeben.

    Wenn der Wert new-password Leerzeichen oder andere Zeichen enthält, die von Ihrem Befehls-Interpreter als Sonderzeichen interpretiert werden, dann müssen Sie es in Anführungszeichen setzen. Dabei sind unter Windows in jedem Fall doppelte statt einfache Anführungszeichen zu benutzen, da Letztere bei der Verarbeitung nicht entfernt, sondern als Teil des Passworts betrachtet werden. Ein Beispiel:

    shell> mysqladmin password "my new password"
    
    Achtung

    Verwenden Sie diesen Befehl nicht, wenn der Server mit der Option --skip-grant-tables gestartet wurde. Es wird keine Kennwortänderung angewendet. Dies gilt auch, wenn Sie den password-Befehl durch flush-privileges auf der gleichen Befehlszeile einleiten, um die Berechtigungstabellen wieder zu aktivieren, weil die Leerungsoperation auftritt, nachdem Sie eine Verbindung hergestellt haben. Allerdings können Sie mysqladmin flush-privileges verwenden, um die Berechtigungstabelle wieder zu aktivieren, und dann einen gesonderten mysqladmin password-Befehl verwenden, um das Kennwort zu ändern.

  • ping

    Überprüft, ob der Server ausgeführt wird. Der Rückgabestatus von mysqladmin ist 0, wenn der Server ausgeführt wird, und 1, wenn er nicht ausgeführt wird. Er ist sogar bei einem Fehler wie Access denied 0, da dies heißt, dass der Server ausgeführt wird, aber die Verbindung ablehnte, ein Unterschied zu einem Server, der gar nicht ausgeführt wird.

  • processlist

    Zeigt eine Liste aktiver Server-Threads an. Dies ähnelt der Ausgabe der Anweisung SHOW PROCESSLIST. Wird die Option --verbose angegeben, dann entspricht die Ausgabe derjenigen von SHOW FULL PROCESSLIST. (Siehe auch Abschnitt 8.5.5.31, „SHOW PROCESSLIST.)

  • reload

    Lädt die Grant-Tabellen neu.

  • refresh

    Synchronisiert alle Tabellen und schließt und öffnet die Logdateien.

  • shutdown

    Halten Sie den Server an.

  • start-slave

    Startet die Replikation auf einem Slave-Server.

  • status

    Zeigt eine kurze Meldung zum Serverstatus an.

  • stop-slave

    Beendet die Replikation auf einem Slave-Server.

  • variables

    Zeigt die Serversystemvariablen und ihre jeweiligen Werte an.

  • version

    Zeigt Versionsinformationen vom Server an.

Alle Befehle lassen sich auf ein beliebiges eindeutiges Präfix kürzen. Ein Beispiel:

shell> mysqladmin proc stat
+----+-------+-----------+----+---------+------+-------+------------------+
| Id | User  | Host      | db | Command | Time | State | Info             |
+----+-------+-----------+----+---------+------+-------+------------------+
| 51 | monty | localhost |    | Query   | 0    |       | show processlist |
+----+-------+-----------+----+---------+------+-------+------------------+
Uptime: 1473624  Threads: 1  Questions: 39487
Slow queries: 0  Opens: 541  Flush tables: 1
Open tables: 19  Queries per second avg: 0.0268

Die Ausgabe des Befehls mysqladmin status zeigt die folgenden Werte an:

  • Uptime

    Dauer seit dem Serverstart (in Sekunden).

  • Threads

    Anzahl der aktiven Threads (Clients).

  • Questions

    Anzahl der Abfragen, die seit dem Serverstart von Clients eingegangen sind.

  • Slow queries

    Anzahl der Abfragen, die länger als die durch long_query_time angegebene Anzahl von Sekunden dauerten. Siehe auch The Slow Query Log.

  • Opens

    Anzahl der Tabellen, die vom Server geöffnet wurden.

  • Flush tables

    Anzahl der vom Server ausgeführten flush-*-, refresh- und reload-Befehle.

  • Open tables

    Anzahl der derzeit offenen Tabellen.

  • Memory in use

    Umfang des Speichers, der direkt von mysqld reserviert wurde. Der Wert wird nur angezeigt, wenn MySQL mit der Option --with-debug=full kompiliert wurde.

  • Maximum memory used

    Maximaler Umfang des Speichers, der direkt von mysqld reserviert wurde. Der Wert wird nur angezeigt, wenn MySQL mit der Option --with-debug=full kompiliert wurde.

Wenn Sie mysqladmin shutdown beim Herstellen einer Verbindung zu einem lokalen Server mithilfe einer Unix-Socketdatei ausführen, wartet mysqladmin, bis die Prozesskennungsdatei des Servers entfernt wurde, um sicherzustellen, dass der Server korrekt beendet wurde.

mysqladmin unterstützt die Optionen in der folgenden Liste. Es liest auch Optionsdateien und unterstützt die beschriebenen Optionen für deren Verarbeitung (siehe Command-Line Options that Affect Option-File Handling).

  • --help, -?

    Zeigt eine Hilfsmeldung an und wird dann beendet.

  • --character-sets-dir=path

    Das Verzeichnis, in dem Zeichensätze installiert sind. Siehe auch Character Set Configuration.

  • --compress, -C

    Komprimiert alle Daten, die zwischen Client und Server ausgetauscht werden, sofern beide die Komprimierung unterstützen.

  • --count=N, -c N

    Die Anzahl von Iterationen für eine wiederholte Befehlsausführung, wenn die --sleep-Option gegeben ist.

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

    Schreibt ein Debuglog. Der String debug_options heißt häufig 'd:t:o,file_name'. Standardwert ist 'd:t:o,/tmp/mysqladmin.trace'.

  • --debug-check

    Gibt einige Debuginformationen aus, wenn das Programm beendet wird. Diese Option wurde in MySQL 5.1.21 hinzugefügt.

  • --debug-info

    Druckt Debuginformationen sowie Speicher- und CPU-Nutzungsstatistiken, wenn das Programm beendet wird. Diese Option wurde in MySQL 5.1.14 hinzugefügt.

  • --default-character-set=charset_name

    Verwendet charset_name als Standardzeichensatz. Siehe auch Character Set Configuration.

  • --force, -f

    Fordert für den Befehl drop db_name keine Bestätigung an. Bei mehreren Befehlen erfolgt auch bei Auftreten eines Fehlers kein Abbruch.

  • --host=host_name, -h host_name

    Stellt eine Verbindung zum MySQL Server auf dem angegebenen Host her.

  • --no-beep, -b

    Unterdrückt den Warnton, der standardmäßig für Fehler wie das Fehlschlagen, eine Verbindung zum Server herzustellen, ausgelöst wird. Diese Option wurde in MySQL 5.1.17 hinzugefügt.

  • --password[=password], -p[password]

    Verwendet das angegebene Passwort zur Verbindung mit dem Server. Wenn Sie die Kurzform der Option (-p) verwenden, dürfen Sie kein Leerzeichen zwischen Option und Passwort setzen. Lassen Sie den Wert password auf die Option --password bzw. -p folgend weg, dann werden Sie zur Eingabe des Passworts aufgefordert.

    Die Angabe eines Passworts direkt auf der Befehlszeile ist als nicht sicher einzuordnen. Siehe auch End-User Guidelines for Password Security.

  • --pipe, -W

    Stellt unter Windows eine Verbindung mit dem Server über eine Named Pipe her. Diese Option gilt nur für Verbindungen zu einem lokalen Server und nur wenn der Server Named-Pipe-Verbindungen unterstützt.

  • --port=port_num, -P port_num

    Die TCP/IP-Portnummer, die für die Verbindung verwendet werden soll.

  • --protocol={TCP|SOCKET|PIPE|MEMORY}

    Das Verbindungsprotokoll, das für die Verbindung mit dem Server verwendet wird. Es ist nützlich, wenn die anderen Verbindungsparameter normalerweise dazu führen würden, dass ein anderes Protokoll verwendet wird als dasjenige, das Sie wollen. Details zu den zulässigen Werten finden Sie unter Connecting to the MySQL Server.

  • --relative, -r

    Zeigt bei gemeinsamer Verwendung mit der Option --sleep den Unterschied zwischen aktuellem und vorherigem Wert. Derzeit funktioniert diese Option nur mit dem Befehl extended-status.

  • --silent, -s

    Wenn keine Verbindung zum Server hergestellt werden kann, erfolgt eine stillschweigende Beendigung.

  • --sleep=delay, -i delay

    Führt Befehle wiederholt aus, wobei dazwischen die mit delay angegebene Anzahl von Sekunden verstreicht. Die Option --count bestimmt die Anzahl der Iterationen. Wenn --count nicht angegeben ist, führt mysqladmin Befehle unbeschränkt aus, bis sie unterbrochen werden.

  • --socket=path, -S path

    Bei Verbindungen mit localhost ist dies die zu verwendende Unix-Socketdatei bzw. (unter Windows) der Name der zu verwendenden Named Pipe.

  • --ssl*

    Optionen, die mit --ssl anfangen, geben an, ob Sie eine Serververbindung über SSL herstellen und wo Sie SSL-Schlüssel und Zertifikate finden. Siehe auch SSL Command Options.

  • --user=user_name, -u user_name

    Verwendet den angegebenen MySQL-Benutzernamen zur Verbindung mit dem Server.

  • --verbose, -v

    Ausführlicher Modus. Es werden zusätzliche Angaben zu den Aktivitäten des Programms ausgegeben.

  • --version, -V

    Zeigt die Versionsinformation an und wird dann beendet.

  • --vertical, -E

    Erzeugt eine vertikale Ausgabe. Dies ähnelt --relative, die Ausgabe erfolgt jedoch vertikal.

  • --wait[=count], -w[count]

    Wenn die Verbindung nicht hergestellt werden kann, erfolgt anstelle eines Abbruchs nach einer Wartezeit ein neuer Verbindungsversuch. Wenn ein count-Wert spezifiziert wird, gibt dieser die Anzahl der Wiederholungsversuche an. Standardmäßig erfolgt genau eine Wiederholung.

Sie können auch unter Verwendung von --var_name=value die folgenden Variablen setzen. Das Format --set-variable ist veraltet. Syntax:

  • connect_timeout

    Maximale Anzahl der Sekunden bis zur Zeitüberschreitung der Verbindung. Der Vorgabewert ist 43.200 (12 Stunden).

  • shutdown_timeout

    Gibt an (in Sekunden), wie lange auf das Herunterfahren des Servers gewartet wird. Der Vorgabewert ist 3.600 (1 Stunde).

3.3. mysqlcheck — ein Tabellenwartungsprogramm

Der mysqlcheck-Client führt eine Tabellenwartung aus: Er überprüft, repariert, optimiert oder analysiert Tabellen.

Jede Tabelle wird gesperrt und ist deswegen für andere Sitzungen nicht verfügbar, während sie verarbeitet wird. Tabellenwartungsarbeiten können zeitaufwendig sein, besonders für große Tabellen. Wenn Sie die Option --databases oder --all-databases verwenden, um alle Tabellen in einer oder mehreren Datenbanken zu verarbeiten, könnte ein Aufruf von mysqlcheck sehr lange brauchen. (Dies gilt auch für mysql_upgrade, weil dieses Programm mysqlcheck aufruft, um alle Tabellen zu überprüfen und sie im Bedarfsfall zu reparieren.)

mysqlcheck ähnelt hinsichtlich seines Funktionsumfangs myisamchk, funktioniert aber anders. Der wesentliche Unterschied besteht darin, dass mysqlcheck verwendet werden muss, wenn der Server mysqld ausgeführt wird, wohingegen myisamchk verwendet werden sollte, wenn er nicht läuft. Der Vorteil der Verwendung von mysqlcheck besteht darin, dass Sie den Server nicht beenden müssen, um die Tabellenwartung durchzuführen.

mysqlcheck verwendet die SQL-Anweisungen CHECK TABLE, REPAIR TABLE, ANALYZE TABLE und OPTIMIZE TABLE auf eine für den Benutzer praktische Weise. Das Programm bestimmt, welche Anweisungen für die gewünschte Operation durchzuführen sind, und sendet diese Anweisungen dann zur Ausführung an den Server. Weitere Informationen dazu, bei welchen Speicher-Engines die jeweiligen Anweisungen funktionieren, finden Sie in Abschnitt 8.5.2, „Anweisungen für die Tabellenwartung“.

Die MyISAM-Speicher-Engine unterstützt alle vier Wartungsoperationen, d. h., mysqlcheck kann zur Durchführung aller Wartungsoperationen an MyISAM-Tabellen verwendet werden. Andere Speicher-Engines unterstützen nicht unbedingt alle Operationen. Gegebenenfalls wird eine Fehlermeldung angezeigt. Wenn beispielsweise test.t eine MEMORY-Tabelle ist, dann führt der Versuch, sie zu überprüfen, zu folgendem Ergebnis:

shell> mysqlcheck test t
test.t
note     : The storage engine for the table doesn't support check

Wenn mysqlcheck keine Tabelle wiederherstellen kann, finden Sie unter Abschnitt 2.12.4, „Reparieren und Neuerstellen von Tabellen und Indizes“ manuelle Tabellenwiederherstellungsstrategien. Dies ist zum Beispiel der Fall für InnoDB-Tabellen, die zwar mit CHECK TABLE überprüft, aber nicht mit REPAIR TABLE wiederhergestellt werden können.

Die Verwendung von mysqlcheck mit partitionierten Tabellen wird nicht vor MySQL 5.1.27 unterstützt.

Achtung

Es ist am besten, eine Datensicherung einer Tabelle zu erstellen, bevor Sie eine Tabellenwiederherstellung ausführen; unter einigen Umständen könnte die Operation einen Datenverlust verursachen. Mögliche Ursachen sind u. A. Dateisystemfehler.

Es gibt drei Möglichkeiten, mysqlcheck aufzurufen:

shell> mysqlcheck [options] db_name [tables]
shell> mysqlcheck [options] --databases db_name1 [db_name2 db_name3...]
shell> mysqlcheck [options] --all-databases

Wenn Sie auf db_name folgend keine Tabellen aufführen oder die Optionen --databases oder --all-databases verwenden, dann werden ganze Datenbanken überprüft.

mysqlcheck bietet eine im Vergleich zu anderen Clientprogrammen spezielle Funktion. Das Standardverhalten des Überprüfens von Tabellen (--check) kann geändert werden, indem die Binärdatei umbenannt wird. Wenn Sie ein Tool benötigen, das Tabellen standardmäßig wiederherstellt, sollten Sie einfach eine Kopie von mysqlcheck namens mysqlrepair oder eine symbolische Verknüpfung zu mysqlcheck namens mysqlrepair erstellen. Wenn Sie dann mysqlrepair aufrufen, werden die Tabellen wiederhergestellt.

Die folgenden Namen können verwendet werden, um das Standardverhalten von mysqlcheck zu ändern.

mysqlrepairDie Standardoption ist --repair.
mysqlanalyzeDie Standardoption ist --analyze.
mysqloptimizeDie Standardoption ist --optimize.

mysqlcheck unterstützt die Optionen in der folgenden Liste. Es liest auch Optionsdateien und unterstützt die beschriebenen Optionen für deren Verarbeitung (siehe Command-Line Options that Affect Option-File Handling).

  • --help, -?

    Zeigt eine Hilfsmeldung an und wird dann beendet.

  • --all-databases, -A

    Überprüft alle Tabellen in allen Datenbanken. Dies entspricht der Option --databases bei gleichzeitiger Nennung aller Datenbanken auf der Befehlszeile.

  • --all-in-1, -1

    Statt eine Anweisung für jede Tabelle einzeln abzusetzen, wird eine einzelne Anweisung für jede Datenbank ausgeführt, die alle zu verarbeitenden Tabellen aus dieser Datenbank benennt.

  • --analyze, -a

    Analysiert die Tabellen.

  • --auto-repair

    Wenn eine überprüfte Tabelle beschädigt ist, wird sie automatisch repariert. Reparaturarbeiten werden erledigt, nachdem alle Tabellen überprüft wurden.

  • --character-sets-dir=path

    Das Verzeichnis, in dem Zeichensätze installiert sind. Siehe auch Character Set Configuration.

  • --check, -c

    Überprüft die Tabellen auf Fehler. Dies ist die Standardoperation.

  • --check-only-changed, -C

    Überprüft nur solche Tabellen, die seit der letzten Überprüfung geändert oder aber nicht korrekt geschlossen wurden.

  • --check-upgrade, -g

    Rufen Sie CHECK TABLE mit der FOR UPGRADE-Option auf, um Tabellen auf Inkompatibilität mit der aktuellen Serverversion zu überprüfen. Diese Option aktiviert automatisch die Optionen --fix-db-names und --fix-table-names. --check-upgrade wurde in MySQL 5.1.7. hinzugefügt.

  • --compress

    Komprimiert alle Daten, die zwischen Client und Server ausgetauscht werden, sofern beide die Komprimierung unterstützen.

  • --databases, -B

    Verarbeitet alle Tabellen in den aufgeführten Datenbanken. Normalerweise betrachtet mysqlcheck das erste Namensargument auf der Befehlszeile als Datenbank- und alle nachfolgenden Argumente als Tabellennamen. Bei dieser Option hingegen werden alle Namensargumente als Datenbanknamen behandelt.

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

    Schreibt ein Debuglog. Der String debug_options heißt häufig 'd:t:o,file_name'. Standardwert ist 'd:t:o'.

  • --debug-check

    Gibt einige Debuginformationen aus, wenn das Programm beendet wird. Diese Option wurde in MySQL 5.1.21 hinzugefügt.

  • --debug-info

    Druckt Debuginformationen sowie Speicher- und CPU-Nutzungsstatistiken, wenn das Programm beendet wird. Diese Option wurde in MySQL 5.1.14 hinzugefügt.

  • --default-character-set=charset_name

    Verwendet charset_name als Standardzeichensatz. Siehe auch Character Set Configuration.

  • --extended, -e

    Wenn Sie diese Option zur Überprüfung von Tabellen einsetzen, ist sichergestellt, dass diese hundertprozentig konsistent sind; der Vorgang dauert allerdings sehr lange.

    Wenn Sie die Option bei der Reparatur von Tabellen einsetzen, wird eine erweiterte Reparatur durchgeführt, deren Ausführung nicht nur extrem lange dauert, sondern die auch eine Menge überflüssiger Datensätze erzeugt!

  • --fast, -F

    Überprüft nur Tabellen, die nicht ordnungsgemäß geschlossen wurden.

  • --fix-db-names

    Konvertiert Datenbanknamen in das 5.1-Format. Nur Datenbanknamen, die Sonderzeichen enthalten, werden konvertiert. Diese Option wurde in MySQL 5.1.7 hinzugefügt.

  • --fix-table-names

    Konvertiert Tabellennamen in das 5.1-Format. Nur Tabellennamen, die Sonderzeichen enthalten, werden konvertiert. Diese Option wurde in MySQL 5.1.7. hinzugefügt. Ab MySQL 5.1.23 gilt diese Option auch für Ansichten.

  • --force, -f

    Das Programm wird auch dann fortgesetzt, wenn ein SQL-Fehler auftritt.

  • --host=host_name, -h host_name

    Stellt eine Verbindung zum MySQL Server auf dem angegebenen Host her.

  • --medium-check, -m

    Führt eine Überprüfung durch, die schneller ist als eine --extended-Operation. Hierdurch werden nur 99,99 Prozent aller Fehler gefunden (dies sollte allerdings in den meisten Fällen ausreichend sein).

  • --optimize, -o

    Optimiert die Tabellen.

  • --password[=password], -p[password]

    Verwendet das angegebene Passwort zur Verbindung mit dem Server. Wenn Sie die Kurzform der Option (-p) verwenden, dürfen Sie kein Leerzeichen zwischen Option und Passwort setzen. Lassen Sie den Wert password auf die Option --password bzw. -p folgend weg, dann werden Sie zur Eingabe des Passworts aufgefordert.

    Die Angabe eines Passworts direkt auf der Befehlszeile ist als nicht sicher einzuordnen. Siehe auch End-User Guidelines for Password Security.

  • --pipe, -W

    Stellt unter Windows eine Verbindung mit dem Server über eine Named Pipe her. Diese Option gilt nur für Verbindungen zu einem lokalen Server und nur wenn der Server Named-Pipe-Verbindungen unterstützt.

  • --port=port_num, -P port_num

    Die TCP/IP-Portnummer, die für die Verbindung verwendet werden soll.

  • --protocol={TCP|SOCKET|PIPE|MEMORY}

    Das Verbindungsprotokoll, das für die Verbindung mit dem Server verwendet wird. Es ist nützlich, wenn die anderen Verbindungsparameter normalerweise dazu führen würden, dass ein anderes Protokoll verwendet wird als dasjenige, das Sie wollen. Details zu den zulässigen Werten finden Sie unter Connecting to the MySQL Server.

  • --quick, -q

    Wenn Sie mit dieser Option Tabellen überprüfen, wird verhindert, dass die Datensätze auf falsche Verknüpfungen geprüft werden. Dies ist die schnellste Prüfmethode.

    Wenn Sie die Option bei der Reparatur von Tabellen einsetzen, wird versucht, nur den Indexbaum zu reparieren. Dies ist die schnellste Reparaturmethode.

  • --repair, -r

    Führt eine Reparatur durch, die fast alle Fehler beheben kann. Ausgenommen sind lediglich eindeutige Schlüssel, die nicht eindeutig sind.

  • --silent, -s

    Stummer Modus. Gibt nur Fehlermeldungen aus.

  • --socket=path, -S path

    Bei Verbindungen mit localhost ist dies die zu verwendende Unix-Socketdatei bzw. (unter Windows) der Name der zu verwendenden Named Pipe.

  • --ssl*

    Optionen, die mit --ssl anfangen, geben an, ob Sie eine Serververbindung über SSL herstellen und wo Sie SSL-Schlüssel und Zertifikate finden. Siehe auch SSL Command Options.

  • --tables

    Setzt die Option --databases bzw. -B außer Kraft. Alle auf die Option folgenden Namensargumente werden als Tabellennamen betrachtet.

  • --use-frm

    Ruft für Wiederherstellungsoperationen in MyISAM-Tabellen die Tabellenstruktur der .frm-Datei so ab, dass die Tabelle wiederhergestellt werden kann, auch wenn der .MYI-Header beschädigt ist.

  • --user=user_name, -u user_name

    Verwendet den angegebenen MySQL-Benutzernamen zur Verbindung mit dem Server.

  • --verbose, -v

    Ausführlicher Modus. Gibt Informationen zu den verschiedenen Stufen des Programmablaufs aus.

  • --version, -V

    Zeigt die Versionsinformation an und wird dann beendet.

3.4. mysqldump — ein Datenbanksicherungsprogramm

Der Client mysqldump ist ein Sicherungsprogramm, das ursprünglich von Igor Romanenko geschrieben wurde. Er kann zur Erstellung eines Speicherauszugs einer Datenbank oder einer Sammlung von Datenbanken zu Sicherungszwecken oder zur Übertragung auf einen anderen SQL-Server verwendet werden (dies muss nicht unbedingt ein MySQL Server sein). Der Speicherauszug enthält gewöhnlich SQL-Anweisungen zur Erstellung und/oder zum Ausfüllen einer Tabelle. Allerdings kann mysqldump auch verwendet werden, um Dateien in CSV-, begrenztem Text- oder XML-Format zu generieren.

Wenn Sie eine Sicherung auf dem Server durchführen und es sich bei Ihren Tabellen ausschließlich um MyISAM-Tabellen handelt, sollten Sie stattdessen die Verwendung von mysqlhotcopy in Betracht ziehen, weil dies Sicherung und Wiederherstellung erheblich beschleunigt. Siehe auch mysqlhotcopy.

Es gibt drei Möglichkeiten, mysqldump aufzurufen:

shell> mysqldump [options] db_name [tables]
shell> mysqldump [options] --databases db_name1 [db_name2 db_name3...]
shell> mysqldump [options] --all-databases

Wenn Sie auf db_name folgend keine Tabellen aufführen oder die Optionen --databases oder --all-databases verwenden, dann werden Speicherauszüge ganzer Datenbanken erstellt.

mysqldump erstellt keinen Speicherauszug der INFORMATION_SCHEMA-Datenbank. Wenn Sie diese Datenbank explizit auf der Befehlszeile nennen, ignoriert mysqldump sie stumm.

Um eine Liste der Optionen zu erhalten, die Ihre Version von mysqldump unterstützt, führen Sie mysqldump --help aus.

Einige Optionen von mysqldump sind Kurzformen für Gruppen von anderen Optionen. --opt und --compact fallen in diese Kategorie. Zum Beispiel entspricht die Verwendung von --opt der Angabe von --add-drop-table --add-locks --create-options --disable-keys --extended-insert --lock-tables --quick --set-charset. Beachten Sie, dass alle Optionen, für die --opt steht, standardmäßig aktiviert sind, weil --opt ebenfalls standardmäßig aktiviert ist.

Um die Wirkung einer Gruppenoption umzukehren, verwenden Sie ihre Form --skip-xxx (--skip-opt oder --skip-compact). Es ist auch möglich, nur einen Teil der Wirkung einer Gruppenoption auszuwählen, indem Sie ihm Optionen anhängen, die bestimmte Features aktivieren oder deaktivieren. Hier sind einige Beispiele:

  • Um die Wirkung von --opt mit Ausnahme einiger Funktionen auszuwählen, verwenden Sie die Option --skip für jede Funktion. Um zum Beispiel erweiterte Einfügeoperationen und Speicherpufferung zu deaktivieren, verwenden Sie --opt --skip-extended-insert --skip-quick. (Ab MySQL 5.1 reicht --skip-extended-insert --skip-quick aus, weil --opt standardmäßig aktiviert ist.)

  • Um --opt für alle Funktionen außer Indexdeaktivierung und Tabellensperre umzukehren, verwenden Sie --skip-opt --disable-keys --lock-tables.

Wenn Sie selektiv die Wirkung einer Gruppenoption aktivieren oder deaktivieren, ist die Reihenfolge wichtig, weil Optionen von vorne nach hinten verarbeitet werden. Zum Beispiel hätte --disable-keys --lock-tables --skip-opt nicht die geplante Wirkung; es ist dasselbe, als würden Sie --skip-opt allein verwenden.

mysqldump kann Tabelleninhalte Zeile für Zeile abrufen und in einem Speicherauszug ablegen, oder es kann den gesamten Inhalt einer Tabelle abrufen und kann ihn im Speicher puffern, bevor es einen Speicherauszug erstellt. Speicherpufferung kann ein Problem sein, wenn Sie Speicherauszüge großer Tabellen erstellen. Um Tabellen Zeile für Zeile in einem Speicherauszug abzulegen, verwenden Sie die Option --quick (oder die Option --opt, die --quick aktiviert). Die Option --opt (und daher --quick) ist standardmäßig in MySQL 5.1 aktiviert; um Speicherpufferung zu aktivieren, verwenden Sie --skip-quick.

Wenn Sie eine aktuelle Version von mysqldump zur Erzeugung eines Speicherauszugs verwenden, der in einen sehr alten MySQL Server geladen werden soll, dann sollten Sie die Optionen --opt oder --extended-insert nicht benutzen. Verwenden Sie stattdessen --skip-opt.

Anmerkung

mysqldump aus der MySQL 5.1.21-Distribution kann nicht verwendet werden, um Speicherauszüge der MySQL-Serverversionen 5.1.20 und älter einzurichten. Dies ist in MySQL 5.1.22 behoben. (Bug#30123)

mysqldump unterstützt die Optionen in der folgenden Liste. Es liest auch Optionsdateien und unterstützt die beschriebenen Optionen für deren Verarbeitung (siehe Command-Line Options that Affect Option-File Handling).

  • --help, -?

    Zeigt eine Hilfsmeldung an und wird dann beendet.

  • --add-drop-database

    Fügt eine DROP DATABASE-Anweisung vor jede CREATE DATABASE-Anweisung ein.

  • --add-drop-table

    Fügt eine DROP TABLE-Anweisung vor jede CREATE TABLE-Anweisung ein.

  • --add-locks

    Setzt jeden Tabellenspeicherauszug zwischen eine LOCK TABLES- und eine UNLOCK TABLES-Anweisung. Hierdurch werden die Einfügevorgänge beim Neuladen der Speicherauszugsdatei beschleunigt. Siehe auch Abschnitt 4.2.21, „Geschwindigkeit von INSERT-Anweisungen“.

  • --all-databases, -A

    Erstellt einen Speicherauszug aller Tabellen in allen Datenbanken. Dies entspricht der Option --databases bei gleichzeitiger Nennung aller Datenbanken auf der Befehlszeile.

  • --all-tablespaces, -Y

    Fügt zum Tabellenspeicherauszug alle SQL-Anweisungen hinzu, die zur Erstellung von Tablespaces für eine NDBCLUSTER-Tabelle erforderlich sind. Diese Informationen können nur auf diese Weise in der Ausgabe von mysqldump angegeben werden. Die Option ist derzeit nur für MySQL-Cluster-Tabellen relevant.

    Diese Option wurde in MySQL 5.1.6 hinzugefügt.

  • --allow-keywords

    Erlaubt die Erstellung von Spaltennamen, die Schlüsselwörter sind. Dies funktioniert, indem jedem Spaltennamen der Tabellenname vorangestellt wird.

  • --character-sets-dir=path

    Das Verzeichnis, in dem Zeichensätze installiert sind. Siehe auch Character Set Configuration.

  • --comments, -i

    Schreibt zusätzliche Informationen in die Speicherauszugsdatei wie etwa Programmversion, Serverversion und Host. Die Option ist standardmäßig aktiviert. Um diese Zusatzinformationen zu unterdrücken, verwenden Sie --skip-comments.

  • --compact

    Erzeugt eine weniger ausführliche Ausgabe. Diese Option aktiviert die Optionen --skip-add-drop-table, --skip-add-locks, --skip-comments, --skip-disable-keys und --skip-set-charset.

    Anmerkung

    Vor Release 5.1.21 erstellte diese Option keine zulässige SQL, wenn der Datenbankauszug Ansichten enthielt. Für die Neuerstellung von Ansichten ist es erforderlich, dass temporäre Tabellen erstellt und entfernt werden; diese Option unterdrückte die Entfernung dieser temporären Tabellen. Als Workaround verwenden Sie die Option --compact mit --add-drop-table und passen dann manuell die Speicherauszugsdatei an.

  • --compatible=name

    Erzeugt eine Ausgabe, bei der die Kompatibilität mit anderen Datenbanksystemen oder älteren MySQL-Servern höher ist. Der Wert von name kann ansi, mysql323, mysql40, postgresql, oracle, mssql, db2, maxdb, no_key_options, no_table_options oder no_field_options sein. Um mehrere Werte zu verwenden, trennen Sie diese durch Kommata. Diese Werte haben dieselbe Bedeutung wie die entsprechenden Optionen zur Einstellung des SQL-Modus am Server. Siehe auch Server SQL Modes.

    Die Option garantiert keine Kompatibilität mit anderen Servern. Vielmehr aktiviert sie nur diejenigen SQL-Moduswerte, die zum gegebenen Zeitpunkt verfügbar sind, um die Kompatibilität der Speicherauszugsausgabe zu erhöhen. So führt --compatible=oracle weder eine Zuordnung von Datentypen zu Oracle-Typen durch noch wird die Oracle-Kommentarsyntax verwendet.

    Diese Option benötigt die Serverversion 4.1.0 oder höher. Auf älteren Servern führt sie keine Aktion aus.

  • --complete-insert, -c

    Verwendet vollständige INSERT-Anweisungen, die auch Spaltennamen enthalten.

  • --compress, -C

    Komprimiert alle Daten, die zwischen Client und Server ausgetauscht werden, sofern beide die Komprimierung unterstützen.

  • --create-options

    Fügt alle MySQL-spezifischen Tabellenoptionen in die CREATE TABLE-Anweisungen ein.

  • --databases, -B

    Erstellt einen Speicherauszug mehrerer Datenbanken. Normalerweise betrachtet mysqldump das erste Namensargument auf der Befehlszeile als Datenbank- und alle nachfolgenden Argumente als Tabellennamen. Bei dieser Option hingegen werden alle Namensargumente als Datenbanknamen behandelt. CREATE DATABASE- und USE-Anweisungen werden für jede neue Datenbank in die Ausgabe eingefügt.

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

    Schreibt ein Debuglog. Der String debug_options heißt häufig 'd:t:o,file_name'. Der Standardwert ist 'd:t:o,/tmp/mysqldump.trace'.

  • --debug-check

    Gibt einige Debuginformationen aus, wenn das Programm beendet wird. Diese Option wurde in MySQL 5.1.21 hinzugefügt.

  • --debug-info

    Druckt Debuginformationen sowie Speicher- und CPU-Nutzungsstatistiken, wenn das Programm beendet wird. Diese Option wurde in MySQL 5.1.14 hinzugefügt.

  • --default-character-set=charset_name

    Verwendet charset_name als Standardzeichensatz. So bietet etwa die C-API eine Anzahl von Funktionsaufrufen, die eine API für vorbereitete Anweisungen darstellen. Siehe auch Character Set Configuration. Wenn kein Zeichensatz angegeben wird, verwendet mysqldump utf8; frühere Versionen verwenden latin1.

    Vor MySQL 5.1.38 hatte diese Option keine Wirkung auf Ausgabedatendateien, die unter Verwendung der --tab-Option erstellt wurden. Siehe Beschreibung zu dieser Option.

  • --delayed-insert

    Schreibt INSERT DELAYED- statt INSERT-Anweisungen.

  • --delete-master-logs

    Löscht auf einem Master-Replikationsserver nach Erstellung des Speicherauszugs die Binärlogs. Diese Option aktiviert automatisch --master-data.

  • --disable-keys, -K

    Umschließen Sie für jede Tabelle die INSERT-Anweisungen mit /*!40000 ALTER TABLE tbl_name DISABLE KEYS */; und /*!40000 ALTER TABLE tbl_name ENABLE KEYS */;. Dies beschleunigt das Laden der Speicherauszugsdatei, weil die Indizes nach Einfügen aller Datensätze erstellt werden. Diese Option ist nur für nichteindeutige Indizes von MyISAM-Tabellen wirksam.

  • --dump-date

    mysqldump erzeugt den Kommentar -- Dump completed on DATE am Ende des Speicherauszugs, wenn die --comments-Option angegeben wurde. Allerdings führt DATE dazu, dass Speicherauszugsdateien für identische Daten, die zu unterschiedlichen Zeiten erstellt wurden, unterschiedlich zu sein scheinen. --dump-date und --skip-dump-date steuern, ob das Datum dem Kommentar hinzugefügt wird. Die Voreinstellung ist --dump-date (das Datum in den Kommentar aufnehmen). --skip-dump-date unterdrückt die Datumsausgabe. Diese Option wurde in MySQL 5.1.23 hinzugefügt.

  • --events, -E

    Erstellt Speicherauszüge von Ereignissen aus den Speicherauszugsdatenbanken. Diese Option wurde in MySQL 5.1.8 hinzugefügt.

  • --extended-insert, -e

    Verwendet die INSERT-Syntax für mehrere Datensätze (diese enthält verschiedene VALUES-Listen). Ergebnis sind eine kleinere Speicherauszugsdatei und beschleunigte Einfügeoperationen beim Neuladen der Datei.

  • --fields-terminated-by=..., --fields-enclosed-by=..., --fields-optionally-enclosed-by=..., --fields-escaped-by=...

    Diese Optionen werden mit der Option -T verwendet und haben dieselben Bedeutungen wie die jeweiligen Klauseln für LOAD DATA INFILE. Siehe auch Abschnitt 8.2.6, „LOAD DATA INFILE.

  • --first-slave, -x

    Veraltet. Heißt jetzt --lock-all-tables.

  • --flush-logs, -F

    Synchronisiert die Logdateien des MySQL Servers auf Festplatte, bevor der Speicherauszugsvorgang gestartet wird. Diese Option erfordert die Berechtigung RELOAD. Beachten Sie, dass, wenn Sie diese Option in Verbindung mit der Option --all-databases (bzw. -A) verwenden, die Logs für jede Datenbank, für die ein Speicherauszug erstellt wird, synchronisiert werden. Die Ausnahme ist, wenn Sie --lock-all-tables oder --master-data verwenden: In diesem Fall werden die Protokolle nur einmal geleert, und zwar in dem Moment, wenn alle Tabellen gesperrt werden. Wenn Sie wollen, dass Speicherauszug und Logsynchronisierung im exakt gleichen Moment erfolgen, sollten Sie --flush-logs wahlweise gemeinsam mit --lock-all-tables oder --master-data verwenden.

  • --flush-privileges

    Gibt eine FLUSH PRIVILEGES-Anweisung aus, nachdem Sie einen Speicherauszug der mysql-Datenbank erstellt haben. Diese Option sollte immer dann verwendet werden, wenn der Auszug die mysql-Datenbank und eine andere Datenbank enthält, die von den Daten in der mysql-Datenbank zur korrekten Wiederherstellung abhängt. Diese Option wurde in MySQL 5.1.12 hinzugefügt.

  • --force, -f

    Setzt die Ausführung auch dann fort, wenn ein SQL-Fehler während eines Speicherauszugsvorgangs auftritt.

    Eine Verwendung für diese Option besteht darin, die Ausführung von mysqldump weiter zu verursachen, auch wenn es eine Ansicht findet, die ungültig geworden ist, weil die Definition sich auf eine Tabelle bezieht, die verworfen wurde. Ohne --force wird mysqldump mit einer Fehlermeldung beendet. Mit --force druckt mysqldump die Fehlermeldung, aber schreibt zusätzlich einen SQL-Kommentar, der die Ansichtdefinition zur Auszugsausgabe enthält, und fährt mit der Ausführung fort.

  • --host=host_name, -h host_name

    Speichert den Speicherauszug der Daten vom MySQL Server auf den angegebenen Host. Der Standardhost ist localhost.

  • --hex-blob

    Erstellt den Speicherauszug unter Verwendung der Hexadezimalnotation (z. B. wird aus 'abc' 0x616263). Betroffen sind die Datentypen BINARY, VARBINARY, BLOB und BIT.

  • --ignore-table=db_name.tbl_name

    Erstellt keinen Speicherauszug der bestimmten Tabelle, die sowohl mit dem Datenbank- als auch dem Tabellennamen angegeben werden muss. Um mehrere Tabellen zu ignorieren, verwenden Sie mehrere Instanzen dieser Option. Diese Option kann auch verwendet werden, um Ansichten zu ignorieren.

  • --insert-ignore

    Schreibt INSERT-Anweisungen mit der IGNORE-Option.

  • --lines-terminated-by=...

    Diese Option wird mit der Option -T verwendet und hat dieselbe Bedeutung wie die jeweilige Klausel für LOAD DATA INFILE. Siehe auch Abschnitt 8.2.6, „LOAD DATA INFILE.

  • --lock-all-tables, -x

    Sperrt datenbankübergreifend alle Tabellen. Dieses wird erreicht, indem eine globale Lesesperre für die Gesamtdauer des Speicherauszugs erwirkt wird. Die Option schaltet --single-transaction und --lock-tables automatisch ab.

  • --lock-tables, -l

    Sperrt alle Tabellen, bevor ein Speicherauszug erstellt wird. Die Tabellen werden im Falle von MyISAM-Tabellen mit READ LOCAL gesperrt, um nebenläufige Einfügeoperationen durchführen zu können. Bei transaktionssicheren Tabellen wie InnoDB ist --single-transaction eine wesentlich bessere Option, denn sie erfordert überhaupt kein Sperren der Tabellen.

    Beachten Sie, dass, wenn Sie Speicherauszüge mehrerer Datenbanken erstellen, --lock-tables die Tabellen für jede Datenbank separat sperrt. Insofern stellt diese Option nicht sicher, dass die Tabellen in der Speicherauszugsdatei datenbankübergreifend logisch konsistent sind. Die Tabellen in verschiedenen Datenbanken, von denen ein Speicherauszug erstellt wird, befinden sich unter Umständen in vollkommen unterschiedlichen Zuständen.

  • --log-error=file_name

    Hängt Warnungen und Fehler an die benannte Datei an. Diese Option wurde in MySQL 5.1.18 hinzugefügt.

  • --master-data[=value]

    Verwenden Sie diese Option, um einen Speicherauszug eines Masterreplikationsservers zu erstellen, um so eine Speicherauszugsdatei zu erstellen, die zum Einrichten eines anderen Servers als Slave zum Master verwendet werden kann. Sie führt dazu, dass die Auszugsausgabe eine CHANGE MASTER TO-Anweisung enthält, die die Binärlogkoordinaten (Dateiname und Position) des gedumpten Servers anzeigt. Dies sind die Masterserverkoordinaten, mit denen der Slave die Replikation starten muss.

    Wenn der Optionswert 2 ist, wird die CHANGE MASTER TO-Anweisung als SQL-Kommentar geschrieben, und ist somit nur informativ; sie hat keine Wirkung, wenn die Speicherauszugsdatei nachgeladen wird. Wenn der Optionswert 1 ist, tritt die Anweisung in Kraft, wenn die Speicherauszugsdatei nachgeladen wird. Wenn der Optionswert nicht angegeben ist, ist der Standardwert 1.

    Diese Option erfordert die Berechtigung RELOAD, und das Binärlog muss aktiviert sein.

    Die --master-data-Option deaktiviert automatisch --lock-tables. Sie deaktiviert auch --lock-all-tables, es sei denn, --single-transaction ist ebenfalls angegeben. In diesem Fall wird eine globale Lesesperre nur für eine kurze Zeit am Anfang des Auszugs erwirkt (siehe Beschreibung zu --single-transaction). In allen Fällen erfolgen Vorgänge an Logs im exakten Moment des Speicherauszugs.

    Es ist auch möglich, einen Slave durch das Erstellen eines Speicherauszugs eines existierenden Slaves vom Master einzurichten. Dazu verwenden Sie die folgende Prozedur auf dem existierenden Slave:

    1. Stoppen Sie den SQL-Thread des Slaves, und rufen Sie seinen aktuellen Status ab:

      mysql> STOP SLAVE SQL_THREAD;
      mysql> SHOW SLAVE STATUS;
      
    2. Rufen Sie aus der Ausgabe der SHOW SLAVE STATUS-Anweisung die Binärlogkoordinaten des Masterservers ab, von dem der neue Slave replizieren soll. Diese Koordinaten sind die Werte der Werte Relay_Master_Log_File und Exec_Master_Log_Pos. Zeigen Sie diese Werte als file_name und file_pos an.

    3. Erstellen Sie einen Speicherauszug des Slave-Servers:

      shell> mysqldump --master-data=2 --all-databases > dumpfile
      
    4. Starten Sie den Slave neu:

      mysql> START SLAVE;
      
    5. Laden Sie auf dem neuen Slave die Speicherauszugsdatei nach:

      shell> mysql < dumpfile
      
    6. Setzen Sie auf dem neuen Slave die Replikationskoordinaten auf die des zuvor erhaltenen Masterservers:

      mysql> CHANGE MASTER TO
          -> MASTER_LOG_FILE = 'file_name', MASTER_LOG_POS = file_pos;
      

      Die CHANGE MASTER TO-Anweisung könnte auch andere Parameter wie MASTER_HOST benötigen, um den Slave auf den richtigen Masterserver-Host zu verweisen. Fügen Sie solche Parameter ggf. hinzu.

  • --no-autocommit

    Setzen Sie die INSERT-Anweisungen für jede gedumpte Tabelle in SET autocommit = 0- und COMMIT-Anweisungen.

  • --no-create-db, -n

    Diese Option unterdrückt die CREATE DATABASE-Anweisungen, die andernfalls in der Ausgabe enthalten wären, wenn die Optionen --databases oder --all-databases angegeben wurden.

  • --no-create-info, -t

    Es werden keine CREATE TABLE-Anweisungen geschrieben, die jede gespeicherte Tabelle neu erstellen.

  • --no-data, -d

    Schreibt keine Tabellenzeileninformationen (das heißt, erstellt keinen Speicherauszug des Tabelleninhalts). Dies ist recht nützlich, wenn Sie einen Speicherauszug nur für die CREATE TABLE-Anweisung für die Tabelle erstellen wollen.

  • --no-set-names

    Diese Option ist veraltet. Verwenden Sie --skip-set-charset als Alternative.

  • --opt

    Dies ist eine Kurzform, die für folgende Option steht: --add-drop-table --add-locks --create-options --disable-keys --extended-insert --lock-tables --quick --set-charset. Ergebnis sollte ein schneller Speicherauszugsprozess sein, an dessen Ende eine Speicherauszugsdatei steht, die problemlos in einen MySQL Server eingeladen werden kann.

    Die --opt-Option ist standardmäßig aktiviert. Verwenden Sie --skip-opt, um sie zu deaktivieren. In der Diskussion am Anfang dieses Abschnitts erhalten Sie Informationen darüber, wie Sie bestimmte Optionen aktivieren oder deaktivieren, die von --opt betroffen sind.

  • --order-by-primary

    Sortiert die Datensätze jeder Tabelle nach ihrem Primärschlüssel oder nach ihrem ersten eindeutigen Index, wenn ein solcher Index existiert. Dies ist nützlich, wenn Sie einen Speicherauszug einer MyISAM-Tabelle erstellen, die in eine InnoDB-Tabelle geladen werden soll, macht die Erstellung des Auszugs selbst aber erheblich länger.

  • --password[=password], -p[password]

    Verwendet das angegebene Passwort zur Verbindung mit dem Server. Wenn Sie die Kurzform der Option (-p) verwenden, dürfen Sie kein Leerzeichen zwischen Option und Passwort setzen. Lassen Sie den Wert password auf die Option --password bzw. -p folgend weg, dann werden Sie zur Eingabe des Passworts aufgefordert.

    Die Angabe eines Passworts direkt auf der Befehlszeile ist als nicht sicher einzuordnen. Siehe auch End-User Guidelines for Password Security.

  • --pipe, -W

    Stellt unter Windows eine Verbindung mit dem Server über eine Named Pipe her. Diese Option gilt nur für Verbindungen zu einem lokalen Server und nur wenn der Server Named-Pipe-Verbindungen unterstützt.

  • --port=port_num, -P port_num

    Die TCP/IP-Portnummer, die für die Verbindung verwendet werden soll.

  • --protocol={TCP|SOCKET|PIPE|MEMORY}

    Das Verbindungsprotokoll, das für die Verbindung mit dem Server verwendet wird. Es ist nützlich, wenn die anderen Verbindungsparameter normalerweise dazu führen würden, dass ein anderes Protokoll verwendet wird als dasjenige, das Sie wollen. Details zu den zulässigen Werten finden Sie unter Connecting to the MySQL Server.

  • --quick, -q

    Diese Option ist nützlich, um einen Speicherauszug großer Tabellen zu erstellen. Hier wird mysqldump gezwungen, die Datensätze für eine Tabelle datensatzweise vom Server abzurufen, statt vor dem Schreiben die gesamte Ergebnismenge zu holen und sie temporär im Speicher abzulegen.

  • --quote-names, -Q

    Setzt Datenbank-, Tabellen- und Spaltennamen in „`“-Zeichen. Wenn der SQL-Modus ANSI_QUOTES aktiviert ist, werden die Namen in die „"“-Anführungszeichen gesetzt. Die Option ist standardmäßig aktiviert. Sie kann mit --skip-quote-names deaktiviert werden, aber diese Option sollte nach anderen Optionen wie etwa --compatible angegeben werden, mit denen --quote-names aktiviert werden könnte.

  • --replace

    Schreibt REPLACE- statt INSERT-Anweisungen. Wurde in MySQL 5.1.3 hinzugefügt.

  • --result-file=file_name, -r file_name

    Die Ausgabe erfolgt direkt in die angegebene Datei. Diese Option sollte unter Windows benutzt werden, um die Konvertierung von Zeilenumbrüchen („\n“) in Folgen von Absatzschaltung und Zeilenumbruch („\r\n“) zu verhindern. Die Ergebnisdatei wird eingerichtet und ihr Inhalt überschrieben, auch wenn ein Fehler auftritt, während der Auszug generiert wird. Der bisherige Inhalt geht verloren.

  • --routines, -R

    Erstellt einen Speicherauszug gespeicherter Routinen (Funktionen und Prozeduren) aus Datenbankspeicherauszügen. Für die Verwendung dieser Option ist die SELECT-Berechtigung für die mysql.proc-Tabelle erforderlich. Die mit --routines erzeugte Ausgabe enthält CREATE PROCEDURE- und CREATE FUNCTION-Anweisungen zur Neuerstellung der Routinen. Allerdings enthalten diese Anweisungen keine Attribute wie die Zeitstempel für die Routinenerstellung und -änderung. Das heißt, wenn die Routinen nachgeladen werden, werden sie mit den Zeitstempeln eingerichtet, die sie zur Neuladezeit hatten.

    Wenn Sie Routinen benötigen, die mit den Originalattributen für Zeitstempel neu erstellt wurden, verwenden Sie --routines nicht. Stattdessen erstellen Sie unter Verwendung eines MySQL-Kontos, das die erforderlichen Berechtigungen für die Datenbank mysql hat, direkt einen Speicherauszug des Inhalts der Tabelle mysql.proc und laden diesen Inhalt dann neu.

    Diese Option wurde in MySQL 5.1.2 hinzugefügt. Zuvor war ein Speicherauszug gespeicherter Routinen nicht möglich. Für Routinen-DEFINER-Werte werden erst ab MySQL 5.1.8 Speicherauszüge erstellt. Das heißt, dass vor Release 5.1.8 beim Neuladen von Routinen diese mit der Definition erstellt werden, die auf den neu ladenden Benutzer eingerichtet sind. Wenn Sie möchten, dass Routinen mit ihrer ursprünglichen Definition neu eingerichtet werden sollen, erstellen Sie einen Speicherauszug des Inhalts der mysql.proc-Tabelle und laden diesen direkt, wie oben beschrieben.

  • --set-charset

    Fügt SET NAMES default_character_set zur Ausgabe hinzu. Die Option ist standardmäßig aktiviert. Um die SET NAMES-Anweisung zu unterdrücken, verwenden Sie --skip-set-charset.

  • --single-transaction

    Diese Option setzt eine SQL-Anweisung BEGIN ab, bevor der Speicherauszug vom Server durchgeführt wird. Sie ist nur bei transaktionssicheren Tabellen wie InnoDB nützlich, denn der Speicherauszug spiegelt den konsistenten Zustand der Datenbank zu dem Zeitpunkt wider, an dem BEGIN abgesetzt wurde, ohne dass Anwendungen gesperrt werden.

    Wenn Sie diese Option verwenden, sollten Sie beachten, dass ein Speicherauszug nur von InnoDB-Tabellen in einem konsistenten Zustand erstellt werden kann. MyISAM- oder MEMORY-Tabellen, für die unter Verwendung dieser Option ein Speicherauszug erstellt wird, können ihren Zustand trotzdem noch ändern.

    Während ein --single-transaction-Auszug läuft, sollte keine andere Verbindung die Anweisungen ALTER TABLE, DROP TABLE, RENAME TABLE und TRUNCATE TABLE verwenden, um eine zulässige Speicherauszugsdatei sicherzustellen (richtiger Tabelleninhalt und Binärlogposition). Eine konsistente Leseoperation ist nicht isoliert von diesen Anweisungen zu betrachten, d. h. eine Verwendung dieser Anweisungen für eine zu dumpende Tabelle kann dazu führen, dass das von mysqldump ausgeführte SELECT den Tabelleninhalt abruft und dabei falsche Inhalte erhält oder sogar fehlschlägt.

    Diese Option wird nicht für MySQL Cluster-Tabellen unterstützt; es kann nicht garantiert werden, dass die Ergebnisse konsistent sind, da die NDBCLUSTER-Speicher-Engine nur die Transaktionsisolationsebene READ_COMMITTED unterstützt. Sie sollten stattdessen immer NDB-Datensicherung-/wiederherstellung verwenden.

    Die Optionen --single-transaction und --lock-tables schließen sich gegenseitig aus, weil LOCK TABLES implizit das Schreiben anhängiger Transaktionen auslöst.

    Um Speicherauszüge großer Tabellen zu erstellen, sollten Sie diese Option mit --quick kombinieren.

  • --skip-comments

    Siehe Beschreibung zu --comments.

  • --skip-opt

    Siehe Beschreibung zu --opt.

  • --socket=path, -S path

    Bei Verbindungen mit localhost ist dies die zu verwendende Unix-Socketdatei bzw. (unter Windows) der Name der zu verwendenden Named Pipe.

  • --ssl*

    Optionen, die mit --ssl anfangen, geben an, ob Sie eine Serververbindung über SSL herstellen und wo Sie SSL-Schlüssel und Zertifikate finden. Siehe auch SSL Command Options.

  • --tab=path, -T path

    Erzeugt tabulatorgetrennte Datendateien. Für jede Tabelle, für die ein Speicherauszug erstellt wurde, erzeugt mysqldump eine tbl_namesql-Datei, welche die CREATE TABLE-Anweisung, mit der die Tabelle erstellt wird, enthält, und eine tbl_name.txt mit den Daten dieser Tabelle. Der Optionswert ist das Verzeichnis, in das die Dateien geschrieben werden.

    Standardmäßig werden die .txt-Datendateien mit Tabulatorzeichen zwischen den Spaltenwerten und einem Zeilenumbruch am Ende jeder Zeile formatiert. Das Format kann aber auch explizit mit den Optionen --fields-xxx und --lines-terminated-by angegeben werden.

    Ab MySQL 5.1.38 werden Spaltenwerte als in den von der Option--default-character-set angegebenen Zeichensatz konvertierte Werte geschrieben. Vor 5.1.38 oder ohne eine solche Option werden die Speicherauszüge von Werten unter Verwendung des binary-Zeichensatzes erstellt. In Wirklichkeit gibt es keine Zeichensatzkonvertierung. Wenn eine Tabelle Spalten in mehreren Zeichensätzen enthält, wird dies die Ausgabedatendatei ebenso tun. Unter Umständen können Sie die Datei nicht richtig neu laden.

    Anmerkung

    Diese Option sollte nur dann verwendet werden, wenn mysqldump auf demselben Computer läuft wie der Server mysqld. Sie benötigen die Berechtigung FILE, und der Server muss eine Berechtigung zum Schreiben von Dateien in das von Ihnen angegebene Verzeichnis haben.

  • --tables

    Setzt die Option --databases bzw. -B außer Kraft. mysqldump behandelt alle Namensargumente nach der Option als Tabellennamen.

  • --triggers

    Erstellt einen Speicherauszug für Trigger für jede Tabelle, für die ein Speicherauszug erstellt wurde. Die Option ist standardmäßig aktiviert. Sie können sie mithilfe von --skip-triggers deaktivieren.

  • --tz-utc

    Diese Option ermöglicht ein Erstellen eines Speicherauszugs von TIMESTAMP-Spalten und Neuladen dieser Spalten zwischen Servern in verschiedenen Zeitzonen. mysqldump setzt seine Verbindungszeit auf UTC in Zonen aufteilen und fügt der Speicherauszugsdatei SET TIME_ZONE='+00:00' hinzu. Ohne diese Option werden TIMESTAMP-Spalten in den Zeitzonen gespeichert und geladen, die für den Quell- bzw. Zielserver lokal sind; dies kann Werteänderungen zur Folge haben. Außerdem schützt --tz-utc gegen sommerzeitbedingte Änderungen. --tz-utc ist standardmäßig aktiviert. Um es zu deaktivieren, verwenden Sie --skip-tz-utc. Diese Option wurde in MySQL 5.1.2 hinzugefügt.

  • --user=user_name, -u user_name

    Verwendet den angegebenen MySQL-Benutzernamen zur Verbindung mit dem Server.

  • --verbose, -v

    Ausführlicher Modus. Es werden zusätzliche Angaben zu den Aktivitäten des Programms ausgegeben.

  • --version, -V

    Zeigt die Versionsinformation an und wird dann beendet.

  • --where='where_condition', -w 'where_condition'

    Fügt nur diejenigen Datensätze in den Speicherauszug ein, die aufgrund der WHERE-Bedingung ausgewählt werden. Die Bedingung muss zwingend in Anführungszeichen gesetzt werden, wenn sie Leerzeichen oder andere Zeichen enthält, die Ihr Befehls-Interpreter als Sonderzeichen interpretiert.

    Ein paar Beispiele:

    --where="user='jimf'"
    -w"userid>1"
    -w"userid<1"
    
  • --xml, -X

    Schreibt die Ausgabe des Speicherauszugs als sauber formatiertes XML.

    NULL-, 'NULL'- und leere Werte: Für einige Spalten, die mit column_name benannt sind, werden der NULL-Wert, ein leerer String und der Stringwert 'NULL' voneinander in der von dieser Option generierten Ausgabe folgendermaßen unterschieden.

    Wert:XML-Darstellung:
    NULL (unbekannter Wert)

    <field name="column_name" xsi:nil="true" />

    '' (leerer String)

    <field name="column_name"></field>

    'NULL' (Stringwert)

    <field name="column_name">NULL</field>

    Ab MySQL 5.1.12 folgt die Ausgabe des mysql-Clients bei der Ausführung mit der --xml-Option diesen Regeln. (Siehe auch Abschnitt 3.1.1, „mysql Optionen“.)

    Ab MySQL 5.1.18 schließt die XML-Ausgabe von mysqldump den XML-Namensraum, wie hier gezeigt, ein:

    shell> mysqldump --xml -u root world City
    <?xml version="1.0"?>
    <mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <database name="world">
    <table_structure name="City">
    <field Field="ID" Type="int(11)" Null="NO" Key="PRI" Extra="auto_increment" />
    <field Field="Name" Type="char(35)" Null="NO" Key="" Default="" Extra="" />
    <field Field="CountryCode" Type="char(3)" Null="NO" Key="" Default="" Extra="" />
    <field Field="District" Type="char(20)" Null="NO" Key="" Default="" Extra="" />
    <field Field="Population" Type="int(11)" Null="NO" Key="" Default="0" Extra="" />
    <key Table="City" Non_unique="0" Key_name="PRIMARY" Seq_in_index="1" Column_name="ID" Collation="A" Cardinality="4079"
    Null="" Index_type="BTREE" Comment="" />
    <options Name="City" Engine="MyISAM" Version="10" Row_format="Fixed" Rows="4079" Avg_row_length="67" Data_length="27329
    3" Max_data_length="18858823439613951" Index_length="43008" Data_free="0" Auto_increment="4080" Create_time="2007-03-31 01:47:01" Updat
    e_time="2007-03-31 01:47:02" Collation="latin1_swedish_ci" Create_options="" Comment="" />
    </table_structure>
    <table_data name="City">
    <row>
    <field name="ID">1</field>
    <field name="Name">Kabul</field>
    <field name="CountryCode">AFG</field>
    <field name="District">Kabol</field>
    <field name="Population">1780000</field>
    </row>
    ...
    <row>
    <field name="ID">4079</field>
    <field name="Name">Rafah</field>
    <field name="CountryCode">PSE</field>
    <field name="District">Rafah</field>
    <field name="Population">92020</field>
    </row>
    </table_data>
    </database>
    </mysqldump>
    

Sie können mit der Syntax --var_name=value auch die folgenden Variablen einstellen:

  • max_allowed_packet

    Maximale Größe des Puffers für die Client/Server-Kommunikation. Der Maximalwert beträgt 1 Gbyte.

  • net_buffer_length

    Ausgangsgröße des Puffers für die Client/Server-Kommunikation. Wenn Sie Einfügeanweisungen für mehrere Datensätze (wie etwa mit den Optionen --extended-insert oder --opt) erstellen, legt mysqldump Datensätze an, deren maximale Länge durch net_buffer_length festgelegt ist. Wenn Sie den Wert dieser Variablen erhöhen, sollten Sie auch sicherstellen, dass die Variable net_buffer_length am MySQL Server mindestens genauso groß ist.

Die häufigste Anwendung von mysqldump ist wahrscheinlich die Erstellung eines Backups einer vollständigen Datenbank:

shell> mysqldump db_name > backup-file.sql

Die Speicherauszugsdatei können Sie wie folgt wieder in den Server einlesen.

shell> mysql db_name < backup-file.sql

Oder aber so:

shell> mysql -e "source /path-to-backup/backup-file.sql" db_name

mysqldump ist ferner sehr nützlich zum Ausfüllen von Datenbanken durch Kopieren von Daten von einem MySQL Server auf einen anderen:

shell> mysqldump --opt db_name | mysql --host=remote_host -C db_name

Sie können mit einem einzigen Befehl einen Speicherauszug mehrerer Datenbanken erstellen:

shell> mysqldump --databases db_name1 [db_name2 ...] > my_databases.sql

Um einen Speicherauszug aller Datenbanken zu erstellen, verwenden Sie die Option --all-databases:

shell> mysqldump --all-databases > all_databases.sql

Bei InnoDB-Tabellen bietet mysqldump die Möglichkeit, eine Online-Sicherung zu erstellen:

shell> mysqldump --all-databases --single-transaction > all_databases.sql

Diese Datensicherung erwirkt vor Beginn des Speicherauszugsvorgangs (mit FLUSH TABLES WITH READ LOCK) eine globale Lesesperre für alle Tabellen. Sobald diese Sperre aktiv ist, werden die Koordinaten des Binärlogs ausgelesen, und die Sperre wird aufgehoben. Wenn lange Aktualisierungsanweisungen ausgeführt werden, während die FLUSH-Anweisung ausgegeben wird, kann der MySQL-Server unter Umständen "hängen", bis diese Anweisungen abgearbeitet wurden. Danach wird der Auszug sperrenfrei und stört Lese- und Schreiboperationen in den Tabellen nicht mehr. Wenn die vom MySQL Server empfangenen Änderungsanweisungen (in Bezug auf ihre Ausführungsdauer) kurz sind, sollte die anfängliche Sperrperiode auch bei vielen Änderungen nicht spürbar sein.

Bei der Point-in-Time-Wiederherstellung (die auch als „Roll-Forward“ bezeichnet wird, wenn Sie ein altes Backup wiederherstellen und die seitdem durchgeführten Änderungen neu aufspielen müssen) ist es häufig nützlich, das Binärlog zu rotieren (siehe The Binary Log) oder zumindest die Binärlogkoordinaten zu kennen, denen der Speicherauszug entspricht:

shell> mysqldump --all-databases --master-data=2 > all_databases.sql

Oder:

shell> mysqldump --all-databases --flush-logs --master-data=2
              > all_databases.sql

Die Optionen --master-data und --single-transaction können gleichzeitig verwendet werden. Dies eignet sich sehr gut, um eine Onlinedatensicherung zu erstellen, so dass eine Point-in-Time-Recovery ausgeführt werden kann, wenn Tabellen mit der InnoDB-Speicher-Engine gespeichert werden.

Weitere Informationen zur Erstellung von Backups finden Sie in Database Backup Methods, und Example Backup and Recovery Strategy.

Wenn Sie auf Probleme beim Sichern von Ansichten stoßen, lesen Sie bitte den Abschnitt, der Beschränkungen zu Ansichten abdeckt. Hier finden Sie einen Workaround zum Sichern von Ansichten, wenn dies aufgrund von ungenügenden Berechtigungen scheitert. Siehe auch Restrictions on Views.

3.5. mysqlcheck — ein Datenimportprogramm

Der Client mysqlimport stellt eine Befehlszeilenoberfläche für die SQL-Anweisung LOAD DATA INFILE bereit. Die meisten Optionen für mysqlimport entsprechen direkt Klauseln der LOAD DATA INFILE-Syntax. Siehe auch Abschnitt 8.2.6, „LOAD DATA INFILE.

Rufen Sie mysqlimport wie folgt auf:

shell> mysqlimport [options] db_name textfile1 [textfile2 ...]

Bei jeder Textdatei, die auf der Befehlszeile angegeben wird, entfernt mysqlimport die Dateinamenserweiterung und bestimmt anhand des Ergebnisses den Namen der Tabelle, in die der Inhalt der Datei importiert werden soll. So würden beispielsweise die Dateien mit den Namen patient.txt, patient.text und patient alle in eine Tabelle namens patient importiert.

mysqlimport unterstützt die Optionen in der folgenden Liste. Es liest auch Optionsdateien und unterstützt die beschriebenen Optionen für deren Verarbeitung (siehe Command-Line Options that Affect Option-File Handling).

  • --help, -?

    Zeigt eine Hilfsmeldung an und wird dann beendet.

  • --character-sets-dir=path

    Das Verzeichnis, in dem Zeichensätze installiert sind. Siehe auch Character Set Configuration.

  • --columns=column_list, -c column_list

    Diese Option nimmt eine kommagetrennte Liste der Spaltennamen als Wert entgegen. Die Reihenfolge der Spaltennamen gibt an, wie die Spalten in der Datendatei den Tabellenspalten zuzuordnen sind.

  • --compress, -C

    Komprimiert alle Daten, die zwischen Client und Server ausgetauscht werden, sofern beide die Komprimierung unterstützen.

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

    Schreibt ein Debuglog. Der String debug_options heißt häufig 'd:t:o,file_name'. Standardwert ist 'd:t:o'.

  • --debug-check

    Gibt einige Debuginformationen aus, wenn das Programm beendet wird. Diese Option wurde in MySQL 5.1.21 hinzugefügt.

  • --debug-info

    Druckt Debuginformationen sowie Speicher- und CPU-Nutzungsstatistiken, wenn das Programm beendet wird. Diese Option wurde in MySQL 5.1.14 hinzugefügt.

  • --default-character-set=charset_name

    Verwendet charset_name als Standardzeichensatz. Siehe auch Character Set Configuration.

  • --delete, -D

    Leert die Tabelle vor dem Import der Textdatei.

  • --fields-terminated-by=..., --fields-enclosed-by=..., --fields-optionally-enclosed-by=..., --fields-escaped-by=...

    Diese Optionen haben dieselbe Bedeutung wie die entsprechenden Klauseln für LOAD DATA INFILE. Siehe auch Abschnitt 8.2.6, „LOAD DATA INFILE.

  • --force, -f

    Ignoriert Fehler. Wenn beispielsweise eine Tabelle für eine Textdatei nicht vorhanden ist, wird ggf. mit der Verarbeitung weiterer vorhandener Dateien fortgefahren. Ohne --force wird mysqlimport beendet, wenn eine Tabelle nicht vorhanden ist.

  • --host=host_name, -h host_name

    Importiert Daten in den MySQL Server auf dem angegebenen Host. Der Standardhost ist localhost.

  • --ignore, -i

    Siehe Beschreibung zu --replace.

  • --ignore-lines=N

    Ignoriert die ersten N Zeilen der Datendatei.

  • --lines-terminated-by=...

    Diese Option hat die gleiche Bedeutung wie die entsprechende Klausel für LOAD DATA INFILE. Um zum Beispiel Windows-Dateien zu importieren, deren Zeilen mit Wagenrücklauf/Zeilenvorschub-Paaren enden, verwenden Sie --lines-terminated-by="\r\n". (Unter Umständen müssen Sie den Backslash, abhängig von den Escape-Konventionen Ihres Befehls-Interpreters, verdoppeln.) Siehe auch Abschnitt 8.2.6, „LOAD DATA INFILE.

  • --local, -L

    Liest die Eingabedateien lokal vom Clienthost.

  • --lock-tables, -l

    Sperrt alle Tabellen für Schreiboperationen, bevor mit der Verarbeitung der Textdateien begonnen wird. Hierdurch ist sichergestellt, dass alle Tabellen auf dem Server synchronisiert sind.

  • --low-priority

    Verwenden Sie LOW_PRIORITY, wenn Sie die Tabelle laden. Dies wirkt sich nur auf Speicher-Engines aus, die eine Tabellenebenensperrung verwenden (MyISAM, MEMORY, MERGE).

  • --password[=password], -p[password]

    Verwendet das angegebene Passwort zur Verbindung mit dem Server. Wenn Sie die Kurzform der Option (-p) verwenden, dürfen Sie kein Leerzeichen zwischen Option und Passwort setzen. Lassen Sie den Wert password auf die Option --password bzw. -p folgend weg, dann werden Sie zur Eingabe des Passworts aufgefordert.

    Die Angabe eines Passworts direkt auf der Befehlszeile ist als nicht sicher einzuordnen. Siehe auch End-User Guidelines for Password Security.

  • --pipe, -W

    Stellt unter Windows eine Verbindung mit dem Server über eine Named Pipe her. Diese Option gilt nur für Verbindungen zu einem lokalen Server und nur wenn der Server Named-Pipe-Verbindungen unterstützt.

  • --port=port_num, -P port_num

    Die TCP/IP-Portnummer, die für die Verbindung verwendet werden soll.

  • --protocol={TCP|SOCKET|PIPE|MEMORY}

    Das Verbindungsprotokoll, das für die Verbindung mit dem Server verwendet wird. Es ist nützlich, wenn die anderen Verbindungsparameter normalerweise dazu führen würden, dass ein anderes Protokoll verwendet wird als dasjenige, das Sie wollen. Details zu den zulässigen Werten finden Sie unter Connecting to the MySQL Server.

  • --replace, -r

    Die Optionen --replace und --ignore steuern den Umgang mit eingegebenen Datensätzen, die Duplikate vorhandener Datensätze mit eindeutigen Schlüsselwerten darstellen. Wenn Sie --replace angeben, ersetzen die neuen die vorhandenen Datensätze, die denselben eindeutigen Schlüsselwert aufweisen. Bei Angabe von --ignore hingegen werden neue Datensätze, deren eindeutiger Schlüsselwert bereits einem vorhandenen Datensatz zugewiesen ist, ignoriert. Geben Sie keine Option an, dann tritt ein Fehler auf, wenn ein doppelter Schlüsselwert gefunden wird; in diesem Fall wird der Rest der Textdatei ignoriert.

  • --silent, -s

    Stummer Modus. Eine Ausgabe erfolgt nur, wenn ein Fehler auftritt.

  • --socket=path, -S path

    Bei Verbindungen mit localhost ist dies die zu verwendende Unix-Socketdatei bzw. (unter Windows) der Name der zu verwendenden Named Pipe.

  • --ssl*

    Optionen, die mit --ssl anfangen, geben an, ob Sie eine Serververbindung über SSL herstellen und wo Sie SSL-Schlüssel und Zertifikate finden. Siehe auch SSL Command Options.

  • --user=user_name, -u user_name

    Verwendet den angegebenen MySQL-Benutzernamen zur Verbindung mit dem Server.

  • --use-threads=N

    Lädt Dateien parallel unter Verwendung von N Threads. Diese Option wurde in MySQL 5.1.7 hinzugefügt.

  • --verbose, -v

    Ausführlicher Modus. Es werden zusätzliche Angaben zu den Aktivitäten des Programms ausgegeben.

  • --version, -V

    Zeigt die Versionsinformation an und wird dann beendet.

Die nachfolgende Beispielsitzung veranschaulicht die Verwendung von mysqlimport:

shell> mysql -e 'CREATE TABLE imptest(id INT, n VARCHAR(30))' test
shell> ed
a
100     Max Sydow
101     Count Dracula
.
w imptest.txt
32
q
shell> od -c imptest.txt
0000000   1   0   0  \t   M   a   x       S   y   d   o   w  \n   1   0
0000020   1  \t   C   o   u   n   t       D   r   a   c   u   l   a  \n
0000040
shell> mysqlimport --local test imptest.txt
test.imptest: Records: 2  Deleted: 0  Skipped: 0  Warnings: 0
shell> mysql -e 'SELECT * FROM imptest' test
+------+---------------+
| id   | n             |
+------+---------------+
|  100 | Max Sydow     |
|  101 | Count Dracula |
+------+---------------+

3.6. mysqlshow — Anzeigen von Datenbank-, Tabellen- und Spalteninformationen

Mit dem Client mysqlshow können Sie Informationen zu den vorhandenen Datenbanken, deren Tabellen oder den Spalten oder Indizes einer Tabelle schnell anzeigen.

mysqlshow stellt eine Befehlszeilenoberfläche für mehrere SQL-SHOW-Anweisungen bereit. So bietet etwa die C-API eine Anzahl von Funktionsaufrufen, die eine API für vorbereitete Anweisungen darstellen. Siehe auch Abschnitt 8.5.5, „SHOW-Syntax“. Dieselben Informationen können Sie auch durch direkte Verwendung dieser Anweisungen abrufen. Sie können sie beispielsweise über das Clientprogramm mysql absetzen.

Rufen Sie mysqlshow wie folgt auf:

shell> mysqlshow [options] [db_name [tbl_name [col_name]]]
  • Wenn keine Datenbank angegeben wird, erscheint eine Liste aller Datenbanknamen.

  • Wird keine Tabelle angegeben, dann werden alle passenden Tabellen in der Datenbank angezeigt.

  • Wird keine Spalte angegeben, dann werden alle passenden Spalten und Spaltentypen in der Tabelle angezeigt.

Die Ausgabe zeigt nur die Namen derjenigen Datenbanken, Tabellen oder Spalten an, für die Sie ausreichende Berechtigungen haben.

Enthält das letzte Argument Shell- oder SQL-spezifische Jokerzeichen („*“, „?“, „%“ oder „_“), dann werden nur diejenigen Namen gezeigt, die den jeweiligen Jokerzeichen entsprechen. Enthält ein Datenbankname Unterstriche, dann sollten diese mit einem Backslash (bei manchen Unix-Shells zwingend auch mit zwei Backslashs) markiert werden, um eine Liste der passenden Tabellen oder Spalten zu erhalten. Die Zeichen „*“ und „?“ werden in die SQL-Jokerzeichen „%“ und „_“ konvertiert. Dies kann zu Verwirrung führen, wenn Sie versuchen, die Spalten einer Tabelle mit einem „_“ im Namen anzuzeigen, denn in diesem Fall zeigt Ihnen mysqlshow nur die Tabellennamen an, die dem Muster entsprechen. Dieses Problem lässt sich allerdings ganz einfach beheben, indem Sie am Ende der Befehlszeile ein zusätzliches „%“ als separates Argument anhängen.

mysqlshow unterstützt die Optionen in der folgenden Liste. Es liest auch Optionsdateien und unterstützt die beschriebenen Optionen für deren Verarbeitung (siehe Command-Line Options that Affect Option-File Handling).

  • --help, -?

    Zeigt eine Hilfsmeldung an und wird dann beendet.

  • --character-sets-dir=path

    Das Verzeichnis, in dem Zeichensätze installiert sind. Siehe auch Character Set Configuration.

  • --compress, -C

    Komprimiert alle Daten, die zwischen Client und Server ausgetauscht werden, sofern beide die Komprimierung unterstützen.

  • --count

    Zeigt die Anzahl von Datensätzen pro Tabelle an. Dieser Vorgang kann für Nicht-MyISAM-Tabellen langsam sein.

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

    Schreibt ein Debuglog. Der String debug_options heißt häufig 'd:t:o,file_name'. Standardwert ist 'd:t:o'.

  • --debug-check

    Gibt einige Debuginformationen aus, wenn das Programm beendet wird. Diese Option wurde in MySQL 5.1.21 hinzugefügt.

  • --debug-info

    Druckt Debuginformationen sowie Speicher- und CPU-Nutzungsstatistiken, wenn das Programm beendet wird. Diese Option wurde in MySQL 5.1.14 hinzugefügt.

  • --default-character-set=charset_name

    Verwendet charset_name als Standardzeichensatz. Siehe auch Character Set Configuration.

  • --host=host_name, -h host_name

    Stellt eine Verbindung zum MySQL Server auf dem angegebenen Host her.

  • --keys, -k

    Zeigt die Tabellenindizes an.

  • --password[=password], -p[password]

    Verwendet das angegebene Passwort zur Verbindung mit dem Server. Wenn Sie die Kurzform der Option (-p) verwenden, dürfen Sie kein Leerzeichen zwischen Option und Passwort setzen. Lassen Sie den Wert password auf die Option --password bzw. -p folgend weg, dann werden Sie zur Eingabe des Passworts aufgefordert.

    Die Angabe eines Passworts direkt auf der Befehlszeile ist als nicht sicher einzuordnen. Siehe auch End-User Guidelines for Password Security.

  • --pipe, -W

    Stellt unter Windows eine Verbindung mit dem Server über eine Named Pipe her. Diese Option gilt nur für Verbindungen zu einem lokalen Server und nur wenn der Server Named-Pipe-Verbindungen unterstützt.

  • --port=port_num, -P port_num

    Die TCP/IP-Portnummer, die für die Verbindung verwendet werden soll.

  • --protocol={TCP|SOCKET|PIPE|MEMORY}

    Das Verbindungsprotokoll, das für die Verbindung mit dem Server verwendet wird. Es ist nützlich, wenn die anderen Verbindungsparameter normalerweise dazu führen würden, dass ein anderes Protokoll verwendet wird als dasjenige, das Sie wollen. Details zu den zulässigen Werten finden Sie unter Connecting to the MySQL Server.

  • --show-table-type, -t

    Zeigt eine Spalte an, die den Tabellentyp angibt (wie bei SHOW FULL TABLES). Der Typ ist BASE TABLE oder VIEW.

  • --socket=path, -S path

    Bei Verbindungen mit localhost ist dies die zu verwendende Unix-Socketdatei bzw. (unter Windows) der Name der zu verwendenden Named Pipe.

  • --ssl*

    Optionen, die mit --ssl anfangen, geben an, ob Sie eine Serververbindung über SSL herstellen und wo Sie SSL-Schlüssel und Zertifikate finden. Siehe auch SSL Command Options.

  • --status, -i

    Zeigt zusätzliche Informationen zu jeder Tabelle an.

  • --user=user_name, -u user_name

    Verwendet den angegebenen MySQL-Benutzernamen zur Verbindung mit dem Server.

  • --verbose, -v

    Ausführlicher Modus. Es werden zusätzliche Angaben zu den Aktivitäten des Programms ausgegeben. Diese Option kann mehrfach verwendet werden, um den Umfang der angezeigten Informationen zu erhöhen.

  • --version, -V

    Zeigt die Versionsinformation an und wird dann beendet.

3.7. mysqlslap — Lastemulations-Client

mysqlslap ist ein Diagnoseprogramm, dessen Zweck die Emulation einer Clientlast für einen MySQL Server ist und das zeitbezogene Angaben der einzelnen Operationsstufen meldet. Er simuliert den Zugriff mehrerer Clients auf den Server. mysqlslap ist ab MySQL 5.1.4 verfügbar.

Rufen Sie mysqlslap wie folgt auf:

shell> mysqlslap [options]

Einige Optionen wie --create oder --query ermöglichen Ihnen, einen String anzugeben, der eine SQL-Anweisung oder eine Anweisungen enthaltende Datei enthält. Wenn Sie eine Datei angeben, muss sie standardmäßig eine Anweisung pro Zeile enthalten. (Das heißt, der implizite Anweisungsbegrenzer ist das Zeilenumbruch-Zeichen.) Verwenden Sie die --delimiter-Option, um einen anderen Begrenzer anzugeben, der es Ihnen ermöglicht, Anweisungen anzugeben, die mehrere Zeilen umfassen, oder mehrere Anweisungen auf einer einzigen Zeile zu platzieren. Sie können keine Kommentare in eine Datei aufnehmen; mysqlslap versteht sie nicht.

mysqlslap wird in drei Stufen ausgeführt:

  1. Einrichten des Schemas, der Tabelle und (optional) der gespeicherten Programme oder Daten, die Sie für den Test verwenden möchten. Diese Stufe verwendet eine einzelne Clientverbindung.

  2. Ausführen des Lasttests. Diese Stufe kann viele Clientverbindungen verwenden.

  3. Bereinigen (Verbindung trennen, ggf. Tabelle verwerfen). Diese Stufe verwendet eine einzelne Clientverbindung.

Ein paar Beispiele:

Geben Sie eigene SQL-Create- und Query-Anweisungen an, mit 50 abfragenden Clients und 200 Selects für jeden Client:

mysqlslap --delimiter=";" \
  --create="CREATE TABLE a (b int);INSERT INTO a VALUES (23)" \
  --query="SELECT * FROM a" --concurrency=50 --iterations=200

Lassen Sie die SQL-Query-Anweisung von mysqlslap mit einer Tabelle erstellen, die zwei INT-Spalten und drei VARCHAR-Spalten enthält. Verwenden Sie fünf Clients, die jeweils 20 Abfragen starten. Richten Sie die Tabelle nicht ein bzw. fügen Sie keine Daten ein (das heißt, verwenden Sie das Schema und die Daten des vorherigen Tests):

mysqlslap --concurrency=5 --iterations=20 \
  --number-int-cols=2 --number-char-cols=3 \
  --auto-generate-sql

Teilen Sie dem Programm mit, dass es die SQL-Anweisungen Create, Insert und Query aus den angegebenen Dateien laden soll. Dabei hat die create.sql-Datei mehrere Tabellenerstellungsanweisungen, die durch ';' begrenzt werden, und mehrere Einfügeanweisungen, die durch ';' begrenzt werden. Die Datei --query wird somit mehrere Abfragen enthalten, die durch ';' voneinander abgegrenzt sind. Führen Sie alle Ladeanweisungen aus, und führen Sie dann alle Abfragen in der Abfragedatei mit fünf Clients aus (jeweils fünf Mal):

mysqlslap --concurrency=5 \
  --iterations=5 --query=query.sql --create=create.sql \
  --delimiter=";"

mysqlslap unterstützt die Optionen in der folgenden Liste. Es liest auch Optionsdateien und unterstützt die beschriebenen Optionen für deren Verarbeitung (siehe Command-Line Options that Affect Option-File Handling).

  • --help, -?

    Zeigt eine Hilfsmeldung an und wird dann beendet.

  • --auto-generate-sql, -a

    Erzeugt automatisch SQL-Anweisungen, wenn diese nicht in Dateien oder als Befehlsoptionen übergeben wurden.

  • --auto-generate-sql-add-autoincrement

    Fügt automatisch generierten Tabellen eine AUTO_INCREMENT-Spalte hinzu. Diese Option wurde in MySQL 5.1.18 hinzugefügt.

  • --auto-generate-sql-execute-number=N

    Gibt an, wie viele Abfragen automatisch generiert werden sollen. Diese Option wurde in MySQL 5.1.18 hinzugefügt.

  • --auto-generate-sql-guid-primary

    Fügt automatisch generierten Tabellen einen GUID-basierten Primärschlüssel hinzu. Diese Option wurde in MySQL 5.1.18 hinzugefügt.

  • --auto-generate-sql-load-type=type

    Gibt den Testladetyp an. Die zulässigen Werte sind read (Tabellen durchsuchen), write (in Tabellen einfügen), key (Primärschlüssel lesen), update (Primärschlüssel aktualisieren) und mixed (halb Einfügeoperationen, halb durchsuchende Selects). Die Voreinstellung ist mixed. Diese Option wurde in MySQL 5.1.16 hinzugefügt.

  • --auto-generate-sql-secondary-indexes=N

    Gibt an, wie viele sekundäre Indizes für automatisch generierte Tabellen hinzugefügt werden sollen. Standardmäßig werden keine hinzugefügt. Diese Option wurde in MySQL 5.1.18 hinzugefügt.

  • --auto-generate-sql-unique-query-number=N

    Gibt an, wie viele unterschiedliche Abfragen für automatische Tests generiert werden. Wenn Sie z. B. einen key-Test ausführen, der 1000 Selects ausführt, können Sie diese Option mit einem Wert von 1000 verwenden, um 1000 eindeutige Abfragen auszuführen, oder mit einem Wert von 50 verwenden, um 50 unterschiedliche Selects auszuführen. Der Standardwert ist 10. Diese Option wurde in MySQL 5.1.18 hinzugefügt.

  • --auto-generate-sql-unique-write-number=N

    Gibt an, wie viele unterschiedliche Abfragen für --auto-generate-sql-write-number generiert werden. Der Standardwert ist 10. Diese Option wurde in MySQL 5.1.18 hinzugefügt.

  • --auto-generate-sql-write-number=N

    Gibt an, wie viele Zeileneinfügeoperationen auf jedem Thread ausgeführt werden. Der Standardwert ist 100. Diese Option wurde in MySQL 5.1.16 hinzugefügt.

  • --commit=N

    Gibt an, wie viele Anweisungen vor einem Commit ausgeführt werden. Die Voreinstellung ist 0 (es werden keine Commits ausgeführt). Diese Option wurde in MySQL 5.1.21 hinzugefügt.

  • --compress, -C

    Komprimiert alle Daten, die zwischen Client und Server ausgetauscht werden, sofern beide die Komprimierung unterstützen.

  • --concurrency=N, -c N

    Anzahl der zu simulierenden Clients beim Absetzen der SELECT-Anweisung.

  • --create=value

    Datei oder String mit der Anweisung, die zur Erstellung der Tabelle verwendet wird.

  • --create-schema=value

    Schema, in dem die Tests ausgeführt werden. Diese Option wurde in MySQL 5.1.5 hinzugefügt.

  • --csv[=file_name]

    Erzeugt eine Ausgabe von Werten in kommagetrennter Form. Die Ausgabe erfolgt in die angegebene Datei oder, wenn keine Datei angegeben ist, in die Standardausgabe. Diese Option wurde in MySQL 5.1.5 hinzugefügt.

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

    Schreibt ein Debuglog. Der String debug_options heißt häufig 'd:t:o,file_name'. Standardwert ist 'd:t:o,/tmp/mysqlslap.trace'.

  • --debug-check

    Gibt einige Debuginformationen aus, wenn das Programm beendet wird. Diese Option wurde in MySQL 5.1.21 hinzugefügt.

  • --debug-info, -T

    Druckt Debuginformationen sowie Speicher- und CPU-Nutzungsstatistiken, wenn das Programm beendet wird. Diese Option wurde in MySQL 5.1.21 hinzugefügt.

  • --delimiter=str, -F str

    Trennzeichen, das in SQL-Anweisungen verwendet wird, die in Dateien oder über Befehlsoptionen angegeben werden.

  • --detach=N

    Trennt (schließt und öffnet wieder) nach allen N Anweisungen jede Verbindung. Die Voreinstellung ist 0 (Verbindungen werden nicht getrennt). Diese Option wurde in MySQL 5.1.21 hinzugefügt.

  • --engine=engine_name, -e engine_name

    Speicher-Engine, die zur Erstellung von Tabellen verwendet wird.

  • --host=host_name, -h host_name

    Stellt eine Verbindung zum MySQL Server auf dem angegebenen Host her.

  • --iterations=N, -i N

    Häufigkeit, mit der die Tests durchgeführt werden.

  • --lock-directory=path

    Verzeichnis, das zur Speicherung von Sperren verwendet wird. Diese Option wurde in MySQL 5.1.5 hinzugefügt und in 5.1.18 entfernt.

  • --number-char-cols=N, -x N

    Anzahl der VARCHAR-Spalten, die verwendet werden, wenn --auto-generate-sql angegeben ist.

  • --number-int-cols=N, -y N

    Anzahl der INT-Spalten, die verwendet werden, wenn --auto-generate-sql angegeben ist.

  • --number-of-queries=N

    Anzahl der Abfragen, auf die jeder Client ungefähr beschränkt wird. Diese Option wurde in MySQL 5.1.5 hinzugefügt.

  • --only-print

    Stellt keine Verbindung zu Datenbanken her. mysqlslap druckt nur, was es ausgeführt hätte. Diese Option wurde in MySQL 5.1.5 hinzugefügt.

  • --password[=password], -p[password]

    Verwendet das angegebene Passwort zur Verbindung mit dem Server. Wenn Sie die Kurzform der Option (-p) verwenden, dürfen Sie kein Leerzeichen zwischen Option und Passwort setzen. Lassen Sie den Wert password nach der Option --password bzw. -p auf der Befehlszeile weg, so werden Sie aufgefordert, einen Wert einzugeben.

    Die Angabe eines Passworts direkt auf der Befehlszeile ist als nicht sicher einzuordnen. Siehe auch End-User Guidelines for Password Security.

  • --pipe, -W

    Stellt unter Windows eine Verbindung mit dem Server über eine Named Pipe her. Diese Option gilt nur für Verbindungen zu einem lokalen Server und nur wenn der Server Named-Pipe-Verbindungen unterstützt.

  • --port=port_num, -P port_num

    Die TCP/IP-Portnummer, die für die Verbindung verwendet werden soll.

  • --post-query=value

    Datei oder String mit der Anweisung, die nach Abschluss der Tests auszuführen ist. Diese Ausführung wird im Timer nicht mitgezählt. Diese Option wurde in MySQL 5.1.18 hinzugefügt.

  • --shared-memory-base-name=name

    Unter Windows, der zu verwendende Shared-Memory-Name für über gemeinsamen Speicher hergestellte Verbindungen zu einem lokalen Server. Diese Option gilt nur, wenn der Server Shared-Memory-Verbindungen unterstützt.

  • --post-system=str

    Der über system() auszuführende String, nachdem die Tests abgeschlossen sind. Diese Ausführung wird im Timer nicht mitgezählt. Diese Option wurde in MySQL 5.1.21 hinzugefügt.

  • --pre-query=value

    Datei oder String mit der Anweisung, die vor Ausführung der Tests auszuführen ist. Diese Ausführung wird im Timer nicht mitgezählt. Diese Option wurde in MySQL 5.1.18 hinzugefügt.

  • --pre-system=str

    Der über system() auszuführende String, bevor die Tests ausgeführt werden. Diese Ausführung wird im Timer nicht mitgezählt. Diese Option wurde in MySQL 5.1.21 hinzugefügt.

  • --preserve-schema

    Behält das Schema der mysqlslap-Ausführung bei. Die Optionen--auto-generate-sql und --create deaktivieren diese Option. Diese Option wurde in MySQL 5.1.5 hinzugefügt und in 5.1.23 entfernt.

  • --protocol={TCP|SOCKET|PIPE|MEMORY}

    Das Verbindungsprotokoll, das für die Verbindung mit dem Server verwendet wird. Es ist nützlich, wenn die anderen Verbindungsparameter normalerweise dazu führen würden, dass ein anderes Protokoll verwendet wird als dasjenige, das Sie wollen. Details zu den zulässigen Werten finden Sie unter Connecting to the MySQL Server.

  • --query=value, -q value

    Datei oder String, der bzw. die die SELECT-Anweisung enthält, die zum Abrufen von Daten verwendet wird.

  • --silent, -s

    Stummer Modus. Es erfolgt keine Ausgabe.

  • --slave

    Folgt den Master-Sperren für andere mysqlslap-Clients. Verwenden Sie diese Option, wenn Sie die Synchronisation zu einem Master-Server mit --lock-directory und NFS beabsichtigen. Diese Option wurde in MySQL 5.1.5 hinzugefügt und in 5.1.18 entfernt.

  • --socket=path, -S path

    Bei Verbindungen mit localhost ist dies die zu verwendende Unix-Socketdatei bzw. (unter Windows) der Name der zu verwendenden Named Pipe.

  • --ssl*

    Optionen, die mit --ssl anfangen, geben an, ob Sie eine Serververbindung über SSL herstellen und wo Sie SSL-Schlüssel und Zertifikate finden. Siehe auch SSL Command Options.

  • --use-threads

    Auf Unix wird die Voreinstellung fork()-Aufrufe verwendet; diese Option führt dazu, dass stattdessen pthread-Aufrufe verwendet werden. (Unter Windows werden pthread-Aufrufe ohnehin standardmäßig verwendet, d. h., die Option hat keine Auswirkungen.) Diese Option wurde in MySQL 5.1.6 hinzugefügt und in 5.1.18 entfernt.

  • --user=user_name, -u user_name

    Verwendet den angegebenen MySQL-Benutzernamen zur Verbindung mit dem Server.

  • --verbose, -v

    Ausführlicher Modus. Es werden zusätzliche Angaben zu den Aktivitäten des Programms ausgegeben. Diese Option kann mehrfach verwendet werden, um den Umfang der angezeigten Informationen zu erhöhen.

  • --version, -V

    Zeigt die Versionsinformation an und wird dann beendet.

Kapitel 4. Optimierung

Inhaltsverzeichnis

4.1. Optimierungsübersicht
4.1.1. MySQL-Design-Beschränkungen und Kompromisse
4.1.2. Programme für Portabilität auslegen
4.1.3. Wofür wir MySQL verwendet haben
4.1.4. Die MySQL-Benchmark-Suite
4.1.5. Ihre eigenen Benchmarks verwenden
4.2. SELECT und andere Anweisungen optimieren
4.2.1. Abfragen mit EXPLAIN optimieren
4.2.2. Abschätzen der Abfrageleistung
4.2.3. Geschwindigkeit von SELECT-Abfragen
4.2.4. WHERE-Klausel-Optimierung
4.2.5. Bereichsoptimierung
4.2.6. Index-Merge-Optimierung
4.2.7. Condition Pushdown-Optimierung
4.2.8. IS NULL-Optimierung
4.2.9. LEFT-JOIN- und RIGHT-JOIN-Optimierung
4.2.10. Nested-Loop Join-Algorithmen
4.2.11. Nested Join-Optimierung
4.2.12. Vereinfachung des äußeren Join
4.2.13. ORDER BY-Optimierung
4.2.14. GROUP BY-Optimierung
4.2.15. DISTINCT-Optimierung
4.2.16. Optimieren der IN/=ANY-Unterabfragen
4.2.17. LIMIT-Optimierung
4.2.18. Den Optimierer mit optimizer_switch steuern
4.2.19. So vermeiden Sie Tabellenscans
4.2.20. INFORMATION_SCHEMA-Optimierung
4.2.21. Geschwindigkeit von INSERT-Anweisungen
4.2.22. Geschwindigkeit von UPDATE-Anweisungen
4.2.23. Geschwindigkeit von DELETE-Anweisungen
4.2.24. Weitere Optimierungstipps
4.3. Sperrprobleme
4.3.1. Interne Sperrmethoden
4.3.2. Tabellensperrprobleme
4.3.3. Gleichzeitige Einfügeoperationen
4.3.4. Externe Sperren
4.4. Optimieren der Datenbank-Struktur
4.4.1. Machen Sie Ihre Daten so klein wie möglich
4.4.2. Spaltenindizes
4.4.3. Mehrfachspaltenindizes
4.4.4. So verwendet MySQL Indizes
4.4.5. Der MyISAM-Schlüsselcache
4.4.6. MyISAM-Indexstatistiksammlung
4.4.7. So öffnet und schließt MySQL Tabellen
4.4.8. Nachteile durch das Erstellen vieler Tabellen in der gleichen Datenbank
4.5. Optimieren des MySQL-Servers
4.5.1. So wirken sich Kompilieren und Verknüpfen auf die Geschwindigkeit von MySQL aus
4.5.2. Systemfaktoren und Startup-Parameter-Tuning
4.5.3. Tuning der Server-Parameter
4.5.4. Steuern der Abfrageoptimiererleistung
4.5.5. Der MySQL-Abfragen-Cache
4.5.6. Prüfen der Thread-Informationen
4.5.7. So verwendet MySQL Threads für Clientverbindungen
4.5.8. So verwendet MySQL Speicher
4.5.9. Aktivierung der Unterstützung großer Seiten
4.5.10. So verwendet MySQL interne temporäre Tabellen
4.5.11. So verwendet MySQL DNS
4.6. Festplattenprobleme
4.6.1. Symbolische Verknüpfungen

Die Optimierung ist eine komplexe Aufgabe, denn sie setzt letztendlich ein umfassendes Verständnis des gesamten zu optimierenden Systems voraus. Zwar ist es möglich, in eingeschränktem Maße lokale Optimierungen ohne umfangreiche Kenntnisse Ihres Systems oder Ihrer Anwendung vorzunehmen, aber je optimaler Sie Ihr System gestalten wollen, desto mehr müssen Sie darüber wissen.

Dieses Kapitel erklärt unterschiedliche Möglichkeiten für die Optimierung von MySQL und liefert Beispiele. Bedenken Sie aber, dass es stets zusätzliche Möglichkeiten gibt, das System zu beschleunigen, wobei dabei jedoch immer auch der entsprechende Aufwand zu berücksichtigen ist.

4.1. Optimierungsübersicht

Der wesentlichste Faktor bei der Beschleunigung eines Systems ist sein grundsätzlicher Aufbau. Ferner müssen Sie wissen, welche Bearbeitungen Ihr System durchführt und wo Engpässe vorliegen. In den meisten Fällen treten Engpässe aufgrund folgender Ursachen auf:

  • Suchvorgänge auf der Festplatte. Die Festplatte braucht Zeit, um Daten zu finden. Bei modernen Festplatten beträgt die durchschnittliche Dauer eines Suchvorgangs weniger als 10 Millisekunden, d. h., wir können von einem theoretischen Wert von 100 Suchvorgängen pro Sekunden ausgehen. Dieser Wert lässt sich durch neue Festplatten nur geringfügig verbessern und ist für nur eine einzige Tabelle sehr schwierig zu optimieren. Die Verteilung von Daten auf mehrere Festplatten ist jedoch geeignet, die Suchdauer zu verbessern.

  • Lese- und Schreiboperationen auf Festplatte. Wenn die Festplatte die korrekte Position erreicht hat, müssen die Daten gelesen werden. Moderne Festplatten liefern einen Datendurchsatz von mindestens 10 bis 20 Mbyte/s. Dieser Wert ist einfacher zu optimieren als der Suchwert, da parallel von mehreren Festplatten gelesen werden kann.

  • Prozessorzyklen. Wenn die Daten im Hauptspeicher gelandet sind, müssen wir sie verarbeiten, um das gewünschte Ergebnis zu erhalten. Der am meisten einengende Faktor ist das Vorhandensein von im Vergleich zum verfügbaren Speicher kleinen Tabellen. Bei kleinen Tabellen wiederum ist Geschwindigkeit jedoch nicht das Problem.

  • Speicherbandbreite. Wenn der Prozessor mehr Daten benötigt, als in den Prozessor-Cache passen, dann wird die Bandbreite des Hauptspeichers zum Engpass. Dies kommt zwar bei den meisten Systemen höchst selten vor, sollte jedoch immer in Betracht gezogen werden.

4.1.1. MySQL-Design-Beschränkungen und Kompromisse

Wenn Sie die MyISAM-Speicher-Engine verwenden, benutzt MySQL eine extrem schnelle Tabellensperrung, die mehrere lesende Benutzer oder einen schreibenden Benutzer gestattet. Das größte Problem bei dieser Speicher-Engine tritt auf, wenn ein konstanter Strom von gemischten Änderungs- und langsamen Auswahlanweisungen für eine einzelne Tabelle vorhanden ist. Wenn dies bei bestimmten Tabellen ein Problem darstellt, können Sie für diese eine andere Speicher-Engine verwenden. Siehe auch Storage Engines.

MySQL arbeitet sowohl mit transaktionsfähigen als auch mit nicht transaktionsfähigen Tabellen. Um ein sauberes Arbeiten mit nicht transaktionsfähigen Tabellen zu vereinfachen (bei denen ein Rollback nicht möglich ist, wenn etwas schief geht), hat MySQL die folgenden Regeln. Beachten Sie, dass diese Regeln nur dann gültig sind, wenn MySQL nicht im strikten SQL-Modus ausgeführt wird oder Sie IGNORE für INSERT- oder UPDATE-Anweisungen angegeben haben.

  • Für alle Spalten gibt es Vorgabewerte.

  • Wenn Sie einen unpassenden oder ungültigen Wert in eine Spalte eingeben, setzt MySQL diesen automatisch auf den „bestmöglichen“ Wert, statt einen Fehler zu melden. Bei numerischen Werten ist dies entweder 0 oder der kleinst- oder größtmögliche Wert. Bei Strings wird entweder der Leer-String oder der Bestandteil des Strings benutzt, der noch in der Spalte gespeichert werden kann.

  • Alle berechneten Ausdrücke geben einen Wert zurück, der verwendet werden kann, statt eine Fehlerbedingung auszugeben. So gibt etwa 1 ÷ 0 NULL zurück.

Um obiges Verhalten zu ändern, können Sie eine striktere Datenverarbeitung aktivieren, indem Sie den SQL-Modus auf dem Server entsprechend ändern. Weitere Informationen zum Umgang mit Daten finden Sie in How MySQL Deals with Constraints, Server SQL Modes, und Abschnitt 8.2.5, „INSERT. Applikationskonzepte unter Beachtung von Portabilitätsaspekten

4.1.2. Programme für Portabilität auslegen

Da alle SQL-Server unterschiedliche Teile des SQL-Standards implementieren, ist die Entwicklung portierbarer Datenbankanwendungen sehr aufwändig. Bei sehr simplen Auswahl- und Einfügeoperationen mag die einfache Portierbarkeit noch gegeben sein, aber je mehr Funktionalitäten Sie benötigen, umso komplexer wird sie. Wenn Sie eine Anwendung brauchen, die auf vielen verschiedenen Datenbanksystemen schnell ist, wird es noch schwieriger.

Alle Datenbanksysteme haben Schwachpunkte: Entwicklungsseitig enthalten sie Kompromisse, die ein unterschiedliches Verhalten verursachen.

Um eine komplexe Anwendung portierbar zu machen, müssen Sie zunächst ermitteln, auf welchen SQL-Servern sie laufen muss, und dann bestimmen, welche Funktionen diese Server unterstützen. Sie können das MySQL-Programm crash-me verwenden, um Funktionen, Typen, und Grenzen zu finden, die Sie mit einer Auswahl von Datenbankservern verwenden können. crash-me überprüft nicht auf alle möglichen Funktionen, aber es ist ausreichend umfassend und führt ungefähr 450 Tests durch. Ein Beispiel für die Art von Informationen, die sich mit crash-me ermitteln lassen, ist etwa die Tatsache, dass Sie keine Spaltennamen verwenden sollten, die mehr als 18 Zeichen umfassen, wenn Sie Informix oder DB2 einsetzen wollen.

Das Programm crash-me und die MySQL-Benchmarks hängen stark von der jeweiligen Datenbank ab. Sehen Sie sich einmal an, wie sie geschrieben sind, um ein Gefühl dafür erhalten, was Sie tun müssen, um Ihre eigenen Anweisungen so datenbankunabhängig wie möglich zu machen. Sie finden die Programme im Verzeichnis sql-bench der MySQL-Quelldistributionen. Sie sind in Perl geschrieben und verwenden die DBI-Datenbankschnittstelle. Bereits die Verwendung von DBI löst das Portabilitätsproblem teilweise, denn die Schnittstelle bietet datenbankübergreifende Zugriffsmethoden. Siehe auch Abschnitt 4.1.4, „Die MySQL-Benchmark-Suite“.

Wenn Sie nach Datenbankunabhängigkeit streben, brauchen Sie ein gutes Gespür für die Engpässe auf den einzelnen SQL-Servern. So ist MySQL beispielsweise sehr schnell, wenn es um das Abrufen und Aktualisieren von Datensätzen in MyISAM-Tabellen geht, hat aber Probleme bei Fällen, in denen gleichzeitig langsame Lese- und Schreibvorgänge verwaltet werden müssen. Transaktionssichere Datenbanksysteme sind generell nicht besonders gut zur Erstellung von Zusammenfassungstabellen aus Logtabellen geeignet, weil in diesem Fall die Sperrung von Datensätzen praktisch nutzlos ist.

Um Ihre Anwendung wirklich datenbankunabhängig zu machen, sollten Sie eine leicht zu erweiternde Schnittstelle definieren, über die Sie Ihre Daten manipulieren. C++ beispielsweise ist auf den meisten Systemen verfügbar, weswegen es sinnvoll ist, eine Datenbankschnittstelle auf Basis einer C++-Klasse zu verwenden.

Wenn Sie die eine oder andere Funktion verwenden, die für ein gegebenes Datenbanksystem spezifisch ist (z. B. die MySQL-Anweisung REPLACE), dann sollten Sie dieselbe Funktion für andere SQL-Server implementieren, indem Sie eine alternative Methode einkodieren. Auch wenn diese Alternative langsamer ist, so erlaubt sie es anderen Servern doch, dieselben Aufgaben auszuführen.

Mit MySQL können Sie die /*! */ Syntax verwenden, um einer Anweisung MySQL-spezifische Schlüsselwörter hinzuzufügen. Der Code in /* */ wird von den meisten anderen SQL-Servern als Kommentar betrachtet (und insofern ignoriert). Informationen zum Schreiben von Kommentaren finden Sie in Abschnitt 5.5, „Kommentarsyntax“.

Wenn die Leistungsfähigkeit wichtiger ist als die Genauigkeit (wie es beispielsweise bei Webanwendungen der Fall ist), dann können Sie eine Anwendungsschicht erstellen, die alle Ergebnisse zwischenspeichert, um die Performance noch besser zu optimieren. Indem Sie ältere Ergebnisse nach einer bestimmten Zeit ungültig werden lassen, können Sie den Cache ausreichend aktuell halten. Auf diese Weise können Sie Belastungsspitzen abfangen, indem Sie die Cache-Größe dynamisch erhöhen und den Ungültigkeitszeitpunkt nach hinten verschieben, bis sich die Belastung wieder normalisiert hat.

In diesem Fall sollten die Angaben zur Tabellenerstellung Informationen zur ursprünglichen Cache-Größe und dazu enthalten, wie oft die Tabelle normalerweise aktualisiert wird.

Eine interessante Alternative zur Implementierung eines Anwendungs-Caches ist die Verwendung des Abfrage-Caches von MySQL. Wenn Sie den Abfrage-Cache aktivieren, bestimmt der Server selbst, ob ein Abfrageergebnis wiederverwendet werden kann. Dies vereinfacht Ihre Anwendung. Siehe auch Abschnitt 4.5.5, „Der MySQL-Abfragen-Cache“.

4.1.3. Wofür wir MySQL verwendet haben

Dieser Abschnitt beschreibt eine sehr frühe Anwendung für MySQL.

Im Verlauf der ursprünglichen Entwicklung von MySQL wurden die Funktionen an die Anforderungen unseres größten Kunden angepasst, der das Data-Warehousing für einige der großen schwedischen Handelshäuser implementierte.

Von allen Läden erhielten wir wöchentliche Übersichten über alle Kundenkartentransaktionen, und es wurde von uns verlangt, brauchbare Informationen für Geschäftsinhaber bereitzustellen, damit diese feststellen konnten, wie sich ihre Werbekampagnen auf das Kaufverhalten ihrer Kunden auswirkten.

Das Datenvolumen war gewaltig (ca. sieben Millionen Transaktionen pro Monat), und wir hatten Daten für vier bis zehn Jahre, die wir den Benutzern präsentieren sollten. Allwöchentlich erhielten wir Anfragen von unseren Kunden, die sofortigen Zugriff auf neue, auf diesen Daten basierende Berichte benötigten.

Wir lösten dieses Problem, indem wir alle Information pro Monat in komprimierten „Transaktionstabellen“ speicherten. Wir hatten eine Gruppe einfacher Makros, die Zusammenfassungstabellen nach unterschiedlichen Kriterien gruppiert (Produktgruppe, Kundenkennung, Speicher, und so weiter) aus den Tabellen generierten, in denen die Transaktionen gespeichert waren. Diese Berichte waren Webseiten, die mithilfe eines kleinen Perl-Skripts dynamisch erzeugt wurden. Das Skript analysierte eine Webseite, führte die enthaltenen SQL-Anweisungen aus und fügte die Ergebnisse ein. Wir hätten stattdessen sicher PHP oder mod_perl verwendet, aber diese waren seinerzeit noch nicht verfügbar.

Für die grafische Ausgabe schrieben wir ein kleines Tool in C, das SQL-Abfrageergebnisse verarbeiten und auf Basis der Ergebnisse GIF-Grafiken erstellen konnte. Auch dieses Tool wurde von dem Perl-Skript, welches die Webseiten analysierte, dynamisch ausgeführt.

In den meisten Fällen konnte ein neuer Bericht einfach erstellt werden, indem man ein vorhandenes Skript kopierte und die von ihm verwendete SQL-Abfrage einfach anpasste. In manchen Fällen mussten wir neue Spalten zu einer vorhandenen Übersichtstabelle hinzufügen oder eine neue Tabelle erstellen. Auch dies war ganz einfach, weil wir alle Tabellen mit den Transaktionen auf Festplatte speicherten. (In der Summe hatten wir dann 50 Gbyte Transaktionstabellen sowie 200 Gbyte weiterer Kundendaten.)

Außerdem gestatteten wir unseren Kunden via ODBC den direkten Zugriff auf die Übersichtstabellen, sodass Kunden bei Bedarf selbst mit den Daten experimentieren konnten.

Dieses System funktionierte gut und wir hatten keine Probleme, die Daten mit wirklich bescheidener Sun Ultra SPARCstation-Hardware (2×200MHz) zu behandeln. Am Ende wurde das System dann auf Linux migriert.

4.1.4. Die MySQL-Benchmark-Suite

Anhand dieser Benchmark-Reihe kann jeder Benutzer ermitteln, welche Operationen eine gegebene SQL-Implementierung gut oder weniger gut ausführt. Sie können sich einen guten Eindruck davon verschaffen, wie die Benchmarks funktionieren, indem Sie sich den Code und die Ergebnisse im Verzeichnis sql-bench einer beliebigen MySQL-Quelldistribution ansehen.

Beachten Sie, dass dieser Benchmark nur einen Thread verwendet - er misst also die Mindestdauer der durchgeführten Operationen. Wir planen, die Benchmark-Reihe in Zukunft durch Multithread-Tests zu ergänzen.

Um die Benchmark-Reihe verwenden zu können, müssen folgende Voraussetzungen erfüllt sein:

  • Die Benchmark-Reihe wird als Bestandteil der MySQL-Quelldistributionen ausgeliefert. Sie können entweder eine freigegebene Distribution von http://dev.mysql.com/downloads/ herunterladen oder den aktuellen Entwicklungs-Source-Tree verwenden. (Siehe auch Abschnitt 2.10.3, „Installation vom Entwicklungs-Source-Tree“.)

  • Die Benchmark-Skripten sind in Perl geschrieben und verwenden das Perl-DBI-Modul für den Zugriff auf Datenbankserver; insofern muss DBI installiert sein. Ferner benötigen Sie die serverspezifischen BDB-Treiber für jeden Server, den Sie testen wollen. Um beispielsweise MySQL, PostgreSQL und DB2 prüfen zu können, müssen die Module DBD::mysql, DBD::Pg und DBD::DB2 installiert sein. Siehe auch Abschnitt 2.15, „Anmerkungen zur Perl-Installation“.

Nachdem Sie sich eine MySQL-Quelldistribution besorgt haben, finden Sie die Benchmark-Reihe im dortigen Verzeichnis sql-bench. Um die Benchmark-Tests durchzuführen, erstellen Sie MySQL und wechseln dann in das Verzeichnis sql-bench. Dort führen Sie das Skript run-all-tests aus:

shell> cd sql-bench
shell> perl run-all-tests --server=server_name

server_name sollte der Name eines der unterstützten Server sein. Um eine Liste aller Optionen und unterstützten Server zu erhalten, rufen Sie folgenden Befehl auf:

shell> perl run-all-tests --help

Das Skript crash-me befindet sich auch im Verzeichnis sql-bench. Durch Ausführen von Abfragen versucht crash-me zu entscheiden, welche Funktionen ein Datenbanksystem unterstützt und was seine Möglichkeiten und Begrenzungen sind. Beispielsweise wird ermittelt,

  • welche Datentypen unterstützt werden,

  • wie viele Indizes unterstützt werden,

  • welche Funktionen unterstützt werden,

  • wie groß eine Abfrage sein darf,

  • wie groß eine VARCHAR-Spalte sein darf.

Weitere Informationen über Benchmark erhalten Sie unter http://www.mysql.com/why-mysql/benchmarks/.

4.1.5. Ihre eigenen Benchmarks verwenden

Sie sollten Ihre Anwendung und Ihre Datenbank in jedem Fall mit der Benchmark-Reihe prüfen, um festzustellen, wo ggf. Engpässe vorhanden sind. Wenn Sie einen Engpass behoben (oder ihn durch ein „Dummymodul“ ersetzt) haben, können Sie mit der Suche nach weiteren Engpässen fortfahren. Auch wenn die Gesamtleistung für Ihre Anwendung derzeit akzeptabel sein sollte, sollten Sie zumindest einen Plan für jeden Engpass erstellen und entscheiden, wie Sie ihn bei Bedarf beseitigen, sofern dieser Bedarf eines Tages auftreten sollte.

Beispiele für portable Benchmark-Programme finden Sie in der MySQL-Benchmark-Reihe. Siehe auch Abschnitt 4.1.4, „Die MySQL-Benchmark-Suite“. Sie können ein beliebiges Programm dieser Reihe nehmen und an Ihre eigenen Bedürfnisse anpassen. Dies erlaubt Ihnen, verschiedene Lösungen für Ihr Problem auszuprobieren und zu ermitteln, welche wirklich die schnellste ist.

Eine andere kostenlose Benchmark-Suite ist die Open-Source-Datenbank-Benchmark, verfügbar unter http://osdb.sourceforge.net/.

Häufig treten Probleme nur dann auf, wenn das System sehr stark ausgelastet ist. Viele unserer Kunden wenden sich an uns, wenn sie ein (getestetes) Produktionssystem haben, welches unter Last Ausfallerscheinungen zeigt. In den meisten Fällen werden leistungsbezogene Probleme durch Faktoren des grundlegenden Datenbankdesigns (etwa im Fall von Schwächen bei Tabellenscans unter Last) oder durch Probleme mit dem Betriebssystem oder mit Bibliotheken verursacht. Meistens würden sich diese Probleme wesentlich einfacher beheben lassen, wenn das jeweilige System nicht bereits in der Produktion verwendet würde.

Um derartige Probleme zu vermeiden, sollten Sie den Aufwand auf sich nehmen und Benchmark-Tests Ihrer Anwendung unter maximaler Last durchführen:

Wie die Namen dieser Programme bereits suggerieren, besteht ihr Zweck darin, Ihr System in die Knie zu zwingen. Es sollte also klar sein, dass Sie diese Programme nur auf Entwicklungssystemen einsetzen.

4.2. SELECT und andere Anweisungen optimieren

Zuallererst beeinflusst ein Faktor alle Anweisungen: Je komplexer Ihr Genehmigungssetup, desto mehr Mehrbelastung haben Sie. Die Verwendung einfacherer Berechtigungen beim Absetzen von GRANT-Anweisungen gestattet MySQL eine Verringerung der berechtigungsbedingten Mehrbelastung, wenn Clients Anweisungen ausführen. Wenn Sie beispielsweise keine Berechtigungen auf Tabellen- oder Spaltenebene gewähren, muss der Server keinerlei Überprüfung der Tabellen tables_priv und columns_priv durchführen. Analog ist auch keine Ressourcenzählung durchzuführen, wenn Sie die Ressourcen für kein Konto beschränken. Wenn Sie eine sehr hohe Auslastung durch die Anweisungsverarbeitung haben, kann es lohnenswert sein, eine vereinfachte Gewährungsstruktur zu verwenden, um die Mehrbelastung durch die Überprüfung von Berechtigungen zu verringern.

Hängt Ihr Problem mit einem bestimmten MySQL-Ausdruck oder einer MySQL-Funktion zusammen, dann können Sie eine Timingprüfung durchführen, indem Sie die Funktion BENCHMARK() mithilfe des Clientprogramms mysql aufrufen. Ihre Syntax ist BENCHMARK(loop_count,expression). Der Rückgabewert ist immer null, aber mysql gibt eine Zeile aus, die näherungsweise die Ausführungsdauer der Anweisung angibt. Ein Beispiel:

mysql> SELECT BENCHMARK(1000000,1+1);
+------------------------+
| BENCHMARK(1000000,1+1) |
+------------------------+
|                      0 |
+------------------------+
1 row in set (0.32 sec)

Dieses Ergebnis wurde mit einem Pentium II-System (400 MHz) ermittelt. Es zeigt, dass MySQL auf diesem System 1.000.000 einfache Additionsausdrücke in 0,32 Sekunden ausführen kann.

Eigentlich sollten alle MySQL-Funktionen hochgradig optimiert sein, aber es gibt unter Umständen ein paar Ausnahmen. BENCHMARK() ist ein ausgezeichnetes Tool dafür, um zu ermitteln, ob einige Funktionen ein Problem für Ihre Abfragen sind.

4.2.1. Abfragen mit EXPLAIN optimieren

Die EXPLAIN-Anweisung kann entweder als Synonym für DESCRIBE oder als Möglichkeit verwendet werden, um Informationen bezüglich der Frage zu ermitteln, wie MySQL eine SELECT-Anweisung ausführt:

  • EXPLAIN tbl_name ist synonym zu DESCRIBE tbl_name oder SHOW-COLUMNS-FROM tbl_name:

    EXPLAIN tbl_name
    
  • Wenn Sie einer SELECT-Anweisung das Schlüsselwort EXPLAIN voranstellen, zeigt MySQL Informationen des Optimierers zum Ausführungsplan der Abfrage an. MySQL erläutert also, wie es die SELECT-Anweisung verarbeiten würde, und gibt zudem an, wie und in welcher Reihenfolge Tabellen miteinander verknüpft werden:

    EXPLAIN [EXTENDED | PARTITIONS] SELECT select_options
    

  • EXPLAIN PARTITIONS ist ab MySQL 5.1.5 verfügbar. Es ist nur nützlich, wenn man Abfragen prüft, die partitionierte Tabellen betreffen. Detaillierte Informationen finden Sie in Obtaining Information About Partitions.

Dieser Abschnitt beschreibt die zweite Verwendungsmöglichkeit von EXPLAIN: die Anforderung von Informationen zum Abfrageausführungsplan. Siehe auch Abschnitt 8.3.2, „EXPLAIN-Syntax“. Eine Beschreibung der Anweisungen DESCRIBE und SHOW COLUMNS finden Sie in Abschnitt 8.3.1, „DESCRIBE (Informationen über Spalten abrufen)“, und Abschnitt 8.5.5.6, „SHOW COLUMNS-Syntax“.

Mit Hilfe von EXPLAIN können Sie erkennen, wo Sie Indizes zu Tabellen hinzufügen sollten, um ein schnelleres SELECT, zu erhalten, das Indizes verwendet, um Zeilen zu finden. Sie können mit EXPLAIN auch überprüfen, ob der Optimierer die Tabellen in optimaler Reihenfolge verknüpft. Um dem Optimierer einen Hinweis zu geben, eine Verknüpfungsreihenfolge in der Reihenfolge der Tabellen in der SELECT-Anweisung zu verwenden, beginnen Sie die Anweisung mit SELECT STRAIGHT_JOIN statt einfach mit SELECT. (Siehe auch Abschnitt 8.2.8, „SELECT.)

Wenn das Problem auftritt, dass Indizes nicht benutzt werden, obwohl Sie annehmen, dass dies eigentlich der Fall sein sollte, dann führen Sie ANALYZE TABLE aus, um die Tabellenstatistiken wie etwa die Kardinalität der Schlüssel, die sich auf die durch den Optimierer vorgenommene Auswahl auswirken kann, zu aktualisieren. Siehe auch Abschnitt 8.5.2.1, „ANALYZE TABLE-Syntax“.

EXPLAIN gibt eine Informationszeile für jede in der SELECT-Anweisung verwendete Tabelle zurück. Die Tabellen sind in der Ausgabe in der Reihenfolge aufgeführt, in der MySQL sie bei der Verarbeitung der Abfrage lesen würde. MySQL löst alle Joins mithilfe einer Methode auf, die Single-Sweep-Multi-Join heißt. Hierbei liest MySQL einen Datensatz aus der ersten Tabelle und sucht dann einen passenden Datensatz in der zweiten Tabelle, der dritten Tabelle usw. Sind alle Tabellen verarbeitet, dann gibt MySQL die gewählten Spalten aus und durchsucht die Tabellenliste in umgekehrter Reihenfolge, bis eine Tabelle gefunden wird, bei der mehr passende Datensätze vorhanden sind. Der nächste Datensatz wird aus genau dieser Tabelle gelesen, und dann wird der Prozess mit der nächsten Tabelle fortgesetzt.

Wenn das Schlüsselwort EXTENDED verwendet wird, erzeugt EXPLAIN zusätzliche Informationen, die durch Absetzen einer SHOW WARNINGS-Anweisung nach der EXPLAIN-Anweisung angezeigt werden können. Diese Informationen geben Hinweise zum Optimierungsprozess, z. B. wie der Optimierer Tabellen- und Spaltennamen in der SELECT-Anweisung qualifiziert oder wie die SELECT-Anweisung nach der Anwendung der Umformulierungs- und Optimierungsregeln aussieht. EXPLAIN-EXTENDED zeigt ab MySQL 5.1.12 auch die gefilterte Spalte.

Anmerkung

Sie können die Schlüsselwörter EXTENDED und PARTITIONS nicht gemeinsam in derselben EXPLAIN-Anweisung verwenden.

Jeder von EXPLAIN ausgegebene Datensatz enthält Angaben zu genau einer Tabelle. Dabei enthält jeder Datensatz die folgenden Spalten:

  • id

    Der Bezeichner SELECT. Dies ist die Sequenznummer der SELECT-Anweisung innerhalb der Abfrage.

  • select_type

    Der Typ der SELECT-Anweisung. Dies kann jeder der in der folgenden Tabelle aufgeführten Typen sein.

    SIMPLEeinfache SELECT-Anweisung (ohne UNION oder Unterabfragen).
    PRIMARYäußerste SELECT-Anweisung.
    UNIONzweite oder spätere SELECT-Anweisung in einer UNION
    DEPENDENT UNIONzweite oder spätere SELECT-Anweisung in einer UNION, abhängig von der äußeren Abfrage.
    UNION RESULTErgebnis einer UNION.
    SUBQUERYerste SELECT-Anweisung in einer Unterabfrage
    DEPENDENT SUBQUERYerste SELECT-Anweisung in einer Unterabfrage, abhängig von der äußeren Abfrage.
    DERIVEDabgeleitete Tabellen-SELECT-Anweisung (Unterabfrage in FROM-Klausel).
    UNCACHEABLE SUBQUERYEine Unterabfrage, für die das Ergebnis nicht gezwischenspeichert werden kann und die für jede Zeile von der äußeren Abfrage wieder ausgewertet werden muss
    UNCACHEABLE UNIONDie zweite oder spätere SELECT in einer UNION, die zu einer nicht zwischenspeicherbaren Unterabfrage gehört (siehe (UNCACHEABLE SUBQUERY )

    DEPENDENT bezeichnet normalerweise die Verwendung einer korrelierten Unterabfrage. Siehe auch Abschnitt 8.2.9.7, „Korrelierte Unterabfragen“.

    Die „DEPENDENT SUBQUERY“-Auswertung unterscheidet sich von derUNCACHEABLE SUBQUERY-Auswertung. Bei „DEPENDENT SUBQUERY“ wird die Unterabfrage nur einmal für jede Menge unterschiedlicher Werte der Variablen aus dem äußeren Kontext wieder ausgewertet. Bei UNCACHEABLE SUBQUERY wird die Unterabfrage für jede Zeile aus dem äußeren Kontext wieder ausgewertet. Die Zwischenspeicherbarkeit von Unterabfragen unterliegt den in Abschnitt 4.5.5.1, „So funktioniert der Abfrage-Cache“ behandelten Beschränkungen. Der Verweis auf Benutzervariablen macht eine Unterabfrage zum Beispiel nicht zwischenspeicherbar.

  • table

    Die Tabelle, die der Ausgabedatensatz referenziert.

  • type

    Die Verknüpfungsart. Die unterschiedlichen Join-Typen werden hier aufgelistet, sortiert vom besten Typ zum schlechtesten:

    • System

      Diese Tabelle hat nur einen Datensatz (Systemtabelle). Dies ist ein Sonderfall des Join-Typs const.

    • const

      Die Tabelle hat maximal einen passenden Datensatz, der beim Start der Abfrage gelesen wird. Weil es nur eine Zeile gibt, können Werte aus der Spalte in dieser Zeile vom Rest des Optimierers als Konstanten betrachtet werden. const-Tabellen sind sehr schnell, weil sie nur einmal gelesen werden.

      const wird verwendet, wenn Sie alle Teile eines PRIMARY KEY- oder UNIQUE-Indexes mit konstanten Werten vergleichen. In der folgenden Abfrage kann tbl_name als const-Tabelle verwendet werden:

      SELECT * FROM tbl_name WHERE primary_key=1;
      SELECT * FROM tbl_name
        WHERE primary_key_part1=1 AND primary_key_part2=2;
      
    • eq_ref

      Für jede Datensatzkombination aus den vorherigen Tabellen wird genau ein Datensatz aus dieser Tabelle gelesen. Abgesehen von den Typen system und const ist dies der beste Join-Typ. Er wird verwendet, wenn alle Teile eines Indexes vom Join verwendet werden und der Index ein PRIMARY KEY- oder UNIQUE-Index ist.

      eq_ref kann für indizierte Spalten benutzt werden, die mithilfe des Operators = verglichen werden. Der Vergleichswert kann eine Konstante oder ein Ausdruck sein, der Spalten aus Tabellen verwendet, die vor dieser Tabelle gelesen wurden. In den folgenden Beispielen kann MySQL einen eq_ref-Join zur Verarbeitung von ref_table verwenden:

      SELECT * FROM ref_table,other_table
        WHERE ref_table.key_column=other_table.column;
      SELECT * FROM ref_table,other_table
        WHERE ref_table.key_column_part1=other_table.column
        AND ref_table.key_column_part2=1;
      
    • ref

      Alle Zeilen mit übereinstimmenden Indexwerten werden aus dieser Tabelle für jede Kombination aus Zeilen der vorherigen Tabellen gelesen. ref wird verwendet, wenn Join nur ein Leftmost-Präfix des Schlüssels verwendet oder wenn der Schlüssel kein PRIMARY KEY- oder UNIQUE-Index ist (mit anderen Worten, wenn Join mit dem Schlüsselwert keine Einzelzeile selektieren kann). Wenn der verwendete Schlüssel nur einigen wenigen Datensätzen entspricht, ist dies ein guter Join-Typ.

      ref kann für indizierte Spalten benutzt werden, die mithilfe der Operatoren = oder <=> verglichen werden. In den folgenden Beispielen kann MySQL einen ref-Join zur Verarbeitung von ref_table verwenden:

      SELECT * FROM ref_table WHERE key_column=expr;
      SELECT * FROM ref_table,other_table
        WHERE ref_table.key_column=other_table.column;
      SELECT * FROM ref_table,other_table
        WHERE ref_table.key_column_part1=other_table.column
        AND ref_table.key_column_part2=1;
      
    • fulltext

      Die Verknüpfung wird mithilfe eines FULLTEXT-Indexes ausgeführt.

    • ref_or_null

      Dieser Join ähnelt ref, aber mit dem Zusatz, dass MySQL eine zusätzliche Suche nach Zeilen ausführt, die NULL-Werte enthalten. Diese Join-Typ-Optimierung wird meistens bei der Auflösung von Unterabfragen verwendet. In den folgenden Beispielen kann MySQL einen ref_or_null-Join zur Verarbeitung von ref_table verwenden:

      SELECT * FROM ref_table
        WHERE key_column=expr OR key_column IS NULL;
      

      Siehe auch Abschnitt 4.2.8, „IS NULL-Optimierung“.

    • index_merge

      Dieser Join-Typ gibt an, dass die Indexverschmelzungsoptimierung verwendet wird. In diesem Fall enthält die Spalte key in der Ausgabezeile eine Liste der verwendeten Indizes und key_len enthält eine Liste der längsten Schlüsselteile für die verwendeten Indizes. Weitere Informationen siehe Abschnitt 4.2.6, „Index-Merge-Optimierung“.

    • unique_subquery

      Dieser Typ ersetzt ref für einige IN-Unterabfragen der folgenden Form:

      value IN (SELECT primary_key FROM single_table WHERE some_expr)
      

      unique_subquery ist eine Nachschlagefunktion für Indizes, die zur Effizienzsteigerung die Unterabfrage vollständig ersetzt.

    • index_subquery

      Dieser Join-Typ ähnelt unique_subquery. Er ersetzt IN-Unterabfragen, aber er funktioniert für nichteindeutige Indizes in Unterabfragen der folgenden Form:

      value IN (SELECT key_column FROM single_table WHERE some_expr)
      
    • range

      Es werden nur Datensätze abgerufen, die in einem gegebenen Bereich liegen. Sie werden anhand eines Indexes ausgewählt. Die Spalte key im Ausgabedatensatz zeigt an, welcher Index verwendet wird. key_len enthält den längsten verwendeten Schlüsselteil. Die Spalte ref ist für diesen Typ NULL.

      range kann verwendet werden, wenn eine Schlüsselspalte unter Verwendung eines der Operatoren =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN oder IN mit einer Konstante verglichen wird:

      SELECT * FROM tbl_name
        WHERE key_column = 10;
      SELECT * FROM tbl_name
        WHERE key_column BETWEEN 10 and 20;
      SELECT * FROM tbl_name
        WHERE key_column IN (10,20,30);
      SELECT * FROM tbl_name
        WHERE key_part1= 10 AND key_part2 IN (10,20,30);
      
    • index

      Dieser Join-Typ ist mit ALL bis auf die Tatsache identisch, dass nur der Indexbaum gescannt wird. Insofern ist er in der Regel schneller als ALL, weil die Indexdatei gewöhnlich kleiner ist als die Datendatei.

      MySQL kann diesen Join-Typ verwenden, wenn die Abfrage nur Spalten benutzt, die Teil eines einzelnen Indexes sind.

    • ALL

      Ein vollständiger Tabellenscan wird für jede Kombination von Datensätzen aus den vorherigen Tabellen durchgeführt. Dies ist normalerweise nicht von Vorteil, wenn die Tabelle die erste nicht als const gekennzeichnete Tabelle ist, und in allen anderen Fällen sogar ganz schlimm. Sie können ALL normalerweise vermeiden, indem Sie Indizes hinzufügen, die das Abrufen von Datensätzen aus der Tabelle basierend auf Konstanten- oder Spaltenwerten aus früheren Tabellen erlauben.

  • possible_keys

    Die Spalte possible_keys gibt an, unter welchen Indizes MySQL auswählen kann, um Datensätze in dieser Tabelle zu suchen. Beachten Sie, dass diese Spalte vollständig unabhängig von der Reihenfolge der Tabellen ist, wie sie in der Ausgabe von EXPLAIN angezeigt wird. Das bedeutet, dass einige der Schlüssel in possible_keys mit der erzeugten Tabellenreihenfolge unter Umständen praktisch nicht verwendbar sind.

    Wenn diese Spalte NULL ist, gibt es keine relevanten Indizes. In diesem Fall können Sie die Leistungsfähigkeit Ihrer Abfrage möglicherweise verbessern, indem Sie die WHERE-Klausel daraufhin untersuchen, ob sie eine oder mehrere Spalten referenziert, die für die Indexerstellung geeignet wären. Sollte dies der Fall sein, so erstellen Sie einen passenden Index und überprüfen die Abfrage dann mit EXPLAIN erneut. Siehe auch Abschnitt 8.1.7, „ALTER TABLE-Syntax“.

    Um zu verstehen, welche Indizes eine Tabelle hat, verwenden Sie SHOW-INDEX-FROM tbl_name .

  • key

    Die Spalte key gibt den Schlüssel(index) an, für dessen Verwendung sich MySQL tatsächlich entschieden hat. Wenn MySQL beschließt, einen der possible_keys-Indizes zu verwenden, um Zeilen zu suchen, wird jener Index als der Schlüsselwert aufgelistet.

    Es ist möglich, dasskey einen Index nennt, der impossible_keys-Wert nicht vorhanden ist. Dies kann geschehen, wenn kein possible_keys-Index dafür geeignet ist, Zeilen zu suchen, aber alle Spalten, die von der Abfrage selektiert werden, Spalten von einem anderen Index sind. Das heißt, der genannte Index deckt die selektierten Spalten ab, so dass, obwohl er nicht für die Entscheidung, welche Zeilen abgefragt werden sollen, verwendet wird, ein Indexscan effizienter ist als ein Datenzeilenscan.

    Für InnoDB könnte ein sekundärer Index die selektierten Spalten auch dann abdecken, wenn die Abfrage auch den Primärschlüssel selektiert, weil InnoDB den primären Schlüsselwert mit jedem Sekundärindex speichert. Wenn key NULL ist, fand MySQL keinen Index für die effizientere Ausführung der Abfrage.

    Um das Verwenden oder Ignorieren eines Indexes, der in der Spalte possible_keys aufgeführt ist, durch MySQL zu erzwingen oder zu ignorieren, verwenden Sie FORCE INDEX oder USE INDEX bzw. IGNORE INDEX in Ihrer Abfrage. Siehe auch Abschnitt 8.2.8.2, „Indexhinweissyntax“.

    Bei MyISAM-Tabellen hilft das Ausführen von ANALYZE TABLE dem Optimizer, bessere Indizes zu wählen. Bei MyISAM-Tabellen tut myisamchk --analyze dasselbe. Siehe auch Abschnitt 8.5.2.1, „ANALYZE TABLE-Syntax“, und MyISAM Table Maintenance and Crash Recovery.

  • key_len

    Die Spalte key_len gibt die Länge des Schlüssels an, für dessen Verwendung sich MySQL entschieden hat. Die Länge ist NULL, wenn die Spalte key NULL ist. Beachten Sie, dass der Wert von key_len Ihnen die Feststellung gestattet, wie viele Teile eines mehrteiligen Schlüssels MySQL tatsächlich verwendet.

  • ref

    Die Spalte ref zeigt an, welche Spalten oder Konstanten mit dem in der Spalte key genannten Index verglichen werden, um Datensätze aus der Tabelle auszuwählen.

  • rows

    Die Spalte rows gibt die Anzahl der Datensätze an, die MySQL glaubt untersuchen zu müssen, um die Abfrage ausführen zu können.

    Bei InnoDB-Tabellen ist diese Zahl eine möglicherweise ungenaue Schätzung.

  • filtered

    Die Spalte filtered zeigt einen geschätzten Prozentsatz der Tabellenzeilen an, die von der Tabellenbedingung gefiltert werden. Das heißt, rows zeigt die geschätzte Anzahl von geprüften Zeilen undrows × filtered /100 zeigt die Anzahl von Zeilen, die mit bisherigen Tabellen verknüpft werden. Diese Spalte wird gezeigt, wenn Sie EXPLAIN EXTENDED verwenden. (Neu in MySQL 5.1.12)

  • Extra

    Diese Spalte enthält zusätzliche Angaben dazu, wie MySQL die Abfrage auflöst. Die folgende Liste erklärt die Werte, die in dieser Spalte erscheinen können. Wenn Sie Ihre Abfragen so schnell wie möglich machen wollen, sollten Sie auf Extra-Werte von Using filesort und Using temporary achten.

    • Distinct

      MySQL sucht nach unterschiedleich Werten, d. h. die Suche nach weiteren Datensätzen zur aktuellen Datensatzkombination wird beendet, sobald der erste Datensatz gefunden wurde.

    • Full scan on NULL key

      Dies tritt bei einer Unterabfrageoptimierung als eine Rückfallstrategie auf, wenn der Optimierer keine Indexsuchzugriffsmethode verwenden kann.

    • Impossible WHERE noticed after reading const tables

      MySQL hat alle const- (und System)-Tabellen gelesen und ermittelt, dass die WHERE-Klausel immer falsch ist.

    • No tables

      Die Abfrage enthält keine FROM-Klausel oder enthält eine FROM DUAL-Klausel.

    • Not exists

      MySQL konnte eine LEFT JOIN-Optimierung an der Abfrage vornehmen und untersucht für die vorhergehende Datensatzkombination keine weiteren Datensätze in dieser Tabelle, sobald ein Datensatz gefunden wurde, der den LEFT JOIN-Kriterien entspricht. Hier ein Beispiel für einen Abfragetyp, der auf diese Weise optimiert werden kann:

      SELECT * FROM t1 LEFT JOIN t2 ON t1.id=t2.id
        WHERE t2.id IS NULL;
      

      Nehmen wir an, t2.id sei als NOT NULL definiert. In diesem Fall scannt MySQL t1 und sucht die Datensätze in t2 unter Verwendung der Werte aus t1.id heraus. Findet MySQL einen passenden Datensatz in t2, dann weiß es, dass t2.id niemals NULL sein kann, und scannt die weiteren Datensätze in t2, die denselben id-Wert aufweisen, nicht mehr. Für jeden Datensatz in t1 muss MySQL also nur einen einzigen Suchvorgang in t2 durchführen – unabhängig davon, wie viele entsprechende Datensätze in t2 tatsächlich vorhanden sind.

    • Range checked for each record (index map: N)

      MySQL hat keinen geeigneten Index gefunden, aber festgestellt, dass einige der Indizes verwendet werden könnten, nachdem Spaltenwerte aus vorhergehenden Tabellen bekannt geworden sind. Für jede Datensatzkombination in den vorherigen Tabellen überprüft MySQL, ob es möglich ist, zum Abrufen von Datensätzen eine der Zugriffsmethoden range oder index_merge zu verwenden. Dies ist nicht sehr schnell, aber immer noch schneller als die Durchführung eines Joins ohne Index. Die Anwendbarkeitskriterien entsprechen den in Abschnitt 4.2.5, „Bereichsoptimierung“, und Abschnitt 4.2.6, „Index-Merge-Optimierung“, beschriebenen, nur sind hier alle Spaltenwerte für die vorhergehende Tabelle bekannt und werden als Konstanten betrachtet.

      Indizes werden mit 1 anfangend in der gleichen Reihenfolge wie von SHOW INDEX für die Tabelle gezeigt nummeriert. Der Indexabbildungswert N ist ein Bitmask-Wert, der zeigt, welche Indizes Kandidaten sind. Zum Beispiel heißt ein Wert von 0x19 (Binärdatei 11001), dass Indizes 1, 4, und 5 berücksichtigt werden werden.

    • Scanned N databases

      Dies zeigt, wieviele Verzeichnisabfragen der Server bei einer Abfrage auf INFORMATION_SCHEMA-Tabellen ausführt, wie in Abschnitt 4.2.20, „INFORMATION_SCHEMA-Optimierung“ beschrieben. Der Wert von N kann 0, 1, oder all sein.

    • Select tables optimized away

      Die Abfrage enthielt nur Aggregatfunktionen (MIN(), MAX()) die alle mithilfe eines Indexes gelöst wurden, oder COUNT(*) bei MyISAM und keine GROUP BY-Klausel. Der Optimierer entschied, dass nur eine Zeile zurückgegeben werden sollte.

    • Skip_open_table, Open_frm_only, Open_trigger_only, Open_full_table

      Diese Werte zeigen Dateiöffnungoptimierungen an, die für Abfragen auf INFORMATION_SCHEMA-Tabellen gelten, wie in Abschnitt 4.2.20, „INFORMATION_SCHEMA-Optimierung“ beschrieben.

      • Skip_open_table: Tabellendateien brauchen nicht geöffnet zu werden. Die Information ist bereits innerhalb der Abfrage durch das Scannen des Datenbankverzeichnisses verfügbar geworden.

      • Open_frm_only: Es braucht nur die .frm-Datei der Tabelle geöffnet zu werden.

      • Open_trigger_only: Es braucht nur die .TRG-Datei der Tabelle geöffnet zu werden.

      • Open_full_table: Die nicht optimierte Informationsanfrage. Es müssen die Dateien .frm, .MYD und .MYI geöffnet werden.

    • Using filesort

      MySQL muss einen zusätzlichen Durchlauf vornehmen, um zu ermitteln, wie die Datensätze in sortierter Reihenfolge abgerufen werden können. Diese Sortierung erfolgt, indem alle Datensätze entsprechend dem Join-Typ überprüft und Sortierschlüssel sowie der Zeiger auf den Datensatz für alle Datensätze gespeichert werden, die der WHERE-Klausel entsprechen. Die Schlüssel werden dann sortiert und die Datensätze entsprechend in sortierter Reihenfolge abgerufen. Siehe auch Abschnitt 4.2.13, „ORDER BY-Optimierung“.

    • Using index

      Die Spaltendaten werden ausschließlich unter Verwendung von Angaben im Indexbaum aus der Tabelle abgerufen - es erfolgt kein zusätzlicher Suchvorgang, um jeweils den eigentlichen Datensatz auszulesen. Diese Strategie kann verwendet werden, wenn die Abfrage nur Spalten benutzt, die Teil eines einzelnen Indexes sind.

      Bei InnoDB-Tabellen, die einen benutzerdefinierten Cluster-Index besitzen, kann jener Index verwendet werden, auch wenn Using indexin der Spalte Extra nicht vorhanden ist. Dies ist der Fall, wenn type gleich index und key gleich PRIMARY ist.

    • Using index for group-by

      Ähnlich wie beim Using index-Tabellenzugriffsverfahren zeigt Using index for group-by an, dass MySQL einen Index fand, der verwendet werden kann, um alle Spalten einer GROUP BY- oderDISTINCT-Abfrage ohne zusätzlichen Festplattenzugriff auf die eigentliche Tabelle zu abzufragen. Außerdem wird der Index auf die effizienteste Art und Weise verwendet, sodass für jede Gruppe nur ein paar wenige Indexeinträge gelesen werden. Detaillierte Informationen finden Sie in Abschnitt 4.2.14, „GROUP BY-Optimierung“.

    • Using join buffer

      Tabellen von früheren Joins werden in Teilen in den Join-Zwischenspeicher gelesen, und dann werden ihre Zeilen vom Zwischenspeicher verwendet, um die Verknüpfung mit der aktuellen Tabelle auszuführen.

    • Using sort_union(...), Using union(...), Using intersect(...)

      Diese Werte geben an, wie Indexscans für den Join-Typ index_merge zusammengefasst werden. Siehe auch Abschnitt 4.2.6, „Index-Merge-Optimierung“.

    • Using temporary

      Um die Abfrage aufzulösen, muss MySQL eine Temporärtabelle zur Aufnahme des Ergebnisses erstellen. Dies geschieht typischerweise, wenn die Abfrage GROUP BY- und ORDER BY-Klauseln enthält, die Spalten unterschiedlich auflisten.

    • Using where

      Mit einer WHERE-Klausel wird festgelegt, welche Datensätze mit der nächsten Tabelle verglichen oder an den Client gesendet werden. Sofern Sie nicht gezielt alle Datensätze aus der Tabelle abrufen oder untersuchen wollen, haben Sie in der Abfrage einen Fehler gemacht, wenn der Wert Extra nicht Using where ist und ALL oder index als Join-Typ für die Tabelle angegeben ist.

    • Using where with pushed condition

      Dieses Element gilt nur für NDBCLUSTER-Tabellen. Das bedeutet, dass MySQL Cluster die Condition-Pushdown-Optimierung verwendet, um die Leistungsfähigkeit eines direkten Vergleichs zwischen einer nichtindizierten Spalte und einer Konstante zu verbessern. In solchen Fällen wird die Bedingung auf die Datenknoten des Clusters „heruntergeschoben“ und gleichzeitig auf allen Datenknoten ausgewertet. Hierdurch wird der Versand unpassender Datensätze über das Netzwerk vermieden, und die entsprechenden Abfragen werden um den Faktor 5 bis 10 im Vergleich zu Fällen beschleunigt, in denen ein Condition Pushdown verwendet werden konnte aber nicht wurde. Weitere Informationen siehe Abschnitt 4.2.7, „Condition Pushdown-Optimierung“.

Sie können einen guten Eindruck davon bekommen, wie gut ein Join ist, wenn Sie das Produkt der Werte in der Spalte rows der EXPLAIN-Ausgabe bilden. Hieraus ergibt sich grob, wie viele Datensätze MySQL untersuchen muss, um die Abfrage auszuführen. Wenn Sie die Abfragen mit der Systemvariablen max_join_size beschränken, wird dieses Datensatzprodukt auch benutzt, um zu bestimmen, welche SELECT-Anweisungen für mehrere Tabellen ausgeführt und welche abgebrochen werden. Siehe auch Abschnitt 4.5.3, „Tuning der Server-Parameter“.

Das folgende Beispiel zeigt, wie ein Join mehrerer Tabellen auf der Basis der von EXPLAIN übermittelten Angaben progressiv optimiert werden kann.

Angenommen, Sie hätten die folgende SELECT-Anweisung, die Sie mit EXPLAIN untersuchen wollen:

EXPLAIN SELECT tt.TicketNumber, tt.TimeIn,
               tt.ProjectReference, tt.EstimatedShipDate,
               tt.ActualShipDate, tt.ClientID,
               tt.ServiceCodes, tt.RepetitiveID,
               tt.CurrentProcess, tt.CurrentDPPerson,
               tt.RecordVolume, tt.DPPrinted, et.COUNTRY,
               et_1.COUNTRY, do.CUSTNAME
        FROM tt, et, et AS et_1, do
        WHERE tt.SubmitTime IS NULL
          AND tt.ActualPC = et.EMPLOYID
          AND tt.AssignedPC = et_1.EMPLOYID
          AND tt.ClientID = do.CUSTNMBR;

Für dieses Beispiel gelten die folgenden Annahmen:

  • Die zu vergleichenden Spalten wurden wie folgt deklariert.

    TabelleSpalteDatentyp
    ttActualPCCHAR(10)
    ttAssignedPCCHAR(10)
    ttClientIDCHAR(10)
    etEMPLOYIDCHAR(15)
    doCUSTNMBRCHAR(15)
  • Die Tabellen haben die folgenden Indizes.

    TabelleIndex
    ttActualPC
    ttAssignedPC
    ttClientID
    etEMPLOYID (Primärschlüssel)
    doCUSTNMBR (Primärschlüssel)
  • Die tt.ActualPC-Werte sind nicht gleichmäßig verteilt.

Anfangs – also vor der Durchführung von Optimierungen – erzeugt die EXPLAIN-Anweisung die folgenden Angaben:

table type possible_keys key  key_len ref  rows  Extra
et    ALL  PRIMARY       NULL NULL    NULL 74
do    ALL  PRIMARY       NULL NULL    NULL 2135
et_1  ALL  PRIMARY       NULL NULL    NULL 74
tt    ALL  AssignedPC,   NULL NULL    NULL 3872
           ClientID,
           ActualPC
      Range checked for each record (index map: 0x23)

Da type für jede Tabelle ALL ist, gibt diese Ausgabe an, dass MySQL ein kartesisches Produkt aller Tabellen erzeugt, also jede mögliche Kombination von Datensätzen. Dies dauert recht lang, weil das Produkt der Anzahl der Datensätze in jeder Tabelle untersucht werden muss. Im vorliegenden Fall beträgt dieses Produkt 74 × 2135 × 74 × 3872 = 45.268.558.720 Datensätze. Wenn die Tabellen noch größer wären, kann man sich nur vage vorstellen, wie lange dies dauern würde.

Ein Problem besteht hier darin, dass MySQL Indizes für Spalten effizienter verwenden kann, wenn sie mit demselben Typ und derselben Größe deklariert wurden. In diesem Zusammenhang werden VARCHAR und CHAR als gleich erachtet, wenn sie mit der gleichen Größe deklariert werden. tt.ActualPC wird als CHAR(10) deklariert und et.EMPLOYID ist CHAR(15), also stimmen die Längen nicht überein.

Um diese Ungleichheit zwischen Spaltenlängen zu korrigieren, verwenden Sie ALTER TABLE, um ActualPC von 10 Zeichen auf 15 Zeichen zu verlängern:

mysql> ALTER TABLE tt MODIFY ActualPC VARCHAR(15);

Jetzt sind tt.ActualPC und et.EMPLOYID beide VARCHAR(15). Die erneute Ausführung der EXPLAIN-Anweisung erzeugt folgende Ausgabe:

table type   possible_keys key     key_len ref         rows    Extra
tt    ALL    AssignedPC,   NULL    NULL    NULL        3872    Using
             ClientID,                                         where
             ActualPC
do    ALL    PRIMARY       NULL    NULL    NULL        2135
      Range checked for each record (index map: 0x1)
et_1  ALL    PRIMARY       NULL    NULL    NULL        74
      Range checked for each record (index map: 0x1)
et    eq_ref PRIMARY       PRIMARY 15      tt.ActualPC 1

Dies ist nicht perfekt, aber viel besser: Das Produkt der rows-Werte ist um einen Faktor von 74 geringer. Diese Version wird in ein paar Sekunden ausgeführt.

Eine weitere Änderung kann vorgenommen werden, um die Nichtübereinstimmung der Spaltenlängen für die Vergleiche tt.AssignedPC = et_1.EMPLOYID und tt.ClientID = do.CUSTNMBR zu beseitigen:

mysql> ALTER TABLE tt MODIFY AssignedPC VARCHAR(15),
    ->                MODIFY ClientID   VARCHAR(15);

Nach dieser Änderung sieht die Ausgabe von EXPLAIN so aus:

table type   possible_keys key      key_len ref           rows Extra
et    ALL    PRIMARY       NULL     NULL    NULL          74
tt    ref    AssignedPC,   ActualPC 15      et.EMPLOYID   52   Using
             ClientID,                                         where
             ActualPC
et_1  eq_ref PRIMARY       PRIMARY  15      tt.AssignedPC 1
do    eq_ref PRIMARY       PRIMARY  15      tt.ClientID   1

An dieser Stelle ist die Abfrage schon fast perfekt optimiert. Als letztes Problem verbleibt die Tatsache, dass MySQL standardmäßig voraussetzt, dass Werte in der Spalte tt.ActualPC gleichmäßig verteilt sind; dies ist aber bei der Tabelle tt nicht der Fall. Glücklicherweise ist es einfach, MySQL zur Analyse der Schlüsselverteilung zu bewegen:

mysql> ANALYZE TABLE tt;

Mit den zusätzlichen Indexangaben ist der Join perfekt, und EXPLAIN erzeugt folgendes Ergebnis:

table type   possible_keys key     key_len ref           rows Extra
tt    ALL    AssignedPC    NULL    NULL    NULL          3872 Using
             ClientID,                                        where
             ActualPC
et    eq_ref PRIMARY       PRIMARY 15      tt.ActualPC   1
et_1  eq_ref PRIMARY       PRIMARY 15      tt.AssignedPC 1
do    eq_ref PRIMARY       PRIMARY 15      tt.ClientID   1

Beachten Sie, dass die Spalte rows in der Ausgabe von EXPLAIN eine begründete Annahme des MySQL-Join-Optimierers ist. Sie sollten überprüfen, ob die Zahlen annähernd realistisch sind, indem Sie das rows-Produkt mit der tatsächlichen Anzahl der von der Abfrage zurückgegebenen Datensätze vergleichen. Unterscheiden sich diese Werte erheblich, dann erhalten Sie unter Umständen eine bessere Leistung, wenn Sie STRAIGHT_JOIN in Ihrer SELECT-Abfrage verwenden und versuchen, die Tabellen in der FROM-Klausel in einer anderen Reihenfolge aufzulisten.

Es ist in einigen Fällen möglich, Anweisungen auszuführen, die Daten modifizieren, wenn EXPLAIN SELECT mit einer Unterabfrage verwendet wird. Weitere Informationen siehe Abschnitt 8.2.9.8, „Unterabfragen in der FROM-Klausel“.

4.2.2. Abschätzen der Abfrageleistung

In den meisten Fällen können Sie die Leistungsfähigkeit von Abfragen einschätzen, indem Sie die Anzahl der Suchvorgänge auf der Festplatte ermitteln. Bei kleinen Tabellen finden Sie gewöhnlich pro derartigen Suchvorgang einen Datensatz (weil der Index im Zweifelsfall im Cache liegt). Bei größeren Tabellen können Sie schätzen, dass Sie unter Verwendung von B-Tree-Indizes so viele Suchvorgänge zum Auffinden eines Datensatzes benötigen: logrow_count) / logindex_block_length / 3 × 2 /index_length + data_pointer_length)) + 1.

In MySQL ist ein Indexblock gewöhnlich 1024 Byte groß, der Datenzeiger umfasst weitere vier Byte. Für eine Tabelle mit 500.000 Datensätzen und einer Schlüsselwertlänge von drei Byte (die Größe von MEDIUMINT) ergibt die Formel log(500,000)/log(1024/3×2/(3+4)) + 1 = 4.

Dieser Index würde eine Speicherkapazität von 500.000 x 7 x 3/2 = 5,2 Mbyte benötigen (ein typisches Indexpuffer-Füllungsverhältnis von 2 : 3 vorausgesetzt), d. h., Sie hätten wahrscheinlich einen Großteil des Indexes im Speicher und benötigen nur ein oder zwei Aufrufe zum Datenlesen, um den Datensatz zu finden.

Bei Schreiboperationen hingegen benötigen Sie vier Suchanforderungen, um zu ermitteln, wo ein neuer Indexwert abgelegt werden muss, und normalerweise zwei Suchvorgänge, um den Index zu aktualisieren und den Datensatz zu schreiben.

Beachten Sie, dass die vorangegangene Beschreibung nicht bedeutet, dass Ihre Anwendungsleistung sich nach und nach um den Logarithmus N verringert. Solange alles vom Betriebssystem oder vom MySQL Server zwischengespeichert wird, verringert sich die Geschwindigkeit nur marginal, wenn die Tabellen größer werden. Sobald die Daten zu umfangreich geworden sind, um zwischengespeichert zu werden, geht alles viel langsamer, bis Ihre Anwendungen nur noch mit Suchvorgängen auf der Festplatte beschäftigt sind (deren Anzahl sich um log N erhöht). Um dies zu vermeiden, müssen Sie die Größe des Schlüssel-Caches erhöhen, wenn der Umfang Ihrer Daten zunimmt. Bei MyISAM-Tabellen wird die Größe des Schlüssel-Caches von der Systemvariablen key_buffer_size gesteuert. Siehe auch Abschnitt 4.5.3, „Tuning der Server-Parameter“.

4.2.3. Geschwindigkeit von SELECT-Abfragen

Wenn Sie eine langsame SELECT ... WHERE-Anweisung beschleunigen wollen, besteht der erste Schritt in aller Regel darin, zu überprüfen, ob Sie einen Index hinzufügen können. Alle Referenzierungen zwischen verschiedenen Tabellen sollten normalerweise über Indizes erfolgen. Sie können mit der EXPLAIN-Anweisung ermitteln, welche Indizes für eine SELECT-Anweisung verwendet werden. Siehe auch Abschnitt 4.2.1, „Abfragen mit EXPLAIN optimieren“, und Abschnitt 4.4.4, „So verwendet MySQL Indizes“.

Hier ein paar allgemeine Tipps zur Beschleunigung von Abfragen für MyISAM-Tabellen:

  • Um MySQL bei der Optimierung von Abfragen zu unterstützen, verwenden Sie ANALYZE TABLE oder führen myisamchk --analyze für eine Tabelle aus, nachdem Sie die Daten dort eingeladen haben. Hierdurch wird ein Wert für jeden Indexteil geändert, der die durchschnittliche Anzahl von Datensätzen angibt, die denselben Wert haben. (Bei eindeutigen Indizes ist dies immer 1.) MySQL verwendet dies, um zu entscheiden, welcher Index beim Join zweier Tabellen basierend auf einem nichtkonstanten Ausdruck gewählt werden soll. Sie können das Ergebnis der Tabellenanalyse überprüfen, indem Sie SHOW INDEX FROM tbl_name verwenden und den Cardinality-Wert prüfen. myisamchk --description --verbosezeigt Indexverteilungsinformationen.

  • Um einen Index und die Daten gemäß diesem Index zu sortieren, verwenden Sie myisamchk --sort-index --sort-records=1 (in diesem Beispiel erfolgt die Sortierung nach Index 1). Dies ist eine gute Möglichkeit, Abfragen zu beschleunigen, wenn Sie einen eindeutigen Index haben, anhand dessen Sie alle Datensätze in der von Index vorgegebenen Reihenfolge auslesen wollen. Das erste Mal, wenn Sie eine große Tabelle auf diese Weise sortieren, kann es eine lange Zeit dauern.

4.2.4. WHERE-Klausel-Optimierung

Dieser Abschnitt behandelt Optimierungen, die für die Verarbeitung von WHERE-Klauseln durchgeführt werden können. Die Beispiele verwenden SELECT-Anweisungen, dieselben Optimierungen gelten aber auch für WHERE-Klauseln in DELETE- und UPDATE-Anweisungen.

Wir arbeiten fortlaufend am MySQL-Optimierer, weswegen dieser Abschnitt nicht vollständig ist. MySQL führt eine Vielzahl von Optimierungen durch, die nicht alle an dieser Stelle dokumentiert sind.

Es folgen einige von MySQL durchgeführte Optimierungen:

  • Entfernung unnötiger Klammern:

       ((a AND b) AND c OR (((a AND b) AND (c AND d))))
    -> (a AND b AND c) OR (a AND b AND c AND d)
    
  • Umstellen von Konstanten:

       (a<b AND b=c) AND a=5
    -> b>5 AND b=c AND a=5
    
  • Entfernung von Konstantenbedingungen (erforderlich zum Umstellen von Konstanten):

       (B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6)
    -> B=5 OR B=6
    
  • Konstantenausdrücke, die von Indizes verwendet werden, werden nur einmal ausgewertet.

  • COUNT(*) für eine einzelne Tabelle ohne WHERE wird direkt aus den Tabellendaten für MyISAM- und MEMORY-Tabellen abgerufen. Dies wird auch für jeden NOT NULL-Ausdruck gemacht, der nur für eine einzige Tabelle verwendet wird.

  • Früherkennung ungültiger Konstantenausdrücke. MySQL erkennt sehr schnell, wenn eine SELECT-Anweisung nicht möglich ist, und gibt keine Datensätze zurück.

  • HAVING wird mit WHERE verschmolzen, wenn Sie GROUP BY nicht verwenden oder Funktionen (wie COUNT(), MIN() usw.) zusammenfassen.

  • Für jede Tabelle in einem Join wird eine einfachere WHERE-Klausel erstellt, um eine schnelle WHERE-Auswertung für die Tabelle zu erhalten und außerdem Datensätze so früh wie möglich zu überspringen.

  • Alle Konstanttabellen werden vor allen anderen Tabellen in der Abfrage gelesen. Zu den Konstantentabellen gehören die folgenden:

    • Leere Tabellen oder solche mit nur einem Datensatz.

    • Tabellen, die mit einer WHERE-Klausel für einen Primärschlüssel oder einen eindeutigen Index verwendet werden, wobei alle Indexteile mit Konstantenausdrücken verglichen werden und als NOT NULL definiert sind.

    Alle folgenden Tabellen werden als Konstantentabellen verwendet:

    SELECT * FROM t WHERE primary_key=1;
    SELECT * FROM t1,t2
      WHERE t1.primary_key=1 AND t2.primary_key=t1.id;
    
  • Die beste Join-Kombination zur Verknüpfung der Tabellen wird durch Ausprobieren aller Möglichkeiten ermittelt. Wenn alle Spalten in den ORDER BY- und GROUP BY-Klauseln aus derselben Tabelle stammen, dann wird diese Tabelle beim Verknüpfen bevorzugt.

  • Wenn eine ORDER BY- und eine davon unterschiedliche GROUP BY-Klausel vorhanden sind, oder wenn ORDER BY oder GROUP BY Spalten aus anderen als der ersten Tabelle in der Join-Warteschlange enthalten, dann wird eine Temporärtabelle erstellt.

  • Wenn Sie die Option SQL_SMALL_RESULT verwenden, dann benutzt MySQL eine speicherresidente Temporärtabelle.

  • Alle Tabellenindizes werden abgefragt, und der beste Index wird verwendet, sofern der Optimierer nicht der Ansicht ist, dass die Verwendung eines Tabellenscans effizienter ist. Früher wurde ein Scan basierend darauf eingesetzt, ob der beste Index sich über einen Anteil von mehr als 30 Prozent der Tabelle erstreckte; mittlerweile wird die Frage, ob ein Index oder ein Scan verwendet werden soll, nicht mehr auf der Basis eines festen Prozentwerts entschieden. Der Optimierer ist mittlerweile komplexer, und seine Schätzungen fußen auf weiteren Faktoren wie Tabellengröße, Anzahl der Datensätze und I/O-Blockgröße.

  • In manchen Fällen kann MySQL Datensätze aus dem Index auslesen, ohne überhaupt die Datendatei abfragen zu müssen. Wenn alle aus dem Index verwendeten Spalten numerisch sind, wird zur Auflösung der Abfrage nur der Indexbaum verwendet.

  • Bevor ein Datensatz ausgegeben wird, werden alle Datensätze, die nicht der HAVING-Klausel entsprechen, übersprungen.

Hier einige Beispiele für Abfragen, die sehr schnell sind:

SELECT COUNT(*) FROM tbl_name;
SELECT MIN(key_part1),MAX(key_part1) FROM tbl_name;
SELECT MAX(key_part2) FROM tbl_name
  WHERE key_part1=constant;
SELECT ... FROM tbl_name
  ORDER BY key_part1,key_part2,... LIMIT 10;
SELECT ... FROM tbl_name
  ORDER BY key_part1 DESC, key_part2 DESC, ... LIMIT 10;

MySQL löst die folgenden Abfragen nur mithilfe des Indexbaums auf und setzt dabei voraus, dass die indizierten Spalten numerisch sind:

SELECT key_part1,key_part2 FROM tbl_name WHERE key_part1=val;
SELECT COUNT(*) FROM tbl_name
  WHERE key_part1=val1 AND key_part2=val2;
SELECT key_part2 FROM tbl_name GROUP BY key_part1;

Die folgenden Abfragen verwendet die Indizierung zur Abfrage von Datensätzen in sortierter Reihenfolge ohne separaten Sortierdurchlauf:

SELECT ... FROM tbl_name
  ORDER BY key_part1,key_part2,... ;
SELECT ... FROM tbl_name
  ORDER BY key_part1 DESC, key_part2 DESC, ... ;

4.2.5. Bereichsoptimierung

Die Zugriffsmethode range ruft mithilfe eines einzelnen Indexes eine Teilmenge der Datensätze ab, die in der Tabelle innerhalb eines oder mehrerer Indexwertintervalle liegen. Sie kann für einen ein- oder mehrteiligen Index verwendet werden. Die folgenden Abschnitte erläutern detailliert, wie Intervalle aus der WHERE-Klausel extrahiert werden.

4.2.5.1. Die Bereichszugriffsmethode für Single-Teils Indizes

Bei einem einteiligen Index lassen sich die Indexwertintervalle bequem durch entsprechende Bedingungen in der WHERE-Klausel darstellen. Deswegen sprechen wir in diesem Fall von Bereichsbedingungen statt von „Intervallen“.

Die Definition einer Bereichsbedingung für einen einteiligen Index sieht wie folgt aus:

  • Bei BTREE- und HASH-Indizes ist der Vergleich eines Schlüsselteils mit einem Konstantenwert eine Bereichsbedingung, wenn die Operatoren =, <=>, IN, IS NULL oder IS NOT NULL verwendet werden.

  • Bei BTREE-Indizes ist der Vergleich eines Schlüsselteiles mit einem konstanten Wert eine Bereichsbedingung, wenn man die Operatoren >, <, >=, <=, BETWEEN, != oder <> oder einenLIKE-Vergleich verwendet, wenn das Argument für LIKE ein konstanter String ist, der mit keinem Platzhalter anfängt.

  • Bei allen Indextypen bilden mehrere Bereichsbedingungen, die mit OR oder AND kombiniert werden, eine Bereichsbedingung.OR oder AND bilden eine Bereichsbedingung.

In den obigen Erläuterungen bezeichnet „Konstantenwert“ eines der folgenden Elemente:

  • eine Konstante aus dem Abfrage-String

  • eine Spalte aus einer const- oder system-Tabelle aus demselben Join

  • das Ergebnis einer unkorrelierten Unterabfrage

  • jeden Ausdruck, der vollständig aus Unterausdrücken der vorangegangenen Typen zusammengesetzt ist

Es folgen ein paar Beispiele für Abfragen mit Bereichsbedingungen in der WHERE-Klausel:

SELECT * FROM t1
  WHERE key_col > 1
  AND key_col < 10;
SELECT * FROM t1
  WHERE key_col = 1
  OR key_col IN (15,18,20);
SELECT * FROM t1
  WHERE key_col LIKE 'ab%'
  OR key_col BETWEEN 'bar' AND 'foo';

Beachten Sie, dass einige nichtkonstante Werte während der Weitergabephase für Konstanten ihrerseits in Konstanten umgewandelt werden könnten.

MySQL versucht, die Bereichsbedingungen für alle möglichen Indizes aus der WHERE-Klausel zu extrahieren. Während des Extraktionsvorgangs werden Bedingungen, die nicht zur Bildung der Bereichsbedingung verwendet werden können, gelöscht; Bedingungen, die überschneidende Bereiche erzeugen, werden kombiniert; schließlich werden Bedingungen, die leere Bereiche erzeugen, entfernt.

Betrachten Sie die folgende Anweisung (hierbei ist key1 eine indizierte Spalte, während nonkey nicht indiziert ist):

SELECT * FROM t1 WHERE
  (key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR
  (key1 < 'bar' AND nonkey = 4) OR
  (key1 < 'uux' AND key1 > 'z');

Der Extraktionsprozess für den Schlüssel key1 sieht wie folgt aus:

  1. Am Anfang steht die ursprüngliche WHERE-Klausel:

    (key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR
    (key1 < 'bar' AND nonkey = 4) OR
    (key1 < 'uux' AND key1 > 'z')
    
  2. Nun werden nonkey = 4 und key1 LIKE '%b' entfernt, weil sie für einen Bereichsscan nicht verwendet werden können. Die korrekte Vorgehensweise zur Entfernung besteht darin, sie durch TRUE zu ersetzen, damit bei der Durchführung des Bereichsscans keine passenden Datensätze übersehen werden. Nach der Ersetzung mit TRUE erhalten wir Folgendes:

    (key1 < 'abc' AND (key1 LIKE 'abcde%' OR TRUE)) OR
    (key1 < 'bar' AND TRUE) OR
    (key1 < 'uux' AND key1 > 'z')
    
  3. Die folgenden Kollapsbedingungen sind immer wahr oder falsch:

    • (key1 LIKE 'abcde%' OR TRUE) ist immer wahr.

    • (key1 < 'uux' AND key1 > 'z') ist immer falsch.

    Wenn wir diese Bedingungen durch Konstanten ersetzen, erhalten wir Folgendes:

    (key1 < 'abc' AND TRUE) OR (key1 < 'bar' AND TRUE) OR (FALSE)
    

    Durch Entfernen unnötiger TRUE- und FALSE-Konstanten erhalten wir:

    (key1 < 'abc') OR (key1 < 'bar')
    
  4. Die Zusammenfassung überschneidender Intervalle hat die Bedingung zum Ergebnis, die endgültig für den Bereichsscan verwendet werden muss:

    (key1 < 'bar')
    

Im Allgemeinen (und wie auch durch obiges Beispiel veranschaulicht) ist die für einen Bereichsscan verwendete Bedingung weniger restriktiv als die WHERE-Klausel. MySQL führt eine zusätzliche Prüfung durch, um Datensätze auszufiltern, die zwar die Bereichsbedingung erfüllen, nicht aber die vollständige WHERE-Klausel.

Der Extraktionsalgorithmus für die Bereichsbedingung kann verschachtelte AND- und/oder OR-Konstrukte beliebiger Tiefe verarbeiten. Außerdem hängt seine Ausgabe nicht von der Reihenfolge ab, in der die Bedingungen in der WHERE-Klausel erscheinen.

Gegenwärtig unterstützt MySQL nicht das Zusammenführung mehrfacher Bereiche für das range-Zugriffsverfahren für raumbezogene Indizes. Als Workaround für diese Einschränkung können Sie eine UNION mit identischen SELECT-Anweisungen verwenden, ausser dass Sie jedes raumbezogene Prädikat in eine andere SELECT-Anweisung setzen.

4.2.5.2. Das Range-Zugriffsverfahren für mehrteilige Indizes

Die Bereichsbedingungen für einen mehrteiligen Index stellen eine Erweiterung der Bereichsbedingungen für einen einteiligen Index dar. Eine Bereichsbedingung für einen mehrteiligen Index beschränkt die Indexdatensätze auf solche, die innerhalb eines oder mehrerer Schlüsseltupelintervalle liegen. Schlüsseltupelintervalle werden über eine Menge von Schlüsseltupeln definiert, wobei die Sortierung dem Index entnommen wird.

Betrachten Sie beispielsweise einen mehrteiligen Index, der als key1(key_part1, key_part2, key_part3) definiert ist, und die folgende Menge der in der Schlüsselreihenfolge aufgelisteten Schlüsseltupel:

key_part1  key_part2  key_part3
  NULL       1          'abc'
  NULL       1          'xyz'
  NULL       2          'foo'
   1         1          'abc'
   1         1          'xyz'
   1         2          'abc'
   2         1          'aaa'

Die Bedingung key_part1 = 1 definiert das folgende Intervall:

(1,-inf,-inf) <= (key_part1,key_part2,key_part3) < (1,+inf,+inf)

Das Intervall deckt das vierte, das fünfte und das sechste Tupel in der obigen Datenmenge ab und kann von der Bereichszugriffsmethode verwendet werden.

Im Gegensatz dazu definiert die Bedingung key_part3 = 'abc' kein einzelnes Intervall und kann von der Bereichszugriffsmethode nicht verwendet werden.

Die folgenden Beschreibungen erläutern im Detail, wie Bereichsbedingungen bei mehrteiligen Indizes funktionieren.

  • Bei HASH-Indizes kann jedes Intervall verwendet werden, das identische Werte enthält. Das bedeutet, dass das Intervall nur für Bedingungen in der folgenden Form erzeugt werden kann:

        key_part1 cmp const1
    AND key_part2 cmp const2
    AND ...
    AND key_partN cmp constN;
    

    Hierbei sind const1, const2, Konstanten, cmp ist einer der Vergleichsoperatoren =, <=> oder IS NULL, und die Bedingungen decken alle Indexbestandteile ab. (Das bedeutet, es gibt N Bedingungen: eine für jeden Teil eines N-teiligen Indexes.) Nachfolgend gezeigt ist etwa eine Bereichsbedingung für einen dreiteiligen HASH-Index:

    key_part1 = 1 AND key_part2 IS NULL AND key_part3 = 'foo'
    

    Eine Definition dessen, was als Konstanten betrachtet wird, finden Sie in Abschnitt 4.2.5.1, „Die Bereichszugriffsmethode für Single-Teils Indizes“.

  • Bei einem BTREE-Index kann ein Intervall für Bedingungen verwendbar sein, die mit AND kombiniert wurden, wobei jede Bedingung einen Schlüsselteil mit einem Konstantenwert unter Verwendung von =, <=>, IS NULL, >, <, >=, <=, !=, <>, BETWEEN oder LIKE 'pattern' vergleicht (wobei 'pattern' nicht mit einem Jokerzeichen beginnen darf). Ein Intervall kann verwendet werden, solange es möglich ist, ein einzelnes Schlüsseltupel zu bestimmen, das alle Datensätze enthält, die der Bedingung entsprechen (bzw. zwei Intervalle, wenn <> oder != verwendet werden). Betrachten Sie etwa folgende Bedingung:

    key_part1 = 'foo' AND key_part2 >= 10 AND key_part3 > 10
    

    Das einzelne Intervall ist:

    ('foo',10,10) < (key_part1,key_part2,key_part3) < ('foo',+inf,+inf)
    

    Es ist möglich, dass das erstellte Intervall mehr Datensätze enthält als die Ursprungsbedingung. So umfasst das obige Intervall beispielsweise den Wert ('foo', 11, 0), der die ursprüngliche Bedingung nicht erfüllt.

  • Wenn Bedingungen, die Mengen von Datensätzen innerhalb von Intervallen abdecken, mit OR kombiniert werden, bilden sie eine Bedingung, die eine Menge von Datensätzen abdeckt, die in der Union dieser Intervalle enthalten sind. Werden die Bedingungen mit AND kombiniert, dann bilden sie eine Bedingung, die die Menge von Datensätzen in der Schnittmenge der Intervalle abdeckt. Betrachten Sie etwa die folgende Bedingung für einen zweiteiligen Index:

    (key_part1 = 1 AND key_part2 < 2) OR (key_part1 > 5)
    

    Die Intervalle sehen hier wie folgt aus:

    (1,-inf) < (key_part1,key_part2) < (1,2)
    (5,-inf) < (key_part1,key_part2)
    

    In diesem Beispiel verwendet das Intervall für die erste Zeile einen Schlüsselteil für die linke Grenze und zwei Schlüsselteile für die rechte Grenze. Das Intervall in der zweiten Zeile benutzt dagegen nur einen Schlüsselteil. Die Spalte key_len in der Ausgabe von EXPLAIN gibt die maximale Länge des verwendeten Schlüsselpräfixes an.

    In manchen Fällen kann key_len anzeigen, dass ein Schlüsselteil verwendet wurde, aber dies entspricht unter Umständen nicht dem, was Sie erwarten. Angenommen, key_part1 und key_part2 können NULL sein. In diesem Fall zeigt die Spalte key_len zwei Schlüsselteillängen für die folgende Bedingung an:

    key_part1 >= 1 AND key_part2 < 2
    

    Tatsächlich aber wird die Bedingung wie folgt konvertiert:

    key_part1 >= 1 AND key_part2 IS NOT NULL
    

Abschnitt 4.2.5.1, „Die Bereichszugriffsmethode für Single-Teils Indizes“, beschreibt, wie Optimierungen zur Kombination oder Beseitigung von Intervallen für Bereichsbedingungen für einen einteiligen Index durchgeführt werden. Für Bereichsbedingungen für mehrteilige Indizes werden die Schritte analog durchgeführt.

4.2.6. Index-Merge-Optimierung

Die Index Merge-Methode wird verwendet, um Datensätze mit mehreren range-Scans abzurufen und deren Ergebnisse zu einem Ergebnis zu verschmelzen. Die Verschmelzung kann Unions, Schnittmengen oder Schnittmengen-Unions der zugrunde liegenden Scans erzeugen. Dieses Zugriffsverfahren führt Indexscans einer einzelnen Tabelle zusammen; es führt keine Scans über mehrere Tabellen zusammen.

In der Ausgabe von EXPLAIN erscheint die Indexverschmelzungsmethode als index_merge in der type-Spalte. In diesem Fall enthält die Spalte key eine Liste der verwendeten Indizes, und key_len enthält eine Liste der längsten Schlüsselteile für diese Indizes.

Ein paar Beispiele:

SELECT * FROM tbl_name WHERE key1 = 10 OR key2 = 20;
SELECT * FROM tbl_name
  WHERE (key1 = 10 OR key2 = 20) AND non_key=30;
SELECT * FROM t1, t2
  WHERE (t1.key1 IN (1,2) OR t1.key2 LIKE 'value%')
  AND t2.key1=t1.some_col;
SELECT * FROM t1, t2
  WHERE t1.key1=1
  AND (t2.key1=t1.some_col OR t2.key2=t1.some_col2);

Die Indexverschmelzungsmethode umfasst mehrere Zugriffsalgorithmen (diese können dem Feld Extra in der Ausgabe von EXPLAIN entnommen werden):

  • Using intersect(...)

  • Using union(...)

  • Using sort_union(...)

Die folgenden Abschnitte beschreiben diese Methoden im Detail.

Anmerkung

Der Optimierungsalgorithmus für Index Merge weist die folgenden bekannten Defizite auf:

  • Wenn ein Bereichsscan auf einem Schlüssel möglich ist, wird der Optimierer die Algorithmen Index Merge Union oder Index Merge Sort Union nicht berücksichtigen. Betrachten Sie etwa folgende Abfrage:

    SELECT * FROM t1 WHERE (goodkey1 < 10 OR goodkey2 < 20) AND badkey < 30;
    

    Hierbei sind zwei Pläne möglich:

    • ein Index Merge-Scan unter Verwendung der Bedingung (goodkey1 < 10 OR goodkey2 < 20)

    • ein Bereichsscan unter Verwendung der Bedingung badkey < 30

    Der Optimierer allerdings zieht nur den zweiten Plan in Betracht.

  • Wenn Ihre Abfrage eine komplexe WHERE-Klausel mit tiefer AND- oder OR-Verschachtelung enthält und MySQL nicht den optimalen Plan auswählt, versuchen Sie die Terme mithilfe der folgenden Identitätsgesetze zu verteilen:

    (x AND y) OR z = (x OR z) AND (y OR z)
    (x OR y) AND z = (x AND z) OR (y AND z)
    
  • Die Indexverschmelzung ist nicht für Volltextindizes einsetzbar. Wir beabsichtigen, dies in einem zukünftigen MySQL-Release zu ändern.

Die Auswahl zwischen verschiedenen möglichen Varianten der Indexverschmelzungsmethode und anderen Zugriffsmethoden basiert auf Kostenschätzungen der verschiedenen verfügbaren Optionen.

4.2.6.1. Der Index Merge Intersection Access-Algorithmus

Diese Zugriffsmethode kann verwendet werden, wenn eine WHERE-Klausel in mehrere Bereichsbedingungen für verschiedene, mit AND kombinierte Schlüssel konvertiert wurde und jede Bedingung eines der folgenden Elemente ist:

  • In dieser Form, wo der Index genau N Teile hat (d. h. alle Indexteile sind abgedeckt):

    key_part1=const1 AND key_part2=const2 ... AND key_partN=constN
    
  • Eine Bereichsbedingung über einem Primärschlüssel einer InnoDB-Tabelle.

Ein paar Beispiele:

SELECT * FROM innodb_table WHERE primary_key < 10 AND key_col1=20;
SELECT * FROM tbl_name
  WHERE (key1_part1=1 AND key1_part2=2) AND key2=2;

Der Indexverschmelzungs-Schnittmengenalgorithmus führt gleichzeitige Scans aller verwendeten Indizes durch und erzeugt die Schnittmenge der Datensatzsequenzen, die er den verschmolzenen Indexscans entnimmt.

Wenn alle in der Abfrage verwendeten Spalten von den verwendeten Indizes abgedeckt werden, werden keine vollständigen Tabellendatensätze abgerufen. (In diesem Fall enthält die Ausgabe von EXPLAIN Using index im Feld Extra.) Hier ein Beispiel für eine solche Abfrage:

SELECT COUNT(*) FROM t1 WHERE key1=1 AND key2=1;

Wenn die verwendeten Indizes nicht alle in der Abfrage verwendeten Spalten abdecken, werden vollständige Datensätze nur dann abgerufen, wenn die Bereichsbedingungen für alle Schlüssel erfüllt sind.

Wenn eine der verschmolzenen Bedingungen eine Bedingung über einen Primärschlüssel einer InnoDB-Tabelle ist, dann wird sie nicht zum Abrufen von Datensätzen, sondern zum Ausfiltern von Datensätzen verwendet, die mit anderen Bedingungen abgerufen wurden.

4.2.6.2. Der Index Merge Union Access-Algorithmus

Der Zugriffsalgorithmus Union bei der Indexverschmelzung Die Anwendbarkeitskriterien für diesen Algorithmus ähneln denen des Schnittmengenalgorithmus der Indexverschmelzungsmethode. Dieser Algorithmus kann verwendet werden, wenn die WHERE-Klausel der Tabelle in mehrere Bereichsbedingungen für verschiedene, mit OR kombinierte Schlüssel konvertiert wurde und jede Bedingung eines der folgenden Elemente ist:

  • In dieser Form, wo der Index genau N Teile hat (d. h. alle Indexteile sind abgedeckt):

    key_part1=const1 AND key_part2=const2 ... AND key_partN=constN
    
  • Eine Bereichsbedingung über einem Primärschlüssel einer InnoDB-Tabelle.

  • Eine Bedingung, auf die der Schnittmengenalgorithmus der Indexverschmelzungsmethode anwendbar ist.

Ein paar Beispiele:

SELECT * FROM t1 WHERE key1=1 OR key2=2 OR key3=3;
SELECT * FROM innodb_table WHERE (key1=1 AND key2=2) OR
  (key3='foo' AND key4='bar') AND key5=5;

4.2.6.3. Der Index Merge Sort Union Access-Algorithmus

Der Zugriffsalgorithmus Sort-Union bei der Indexverschmelzung Dieser Zugriffsalgorithmus wird verwendet, wenn die WHERE-Klausel in verschiedene Bereichsbedingungen konvertiert wurde, die mit OR verknüpft wurden, aber für die der Union-Algorithmus der Indexverschmelzungsmethode nicht anwendbar ist.

Ein paar Beispiele:

SELECT * FROM tbl_name WHERE key_col1 < 10 OR key_col2 < 20;
SELECT * FROM tbl_name
  WHERE (key_col1 > 10 OR key_col2 = 20) AND nonkey_col=30;

Der Unterschied zwischen dem Sort-Union-Algorithmus und dem Union-Algorithmus besteht darin, dass der Sort-Union-Algorithmus zunächst die Datensatzkennungen aller Datensätze abrufen und diese sortieren muss, bevor er Datensätze zurückgeben kann.

4.2.7. Condition Pushdown-Optimierung

Diese Optimierung verbessert die Effizienz eines direkten Vergleichs zwischen einer nichtindizierten Spalte und einer Konstante. In solchen Fällen wird die Bedingung zur Speicher-Engine für Auswertung „heruntergedrückt“. In MySQL 5.1 kann diese Optimierung nur von derNDBCLUSTER Speicher-Engine verwendet werden, aber wir beabsichtigen, es künftig für zusätzliche Speicher-Enginen, MySQL-Versionen zu implementieren.

Für MySQL Cluster kann diese Optimierung die Notwendigkeit beseitigen, nicht übereinstimmende Datensätze über das Netz zwischen den Datenknoten des Clusters und dem MySQL-Server, der die Abfrage ausgab, zu senden, und damit die Abfragen, bei denen sie verwendet wird, um einen Faktor von 5 bis 10 beschleunigen gegenüber Fällen, bei denen Condition Pushdown verwendet werden könnte aber nicht wird.

Angenommen, eine MySQL Cluster-Tabelle wird folgendermaßen definiert:

CREATE TABLE t1 (
    a INT,
    b INT,
    KEY(a)
) ENGINE=NDBCLUSTER;

Condition Pushdown kann mit einer Abfrage gegen diese Tabelle wie die hier gezeigte Abfrage verwendet werden:

SELECT a,b FROM t1 WHERE b = 10;

Dies kann man in der Ausgabe von EXPLAIN SELECT sehen:

mysql> EXPLAIN SELECT a,b FROM t1 WHERE b = 10\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t1
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 10
        Extra: Using where with pushed condition

Allerdings kann Condition Pushdown nicht mit diesen beiden Abfragen verwendet werden:

SELECT a,b FROM t1 WHERE a = 10;
SELECT a,b FROM t1 WHERE b + 1 = 10;

Bezüglich der ersten dieser zwei Abfragen ist der Bedingungs-Pushdown nicht anwendbar, weil in der Spalte a ein Index vorhanden ist. (Ein Indexzugriffsverfahren wäre effizienter und würde daher dem Condition Pushdown vorgezogen.) Im Fall der zweiten Abfrage kann Condition Pushdown nicht gebraucht werden, weil der Vergleich mit der nichtindizierten Spalten b indirekt ist. (Allerdings könnte Condition-Pushdown angewandt werden, wenn Sie in der WHERE-Klausel b + 1 = 10 auf b = 9 reduzierten.)

Condition Pushdown kann auch verwendet werden, wenn eine indizierte Spalte über einen > oder < Operator mit einer Konstanten verglichen wird:

mysql> EXPLAIN SELECT a,b FROM t1 WHERE a<2\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t1
         type: range
possible_keys: a
          key: a
      key_len: 5
          ref: NULL
         rows: 2
        Extra: Using where with pushed condition

Andere Vergleiche, die für Condition Pushdown unterstützt werden, schließen das Folgende ein:

  • Spalte [NOT] LIKE Muster

    Muster muss ein String-Literal sein, das das übereinzustimmende Muster enthält. Syntax siehe Abschnitt 7.4.1, „String-Vergleichsfunktionen“.

  • Spalte IS [NOT] NULL

  • Spalte IN (value_list)

    Jede EIntrag in der value_list muss ein konstanter Literalwert sein.

  • Spalte BETWEEN constant1 ANDconstant2

    constant1 und constant2 müssen jeweils ein konstanter Literalwert sein.

In allen Fällen in der vorausgegandenen Liste ist es möglich, dass die Bedingung in die Form eines oder mehrerer direkter Vergleiche zwischen einer Spalte und einer Konstante konvertiert wird.

Condition Pushdowns werden nicht standardmäßig eingesetzt. Um sie zu aktivieren, können Sie mysqld mit der Option --engine-condition-pushdown starten oder eine der folgenden Anweisungen bei Laufzeit ausführen:

SET engine_condition_pushdown=ON;

SET engine_condition_pushdown=1;

Einschränkungen.  Condition Pushdown unterliegt den folgenden Einschränkungen:

  • In MySQL 5.1 wird Condition Pushdown nur von der Speicher-Engine NDBCLUSTERunterstützt.

  • Spalten können nur mit Konstanten verglichen werden. Allerdings schließt dies Ausdrücke ein, deren Auswertung konstante Werte liefert.

  • In Vergleichen verwendete Spalten dürfen nicht vom Typ BLOB oderTEXT sein.

  • Ein mit einer Spalte zu vergleichender Stringwert muss die gleiche Sortierung wie die Spalte verwenden.

  • Joins werden nicht direkt unterstützt. Mehrere Tabellen betreffende Bedingungen werden, falls möglich, getrennt gepuscht. Verwenden Sie EXPLAIN EXTENDED, um zu entscheiden, welche Bedingungen tatsächlich gepuscht werden.

4.2.8. IS NULL-Optimierung

MySQL kann dieselbe Optimierung an col_name IS NULL vornehmen, die es auch für col_name = constant_value durchführen kann. So kann MySQL etwa Indizes und Bereiche zur Suche nach NULL mit IS NULL verwenden.

Ein paar Beispiele:

SELECT * FROM tbl_name WHERE key_col IS NULL;
SELECT * FROM tbl_name WHERE key_col <=> NULL;
SELECT * FROM tbl_name
  WHERE key_col=const1 OR key_col=const2 OR key_col IS NULL;

Wenn eine WHERE-Klausel eine Bedingung col_name IS NULL für eine Spalte enthält, die als NOT NULL deklariert ist, dann wird dieser Ausdruck wegoptimiert. Diese Optimierung findet allerdings nicht in Fällen statt, in denen die Spalte ohnehin NULL erzeugen könnte – z. B. wenn sie aus einer Tabelle auf der rechten Seite eines LEFT JOIN stammt.

MySQL kann auch die Kombination col_name = expr OR col_name IS NULL optimieren; diese Form tritt bei aufgelösten Unterabfragen häufig auf. EXPLAIN zeigt ref_or_null an, wenn diese Optimierung verwendet wird.

Diese Optimierung kann je Schlüsselteil eine IS NULL-Bedingung verarbeiten.

Es folgen einige Beispiele für optimierte Abfragen (hierbei wird davon ausgegangen, dass ein Index für die Spalten a und b der Tabelle t2 vorhanden ist):

SELECT * FROM t1 WHERE t1.a=expr OR t1.a IS NULL;
SELECT * FROM t1, t2 WHERE t1.a=t2.a OR t2.a IS NULL;
SELECT * FROM t1, t2
  WHERE (t1.a=t2.a OR t2.a IS NULL) AND t2.b=t1.b;
SELECT * FROM t1, t2
  WHERE t1.a=t2.a AND (t2.b=t1.b OR t2.b IS NULL);
SELECT * FROM t1, t2
  WHERE (t1.a=t2.a AND t2.a IS NULL AND ...)
  OR (t1.a=t2.a AND t2.a IS NULL AND ...);

Bei ref_or_null wird zunächst der Referenzschlüssel ausgelesen. Danach erfolgt eine separate Suche nach Datensätzen mit einem NULL-Schlüsselwert.

Beachten Sie, dass die Optimierung nur eine IS NULL-Ebene verarbeiten kann. In der folgenden Abfrage verwendet MySQL Schlüsselsuchvorgänge nur für den Ausdruck (t1.a=t2.a AND t2.a IS NULL). Der Schlüsselteil zu b kann von MySQL nicht verwendet werden:

SELECT * FROM t1, t2
  WHERE (t1.a=t2.a AND t2.a IS NULL)
  OR (t1.b=t2.b AND t2.b IS NULL);

4.2.9. LEFT-JOIN- und RIGHT-JOIN-Optimierung

MySQL implementiert A LEFT JOIN B join_condition wie folgt:

  • Tabelle B ist so konfiguriert, dass sie von Tabelle A und allen Tabellen abhängt, von denen auch Tabelle A abhängt.

  • Tabelle A ist ihrerseits so konfiguriert, dass sie von allen Tabellen (mit Ausnahme von B) abhängt, die in der LEFT JOIN-Bedingung verwendet werden.

  • Anhand der LEFT JOIN-Bedingung wird entschieden, wie Datensätze aus der Tabelle B abgerufen werden. (Das bedeutet, dass keine Bedingung in der WHERE-Klausel verwendet wird.)

  • Alle Standardoptimierungen für Joins werden durchgeführt; einzige Ausnahme ist, dass jede Tabelle stets erst gelesen wird, nachdem alle Tabellen gelesen wurden, von denen sie abhängt. Gibt es eine Zirkelabhängigkeit, dann gibt MySQL einen Fehler aus.

  • Alle Standardoptimierungen für WHERE werden durchgeführt.

  • Wenn ein Datensatz in A vorhanden ist, der der WHERE-Klausel entspricht, aber kein Datensatz in B, der der ON-Bedingung entspricht, dann wird ein zusätzlicher Datensatz in B erzeugt, bei dem alle Spalten auf NULL gesetzt sind.

  • Wenn Sie mit LEFT JOIN Datensätze suchen, die in keiner der Tabellen vorhanden sind, und die Überprüfung col_name IS NULL im WHERE-Teil vorhanden ist (wobei col_name eine als NOT NULL deklarierte Spalte ist), dann beendet MySQL die Suche nach weiteren Datensätzen (für eine bestimmte Schlüsselkombination), wenn es genau einen Datensatz gefunden hat, der der LEFT JOIN-Bedingung entspricht.

Die Implementierung von RIGHT JOIN erfolgt analog zu der von LEFT JOIN, wobei lediglich die Rollen der Tabellen umgekehrt werden.

Der Join-Optimierer berechnet die Reihenfolge, in der die Tabellen verknüpft werden sollten. Die durch LEFT JOIN oder STRAIGHT_JOIN erzwungene Lesereihenfolge für die Tabellen unterstützt den Join-Optimierer bei seiner Arbeit wesentlich effizienter, weil erheblich weniger Tabellenumstellungen zu überprüfen sind. Beachten Sie, dass dies bedeutet, dass, wenn Sie eine Abfrage folgenden Typs ausführen, MySQL einen vollständigen Scan in b durchführt, weil diese Tabelle aufgrund von LEFT JOIN vor d gelesen wird:

SELECT *
  FROM a JOIN b LEFT JOIN c ON (c.key=a.key)
  LEFT JOIN d ON (d.key=a.key)
  WHERE b.key=d.key;

Die Lösung besteht in diesem Fall darin, die Reihenfolge umzukehren, in der a und b in der FROM-Klausel aufgelistet werden:

SELECT *
  FROM b JOIN a LEFT JOIN c ON (c.key=a.key)
  LEFT JOIN d ON (d.key=a.key)
  WHERE b.key=d.key;

Wenn bei einem LEFT JOIN die WHERE-Bedingung für den erzeugten NULL-Datensatz immer falsch ist, dann wird der LEFT JOIN in einen normalen Join umgesetzt. So wäre beispielsweise die WHERE-Klausel in der folgenden Abfrage falsch, wenn t2.column1 NULL wäre:

SELECT * FROM t1 LEFT JOIN t2 ON (column1) WHERE t2.column2=5;

Aus diesem Grund kann die Abfrage problemlos in einen normalen Join konvertiert werden:

SELECT * FROM t1, t2 WHERE t2.column2=5 AND t1.column1=t2.column1;

Dies kann beschleunigt werden, weil MySQL die Tabelle t2 vor der Tabelle t1 verwenden kann, was zu einem besseren Abfrageplan führen würde. Verwenden Sie STRAIGHT_JOIN, um einen Hinweis über die Tabellenverknüpfungsreihenfolge zu erhalten. (Siehe auch Abschnitt 8.2.8, „SELECT.)

4.2.10. Nested-Loop Join-Algorithmen

MySQL führt Joins zwischen Tabellen mithilfe eines Nested-Loop-Algorithmus oder Variationen davon aus.

Nested-Loop Join-Algorithmus

Ein einfacher Nested-Loop Join-Algorithmus (NLJ) liest Datensätze aus der ersten Tabelle in einer Schleife einzeln aus und gibt jeden Datensatz an eine Nested Loop, die die nächste Tabelle im Join bearbeitet. Dieser Prozess wird sooft wiederholt, wie es noch zu verknüpfende Tabellen gibt.

Angenommen, es soll eine Verknüofung zwischen drei Tabellen t1, t2 und t3 mit den folgenden Join-Typen ausgeführt werden:

Table   Join Type
t1      range
t2      ref
t3      ALL

Wenn ein einfacher NLJ-Algorithmus verwendet wird, würde die Verknüpfung so bearbeitet werden:

for each row in t1 matching range {
  for each row in t2 matching reference key {
    for each row in t3 {
      if row satisfies join conditions,
      send to client
    }
  }
}

Weil der NLJ-Algorithmus einzelne Zeilen von den äußeren Schleifen an die inneren Schleifen weitergibt, werden die Tabellen in den inneren Schleifen typischerweise viele Male gelesen.

Block Nested-Loop Join-Algorithmus

Ein Block-Nested-Loop (BNL) Join-Algorithmus verwendet Zwischenspeicherung von Datensätzen, die in äußeren Schleifen gelesen werden, damit die Tabellen in den inneren Schleifen nicht so häufig gelesen werden müssen. Wenn zum Beispiel 10 Zeilen in einen Zwischenspeicher gelesen werden und der Zwischenspeicher an die nächste innere Schleife weitergegeben wird, kann jeder in der inneren Schleife gelesene Datensatz mit allen 10 Datensätzen im Zwischenspeicher verglichen werden. Der reduziert die Lesehäufigkeit der inneen Tabelle um eine Größenordnung.

MySQL verwendet Join-Zwischenspeicherung unter diesen Bedingungen:

  • Die Systemvariable join_buffer_size bestimmt die Größe des jeweiligen Join-Zwischenspeichers.

  • Join-Zwischenspeicherung kann bei den Join-Typen ALL oder index (mit anderen Worten, wenn keine möglichen Schlüssel verwendet werden können und wenn ein Vollscan der Daten oder der Indexzeilen ausgeführt wird) oder range verwendet werden.

  • Ein Zwischenspeicher wird für alle Joins zugeweisen, die zwischengespeichert werden können, damit könnte eine bestimmte Abfrage unter Verwendung mehrerer Join-Zwischenspeicher bearbeitet werden.

  • Ein Join-Zwischenspeicher wird niemals für die erste Nonconst-Tabelle zugewiesen, auch wenn ein Typ ALL oder Index vorliegt.

  • Ein Join-Zwischenspeicher wird vor der Join-Ausführung zugewiesen und nach Fertigstellung der Abfrage freigegeben.

  • Es werden nur die für die Join-Bearbeitung interessanten Spalten im Join-Zwischenspeicher gespeichert, nicht die ganzen Datensätze.

Das oben für den NLJ-Algorithmus (ohne Zwischenspeicherung) beschriebene Join-Beispiel würde wie folgt mit Join-Zwischenspeicherung ausgeführt werden:

for each row in t1 matching range {
  for each row in t2 matching reference key {
    store used columns from t1, t2 in join buffer
    if buffer is full {
      for each row in t3 {
        for each t1, t2 combination in join buffer {
          if row satisfies join conditions,
          send to client
        }
      }
      empty buffer
    }
  }
}
if buffer is not empty {
  for each row in t3 {
    for each t1, t2 combination in join buffer {
      if row satisfies join conditions,
      send to client
    }
  }
}

Ist S die Größe einer gespeicherten t1, t2-Kombination im Join-Zwischenspeicher und C die Anzahl der Kombinationen im Zwischenspeicher, beträgt die Anzahl der Tabellenscans t3:

(S * C)/join_buffer_size + 1

Eine Implikation ist, dass die Anzahl von t3-Scans sich vermindert, wenn der Wert von join_buffer_size anwächst, bis zu dem Punkt, an dem join_buffer_size groß genug ist, alle bisherigen Zeilenkombinationen aufzunehmen. An jenem Punkt gibt es durch Vergrößerung keinen Geschwindigkeitsgewinn mehr.

4.2.11. Nested Join-Optimierung

Die Syntax zum Ausdrücken von Joins gestattet auch verschachtelte Joins. Die nachfolgende Beschreibung bezieht sich auf die in Abschnitt 8.2.8.1, „JOIN, beschriebene Join-Syntax.

Die Syntax von table_factor ist im Vergleich zum SQL-Standard erweitert. SQL akzeptiert nur table_reference, nicht aber eine in Klammern gesetzte Liste mit Referenzierungen. Dies ist eine konservative Erweiterung, sofern wir jedes Komma in einer Liste mit table_reference-Elementen als äquivalent zu einem inneren Join betrachten. Ein Beispiel:

SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                 ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)

ist äquivalent mit

SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                 ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)

In MySQL ist CROSS JOIN syntaktisch ein Äquivalent zu INNER JOIN (diese lassen sich gegeneinander austauschen). Nach SQL-Standard hingegen sind beide nicht äquivalent. INNER JOIN wird bei einer ON-Klausel und CROSS JOIN andernfalls verwendet.

Klammern können in Join-Ausdrücken, die nur innere Join-Operationen enthalten, ignoriert werden. Nach Entfernen der Klammern und Gruppieren der linken Operationen lautet der Join-Ausdruck:

t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.b=t3.b OR t2.b IS NULL)
   ON t1.a=t2.a

wandelt den Ausdruck um in:

(t1 LEFT JOIN t2 ON t1.a=t2.a) LEFT JOIN t3
    ON t2.b=t3.b OR t2.b IS NULL

Trotzdem sind die beiden Ausdrücke nicht äquivalent. Um dies nachzuweisen, nehmen wir an, dass die Tabellen t1, t2 und t3 die folgenden Zustände haben:

  • Tabelle t1 enthält die Datensätze (1), (2)

  • Tabelle t2 enthält Datensatz (1,101)

  • Tabelle t3 enthält Datensatz (101)

In diesem Fall gibt der erste Ausdruck eine Ergebnismenge mit den Datensätzen {1,1,101,101}, {2,NULL,NULL,NULL} zurück; der zweite Ausdruck hingegen gibt die Datensätze {1,1,101,101}, {2,NULL,NULL,101} zurück:

mysql> SELECT *
    -> FROM t1
    ->      LEFT JOIN
    ->      (t2 LEFT JOIN t3 ON t2.b=t3.b OR t2.b IS NULL)
    ->      ON t1.a=t2.a;
+------+------+------+------+
| a    | a    | b    | b    |
+------+------+------+------+
|    1 |    1 |  101 |  101 |
|    2 | NULL | NULL | NULL |
+------+------+------+------+
mysql> SELECT *
    -> FROM (t1 LEFT JOIN t2 ON t1.a=t2.a)
    ->      LEFT JOIN t3
    ->      ON t2.b=t3.b OR t2.b IS NULL;
+------+------+------+------+
| a    | a    | b    | b    |
+------+------+------+------+
|    1 |    1 |  101 |  101 |
|    2 | NULL | NULL |  101 |
+------+------+------+------+

Im folgenden Beispiel wird ein äußerer Join gemeinsam mit einem inneren Join verwendet:

t1 LEFT JOIN (t2, t3) ON t1.a=t2.a

Dieser Ausdruck kann nicht in den folgenden Ausdruck transformiert werden:

t1 LEFT JOIN t2 ON t1.a=t2.a, t3.

Für die gegebenen Tabellenzustände geben die beiden Ausdrücke verschiedene Datensatzmengen zurück:

mysql> SELECT *
    -> FROM t1 LEFT JOIN (t2, t3) ON t1.a=t2.a;
+------+------+------+------+
| a    | a    | b    | b    |
+------+------+------+------+
|    1 |    1 |  101 |  101 |
|    2 | NULL | NULL | NULL |
+------+------+------+------+
mysql> SELECT *
    -> FROM t1 LEFT JOIN t2 ON t1.a=t2.a, t3;
+------+------+------+------+
| a    | a    | b    | b    |
+------+------+------+------+
|    1 |    1 |  101 |  101 |
|    2 | NULL | NULL |  101 |
+------+------+------+------+

Aus diesem Grund ändern wir, wenn wir in einem Join-Ausdruck mit äußeren Join-Operatoren die Klammern weglassen, unter Umständen die Ergebnismenge für den ursprünglichen Ausdruck.

Genauer formuliert: Wir dürfen die Klammern im rechten Operanden der linken äußeren Join-Operation und im linken Operanden einer rechten Join-Operation nicht ignorieren. Oder: Die Klammern der inneren Tabellenausdrücke äußerer Join-Operationen dürfen nicht unbeachtet bleiben. Klammern für den anderen Operanden (d. h. den Operanden der äußeren Tabelle) können hingegen ignoriert werden.

Der Ausdruck

(t1,t2) LEFT JOIN t3 ON P(t2.b,t3.b)

ist äquivalent zu folgendem Ausdruck:

t1, t2 LEFT JOIN t3 ON P(t2.b,t3.b)

Dies gilt für alle Tabellen t1,t2,t3 und alle Bedingungen P für Attribute t2.b und t3.b.

Immer dann, wenn die Join-Operationen in einem Join-Ausdruck (join_table) nicht von links nach rechts ausgeführt werden, redet man von verschachtelten Joins. Betrachten Sie einmal die folgenden Abfragen:

SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.b=t3.b) ON t1.a=t2.a
  WHERE t1.a > 1
SELECT * FROM t1 LEFT JOIN (t2, t3) ON t1.a=t2.a
  WHERE (t2.b=t3.b OR t2.b IS NULL) AND t1.a > 1

Diese Abfragen enthalten die folgenden verschachtelten Joins:

t2 LEFT JOIN t3 ON t2.b=t3.b
t2, t3

Der verschachtelte Join wird in der ersten Abfrage mit einem Left-Join gebildet, während er in der zweiten Abfrage aufgrund einer inneren Join-Operation entsteht.

In der ersten Abfrage können die Klammerzeichen weggelassen werden: Die grammatikalische Struktur des Join-Ausdrucks wird die gleiche Ausführungsreihenfolge Join-Operationen vorschreiben. Bei der zweiten Abfrage dürfen die Klammern nicht weggelassen werden, obwohl der Join-Ausdruck hier auch ohne sie eindeutig interpretiert werden könnte. (In unserer erweiterten Syntax sind die Klammern in (t2, t3) von der zweiten Abfrage erforderlich, obwohl die Abfrage theoretisch ohne sie analysiert werden könnte: Wir hätten weiterhin eine unzweideutige syntaktische Struktur für die Abfrage, weil LEFT-JOIN und ON die Rolle der linken und rechten Begrenzer für den Ausdruck (t2,t3) spielen würden.)

Die obigen Beispiele veranschaulichen die folgenden Aspekte:

  • Bei Join-Ausdrücken, die nur innere Joins (und keine äußeren Joins) enthalten, können die Klammern entfernt werden. Sie können die Klammern entfernen und die Auswertung von links nach rechts vornehmen (tatsächlich kann die Auswertung der Tabellen sogar in beliebiger Reihenfolge erfolgen).

  • Dies gilt allerdings in der Regel nicht für äußere Joins oder mit inneren Joins gemischte äußere Joins. Ein Entfernen der Klammern kann das Ergebnis ändern.

Abfragen mit verschachtelten äußeren Joins werden in derselben Weise ausgeführt wie Abfragen mit inneren Joins. Genauer gesagt, wird eine Abwandlung des Join-Algorithmus mit verschachtelten Schleifen benutzt. Vergegenwärtigen Sie sich, mit welchem Algorithmusschema ein Join mit verschachtelten Schleifen eine Abfrage ausführt. Angenommen, wir haben eine Join-Abfrage über drei Tabellen T1,T2,T3 der folgenden Form:

SELECT * FROM T1 INNER JOIN T2 ON P1(T1,T2)
                 INNER JOIN T3 ON P2(T2,T3)
  WHERE P(T1,T2,T3).

Hierbei seien P1(T1,T2) und P2(T3,T3) Join-Bedingungen (für Ausdrücke), während P(t1,t2,t3) eine Bedingung über Spalten der Tabellen T1,T2,T3 ist.

Der Algorithmus für Joins mit verschachtelten Schleifen würde die Abfrage wie folgt ausführen:

FOR each row t1 in T1 {
  FOR each row t2 in T2 such that P1(t1,t2) {
    FOR each row t3 in T3 such that P2(t2,t3) {
      IF P(t1,t2,t3) {
         t:=t1||t2||t3; OUTPUT t;
      }
    }
  }
}

Die Notation t1||t2||t3bedeutet „ein Datensatz, der durch das Verketten der Spalten der Datensätze t1, t2 und t3 konstruiert wird.“ In einigen der folgenden Beispiele, bedeutet NULL wo ein Datensatzname erscheint, dass NULL für jede Spalte jenes Datensatzes verwendet wird. Beispielsweise bedeutet t1||t2||NULLeinen Datensatz, der aus den verketteten Spalten der Datensätze t1 und t2 sowie NULL für jede Spalte von t3 besteht“.

Betrachten wir nun eine Abfrage mit verschachtelten äußeren Joins:

SELECT * FROM T1 LEFT JOIN
              (T2 LEFT JOIN T3 ON P2(T2,T3))
              ON P1(T1,T2)
  WHERE P(T1,T2,T3).

Für diese Abfrage ändern wir das Muster für verschachtelte Schleifen ab und erhalten Folgendes:

FOR each row t1 in T1 {
  BOOL f1:=FALSE;
  FOR each row t2 in T2 such that P1(t1,t2) {
    BOOL f2:=FALSE;
    FOR each row t3 in T3 such that P2(t2,t3) {
      IF P(t1,t2,t3) {
        t:=t1||t2||t3; OUTPUT t;
      }
      f2=TRUE;
      f1=TRUE;
    }
    IF (!f2) {
      IF P(t1,t2,NULL) {
        t:=t1||t2||NULL; OUTPUT t;
      }
      f1=TRUE;
    }
  }
  IF (!f1) {
    IF P(t1,NULL,NULL) {
      t:=t1||NULL||NULL; OUTPUT t;
    }
  }
}

Generell wird für jede verschachtelte Schleife für die erste innere Tabelle einer äußeren Join-Operation ein Flag eingeführt, welches vor der Schleife gelöscht und danach wieder gesetzt wird. Das Flag wird gesetzt, wenn für den aktuellen Datensatz aus der äußeren Tabelle eine Entsprechung in der Tabelle gefunden wird, die den inneren Operanden darstellt. Wenn das Flag am Ende des Schleifenzyklus immer noch nicht gelöscht ist, dann wurde für den aktuellen Datensatz in der äußeren Tabelle keine Entsprechung gefunden. In diesem Fall wird der Datensatz mit NULL-Werten für die Spalten der inneren Tabellen ergänzt. Der Ergebnisdatensatz wird zur letzten Überprüfung an die Ausgabe oder in die nächste verschachtelte Schleife übergeben – aber nur dann, wenn der Datensatz die Join-Bedingung für alle eingebetteten äußeren Joins erfüllt.

In unserem Beispiel ist die mit dem folgenden Ausdruck beschriebene äußere Join-Tabelle eingebettet:

(T2 LEFT JOIN T3 ON P2(T2,T3))

Beachten Sie, dass der Optimierer für die Abfrage mit inneren Joins eine andere Reihenfolge für verschachtelte Schleifen wählen könnte – etwa die folgende:

FOR each row t3 in T3 {
  FOR each row t2 in T2 such that P2(t2,t3) {
    FOR each row t1 in T1 such that P1(t1,t2) {
      IF P(t1,t2,t3) {
         t:=t1||t2||t3; OUTPUT t;
      }
    }
  }
}

Bei Abfragen mit äußeren Joins kann der Optimierer nur eine Reihenfolge wählen, bei der Schleifen für äußere Tabellen den Schleifen für die inneren Tabellen vorangehen. Insofern ist für unsere Abfrage mit äußeren Joins nur eine Verschachtelungsreihenfolge möglich. Bei der folgenden Abfrage wird der Optimierer zwei verschiedene Verschachtelungen auswerten:

SELECT * T1 LEFT JOIN (T2,T3) ON P1(T1,T2) AND P2(T1,T3)
  WHERE P(T1,T2,T3)

Die Verschachtelungen sind

FOR each row t1 in T1 {
  BOOL f1:=FALSE;
  FOR each row t2 in T2 such that P1(t1,t2) {
    FOR each row t3 in T3 such that P2(t1,t3) {
      IF P(t1,t2,t3) {
        t:=t1||t2||t3; OUTPUT t;
      }
      f1:=TRUE
    }
  }
  IF (!f1) {
    IF P(t1,NULL,NULL) {
      t:=t1||NULL||NULL; OUTPUT t;
    }
  }
}

und

FOR each row t1 in T1 {
  BOOL f1:=FALSE;
  FOR each row t3 in T3 such that P2(t1,t3) {
    FOR each row t2 in T2 such that P1(t1,t2) {
      IF P(t1,t2,t3) {
        t:=t1||t2||t3; OUTPUT t;
      }
      f1:=TRUE
    }
  }
  IF (!f1) {
    IF P(t1,NULL,NULL) {
      t:=t1||NULL||NULL; OUTPUT t;
    }
  }
}

In beiden Verschachtelungen muss T1 in der äußeren Schleife verarbeitet werden, weil sie in einem äußeren Join verwendet wird. T2 und T3 werden hingegen in einem inneren Join benutzt, d. h., der Join muss in der inneren Schleife verarbeitet werden. Allerdings können, weil der Join ein innerer Join ist, T2 und T3 in beliebiger Ordnung verarbeitet werden.

Bei der Beschreibung des Algorithmus mit verschachtelten Schleifen für innere Joins haben wir ein paar Details übergangen, deren Wirkung auf die Leistungsfähigkeit der Abfrageausführung beträchtlich sein kann. Wir haben beispielsweise so genannte „Pushdown-Bedingungen“ nicht erwähnt. Angenommen, unsere WHERE-Bedingung P(T1,T2,T3) könnte mit einer konjunktiven Formel dargestellt werden:

P(T1,T2,T2) = C1(T1) AND C2(T2) AND C3(T3).

In diesem Fall verwendet MySQL in der Tat das folgende Schema mit verschachtelten Schleifen zur Ausführung der Abfrage mit inneren Joins:

FOR each row t1 in T1 such that C1(t1) {
  FOR each row t2 in T2 such that P1(t1,t2) AND C2(t2)  {
    FOR each row t3 in T3 such that P2(t2,t3) AND C3(t3) {
      IF P(t1,t2,t3) {
         t:=t1||t2||t3; OUTPUT t;
      }
    }
  }
}

Sie erkennen, dass die Konjunkte C1(T1), C2(T2) und C3(T3) aus der innersten in die äußerste Schleife verschoben werden, wo sie dann ausgewertet werden können. Wenn C1(T1) eine sehr restriktive Bedingung ist, dann kann dieser Bedingungs-Pushdown die Anzahl der Datensätze aus Tabelle T1, die an die inneren Schleifen weitergegeben werden, erheblich verringern. Hieraus ergibt sich eine beachtliche Verbesserung bei der Ausführungszeit für die Abfrage.

Bei einer Abfrage mit äußeren Joins muss die WHERE-Bedingung erst geprüft werden, wenn festgestellt wurde, dass für den aktuellen Datensatz in der äußeren Tabelle eine Entsprechung in den inneren Tabellen vorhanden ist. Aufgrund dessen kann die Optimierung einer Pushdown-Bedingung aus den inneren verschachtelten Schleifen nicht direkt auf Abfragen mit äußeren Joins angewendet werden. Deswegen müssen an dieser Stelle konditionale Pushdown-Prädikate in Verbindung mit Überwachungs-Flags eingeführt werden, die gesetzt werden, sobald eine Übereinstimmung gefunden wurde.

Betrachten Sie noch einmal unser Beispiel mit äußeren Joins:

P(T1,T2,T3)=C1(T1) AND C(T2) AND C3(T3)

Hier sieht das Schema der verschachtelten Schleifen unter Verwendung überwachter Pushdown-Bedingungen wie folgt aus:

FOR each row t1 in T1 such that C1(t1) {
  BOOL f1:=FALSE;
  FOR each row t2 in T2
      such that P1(t1,t2) AND (f1?C2(t2):TRUE) {
    BOOL f2:=FALSE;
    FOR each row t3 in T3
        such that P2(t2,t3) AND (f1&&f2?C3(t3):TRUE) {
      IF (f1&&f2?TRUE:(C2(t2) AND C3(t3))) {
        t:=t1||t2||t3; OUTPUT t;
      }
      f2=TRUE;
      f1=TRUE;
    }
    IF (!f2) {
      IF (f1?TRUE:C2(t2) && P(t1,t2,NULL)) {
        t:=t1||t2||NULL; OUTPUT t;
      }
      f1=TRUE;
    }
  }
  IF (!f1 && P(t1,NULL,NULL)) {
      t:=t1||NULL||NULL; OUTPUT t;
  }
}

Generell können Pushdown-Prädikate aus Join-Bedingungen wie P1(T1,T2) und P(T2,T3) extrahiert werden. In diesem Fall wird ein Pushdown-Prädikat auch von einem Flag überwacht, das eine Überprüfung des Prädikats auf den mit NULL ergänzten Datensatz verhindert, der im Zuge der entsprechenden Join-Operation erzeugt wurde.

Beachten Sie, dass ein Zugriff nach Schlüssel aus einer inneren Tabelle auf eine andere Tabelle im selben verschachtelten Join unzulässig ist, wenn er durch ein Prädikat aus der WHERE-Bedingung herbeigeführt wird. (Wir könnten in diesem Fall einen bedingten Schlüsselzugriff verwenden, aber diese Methode ist in MySQL 5.1 noch nicht implementiert.)

4.2.12. Vereinfachung des äußeren Join

Tabellenausdrücke in der FROM-Klausel einer Abfrage werden in vielen Fällen vereinfacht.

Auf der Parserebene werden Abfragen mit rechten äußeren Join-Operationen in gleichwertige Abfragen konvertiert, die nur Left-Join-Operationen enthalten. Im Allgemeinen erfolgt die Konvertierung auf der Basis der folgenden Regel:

(T1, ...) RIGHT JOIN (T2,...) ON P(T1,...,T2,...) =
(T2, ...) LEFT JOIN (T1,...) ON P(T1,...,T2,...)

Alle inneren Join-Ausdrücke der Form T1 INNER JOIN T2 ON P(T1,T2) werden durch die Liste T1,T2 ersetzt, und P(T1,T2) wird als Konjunkt mit der WHERE-Bedingung (oder mit der Join-Bedingung des einbettenden Joins, sofern vorhanden) verknüpft.

Wenn der Optimierer Pläne für Join-Abfragen mit einer äußeren Join-Operation auswertet, berücksichtigt er nur diejenigen Pläne, bei denen bei einer solchen Operation zunächst auf die äußeren und erst dann auf die inneren Tabellen zugegriffen wird. Die Optimiereroptionen sind eingeschränkt, weil nur solche Pläne uns die Ausführung von Abfragen mit äußeren Join-Operationen über das Schema mit verschachtelten Schleifen gestatten.

Angenommen, wir haben eine Abfrage folgenden Aussehens:

SELECT * T1 LEFT JOIN T2 ON P1(T1,T2)
  WHERE P(T1,T2) AND R(T2)

Hierbei schränkt R(T2) die Anzahl passender Datensätze aus der Tabelle T2 erheblich ein. Wenn wir die Abfrage in ihrer ursprünglichen Form ausgeführt hätten, hätte der Optimierer keine andere Chance gehabt, als zuerst auf die Tabelle T1 und erst dann auf T2 zuzugreifen. Dies hätte einen sehr ineffizienten Ausführungsplan zur Folge gehabt.

Glücklicherweise wandelt MySQL eine solche Abfrage in eine Abfrage ohne äußere Join-Operation um, wenn die WHERE-Bedingung nullabweisend wird. Eine Bedingung heißt nullabweisend für eine äußere Join-Operation, wenn sie für jeden NULL-ergänzten Datensatz, der für die Operation erstellt wurde, stets FALSE oder UNKNOWN ist.

Betrachten Sie folgenden äußeren Join:

T1 LEFT JOIN T2 ON T1.A=T2.A

Für ihn sind Bedingungen wie die folgenden nullabweisend:

T2.B IS NOT NULL,
T2.B > 3,
T2.C <= T1.C,
T2.B < 2 OR T2.C > 1

Bedingungen wie die folgenden sind hingegen nicht nullabweisend:

T2.B IS NULL,
T1.B < 3 OR T2.B IS NOT NULL,
T1.B < 3 OR T2.B > 3

Die allgemeinen Regeln zur Überprüfung, ob eine Bedingung für einen äußeren Join nullabweisend ist oder nicht, sind recht einfach. Eine Bedingung ist nullabweisend, wenn sie

  • die Form A IS NOT NULL hat, wobei A ein Attribut einer der inneren Tabellen ist,

  • ein Prädikat ist, das eine innere Tabelle referenziert, die UNKNOWN ist, wenn eines ihrer Argumente NULL ist,

  • eine Konjunktion mit einer nullabweisenden Bedingung als Konjunkt ist,

  • eine Disjunktion nullabweisender Bedingungen ist.

Eine Bedingung kann für eine äußere Join-Operation nullabweisend sein und gleichzeitig für eine andere nicht. Betrachten Sie folgende Abfrage:

SELECT * FROM T1 LEFT JOIN T2 ON T2.A=T1.A
                 LEFT JOIN T3 ON T3.B=T1.B
  WHERE T3.C > 0

Hier ist die WHERE-Bedingung für die zweite äußere Join-Operation nullabweisend, nicht jedoch für die erste.

Wenn die WHERE-Bedingung für eine äußere Join-Operation in einer Abfrage nullabweisend ist, wird die äußere Join-Operation durch eine innere Join-Operation ersetzt.

So wird etwa obige Abfrage durch die folgende ersetzt:

SELECT * FROM T1 LEFT JOIN T2 ON T2.A=T1.A
                 INNER JOIN T3 ON T3.B=T1.B
  WHERE T3.C > 0

Für die ursprüngliche Abfrage würde der Optimierer Pläne auswerten, die mit der Zugriffsreihenfolge T1,T2,T3 kompatibel wären. Für die ersetzende Abfrage wird außerdem die Zugriffssequenz T3,T1,T2 in Betracht gezogen.

Eine Konvertierung einer äußeren Join-Operation kann eine Konvertierung einer anderen derartigen Operation auslösen. Betrachten Sie folgende Abfrage:

SELECT * FROM T1 LEFT JOIN T2 ON T2.A=T1.A
                 LEFT JOIN T3 ON T3.B=T2.B
  WHERE T3.C > 0

Diese wird in die folgende Abfrage konvertiert:

SELECT * FROM T1 LEFT JOIN T2 ON T2.A=T1.A
                 INNER JOIN T3 ON T3.B=T2.B
  WHERE T3.C > 0

Diese wiederum ist äquivalent mit dieser Abfrage:

SELECT * FROM (T1 LEFT JOIN T2 ON T2.A=T1.A), T3
  WHERE T3.C > 0 AND T3.B=T2.B

Nun kann die verbleibende äußere Join-Operation ebenfalls durch einen inneren Join ersetzt werden, weil die Bedingung T3.B=T2.B nullabweisend ist und wir eine Abfrage erhalten, die überhaupt keine äußeren Joins enthält:

SELECT * FROM (T1 INNER JOIN T2 ON T2.A=T1.A), T3
  WHERE T3.C > 0 AND T3.B=T2.B

Manchmal gelingt es, eine eingebettete äußere Join-Operation zu ersetzen, aber der einbettende äußere Join kann nicht konvertiert werden. Betrachten Sie folgende Abfrage:

SELECT * FROM T1 LEFT JOIN
              (T2 LEFT JOIN T3 ON T3.B=T2.B)
              ON T2.A=T1.A
  WHERE T3.C > 0

Sie wird wie folgt konvertiert:

SELECT * FROM T1 LEFT JOIN
              (T2 INNER JOIN T3 ON T3.B=T2.B)
              ON T2.A=T1.A
  WHERE T3.C > 0,

Dies lässt sich nur in einer Form umschreiben, die nach wie vor die einbettende äußere Join-Operation enthält:

SELECT * FROM T1 LEFT JOIN
              (T2,T3)
              ON (T2.A=T1.A AND T3.B=T2.B)
  WHERE T3.C > 0.

Wenn Sie versuchen, eine eingebettete äußere Join-Operation zu konvertieren, dann müssen Sie die Join-Bedingung für den einbettenden äußeren Join gemeinsam mit der WHERE-Bedingung berücksichtigen. Betrachten Sie folgende Abfrage:

SELECT * FROM T1 LEFT JOIN
              (T2 LEFT JOIN T3 ON T3.B=T2.B)
              ON T2.A=T1.A AND T3.C=T1.C
  WHERE T3.D > 0 OR T1.D > 0

Hier ist die WHERE-Bedingung für den eingebetteten äußeren Join nicht nullabweisend, wohl aber die Join-Bedingung des einbettenden äußeren Joins T2.A=T1.A AND T3.C=T1.C. Insofern kann die Abfrage wie folgt konvertiert werden:

SELECT * FROM T1 LEFT JOIN
              (T2, T3)
              ON T2.A=T1.A AND T3.C=T1.C AND T3.B=T2.B
  WHERE T3.D > 0 OR T1.D > 0

4.2.13. ORDER BY-Optimierung

In manchen Fällen kann MySQL mit einem Index eine ORDER BY-Klausel erfüllen, ohne dass eine zusätzliche Sortierung erforderlich wäre.

Der Index kann auch verwendet werden, wenn die ORDER BY-Klausel dem Index nicht exakt entspricht, solange alle nicht verwendeten Bestandteile des Indexes und alle zusätzlichen ORDER BY-Spalten Konstanten in der WHERE-Klausel sind. Die folgenden Abfragen lösen den ORDER BY-Teil mithilfe des Indexes auf:

SELECT * FROM t1
  ORDER BY key_part1,key_part2,... ;
SELECT * FROM t1
  WHERE key_part1=constant
  ORDER BY key_part2;
SELECT * FROM t1
  ORDER BY key_part1 DESC, key_part2 DESC;
SELECT * FROM t1
  WHERE key_part1=1
  ORDER BY key_part1 DESC, key_part2 DESC;

In manchen Fällen kann MySQL Indizes nicht zur Auflösung von ORDER BY verwenden, obwohl es mithilfe der Indizes Datensätze findet, die der WHERE-Klausel entsprechen. Dies betrifft u. a. die folgenden Fälle:

  • Sie verwenden ORDER BY für verschiedene Schlüssel:

    SELECT * FROM t1 ORDER BY key1, key2;
    
  • Sie verwenden ORDER BY auf nicht konsekutiven Teilen eines Schlüssels:

    SELECT * FROM t1 WHERE key2=constant ORDER BY key_part2;
    
  • Sie verwenden ASC und DESC gemischt:

    SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC;
    
  • Der Schlüssel, der zum Holen der Datensätze verwendet wird, ist nicht derselbe wie derjenige, der in der ORDER BY-Klausel verwendet wird:

    SELECT * FROM t1 WHERE key2=constant ORDER BY key1;
    
  • Sie verwenden ORDER BY bei einem Ausdruck, der andere Begriffe als den Schlüsselspaltennamen einschließt:

    SELECT * FROM t1 ORDER BY ABS(key);
    SELECT * FROM t1 ORDER BY -key;
    
  • Sie verknüpfen zahlreiche Tabellen, und die Spalten in der ORDER BY-Klausel stammen nicht alle aus der ersten nichtkonstanten Tabelle, die zum Abrufen von Datensätzen verwendet wird. (Dies ist die erste Tabelle in der Ausgabe von EXPLAIN, die nicht den Join-Typ const aufweist.)

  • Sie haben verschiedene ORDER BY- und GROUP BY-Ausdrücke.

  • Sie indizieren nur einen Präfix einer in der ORDER BY-Klausel genannten Spalte. In diesem Fall kann der Index nicht verwendet werden, um die Sortierreihenfolge zu vollständig aufzulösen. Wenn Sie zum Beispiel eine CHAR(20)-Spalte haben, aber nur die ersten 10 Bytes indizieren, kann der Index Werte nach dem 10. Byte nicht unterscheiden und es wird ein filesort nötig.

  • Der Typ des verwendeten Tabellenindexes speichert die Datensätze nicht in ihrer Reihenfolge. Dies gilt beispielsweise für einen HASH-Index in einer MEMORY-Tabelle.

Die Verfügbarkeit eines Indexes für das Sortieren kann durch die Verwendung von Spaltenaliasen beeinträchtigt werden. Angenommen, es wird die Spalte t1.a indiziert. In dieser Anweisung ist der Name der Spalte in der Auswahlliste a. Er bezieht sich auf t1.a, daher kann für den Verweis auf a in ORDER BY der Index verwendet werden:

SELECT a FROM t1 ORDER BY a;

In dieser Anweisung ist auch der Name der Spalte in der Auswahlliste a, aber es ist der Alias-Name. Es bezieht sich auf ABS(a), daher kann der Index für den Verweis auf a in ORDER BY nicht verwendet werden:

SELECT ABS(a) AS a FROM t1 ORDER BY a;

In der folgenden Anweisung bezieht sich ORDER BY auf einen Namen, der nicht der Name einer Spalte in der Auswahlliste ist. Aber es gibt eine Spalte in t1 mit dem Namen a, also verwendet ORDER BY diese und der Index kann verwendet werden. (Die sich ergebende Sortierreihenfolge kann natürlich vollkommen anders als die Reihenfolge für ABS(a) sein.)

SELECT ABS(a) AS b FROM t1 ORDER BY a;

Standardmäßig sortiert MySQL alle GROUP BY col1, col2...-Abfragen als ob Sie auch ORDER BY col1, col2, ... in der Abfrage angegeben hätten. Wenn Sie ausdrücklich eine ORDER BY-Klausel angeben, die dieselbe Spaltenliste enthält, optimiert MySQL diese ohne Geschwindigkeitseinbuße weg, auch wenn die Sortierung tatsächlich stattfindet. Enthält eine Abfrage eine GROUP BY-Klausel, während Sie die Mehrbelastung durch die Sortierung des Ergebnisses vermeiden wollen, dann können Sie diese Sortierung durch Angabe von ORDER BY NULL unterdrücken. Ein Beispiel:

INSERT INTO foo
SELECT a, COUNT(*) FROM bar GROUP BY a ORDER BY NULL;

Mit EXPLAIN SELECT ... ORDER BY können Sie überprüfen, ob MySQL Indizes zur Auflösung der Abfrage verwenden kann. Wenn Sie Using filesort in der Spalte Extra sehen, ist dies nicht möglich. Siehe auch Abschnitt 4.2.1, „Abfragen mit EXPLAIN optimieren“.

MySQL hat zwei filesort-Algorithmen für das Sortieren und Abfragen der Ergebnisse. Die ursprüngliche Methode verwendet nur die ORDER BY-Spalten. Die veränderte Methode verwendet nicht nur die ORDER BY-Spalten, sondern alle Spalten in der Abfrage.

Der Optimierer selektiert, welcher filesort-Algorithmus zu verwenden ist. Er verwendet normalerweise den veränderten Algorithmus, außer wenn BLOB- oder TEXT-Spalten beteiligt sind, dann verwendet er den ursprünglichen Algorithmus.

Der ursprüngliche filesort-Algorithmus funktioniert folgendermaßen:

  1. Alle Datensätze entsprechend Schlüssel- oder Tabellenscan lesen. Datensätze, die nicht mit der WHERE-Klausel übereinstimmen, werden übersprungen.

  2. Für jeden Datensatz ein Wertepaar in einem Zwischenspeicher speichern (Sortierschlüssel und Zeilenzeiger). Die Größe des Zwischenspeichers ist der Wert der Systemvariablen sort_buffer_size.

  3. Wenn der Zwischenspeicher voll wird, ein qsort (quicksort) darauf ausführen und das Ergebnis in einer temporären Datei speichern. Einen Zeiger auf den sortierten Block speichern. (Wenn alle Paare in den Sortierzwischenspeicher passen, wird keine temporäre Datei erstellt.)

  4. Die vorangehenden Schritte wiederholen, bis alle Datensätze gelesen worden sind.

  5. Ein Multimerge von bis zu MERGEBUFF (7) Regionen in einen Block in einer anderen temporären Datei ausführen. Wiederholen, bis sich alle Blöcke aus der ersten Datei in der zweiten Datei befinden.

  6. Das Folgende wiederholen, bis weniger als MERGEBUFF2 (15) übrig sind.

  7. Beim letzten Multimerge wird nur der Zeiger auf die Zeile (der letzte Teil des Sortierschlüssels) in eine Ergebnisdatei geschrieben.

  8. Die Datensätze in sortierter Reihenfolge unter Verwendung der Zeilenzeiger in der Ergebnisdatei lesen. Um dies zu optimieren, lesen wir einen großen Block von Zeilenzeigern ein, sortieren sie, und verwenden sie, um die Zeilen in sortierter Reihenfolge in einen Zeilenzwischenspeicher zu lesen. Die Größe des Zwischenspeichers ist der Wert der Systemvariablen read_rnd_buffer_size. Der Code für diesen Schritt befindet sich in der Quelldatei sql/records.cc.

Ein Problem bei diesem Ansatz ist, dass er Zeilen zweimal liest: Ein Mal, wenn die WHERE-Klausel ausgewertetet wird, und nochmals nach dem Sortieren der Paarwerte. Und auch wenn beim ersten Mal auf die Zeilen aufeinanderfolgend zugegriffen wurde (zum Beispiel wenn ein Tabellenscan ausgeführt wird), erfolgt der zweite Zugriff in Zufallsreihenfolge. (Die Sortierschlüssel sind sortiert, aber die Zeilenpositionen nicht.)

Der veränderte filesort-Algorithmus enthält eine Optimierung, die nicht nur den Sortierschlüsselwert und die Zeilenposition, sondern auch die Spalten für die Abfrage aufzeichnet. Hiermit wird verhindert, dass Datensätze zweimal ausgelesen werden. Der veränderte filesort-Algorithmus funktioniert so:

  1. Die Datensätze, die der WHERE-Klausel entsprechen, werden gelesen.

  2. Für jeden Datensatz wird ein Tupel mit Werten aufgezeichnet, die den Sortierschlüsselwert und die Datensatzposition sowie die Spalten umfassen, die für die Abfrage erforderlich sind.

  3. Die Tupel werden nach dem Sortierschlüsselwert sortiert.

  4. Die Datensätze werden in der sortierten Reihenfolge abgerufen, aber die erforderlichen Spalten werden direkt aus den sortierten Tupeln ausgelesen, statt ein zweites Mal auf die Tabelle zuzugreifen.

Bei Verwendung des veränderten filesort-Algorithmus sind die Tupel länger als die in der ursprünglichen Methode verwendeten Paare und es passen weniger von ihnen in den Sortierzwischenspeicher (dessen Größe von sort_buffer_size angegeben wird). Dadurch ist es möglich, dass zusätzliche E/A den veränderten Ansatz langsamer statt schneller machen. Um eine Verlangsamung zu vermeiden, wird die Optimierung nur verwendet, wenn die Geamtgröße der zusätzlichen Spalten im Sortiertupel den Wert der Systemvariablenmax_length_for_sort_data nicht überschreitet. (Wenn Sie dieser Variablen einen zu hohen Wert zuweisen, treten typische Symptome wie eine hohe Festplatten- und eine niedrige Prozessoraktivität auf.)

Bei langsamen Abfragen, für die filesort nicht verwendet wird, könnten Sie versuchen, max_length_for_sort_data auf einen Wert zu senken, der geeignet ist, einen filesortzu triggern.

Wenn Sie die Geschwindigkeit von ORDER BY erhöhen wollen, überprüfen Sie, ob Sie MySQL dazu bewegen können, Indizes statt einer zusätzlichen Sortierphase zu verwenden. Ist dies nicht möglich, dann können Sie die folgenden Strategien ausprobieren:

  • Sie erhöhen den Wert der Variablen sort_buffer_size.

  • Sie erhöhen den Wert der Variablen read_rnd_buffer_size.

  • Sie verwenden weniger RAM pro Zeile, indem Sie die Spalten nur so groß deklarieren wie sie sein müssen, um die in ihnen gespeicherten Werte aufzunehmen. Zum Beispiel ist CHAR(16) besser als CHAR(200), wenn die Werte niemals länger als 16 Zeichen sind.

  • Sie ändern tmpdir so, das sie auf ein dediziertes Dateisystem mit großem freien Speicherplatz zeigt. Auch akzeptiert diese Option mehrere Pfade, die reihum verwendet werden, daher können Sie diese Funktion verwenden, um die Belastung auf einige Dateiverzeichnisse zu verteilen. Pfade sollten durch Doppelpunkte(„:“) auf Unix und Semikolons(„;“) auf Windows, NetWare, und OS/2 unterteilt werden. Die Pfade sollten für Verzeichnisse in Dateissystemen gelten, die sich auf unterschiedlichen physikalischen Festplatten, nicht unterschiedlichen Partitionen auf der gleichen Festplatte befinden.

4.2.14. GROUP BY-Optimierung

Die allgemeinste Art und Weise, eine GROUP BY-Klausel zu erfüllen, besteht darin, die gesamte Tabelle zu scannen und eine neue Temporärtabelle zu erstellen, in der alle Datensätze aus allen Gruppen aufeinander folgend aufgeführt sind, und dann mithilfe dieser Temporärtabelle Gruppen zu erkennen und – sofern möglich – Zusammenfassungsfunktionen anzuwenden. In manchen Fällen kann MySQL jedoch auf andere Weise wesentlich effizienter vorgehen und die Erstellung von Temporärtabellen umgehen, indem ein Indexzugriff verwendet wird.

Die wichtigsten Voraussetzungen zur Verwendung von Indizes für GROUP BY bestehen darin, dass alle GROUP BY-Spalten Attribute aus demselben Index referenzieren und dass der Index seine Schlüssel in der Reihenfolge speichert (beispielsweise ist dies ein BTREE- und kein HASH-Index). Ob die Verwendung von Temporärtabellen durch einen Indexzugriff ersetzt werden kann, hängt auch davon ab, welche Teile eines Indexes in einer Abfrage verwendet werden, welche Bedingungen für diese Teile spezifiziert sind und welche Zusammenfassungsfunktionen ausgewählt wurden.

Es gibt zwei Möglichkeiten, eine GROUP BY-Abfrage über den Indexzugriff auszuführen; sie beide werden in den folgenden Abschnitten beschrieben. Bei der ersten Methode wird die Gruppierungsoperation ggf. gemeinsam mit allen Bereichsprädikaten angewandt. Die zweite Methode führt zunächst einen Bereichsscan durch und gruppiert dann die Ergebnistupel.

In MySQL wird GROUP BY für das Sortieren verwendet, daher kann der Server auch ORDER BY-Optimierungen auf Gruppierungen anwenden. Siehe auch Abschnitt 4.2.13, „ORDER BY-Optimierung“.

4.2.14.1. Lockerer Indexscan

Die effizienteste Weise, GROUP BY zu bearbeiten, ist die Verwendung eines Indizes, um direkt die Gruppierungsspalten zu holen. Bei dieser Zugriffsmethode verwendet MySQL die Eigenschaft einiger Indextypen, dass die Schlüssel sortiert sind (z. B. BTREE). Diese Eigenschaft erlaubt die Verwendung von Suchvorgangsgruppen in einem Index, ohne dass alle Schlüssel im Index berücksichtigt werden müssten, die die WHERE-Bedingungen erfüllen. Diese Zugriffsmethode berücksichtigt also nur einen Bruchteil der Schlüssel in einem Index und heißt deswegen lockerer Indexscan. Wenn keine WHERE-Klausel vorhanden ist, liest ein lockerer Indexscan so viele Schlüssel, wie Gruppen vorhanden sind. Diese Anzahl kann bedeutend kleiner sein als die aller Schlüssel. Wenn die WHERE-Klausel Bereichsprädikate enthält (siehe auch die Beschreibung des Join-Typs range in Abschnitt 4.2.1, „Abfragen mit EXPLAIN optimieren“), dann sucht ein lockerer Indexscan nach dem jeweils ersten Schlüssel aller Gruppen, die die Bereichsbedingungen erfüllen, und liest dann erneut die kleinstmögliche Anzahl Schlüssel aus. Dies ist unter den folgenden Bedingungen möglich:

  • Die Abfrage gilt einer einzelnen Tabelle.

  • Die GROUP BY-Klausel enthält die ersten aufeinander folgenden Teile des Indexes. (Wenn die Abfrage statt einer GROUP BY- eine DISTINCT-Klausel enthält, referenzieren alle den Anfang des Indexes.)

  • Wenn überhaupt, so werden als einzige Zusammenfassungsfunktionen MIN() und MAX() verwendet, die zudem alle dieselbe Spalte referenzieren.

  • Alle Teile des Indexes, die nicht aus der in der Abfrage referenzierten GROUP BY-Klausel stammen, müssen Konstanten sein (d. h., sie müssen in Gleichungen mit Konstanten referenziert werden). Ausgenommen ist lediglich das Argument der Funktionen MIN() und MAX().

Die EXPLAIN-Ausgabe für solche Abfragen zeigt Using index for group-by in der Spalte Extra an.

Angenommen, es gibt einen Index idx(c1,c2,c3) auf Tabelle t1(c1,c2,c3,c4). Die lockere Indexscanzugriffsmethode kann für die folgenden Abfragen verwendet werden:

SELECT c1, c2 FROM t1 GROUP BY c1, c2;
SELECT DISTINCT c1, c2 FROM t1;
SELECT c1, MIN(c2) FROM t1 GROUP BY c1;
SELECT c1, c2 FROM t1 WHERE c1 < const GROUP BY c1, c2;
SELECT MAX(c3), MIN(c3), c1, c2 FROM t1 WHERE c2 > const GROUP BY c1, c2;
SELECT c2 FROM t1 WHERE c1 < const GROUP BY c1, c2;
SELECT c1, c2 FROM t1 WHERE c3 = const GROUP BY c1, c2;

Die folgenden Abfragen können aus den angegebenen Gründen nicht mit dieser schnellen Auswahlmethode ausgeführt werden:

  • Es gibt andere Aggregatfunktionen als MIN() oder MAX(), zum Beispiel:

    SELECT c1, SUM(c2) FROM t1 GROUP BY c1;
    
  • Die Spalten in der GROUP BY-Klausel beziehen sich nicht auf den Anfang des Indexes, wie hier gezeigt:

    SELECT c1,c2 FROM t1 GROUP BY c2, c3;
    
  • Die Abfrage referenziert einen Teil eines Schlüssels, der nach dem GROUP BY-Teil kommt und für den keine Gleichzeit mit einer Konstante vorliegt. Ein Beispiel:

    SELECT c1,c3 FROM t1 GROUP BY c1, c2;
    

4.2.14.2. Enggefasster Indexscan

Ein enggefasster Indexscan kann je nach Abfragebedingung entweder ein vollständiger Indexscan oder ein Bereichsindexscan sein.

Wenn die Bedingungen für einen lockeren Indexscan nicht erfüllt sind, kann es trotzdem möglich sein, die Einrichtung temporärer Tabellen für GROUP BY-Abfragen zu vermeiden. Wenn in der WHERE-Klausel Bereichsbedingungen vorhanden sind, liest diese Methode nur die Schlüssel aus, die diese Bedingungen erfüllen. Andernfalls wird ein Indexscan durchgeführt. Da diese Methode alle Schlüssel in jedem von der WHERE-Klausel definierten Bereich liest oder den gesamten Index scannt, sofern keine Bereichsbedingungen vorhanden sind, sprechen wir hier vom enggefassten Indexscan. Bei einem enggefassten Indexscan wird die Gruppierungsoperation erst ausgeführt, nachdem alle Schlüssel, die den Bereichsbedingungen entsprechen, gefunden worden sind.

Damit diese Methode funktioniert, ist eine Konstantengleichheitsbedingung für alle Spalten in einer Abfrage ausreichend, wenn diese Abfrage die Schlüssel referenziert, die vor oder zwischen den Teilen des GROUP BY-Schlüssels auftreten. Die Konstanten aus den Gleichheitsbedingungen füllen alle „Lücken“ in den Suchschlüsseln auf, sodass es möglich ist, vollständige Präfixe des Indexes zu bilden. Diese Indexpräfixe können dann für Indexsuchvorgänge verwendet werden. Wenn Sie die Sortierung des GROUP BY-Ergebnisses benötigen und es möglich ist, Suchschlüssel zu bilden, die Präfixe des Indexes sind, dann vermeidet MySQL außerdem zusätzliche Sortieroperationen, weil das Suchen mit Präfixen in einem sortierten Index bereits alle Schlüssel in der korrekten Reihenfolge abruft.

Angenommen, es gibt einen Index idx(c1,c2,c3) auf Tabelle t1(c1,c2,c3,c4). Die folgenden Abfragen funktionieren nicht bei der lockeren, oben beschriebenen Indexscanzugriffsmethode, aber funktionieren mit der enggefassten Indexscanzugriffsmethode.

  • Es gibt eine Lücke in GROUP BY, aber die wird von der Bedingung c2 = 'a'abgedeckt:

    SELECT c1, c2, c3 FROM t1 WHERE c2 = 'a' GROUP BY c1, c3;
    
  • GROUP BY beginnt nicht mit dem ersten Teil des Schlüssels, aber es ist eine Bedingung vorhanden, die eine Konstante für diesen Teil angibt:

    SELECT c1, c2, c3 FROM t1 WHERE c1 = 'a' GROUP BY c2, c3;
    

4.2.15. DISTINCT-Optimierung

DISTINCT kombiniert mit ORDER BY benötigt in vielen Fällen eine Temporärtabelle.

Weil DISTINCT unter Umständen GROUP BY verwendet, sollten Sie wissen, wie MySQL mit Spalten in ORDER BY- oder HAVING-Klauseln verfährt, die nicht Teil der gewählten Spalten sind. Siehe auch Abschnitt 7.12.3, „GROUP BY und HAVING mit verborgenen Spalten“.

In vielen Fällen kann eine DISTINCT-Klausel als Sonderfall von GROUP BY betrachtet werden. So sind beispielsweise die beiden folgenden Abfragen gleichwertig:

SELECT DISTINCT c1, c2, c3 FROM t1
WHERE c1 > const;
SELECT c1, c2, c3 FROM t1
WHERE c1 > const GROUP BY c1, c2, c3;

Aufgrund dieser Äquivalenz können die Optimierungen, die für GROUP BY-Abfragen verwendbar sind, auch auf Abfragen mit einer DISTINCT-Klausel angewendet werden. Insofern sollten Sie, um weitere Informationen zu Optimierungsmöglichkeiten bei DISTINCT-Abfragen zu erhalten, unter Abschnitt 4.2.14, „GROUP BY-Optimierung“, nachschlagen.

Wenn Sie LIMIT row_count mit DISTINCT kombinieren, beendet MySQL die Abfrage, sobald row_count eindeutige Datensätze gefunden wurden.

Wenn Sie nicht Spalten aus allen in einer Abfrage aufgeführten Tabellen verwenden, beendet MySQL das Scannen unbenutzter Tabellen, sobald die erste Übereinstimmung gefunden wurde. Im folgenden Fall (in dem vorausgesetzt wird, dass t1 vor t2 benutzt wird, was mit EXPLAIN verifiziert werden kann) beendet MySQL das Auslesen von t2 für einen beliebigen Datensatz in t1, sobald der erste Datensatz in t2 gefunden wird:

SELECT DISTINCT t1.a FROM t1, t2 where t1.a=t2.a;

4.2.16. Optimieren der IN/=ANY-Unterabfragen

Gewisse Optimierungen sind anwendbar auf Vergleiche, die den OperatorIN verwenden, um Unterabfrageergebnisse zu testen (oder die =ANY verwenden, was gleichwertig ist). Dieser Abschnitt diskutiert diese Optimierungen, insbesondere hinsichtlich der Herausforderungen, die NULL-Werte darstellen. Vorschläge, was Sie ausführen können, um dem Optimierer zu helfen, werden am Ende der Diskussion gegeben.

Betrachten Sie den folgenden Unterabfragevergleich:

outer_expr IN (SELECT inner_expr FROM ... WHERE subquery_where)

MySQL wertet Abfragen „von außerhalb nach innen“ aus. Das heißt, es erlangt zuerst den Wert des äußeren Ausdrucks outer_expr und führt dann die Unterabfrage aus und erfasst die davon erzeugten Datensätze.

Eine sehr nützliche Optimierung ist, die Unterabfrage zu „informieren“, dass nur diejenigen Datenssätze von Interesse sind, bei denen der innere Ausdruck inner_expr gleich outer_expr ist. Das erfolgt duch Pushdown der entsprechenden Gleichheit in die WHERE-Klausel der Unterabfrage. Das heißt, der Vergleich so umgewandelt:

EXISTS (SELECT 1 FROM ... WHERE subquery_where AND outer_expr=inner_expr)

Nach der Umwandlung kann MySQL die Pushed-Down-Gleichheit verwenden, um die Anzahl der Datensätze zu beschränken, die es bei der Auswertung der Unterabfrage prüfen muss.

Im Allgemeinen unterliegt ein Vergleich von N Werten mit einer Unterabfrage, die N-wertige Datensätze zurückgibt, der gleichen Umwandlung. Wenn oe_i und ie_i die entsprechenden äußeren und inneren Ausdruckswerte darstellen, wird dieser Unterabfragevergleich:

(oe_1, ..., oe_N) IN
  (SELECT ie_1, ..., ie_N FROM ... WHERE subquery_where)

zu:

EXISTS (SELECT 1 FROM ... WHERE subquery_where
                          AND oe_1 = ie_1
                          AND ...
                          AND oe_N = ie_N)

Die folgende Diskussion nimmt zur Vereinfachung ein einzelnes Paar äußerer und innener Ausdruckswerte an.

Die gerade beschriebene Umwandlung hat ihre Beschränkungen. Sie ist nur gültig, wenn wir mögliche NULL-Werte ignorieren. Das heißt, die „Pushdown“-Strategie funktioniert, solange diese beiden Bedingungen wahr sind:

  • outer_expr und inner_expr dürfen nicht NULL sein.

  • Sie brauchen die Unterabfrageergebnisse NULL und FALSEnicht zu unterscheiden. (Wenn die Unterabfrage ein Teil eines OR- oder AND-Ausdrucks in der WHERE-Klausel ist, nimmt MySQL an, dass es Ihnen egal ist.)

Gilt mindestens eine der beiden Bedingungen nicht, ist die Optimierung komplexer.

Angenommen, es ist bekannt, dass outer_expr ein Nicht-NULL-Wert ist, aber die Unterabfrage erzeugt keinen Datensatz mit outer_expr = inner_expr. Dann liefert outer_expr IN (SELECT...) folgendes:

  • NULL, wenn SELECT einen Datensatz erzeugt, bei dem inner_expr NULL ist.

  • FALSE, wenn SELECT nur Nicht-NULL-Werte oder nichts produziert.

In dieser Situation ist der Ansatz, Datensätze mit outer_expr = inner_expr zu suchen, nicht mehr zulässig. Es ist notwendig, solche Datensätze zu suchen, werden aber keine gefunden, sind auch Datensätze zu suchen, bei denen inner_expr NULL ist. Grob gesagt kann in die Unterabfrage umgewandelt werden in:

EXISTS (SELECT 1 FROM ... WHERE subquery_where AND
        (outer_expr=inner_expr OR inner_expr IS NULL))

Der Bedarf, die zusätzliche IS-NULL-Bedingung auszuwerten, ist der Grund, warum MySQL die ref_or_null-Zugriffsmethode hat:

mysql> EXPLAIN
    -> SELECT outer_expr IN (SELECT t2.maybe_null_key
    ->                       FROM t2, t3 WHERE ...)
    -> FROM t1;
*************************** 1. row ***************************
           id: 1
  select_type: PRIMARY
        table: t1
...
*************************** 2. row ***************************
           id: 2
  select_type: DEPENDENT SUBQUERY
        table: t2
         type: ref_or_null
possible_keys: maybe_null_key
          key: maybe_null_key
      key_len: 5
          ref: func
         rows: 2
        Extra: Using where; Using index
...

Die unterabfragespezifischen Zugriffsmethoden unique_subquery und index_subquery haben auch or-null-Varianten. Allerdings sind sie in derEXPLAIN-Ausgabe nicht sichtbar, daher müssen Sie EXPLAIN EXTENDED gefolgt von SHOW WARNINGS verwenden (beachten Sie das checking NULL in der Warnmeldung):

mysql> EXPLAIN EXTENDED
    -> SELECT outer_expr IN (SELECT maybe_null_key FROM t2) FROM t1\G
*************************** 1. row ***************************
           id: 1
  select_type: PRIMARY
        table: t1
...
*************************** 2. row ***************************
           id: 2
  select_type: DEPENDENT SUBQUERY
        table: t2
         type: index_subquery
possible_keys: maybe_null_key
          key: maybe_null_key
      key_len: 5
          ref: func
         rows: 2
        Extra: Using index
mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
  Level: Note
   Code: 1003
Message: select (`test`.`t1`.`outer_expr`,
         (((`test`.`t1`.`outer_expr`) in t2 on
         maybe_null_key checking NULL))) AS `outer_expr IN (SELECT
         maybe_null_key FROM t2)` from `test`.`t1`

Die zusätzliche OR... IS-NULL-Bedingung macht den Abfrageablauf ein bisschen komplizierter (und einige Optimierungen innerhalb der Unterabfrage werden ungültig), aber im Allgemeinen ist dies erträglich.

Die Situation ist viel schlechter, wenn outer_expr NULL sein kann. Entsprechend der SQL-Interpretation von NULL als „unbekannter Wert“ sollte NULL-IN (SELECT inner_expr...) folgendes liefern:

  • NULL, wenn SELECT Datensätze erzeugt

  • FALSE, wenn SELECT keine Datensätze erzeugt

Für die richtige Auswertung ist es notwendig, überprüfen zu können, ob SELECT überhaupt Datensätze erzeugt hat, damit kann outer_expr = inner_expr nicht in die Unterabfrage heruntergedrückt werden. Dies ist ein Problem, weil viele Unterabfragen aus der realen Welt sehr langsam werden, außer wenn die Gleichheit heruntergedrückt werden kann.

Grundsätzlich muss es unterschiedliche Weisen geben, die Unterabfrage je nach dem Wert von outer_expr auszuführen. In MySQL-5.1 vor 5.1.16 bevorzugte der Optimierer Geschwindigkeit vor der Unterscheidung der Ergebnisse NULL und FALSE, daher könnten Sie bei einigen Abfragen ein Ergebnis FALSE statt NULL erhalten.

Ab MySQL 5.1.16 bevorzugt der Optimierer SQL-Kompatibilität vor Geschwindigkeit und berücksichtigt damit die Möglichkeit, dass outer_expr NULL sein könnte.

Wenn outer_expr NULL ist, muss SELECT ausgeführt werden, um festzustellen, ob Datensätze erzeugt werden:

NULL IN (SELECT inner_expr FROM ... WHERE subquery_where)

Es ist notwendig, hier das ursprüngliche SELECT ohne Pushed-Down-Gleichheit der früher erwähnten Art auszuführen.

Wenn outer_expr nicht NULL ist, muss dieser Vergleich unbedingt:

outer_expr IN (SELECT inner_expr FROM ... WHERE subquery_where)

in diesen Ausdruck konvertiert werden, der eine Pushed-Down-Bedingung verwendet:

EXISTS (SELECT 1 FROM ... WHERE subquery_where AND outer_expr=inner_expr)

Ohne diese Konvertierung werden Unterabfragen langsam sein. Um das Dilemma davon zu lösen, ob Bedingungen in die Unterabfrage heruntergedrückt werden oder nicht, werden die Bedingungen in „Trigger“-Funktionen eingepackt. Damit wird ein Ausdruck von der folgenden Form:

outer_expr IN (SELECT inner_expr FROM ... WHERE subquery_where)

konvertiert in:

EXISTS (SELECT 1 FROM ... WHERE subquery_where
                          AND trigcond(outer_expr=inner_expr))

Beruht der Unterabfragevergleich auf mehreren Paaren äußerer und innener Ausdrücke, nimmt die Konvertierung diesen Vergleich:

(oe_1, ..., oe_N) IN (SELECT ie_1, ..., ie_N FROM ... WHERE subquery_where)

und konvertiert ihn in diesen Ausdruck:

EXISTS (SELECT 1 FROM ... WHERE subquery_where
                          AND trigcond(oe_1=ie_1)
                          AND ...
                          AND trigcond(oe_N=ie_N)
       )

Jedes trigcond(X) ist eine Sonderfunktion, die folgende Werten ausgibt:

  • X, wenn der „verbundene“ äußere Ausdruck oe_i nicht NULL ist

  • TRUE, wenn der „verbundene“ äußere Ausdruck oe_i NULL ist

Beachten Sie, dass Triggerfunktionen nicht Trigger der Art sind, die Sie mit CREATE TRIGGER anlegen.

Gleichungen, die in trigcond()-Funktionen eingepackt werden, sind keine erstklassigen Prädikate für den Abfrageoptimierer. Die meisten Optimierungen können keine Prädikate behandeln, die bei Abfrageausführungszeit ein- und ausgeschaltet werden können, daher nehmen sie an, dass ein trigcond(X) eine unbekannte Funktion ist und ignorieren sie. Im Augenblick können getriggerte Gleichungen von jenen Optimierungen verwendet werden:

  • Referenzoptimierungen: trigcond(X=Y [ORY IS-NULL]) können verwendet werden, die Tabellenzugriffe ref, eq_ref oder ref_or_null zu konstruieren.

  • Unterabfrageausführungs-Engines auf Indexsuchbasis: trigcond(X=Y) kann verwendet werden, um die Zugriffe unique_subquery oder index_subquery zu konstruieren.

  • Tabellenbedingungsgenerator: Wenn die Unterabfrage ein Join mehrerer Tabellen ist, wird die getriggerte Bedingung so bald wie möglich überprüft.

Wenn der Optimierer eine getriggerte Bedingung verwendet, um eine Art von indexsuchbasiertem Zugriff einzurichten (bezüglich der ersten beiden Positionen der vorangehenden Liste), muss er eine Rückfallstrategie für den Fall haben, dass die Bedingung ausgeschaltet ist. Diese Rückfallstrategie ist immer die gleiche: Einen vollen Tabellenscan ausführen. In der EXPLAIN-Ausgabe zeigt sich der Rückfall als Full scan on NULL key in der Spalte Extra:

mysql> EXPLAIN SELECT t1.col1,
    -> t1.col1 IN (SELECT t2.key1 FROM t2 WHERE t2.col2=t1.col2) FROM t1\G
*************************** 1. row ***************************
           id: 1
  select_type: PRIMARY
        table: t1
        ...
*************************** 2. row ***************************
           id: 2
  select_type: DEPENDENT SUBQUERY
        table: t2
         type: index_subquery
possible_keys: key1
          key: key1
      key_len: 5
          ref: func
         rows: 2
        Extra: Using where; Full scan on NULL key

Wenn Sie EXPLAIN EXTENDED gefolgt von SHOW WARNINGS ausführen, können Sie die getriggerte Bedingung sehen:

*************************** 1. row ***************************
  Level: Note
   Code: 1003
Message: select `test`.`t1`.`col1` AS `col1`,
         <in_optimizer>(`test`.`t1`.`col1`,
         <exists>(<index_lookup>(<cache>(`test`.`t1`.`col1`) in t2
         on key1 checking NULL
         where (`test`.`t2`.`col2` = `test`.`t1`.`col2`) having
         trigcond(<is_not_null_test>(`test`.`t2`.`key1`))))) AS
         `t1.col1 IN (select t2.key1 from t2 where t2.col2=t1.col2)`
         from `test`.`t1`

Die Verwendung von getriggerten Bedingungen hat einige Leistungsimplikationen. Ein Ausdruck NULL IN (SELECT ...) kann jetzt einen vollen Tabellenscan verursachen (der langsam ist), auch wenn es früher nicht tat. Dies ist der für richtige Ergebnisse zu zahlende Preis (das Ziel der Triggerbedingungsstrategie war, Kompatibilität und nicht Geschwindigkeit zu verbessern).

Für Mehrfachtabellenunterabfragen ist die Ausführung von NULL-IN (SELECT...) besonders langsam, weil der Join-Optimierer nicht für den Fall optimiert, bei dem der äußere Ausdruck NULL ist. Er nimmt an, dass Unterabfrageauswertungen mit NULLauf der linken Seite sehr selten sind, auch wenn die Statistik anderes zeigt. Wenn andererseits der äußere Ausdruck NULL sein könnte, aber eigentlich nie ist, gibt es keine Leistungsstrafe.

Um dem Abfrageoptimierer dabei zu helfen, besser Ihre Abfragen auszuführen, verwenden Sie diese Tipps:

  • Eine Spalte muss als NOT NULL deklariert werden, wenn sie es wirklich ist. (Dies hilft auch anderen Aspekten vom Optimierer.)

  • Wenn Sie die Unterabfrageergebnisse NULL und FALSE nicht unterscheiden müssen, können Sie leicht den langsamen Ausführungspfad meiden. Ersetzen Sie einen Vergleich ersetzen, der so aussieht:

    outer_expr IN (SELECT inner_expr FROM ...)
    

    durch diesem Ausdruck:

    (outer_expr IS NOT NULL) AND (outer_expr IN (SELECT inner_expr FROM ...))
    

    Dann wirdNULL-IN (SELECT...) niemals augewertet werden, weil MySQL aufhört, die AND-Teile auszuwerten, sobald das Ausdrucksergebnis klar ist.

4.2.17. LIMIT-Optimierung

In einigen Fällen behandelt MySQL eine Abfrage anders, wenn Sie LIMIT row_count und nicht HAVING verwenden:

  • Wenn Sie nur ein paar Datensätze mit LIMIT auswählen, benutzt MySQL in manchen Fällen Indizes, obwohl eigentlich ein vollständiger Tabellenscan zu bevorzugen wäre.

  • Wenn Sie LIMIT row_count mit ORDER BY benutzen, beendet MySQL die Sortierung, sobald die ersten row_count Datensätze des sortierten Ergebnisses gefunden wurden, statt das gesamte Ergebnis zu sortieren. Erfolgt die Sortierung mithilfe eines Indexes, dann ist sie sehr schnell. Ist eine Dateisortierung erforderlich, dann müssen alle Datensätze ausgewählt werden, die der Abfrage ohne LIMIT-Klausel entsprechen, und die meisten davon (oder alle) müssen sortiert werden, bevor sichergestellt ist, dass die ersten row_count Datensätze gefunden wurden. In jedem Fall ist es, wenn die ersten Datensätze gefunden wurden, nicht mehr notwendig, den Rest der Ergebnismenge zu sortieren, weswegen MySQL dies auch nicht tut.

  • Wenn Sie LIMIT row_count mit DISTINCT kombinieren, beendet MySQL die Abfrage, sobald row_count eindeutige Datensätze gefunden wurden.

  • In manchen Fällen kann eine GROUP BY-Klausel durch Lesen des Schlüssels in der Reihenfolge (oder Durchführung einer Sortierung für den Schlüssel) und nachfolgende Berechnung von Zusammenfassungen aufgelöst werden, bis der Schlüsselwert sich ändert. In diesem Fall berechnet LIMIT row_count keine unnötigen GROUP BY-Werte.

  • Sobald MySQL die erforderliche Anzahl von Datensätzen an den Client gesendet hat, bricht es die Abfrage ab, sofern Sie nicht SQL_CALC_FOUND_ROWS verwenden.

  • LIMIT 0 gibt schnell eine leere Menge zurück. Dies kann praktisch sein, um die Gültigkeit einer Abfrage zu überprüfen. Wenn Sie eines der MySQL-APIs verwenden, können Sie damit auch die Typen der Ergebnisspalten ermitteln. (Dieser Trick funktioniert nicht im MySQL-Monitor (dem mysql-Programm), der in vielen Fällen einfach Empty set anzeigt. Verwenden Sie für diesen Zweck statt dessen SHOW COLUMNS oder DESCRIBE.)

  • Wenn der Server Temporärtabellen zur Auflösung der Abfrage verwendet, dann berechnet er auf der Basis der LIMIT row_count-Klausel, wie viel Speicher erforderlich ist.

4.2.18. Den Optimierer mit optimizer_switch steuern

Die Systemvariableoptimizer_switch ermöglicht die Steuerung des Optimiererverhaltens.

Ab MySQL 5.1.34 ist der Wert der Systemvariablen optimizer_switch eine Menge von Flags, die jeweils den Wert on oder off haben, um zu zeigen, ob das entsprechende Optimiererverhalten aktiviert oder gesperrt ist. Diese Variable hat globale und Sitzungswerte und kann zur Ausführungszeit verändert werden. Die globale Voreinstellung kann bei Serverstart gesetzt werden.

Wählen Sie den Varibalenwert aus, um die gegenwärtige Menge von Optimiererflags zu sehen:

mysql> SELECT @@optimizer_switch\G
*************************** 1. row ***************************
@@optimizer_switch: index_merge=on,index_merge_union=on,
                    index_merge_sort_union=on,
                    index_merge_intersection=on

Um den Wert von optimizer_switch zu verändern, weisen Sie einen Wert zu, der aus einer kommagetrennten Liste eines oder mehrerer Befehle besteht:

SET [GLOBAL|SESSION] optimizer_switch='command[,command]...';

Jeder Befehlswert sollte eine der Formen aus der folgenden Tabelle haben.

BefehlssyntaxBedeutung
StandardwerteJede Optimierung auf ihren Standardwert zurücksetzen
opt_name=defaultDie benannte Optimierung auf ihren Standardwert zurücksetzen
opt_name=offDie benannte Optimierung deaktivieren
opt_name=onDie benannte Optimierung aktivieren

Die Reihenfolge der Befehle im Wert ist nicht wichtig, obwohl deefault zuerst ausgeführt wird, wenn er vorhanden ist. Ein bestimmter opt_name darf nicht mehr als einmal im Wert angegeben werden, denn das verursacht einen Fehler. Fehler im Wert bringen die ganze Anweisung mit einem Fehler zum Scheitern, und der aktuelle Wert von optimizer_switch bleibt unverändert.

Die folgende Tabelle listet die zulässigen opt_name-Flag-Namen auf.

Flag-NameBedeutung
index_mergeSteuert alle Index Merge-Optimierungen
index_merge_unionSteuert die Index Merge Union Access-Optimierung
index_merge_sort_unionSteuert die Index Merge Sort Union Access-Optimierung
index_merge_intersectionSteuert die Index Merge Intersection Access-Optimierung

Informationen über Index Merge erhalten Sie unter Abschnitt 4.2.6, „Index-Merge-Optimierung“.

Wenn Sie optimizer_switch einen Wert zuweisen, behalten Flags, die nicht erwähnt werden, ihre aktuellen Werte. Damit können Sie spezifische Optimiererverhalten in einer einzelnen Anweisung aktivieren oder deaktivieren, ohne andere Verhaltensweise zu beeinflussen. Die Anweisung hängt nicht davon ab, welche anderen Optimizerflags existieren und was ihre Werte sind. Angenommen alle Index Merge-Optimierungen werden aktiviert:

mysql> SELECT @@optimizer_switch\G
*************************** 1. row ***************************
@@optimizer_switch: index_merge=on,index_merge_union=on,
                    index_merge_sort_union=on,
                    index_merge_intersection=on
1 row in set (0.00 sec)

Wenn der Server die Zugriffsmethoden Index Merge Union oder Index Merge Sort Union für bestimmte Abfragen verwendet und Sie überprüfen wollen, ob der Optimierer besser ohne sie funktioniert, setzen Sie den Variablenwert so:

mysql> SET optimizer_switch='index_merge_union=off,index_merge_sort_union=off';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @@optimizer_switch\G
*************************** 1. row ***************************
@@optimizer_switch: index_merge=on,index_merge_union=off,
                    index_merge_sort_union=off,
                    index_merge_intersection=on
1 row in set (0.00 sec)

4.2.19. So vermeiden Sie Tabellenscans

Die Ausgabe von EXPLAIN führt ALL in der Spalte type, wenn MySQL einen Tabellenscan verwendet, um eine Abfrage zu lösen. Dies geschieht in der Regel unter den folgenden Bedingungen:

  • Die Tabelle ist so klein, dass ein Tabellenscan schneller ist als eine Schlüsselsuche. Dies betrifft in erster Linie Tabellen mit weniger als zehn Datensätzen und geringer Datensatzlänge.

  • In der ON- oder WHERE-Klausel für indizierte Spalten sind keine verwendbaren Einschränkungen vorhanden.

  • Sie vergleichen indizierte Spalten mit Konstantenwerten, und MySQL hat (basierend auf dem Indexbaum) berechnet, dass die Konstanten einen zu großen Teil der Tabelle abdecken und ein Tabellenscan schneller ginge. Siehe auch Abschnitt 4.2.4, „WHERE-Klausel-Optimierung“.

  • Sie verwenden einen Schlüssel mit niedriger Kardinalität (d. h., viele Datensätze entsprechen dem Schlüsselwert) über eine andere Spalte. In diesem Fall geht MySQL davon aus, dass die Verwendung des Schlüssels viele Suchvorgänge nach sich ziehen würde und ein Tabellenscan schneller ginge.

Bei kleinen Tabellen ist ein Tabellenscan oft die passende Lösung. Die Auswirkungen auf die Leistung sind vernachlässigbar. Bei großen Tabellen sollten Sie die folgenden Methoden ausprobieren, damit der Optimierer sich nicht fälschlicherweise für einen Tabellenscan entscheidet:

  • Mit ANALYZE TABLE tbl_name können Sie die Schlüsselverteilungen für die gescannte Tabelle aktualisieren. Siehe auch Abschnitt 8.5.2.1, „ANALYZE TABLE-Syntax“.

  • Verwenden Sie FORCE INDEX für die gescannte Tabelle, um MySQL mitzuteilen, dass Tabellenscans im Vergleich zur Verwendung des angegebenen Indexes sehr kostspielig sind:

    SELECT * FROM t1, t2 FORCE INDEX (index_for_column)
      WHERE t1.col_name=t2.col_name;
    

    Siehe auch Abschnitt 8.2.8.2, „Indexhinweissyntax“.

  • Starten Sie mysqld mit der Option --max-seeks-for-key=1000, oder weisen Sie den Optimierer mit SET max_seeks_for_key=1000 an, vorauszusetzen, dass kein Schlüsselscan mehr als 1000 Schlüsselsuchvorgänge auslösen wird. Siehe auch Server System Variables.

4.2.20. INFORMATION_SCHEMA-Optimierung

Ab MySQL 5.1.23 ist die Implementierung von INFORMATION_SCHEMA so, dass bestimmte Arten von Abfragen für INFORMATION_SCHEMA-Tabellen optimiert werden können, damit sie schneller ausgeführt werden. Dieser Abschnitt liefert eine Anleitung für das Schreiben von Abfragen, die diese Optimierungen ausnutzen. Im Allgemeinen minimieren die hier umrissenen Strategien den Bedarf des Servers, auf das Dateisystem zuzugreifen, um die Information zu erhalten, die den Inhalt der INFORMATION_SCHEMA-Tabellen bilden. Durch das Schreiben von Abfragen, die es dem Server ermöglichen, Verzeichnisscans oder das Öffnen von Tabellendateien zu vermeiden, werden Sie bessere Leistung erhalten.

1) Versuchen Sie, konstante Nachschlagewerte für Datenbank und Tabellennamen in der WHERE-Klausel zu verwenden

Sie können dieses Prinzip folgendermaßen nutzen:

  • Um Datenbanken oder Tabellen nachzuschlagen, verwenden Sie Ausdrücke, die eine Konstante ausgeben, z. B. Literalwerte, Funktionen, die eine Konstante zurückgeben, oder skalare Unterabfragen.

  • Vermeiden Sie Abfragen, die einen nichtkonstanten Datenbanknamensnachschlagewert (oder keinen nachschlagewert) verwenden, weil diese einen Scan des Datenverzeichnisses benötigen, um passende Datenbankverzeichnisnamen zu finden.

  • Vermeiden Sie innerhalb einer Datenbank Abfragen, die einen nichtkonstanten Tabellennamensnachhschlagewert (oder keinen nachschlagewert) verwenden, weil sie einen Scan vom Datenbankverzeichnis benötigen, um passende Tabellendateien zu finden.

Dieses Prinzip gilt für die INFORMATION_SCHEMA-Tabellen, die in der folgenden Tabelle gezeigt werden, die jene Spalten zeigt, für die ein konstanter Nachschlagewert es dem Server ermöglicht, einen Verzeichnisscan zu vermeiden. Wenn Sie zum Beispiel aus TABLES selektieren, ermöglicht die Verwendung eines konstanten Nachschlagewerts für TABLE_SCHEMA in der WHERE-Klausel die Vermeidung eines Datenverzeichnisscans.

TabelleAnzugebende Spalte, um einen Datenverzeichnisscan zu vermeidenAnzugebende Spalte, um eine Datenbankverzeichnisscan zu vermeiden
COLUMNSTABLE_SCHEMATABLE_NAME
KEY_COLUMN_USAGETABLE_SCHEMATABLE_NAME
PARTITIONSTABLE_SCHEMATABLE_NAME
REFERENTIAL_CONSTRAINTSCONSTRAINT_SCHEMATABLE_NAME
STATISTICSTABLE_SCHEMATABLE_NAME
TABLESTABLE_SCHEMATABLE_NAME
TABLE_CONSTRAINTSTABLE_SCHEMATABLE_NAME
TRIGGERSEVENT_OBJECT_SCHEMAEVENT_OBJECT_TABLE
VIEWSTABLE_SCHEMATABLE_NAME

Der Vorteil einer auf einen spezifischen konstanten Datenbanknamen beschränkten Abfrage ist, dass Überprüfungen nur auf das genannte Datenbankverzeichnis ausgeführt werden müssen. Beispiel:

SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'test';

Die Verwendung des Literaldatenbanknamens test ermöglicht es dem Server, nur das Datenbankverzeichnis test zu überprüfen, ungeachtet wie viele Datenbanken es geben könnte. Im Gegensatz dazu ist die folgende Abfrage weniger effizient, weil sie einen Scan vom Datenverzeichnis benötigt, um zu entscheiden, welche Datenbanknamen zum Muster 'test%' passen:

SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA LIKE 'test%';

Bei einer Abfrage, die auf einen spezifischen konstanten Tabellennamen beschränkt ist, müssen Überprüfungen nur auf der genannten Tabelle innerhalb des entsprechenden Datenbankverzeichnisses ausgeführt werden. Beispiel:

SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME = 't1';

Die Verwendung des Literaldatenbanknamens t1 ermöglicht es dem Server, nur die Dateien für die Tabelle t1 zu überprüfen, ungeachtet wie viele Tabellen in der Datenbank test vorhanden sein könnten. Im Gegensatz dazu benötigt die folgende Abfrage einen Scan des Datenbankverzeichnisses test um zu entscheiden, welche Tabellennamen zum Muster 't%'passen:

SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME LIKE 't%';

Die folgende Abfrage benötigt einen Scan des Datenbankverzeichnisses, um übereinstimmende Datenbanknamen für das Muster 'test%' zu bestimmen, und für jede übereinstimmende Datenbank benötigt es einen Scan vom Datenbankverzeichnis, um passende Tabellennamen für das Muster 't%' zu bestimmen:

SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'test%' AND TABLE_NAME LIKE 't%';

2) Schreiben Sie Abfragen, die die Anzahl der zu öffnenden Tabellendateien minimieren

Für Abfragen, die sich auf bestimmte INFORMATION_SCHEMA-Tabellenspalten beziehen, sind einige Optimierungen verfügbar, die die Anzahl der zu öffnenden Tabellendateien minimieren. Beispiel:

SELECT TABLE_NAME, ENGINE FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'test';

In diesem Fall werden, nachdem der Server das Datenbankverzeichnis gescannt hat, um die Namen der Tabellen in der Datenbank zu bestimmen, diese Namen ohne weiteres Nachschlagen im Dateisystem verfügbar. Damit braucht TABLE_NAME keine Dateien zu öffnen. Der Wert ENGINE (Speicher-Engine) kann durch das Öffnen der frm-Datei der Tabelle bestimmt werden, ohne dass andere Tabellendateien wie die .MYD- oder .MYI-Datei angefasst werden müssen.

Für einige Werte, z. B. INDEX_LENGTH für MyISAM-Tabellen, muss auch die .MYD- oder .MYI-Datei geöffnet werden.

Die Dateiöffnungoptimierungsarten werden so angegegben:

  • SKIP_OPEN_TABLE: Tabellendateien müssen nicht geöffnet werden. Die Informationen sind schon durch das Scannen des Datenbankverzeichnisses innerhalb der Abfrage verfügbar geworden.

  • OPEN_FRM_ONLY: Nur die . frm-Datei der Tabelle muss geöffnet werden.

  • OPEN_TRIGGER_ONLY: Nur die .TRG-Datei der Tabelle muss geöffnet werden.

  • OPEN_FULL_TABLE: Das nicht optimierte Informationsnachschlagen. Es müssen die .frm-, .MYD- und .MYI-Dateien geöffnet werden.

Die folgende Liste zeigt, wie die vorstehenden Optimierungstypen für dieINFORMATION_SCHEMA-Tabellenspalten gelten. Für nicht benannte Tabellen und Spalten gilt keine Optimierung.

  • COLUMNS: OPEN_FRM_ONLY gilt für alle Spalten

  • KEY_COLUMN_USAGE: OPEN_FULL_TABLE gilt für alle Spalten

  • PARTITIONS: OPEN_FULL_TABLE gilt für alle Spalten

  • REFERENTIAL_CONSTRAINTS: OPEN_FULL_TABLE gilt für alle Spalten

  • STATISTICS:

    SpalteOptimierungstyp
    TABLE_CATALOGOPEN_FRM_ONLY
    TABLE_SCHEMAOPEN_FRM_ONLY
    TABLE_NAMEOPEN_FRM_ONLY
    NON_UNIQUEOPEN_FRM_ONLY
    INDEX_SCHEMAOPEN_FRM_ONLY
    INDEX_NAMEOPEN_FRM_ONLY
    SEQ_IN_INDEXOPEN_FRM_ONLY
    COLUMN_NAMEOPEN_FRM_ONLY
    COLLATIONOPEN_FRM_ONLY
    CARDINALITYOPEN_FULL_TABLE
    SUB_PARTOPEN_FRM_ONLY
    PACKEDOPEN_FRM_ONLY
    NULLABLEOPEN_FRM_ONLY
    INDEX_TYPEOPEN_FULL_TABLE
    COMMENTOPEN_FRM_ONLY
  • TABLES:

    SpalteOptimierungstyp
    TABLE_CATALOGSKIP_OPEN_TABLE
    TABLE_SCHEMASKIP_OPEN_TABLE
    TABLE_NAMESKIP_OPEN_TABLE
    TABLE_TYPEOPEN_FRM_ONLY
    ENGINEOPEN_FRM_ONLY
    VERSIONOPEN_FRM_ONLY
    ROW_FORMATOPEN_FULL_TABLE
    TABLE_ROWSOPEN_FULL_TABLE
    AVG_ROW_LENGTHOPEN_FULL_TABLE
    DATA_LENGTHOPEN_FULL_TABLE
    MAX_DATA_LENGTHOPEN_FULL_TABLE
    INDEX_LENGTHOPEN_FULL_TABLE
    DATA_FREEOPEN_FULL_TABLE
    AUTO_INCREMENTOPEN_FULL_TABLE
    CREATE_TIMEOPEN_FULL_TABLE
    UPDATE_TIMEOPEN_FULL_TABLE
    CHECK_TIMEOPEN_FULL_TABLE
    TABLE_COLLATIONOPEN_FRM_ONLY
    CHECKSUMOPEN_FULL_TABLE
    CREATE_OPTIONSOPEN_FRM_ONLY
    TABLE_COMMENTOPEN_FRM_ONLY
  • TABLE_CONSTRAINTS: OPEN_FULL_TABLE gilt für alle Spalten

  • TRIGGERS: OPEN_FULL_TABLE gilt für alle Spalten

  • VIEWS:

    SpalteOptimierungstyp
    TABLE_CATALOGOPEN_FRM_ONLY
    TABLE_SCHEMAOPEN_FRM_ONLY
    TABLE_NAMEOPEN_FRM_ONLY
    VIEW_DEFINITIONOPEN_FULL_TABLE
    CHECK_OPTIONOPEN_FULL_TABLE
    IS_UPDATABLEOPEN_FULL_TABLE
    DEFINEROPEN_FULL_TABLE
    SECURITY_TYPEOPEN_FULL_TABLE
    CHARACTER_SET_CLIENTOPEN_FULL_TABLE
    COLLATION_CONNECTIONOPEN_FULL_TABLE

3) Verwenden Sie EXPLAIN, um zu entscheiden, ob der Server INFORMATION_SCHEMA-Optimierungen für eine Abfrage verwenden kann

Der Extra-Wert in der EXPLAIN-Ausgabe zeigt an, welche der oben genannten Optimierungen der Server verwenden kann, um die INFORMATION_SCHEMA-Abfragen auszuwerten. Die folgenden Beispiele demonstrieren die Arten von Informationen, die Sie im Extra-Wert sehen können.

mysql> EXPLAIN SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS WHERE
    -> TABLE_SCHEMA = 'test' AND TABLE_NAME = 'v1'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: VIEWS
         type: ALL
possible_keys: NULL
          key: TABLE_SCHEMA,TABLE_NAME
      key_len: NULL
          ref: NULL
         rows: NULL
        Extra: Using where; Open_frm_only; Scanned 0 databases

Die Verwendung von konstanten Datenbank- und Tabellennachschlagewerten ermöglicht es dem Server, Verzeichnisscans zu vermeiden. Für Verweise auf VIEWS.TABLE_NAME braucht nur die .frm-Datei geöffnet zu werden.

mysql> EXPLAIN SELECT TABLE_NAME, ROW_FORMAT FROM INFORMATION_SCHEMA.TABLES\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: TABLES
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: NULL
        Extra: Open_full_table; Scanned all databases

Es werden keine Nachschlagewerte geliefert (es gibt keine WHERE-Klausel), daher muss der Server das Datenverzeichnis und jedes Datenbankverzeichnis scannen. Für jede damit identifizierte Tabelle, werden der Tabellenname und Zeilenformat selektiert. TABLE_NAME erfordert nicht, dass nicht weitere Tabellendateien geöffnet werden (es gilt die SKIP_OPEN_TABLE-Optimierung). ROW_FORMAT erfordert, dass alle Tabellendateien geöffnet werden (OPEN_FULL_TABLE gilt). EXPLAIN meldet OPEN_FULL_TABLE, weil es aufwendiger ist als SKIP_OPEN_TABLE.

mysql> EXPLAIN SELECT TABLE_NAME, TABLE_TYPE FROM INFORMATION_SCHEMA.TABLES
    -> WHERE TABLE_SCHEMA = 'test'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: TABLES
         type: ALL
possible_keys: NULL
          key: TABLE_SCHEMA
      key_len: NULL
          ref: NULL
         rows: NULL
        Extra: Using where; Open_frm_only; Scanned 1 database

Es wird kein Tabellennachschlagewert geliefert, daher muss der Server das Datenbankverzeichnis test scannen. Für die TABLE_NAME- und TABLE_TYPE-Spalten gelten jeweils die Optimierungen SKIP_OPEN_TABLE und OPEN_FRM_ONLY. EXPLAIN meldet OPEN_FRM_ONLY, weil es aufwendiger ist.

mysql> EXPLAIN SELECT B.TABLE_NAME
    -> FROM INFORMATION_SCHEMA.TABLES AS A, INFORMATION_SCHEMA.COLUMNS AS B
    -> WHERE A.TABLE_SCHEMA = 'test'
    -> AND A.TABLE_NAME = 't1'
    -> AND B.TABLE_NAME = A.TABLE_NAME\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: A
         type: ALL
possible_keys: NULL
          key: TABLE_SCHEMA,TABLE_NAME
      key_len: NULL
          ref: NULL
         rows: NULL
        Extra: Using where; Skip_open_table; Scanned 0 databases
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: B
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: NULL
        Extra: Using where; Open_frm_only; Scanned all databases;
               Using join buffer

Für die erste EXPLAIN-Ausgabezeile: Konstante Datenbank- und Tabellennachschlagewerte ermöglichen es dem Server, Verzeichnisscans für TABLES-Werte zu vermeiden. Verweise auf TABLES.TABLE_NAME benötigen keine weiteren Tabellendateien.

Für die zweite EXPLAIN-Ausgabezeile: Alle COLUMNS-Tabellenwerte sind OPEN_FRM_ONLY-Anfragen, daher benötigt COLUMNS.TABLE_NAME das Öffnen der .frm-Datei.

mysql> EXPLAIN SELECT * FROM INFORMATION_SCHEMA.COLLATIONS\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: COLLATIONS
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: NULL
        Extra:

In diesem Fall gelten keine Optimierungen, weil COLLATIONS nicht eine der INFORMATION_SCHEMA-Tabellen ist, für die Optimierungen verfügbar sind.

4.2.21. Geschwindigkeit von INSERT-Anweisungen

Die Zeit, die für das Einfügen eines Datensatzes erforderlich ist, wird von den folgenden Faktoren bestimmt (hierbei geben die Zahlen in den Klammern näherungsweise den Anteil an):

  • Verbinden: (3)

  • Abfrage an Server schicken: (2)

  • Abfrage analysieren: (2)

  • Zeile einfügem: (1 × Zeilengröße)

  • Indizes einfügen: (1 × Indexanzahl)

  • Schließen: (1)

Hierbei wird der Mehraufwand für das Öffnen von Tabellen nicht berücksichtigt (dies ist einmal je nebenläufiger Abfrageausführung erforderlich).

Die Größe der Tabelle verlangsamt das Einfügen von Indizes um den Faktor LogN (für B-Tree-Indizes).

Sie können Einfügeoperationen mit den folgenden Methoden beschleunigen:

  • Wenn Sie gleichzeitig viele Zeilen vom gleichen Clienteneinfügen, verwenden SieINSERT-Anweisungen mit mehrfachen VALUES-Listen, um gleichzeitig mehrere Zeilen einzufügen. Dies ist erheblich schneller (in manchen Fällen sogar um mehrere Größenordnungen) als die Verwendung separater INSERT-Anweisungen für je einen Datensatz. Wenn Sie zu einer Tabelle, die nicht leer ist, Daten hinzufügen, dann können Sie die Variable bulk_insert_buffer_size optimieren, um das Einfügen noch mehr zu beschleunigen. Siehe auch Server System Variables.

  • Wenn mehrere Clienten viele Zeilen einfügen, können Sie eine höhere Geschwindigkeit durch Verwendung der Anweisung INSERT-DELAYED erhalten. Siehe auch Abschnitt 8.2.5.2, „INSERT DELAYED.

  • Bei einer MyISAM-Tabelle können Sie gleichzeitige Einfügeoperationen verwenden, um Zeilen gleichzeitig mit der Ausführung der SELECT-Anweisungen hinzuzufügen, wenn es keine gelöschten Zeilen in der Mitte der Datendatei gibt. Siehe auch Abschnitt 4.3.3, „Gleichzeitige Einfügeoperationen“.

  • Wenn Sie eine Tabelle aus einer Textdatei laden, verwenden Sie LOAD DATA INFILE. Dies ist normalerweise 20-mal schneller als die Verwendung von INSERT-Anweisungen. Siehe auch Abschnitt 8.2.6, „LOAD DATA INFILE.

  • Durch geringen Mehraufwand können Sie LOAD DATA INFILE für eine MyISAM-Tabelle noch schneller machen, wenn diese Tabelle viele Indizes enthält. Verwenden sie die folgende Prozedur:

    1. Erstellen Sie die Tabelle mit CREATE TABLE (optional).

    2. Führen Sie eine FLUSH TABLES-Anweisung oder den Befehl mysqladmin flush-tables aus.

    3. Verwenden Sie myisamchk --keys-used=0 -rq /path/to/db/tbl_name. Dies entfernt die gesamte Verwendung von Indizes für die Tabelle.

    4. Fügen Sie mit LOAD DATA INFILE Daten in die Tabelle ein. Hierbei werden keine Indizes aktualisiert - der Vorgang ist also sehr schnell.

    5. Wenn Sie zukünftig nur aus der Tabelle lesen wollen, komprimieren Sie sie mit myisampack. Siehe auch Compressed Table Characteristics.

    6. Erstellen Sie die Indizes mit myisamchk -rq /path/to/db/tbl_name neu. Hierdurch wird der Indexbaum zunächst im Speicher erstellt, bevor er auf die Festplatte geschrieben wird. Dies ist viel schneller als die Aktualisierung des Indexes im Zuge von LOAD DATA INFILE, da zahlreiche Suchvorgänge auf der Festplatte entfallen. Außerdem ist der resultierende Indexbaum einwandfrei verteilt.

    7. Führen Sie eine FLUSH TABLES-Anweisung oder den Befehl mysqladmin flush-tables aus.

    LOAD DATA INFILE führt die vorangehende Optimierung automatisch aus, wenn die MyISAM-Tabelle, in die Sie Daten einfügen, leer ist. Der Hauptunterschied zwischen automatischer Optimierung und expliziter Verwendung der Prozedur ist, dass myisamchk viel mehr temporären Speicher für die Indexerstellung zuweist, als Sie den Server für die Indexwiedererstellung bei Ausführung der LOAD DATA INFILE-Anweisung zuweisen lassen möchten.

    Sie können die nicht eindeutigen Indizes für eine MyISAM-Tabelle ferner aktivieren oder deaktivieren, indem Sie statt myisamchk die folgenden Anweisungen verwenden. Bei Verwendung dieser Anweisungen können Sie die FLUSH TABLE-Operationen übergehen:

    ALTER TABLE tbl_name DISABLE KEYS;
    ALTER TABLE tbl_name ENABLE KEYS;
    
  • Um INSERT-Operationen zu beschleunigen, die mit mehreren Aweisungenen für nicht transaktionsfähige Tabellen ausgeführt werden, sperren Sie Ihre Tabellen:

    LOCK TABLES a WRITE;
    INSERT INTO a VALUES (1,23),(2,34),(4,33);
    INSERT INTO a VALUES (8,26),(6,29);
    ...
    UNLOCK TABLES;
    

    Hiervon profitiert die Leistungsfähigkeit, weil der Indexpuffer nur einmal auf die Festplatte synchronisiert wird, nachdem alle INSERT-Anweisungen abgeschlossen wurden. Im Normalfall gäbe es so viele Synchronisierungsvorgänge für Indexpuffer, wie INSERT-Anweisungen vorhanden sind. Explizite Sperranweisungen sind nicht erforderlich, wenn Sie alle Datensätze mit einer einzelnen INSERT-Anweisung einfügen können.

    Um schnellere Einfügungen für transaktionsfähige Tabellen zu erhalten, sollten Sie START TRANSACTION und COMMIT an Stelle von LOCK TABLES verwenden.

    Eine Sperrung verringert auch die Gesamtdauer für die Überprüfung mehrerer Verbindungen, auch wenn sich die Gesamtwartezeit für einzelne Verbindungen erhöhen kann, weil diese auf das Erwirken der Sperren warten. Angenommen, fünf Clients versuchen, gleichzeitig Einfügeoperationen folgendermaßen auszuführen:

    • Verbindung 1 führt 1.000 Einfügeoperationen durch.

    • Die Verbindungen 2, 3 und 4 fügen je eine Einfügeoperation durch.

    • Verbindung 5 führt 1.000 Einfügeoperationen durch

    Wenn Sie keine Sperren verwenden, sind Verbindungen 2, 3, und 4 vor 1 und 5 zu Ende. Wenn Sie Sperren verwenden, sind Verbindungen 2, 3, und 4 wahrscheinlich nicht vor 1 oder 5 zu Ende, aber die Gesamtdauer sollte etwa 40 % schneller sein.

    INSERT-, UPDATE- und DELETE-Operationen sind in MySQL sehr schnell, aber Sie können eine noch bessere Gesamtperformance erzielen, indem Sie Sperren für alles setzen, was mehr als fünf aufeinanderfolgende Einfüge- oder Änderungsoperationen umfasst. Wenn Sie sehr viele aufeinander folgende Einfügeoperationen ausführen, könnten Sie ein UNLOCK TABLES gefolgt von einem LOCK TABLES ab und zu mal ausführen (alle 1.000 Zeilen oder so), damit andere Threads auf die Tabelle zugreifen können. Dies bringt trotz allem einen ansehnlichen Leistungsgewinn.

    Auch wenn Sie die soeben beschriebenen Strategien verwenden, ist INSERT beim Laden von Daten allerdings nach wie vor wesentlich langsamer als LOAD DATA INFILE.

  • Um die Leistung bei MyISAM-Tabellen für LOAD DATA INFILE und INSERT gleichermaßen zu optimieren, vergrößern Sie den Schlüssel-Cache, indem Sie den Wert der Systemvariablen key_buffer_size erhöhen. Siehe auch Abschnitt 4.5.3, „Tuning der Server-Parameter“.

4.2.22. Geschwindigkeit von UPDATE-Anweisungen

Eine Änderungsanweisung wird wie eine SELECT-Abfrage optimiert, es kommt jedoch der zusätzliche Mehraufwand einer Schreiboperation hinzu. Die Geschwindigkeit der Schreiboperation hängt von der Menge der zu ändernden Daten und der Anzahl der zu aktualisierenden Indizes ab. Indizes, die nicht geändert werden, werden nicht aktualisiert.

Eine andere Möglichkeit, Updates zu beschleunigen, besteht darin, sie aufzuschieben und dann viele Updates direkt hintereinander durchzuführen. Wenn Sie die Tabelle sperren, ist die gemeinsame Durchführung vieler Änderungen wesentlich schneller, als wenn Sie immer nur ein Update zur selben Zeit durchführen.

Bei einer MyISAM-Tabelle, die das dynamische Datensatzformat verwendet, kann die Änderung eines Datensatzes auf eine höhere Gesamtlänge dazu führen, dass der Datensatz geteilt wird. Wenn Sie dies oft tun, dürfen Sie keinesfalls vergessen, gelegentlich OPTIMIZE TABLE abzusetzen. Siehe auch Abschnitt 8.5.2.5, „OPTIMIZE TABLE.

4.2.23. Geschwindigkeit von DELETE-Anweisungen

Die zum Löschen einzelner Datensätze erforderliche Zeit ist direkt proportional zur Anzahl der Indizes. Um Datensätze schneller zu löschen, können Sie den Wert des Schlüssel-Caches erhöhen, indem Sie die Systemvariable key_buffer_size entsprechend einstellen. Siehe auch Abschnitt 4.5.3, „Tuning der Server-Parameter“.

Wenn Sie alle Zeilen aus einer Tabelle löschen wollen, istTRUNCATE TABLE tbl_name schneller als DELETE FROM tbl_name. Leerungsoperationen sind nicht transaktionssicher: Wenn Sie eine solche Operation während einer aktiven Transaktion oder einer aktiven Tabellensperrung durchführen wollen, tritt ein Fehler auf. Siehe auch Abschnitt 8.2.10, „TRUNCATE-Syntax“.

4.2.24. Weitere Optimierungstipps

Dieser Abschnitt listet eine Anzahl verschiedener Tipps zur Verbesserung der Abfrageverarbeitungsgeschwindigkeit auf:

  • Verwenden Sie permanente Verbindungen zur Datenbank, um die zusätzliche Belastung durch das Herstellen und Abbauen von Verbindungen zu umgehen. Können Sie keine Permanentverbindungen verwenden und stellen Sie viele neue Verbindungen zur Datenbank her, dann sollten Sie den Wert der Variablen thread_cache_size ändern. Siehe auch Abschnitt 4.5.3, „Tuning der Server-Parameter“.

  • Überprüfen Sie immer, ob alle Ihre Abfragen wirklich die Indizes verwenden, die Sie in den Tabellen erstellt haben. In MySQL können Sie dies mit der EXPLAIN-Anweisung tun. Siehe auch Abschnitt 4.2.1, „Abfragen mit EXPLAIN optimieren“.

  • Versuchen Sie komplexe SELECT-Abfragen an häufig aktualisierte MyISAM-Tabellen zu umgehen, um Probleme in Verbindung mit der Tabellensperrung zu vermeiden, die aufgrund des konkurrierenden Zugriffs durch Leser und Schreiber entstehen.

  • MyISAM unterstützt gleichzeitige Einfügeoperationen: Wenn eine Tabelle keine freien Blöcke in der Mitte der Datendatei enthält, können Sie mit INSERT neue Datensätze einfügen, während andere Threads aus der Tabelle lesen. Wenn ein solches Verhalten wichtig ist, sollten Sie die Tabelle so verwenden, dass möglichst keine Datensätze gelöscht werden. Eine andere Möglichkeit besteht darin, die Tabelle mit OPTIMIZE TABLE zu defragmentieren, wenn Sie viele Datensätze gelöscht haben. Dieses Verhalten verändert sich durch das Setzen der Variablen concurrent_insert. Sie können erzwingen, dass neue Zeilen angehängt werden (und damit gleichzeitige Einfügeoperationen erlauben), sogar in Tabellen, die gelöschte Zeilen enthalten. Siehe auch Abschnitt 4.3.3, „Gleichzeitige Einfügeoperationen“.

  • Um Komprimierungsprobleme zu korrigieren, die beim Archivieren von Tabellen mit ARCHIVEaufgetreten sein können, verwenden Sie OPTIMIZE TABLE. Siehe auch The ARCHIVE Storage Engine.

  • Verwenden Sie ALTER TABLE ... ORDER BY expr1, expr2,... , wenn Sie Datensätze gewöhnlich in der Reihenfolge expr1, expr2, ... abrufen. Wenn Sie diese Option nach umfangreicheren Änderungen in der Tabelle verwenden, können Sie die Leistung unter Umständen steigern.

  • In manchen Fällen kann es sinnvoll sein, eine Spalte hinzuzufügen, die auf den Daten in anderen Spalten basierende „Hash-Werte“ enthält. Wenn diese Spalte kurz, ausreichend eindeutig und indiziert ist, kann dies wesentlich schneller sein als ein „breiter“ Index über viele Spalten. In MySQL ist die Verwendung dieser Zusatzspalte ganz einfach:

    SELECT * FROM tbl_name
      WHERE hash_col=MD5(CONCAT(col1,col2))
      AND col1='constant' AND col2='constant';
    
  • Bei MyISAM-Tabellen, die sich häufig verändern, sollten Sie die Verwendung von Spalten variabler Länge (VARCHAR, BLOB und TEXT) möglichst unterlassen. Die Tabelle verwendet das dynamische Datensatzformat, sobald auch nur eine einzige Spalte variabler Länge vorhanden ist. Siehe auch Storage Engines.

  • Es ist normalerweise nicht sinnvoll, eine Tabelle in mehrere getrennte Tabellen zu unterteilen, weil die Datensätze dann sehr groß werden. Beim Zugriff auf einen Datensatz besteht die größte Anforderung aus leistungstechnischer Sicht im Suchvorgang, der auf der Festplatte ausgeführt wird, um das erste Byte des Datensatzes zu finden. Wurde der Beginn der Daten gefunden, dann können die meisten modernen Festplatten den vollständigen Datensatz für die meisten Anwendungen ausreichend schnell lesen. Die einzigen Fälle, in denen das Aufteilen einer Tabelle einen nennenswerten Unterschied macht, liegen vor, wenn es sich um eine MyISAM-Tabelle handelt, die das dynamische Datensatzformat verwendet, welches Sie in eine feste Datensatzgröße umwandeln können, oder wenn Sie die Tabelle sehr häufig scannen müssen, die meisten Spalten aber nicht benötigen. Siehe auch Storage Engines.

  • Müssen Sie häufig Ergebnisse wie beispielsweise Summenwerte basierend auf Daten aus einer Vielzahl von Datensätzen berechnen, dann kann es praktisch sein, eine neue Tabelle einzurichten und den Zähler in Echtzeit zu aktualisieren. Eine Änderung der folgenden Form ist sehr schnell:

    UPDATE tbl_name SET count_col=count_col+1 WHERE key_col=constant;
    

    Dies ist sehr wichtig, wenn Sie MySQL-Speicher-Engines wie MyISAM verwenden, die nur Sperren auf Tabellenebene bieten (d. h. mehrere Leser bei einem Schreiber). Dies bietet auch bei den meisten anderen Datenbanksystemen eine bessere Performance, da der Datensatzsperrmanager in diesem Fall weniger zu tun hat.

  • Wenn Sie Statistiken aus großen Logtabellen ermitteln müssen, sollten Sie Zusammenfassungstabellen verwenden, statt die gesamte Logtabelle zu scannen. Die Zusammenfassungen aufrechtzuerhalten sollte viel schneller sein, als zu versuchen, die Statistik „in Echtzeit“ zu berechnen. Neue Zusammenfassungstabellen aus den Protokollen zu regenerieren, wenn Dinge sich ändern (je nach Geschäftsentscheidungen), ist schneller, als das laufende Programm zu verändern.

  • Sofern möglich, sollten Sie Berichte als „Echtzeitberichte“ oder als „statistische Berichte“ klassifizieren, wobei die für die statistischen Berichte erforderlichen Daten nur aus Zusammenfassungstabellen erzeugt werden, die ihrerseits in regelmäßigen Abständen aus den Echtzeitdaten erstellt werden.Nutzen Sie die Tatsache, dass Spalten Standardwerte haben.

  • Ziehen Sie Nutzen aus der tatsache, dass die Spalten Standardwerte haben. Fügen Sie Werte nur dann explizit ein, wenn sich der einzufügende Wert von der Vorgabe unterscheidet. Hierdurch verringern Sie die Analysearbeit für MySQL und erhöhen die Einfügegeschwindigkeit.

  • In manchen Fällen ist es sinnvoll, Daten zu packen und in einer BLOB-Spalte zu speichern. In diesem Fall muss Ihre Anwendung zwar Code zum Packen und Entpacken der Daten enthalten, aber Sie sparen sich auf einer gewissen Ebene viele Zugriffe. Dies ist praktisch, wenn Sie Daten haben, die sich nicht gut in die zeilen- und spaltenbasierte Struktur einer Tabelle einfügen lassen.

  • Normalerweise sollten Sie alle Daten nichtredundant halten. (Beachten Sie dabei die in der Datenbanktheorie so genannte Dritte Normalform.) Allerdings gibt es auch Situationen, in denen die Duplizierung von Daten oder die Erstellung zusammenfassender Tabellen zur Geschwindigkeitssteigerung beitragen können.

  • Bei einigen Aufgaben können etwa gespeicherte Routinen oder benutzerdefinierte Funktionen Optionen zur Optimierung der Leistung sein. Weitere Informationen finden Sie in Using Stored Routines (Procedures and Functions), und Adding New Functions to MySQL.

  • Sie können Leistung steigern, indem Sie Abfragen oder Antworten in Ihrem Programm zwischenspeichern und dann viele Einfügeoperationen oder Updates zusammen ausführen. Wenn Ihr Datenbanksystem Tabellensperren unterstützt, sollte dies helfen sicherzustellen, dass der Indexcache nach allen Updates nur einmal geleert wird. Sie können auch vom Abfrage-Cache von MySQL profitieren, um ähnliche Ergebnisse zu erhalten (siehe auch Abschnitt 4.5.5, „Der MySQL-Abfragen-Cache“).

  • Verwenden Sie INSERT DELAYED, wenn Sie nicht unbedingt wissen müssen, wann Ihre Daten geschrieben werden. Dies verringert die Gesamtauswirkungen von Einfügeoperationen, weil zahlreiche Datensätze im Zuge eines einzigen Schreibvorgangs auf die Festplatte geschrieben werden.

  • Verwenden Sie INSERT LOW_PRIORITY, wenn Sie SELECT-Anweisungen Vorrang vor den Einfügeoperationen gewähren wollen.

    Verwenden Sie SELECT HIGH_PRIORITY, um abgerufene Datensätze in der Warteschlange nach vorne zu setzen: In diesem Fall wird die SELECT-Anweisung auch ausgeführt, wenn ein anderer Client darauf wartet, schreiben zu können.

    LOW_PRIORITY und HIGH_PRIORITY haben eine Wirkung nur für Speicher-Engines, die nur Sperren auf Tabellenebene verwenden (MyISAM, MEMORY, MERGE).

  • Verwenden Sie INSERT-Anweisungen für mehrere Datensätze, um zahlreiche Daten mit einer SQL-Anweisung zu speichern. Dies wird von vielen SQL-Servern (einschließlich MySQL) unterstützt.

  • Laden Sie mit LOAD DATA INFILE große Datenmengen. Dies ist schneller als die Verwendung von INSERT-Anweisungen.

  • Verwenden SieAUTO_INCREMENT-Spalten, damit jeder Datensatz in einer Tabelle mit einem einzelnen, einduetigen Wert identifiziert werden kann. eindeutige Werte.

  • Verwenden Sie ab und zu OPTIMIZE TABLE, um die Fragmentierung bei MyISAM-Tabellen mit dynamischen Format zu vermeiden. Siehe auch MyISAM Table Storage Formats.

  • Verwenden Sie, sofern möglich, MEMORY-Tabellen, um die Geschwindigkeit zu erhöhen. Siehe auch The MEMORY Storage Engine. MEMORY-Tabellen sind für nichtkritische Daten nützlich, auf die häufig zugegriffen wird, also etwa Informationen zum zuletzt angezeigten Werbebanner für Benutzer, in deren Webbrowser Cookies nicht aktiviert sind. In vielen Webanwendungen stellen Benutzersitzungen eine andere Alternative für den Umgang mit flüchtigen Statusdaten dar.

  • Bei Webservern sollten Bilder und andere Binärressourcen normalerweise als Dateien gespeichert werden: In der Datenbank speichern Sie also statt der Datei selbst nur einen Verweis darauf. Die meisten Webserver können Dateien besser zwischenspeichern als Datenbankinhalte, weswegen die Verwendung von Dateien in der Regel schneller ist.

  • Spalten mit identischen Daten in verschiedenen Tabellen sollten mit identischen Datentypen deklariert werden, damit auf den entsprechenden Spalten basierende Joins beschleunigt werden.

  • Verwenden Sie möglichst einfache Spaltennamen. In einer Tabelle namens customer sollten Sie statt einer Spalte customer_name besser einfach den Spaltennamen name benutzen. Damit die Namen auf andere SQL-Server portierbar sind, sollten Sie sie stets kürzer als 18 Zeichen halten.

  • Wenn Geschwindigkeit für Sie ein absoluter Schlüsselaspekt ist, sollten Sie einen Blick auf maschinennahe Schnittstellen zur Datenspeicherung werfen, die von verschiedenen SQL-Servern unterstützt werden. Indem Sie beispielsweise direkt auf die MyISAM-Speicher-Engine von MySQL zugreifen, können Sie die Geschwindigkeit im Vergleich zur SQL-Schnittstelle um das Zwei- bis Fünffache erhöhen. Zu diesem Zweck müssen die Daten auf demselben Server wie die Anwendung liegen, und der Zugriff sollte möglichst nur von einem Prozess aus erfolgen (da die externe Dateisperrung wirklich langsam ist). Man könnte diese Probleme beseitigen, indem man maschinennahe MyISAM-Befehle am MySQL Server implementiert (dies wäre eine einfache Möglichkeit, bei Bedarf mehr Leistung herauszuholen). Durch sorgfältiges Design der Datenbankschnittstelle könnte es recht einfach sein, diesen Optimierungstyp zu unterstützen.

  • Wenn Sie numerische Daten verwenden, ist es in vielen Fällen schneller, auf Daten in einer Datenbank (über eine laufende Verbindung) statt in einer Textdatei zuzugreifen. Die Daten in der Datenbank sind wahrscheinlich in einem kompakteren Format gespeichert als in der Textdatei, weswegen beim Zugriff weniger Festplattenzugriffe auftreten. Außerdem können Sie Code in Ihrer Anwendung einsparen, denn Sie müssen die Textdateien nicht analysieren, um Zeilen- und Spaltenbegrenzungen zu finden.

  • Bei einigen Operationen kann die Replikation einen Leistungsgewinn bringen. Sie können die Abrufvorgänge durch die Clients auf mehrere Server verteilen, um einen Lastausgleich zu erzielen. Damit der Master bei der Erstellung von Backups nicht verlangsamt wird, können Sie Sicherungen mit einem Slave-Server erstellen. Siehe auch Replication.

  • Die Deklaration einer MyISAM-Tabelle mit der Tabellenoption DELAY_KEY_WRITE=1 beschleunigt Indexaktualisierungen, da diese erst auf Festplatte geschrieben werden, wenn die Tabelle geschlossen wird. Der Nachteil besteht darin, dass Sie, wenn der Server terminiert wird, während eine solche Tabelle geöffnet ist, sicherstellen müssen, dass die Tabelle unbeschädigt ist, indem Sie den Server mit der Option --myisam-recover ausführen oder myisamchk verwenden, bevor Sie den Server neu starten. (Allerdings sollten Sie auch in diesem Fall keine Daten verlieren, wenn Sie DELAY_KEY_WRITE verwenden, weil die Schlüsselinformationen sich immer aus den Datensätzen in der Datendatei ableiten lassen.)

4.3. Sperrprobleme

MySQL verwaltet Konkurrenzbetrieb für Tabelleninhalte mit Hilfe von Sperren:

  • Internes Sperren wird innerhalb des MySQL-Servers ausgeführt, um Konkurrenzbetrieb für Tabelleninhalte durch mehrere Threads zu verwalten. Diese Art von Sperren ist intern, weil es gänzlich vom Server ausgeführt wird und keine anderen Programme betrifft. Siehe auch Abschnitt 4.3.1, „Interne Sperrmethoden“.

  • Externe Sperrung tritt auf, wenn der Server und andere Programme Tabellendateien zur Koordination unter sich sperren, um festzulegen, welche Programme zu welcher Zeit auf die Tabellen zugreifen können. Siehe auch Abschnitt 4.3.4, „Externe Sperren“.

4.3.1. Interne Sperrmethoden

Dieser Abschnitt diskutiert internes Sperren, das heißt, Sperren innerhalb des MySQL-Servers, um Konkurrenzbetrieb für Tabelleninhalte von mehrerern Sitzungen zu verwalten. Diese Art von Sperren ist intern, weil es gänzlich vom Server ausgeführt wird und keine anderen Programme betrifft. Externe Sperrung tritt auf, wenn der Server und andere Programme Tabellendateien zur Koordination unter sich sperren, um festzulegen, welche Programme zu welcher Zeit auf die Tabellen zugreifen können. Siehe auch Abschnitt 4.3.4, „Externe Sperren“.

MySQL verwendet Sperren auf Tabellenebene für MyISAM-, MEMORY-, und MERGE-Tabellen, und Sperren auf Datensatzebene für InnoDB-Tabellen.

In vielen Fällen können Sie eine begründete Annahme dazu treffen, welcher Sperrungstyp der beste für eine Anwendung ist; generell ist es aber schwierig zu sagen, dass ein bestimmter Sperrungstyp besser ist als ein anderer. Alles hängt von der Anwendung ab, und verschiedene Teile einer Anwendung können unterschiedliche Sperrungstypen erfordern.

Um zu entscheiden, ob Sie eine Speicher-Engine mit Sperrung auf Datensatzebene verwenden sollten, müssen Sie einschätzen, was Ihre Anwendung tut und welche Mischung aus Auswahl- und Änderungsanweisungen sie verwendet. Die meisten Webanwendungen führen beispielsweise sehr viele Auswahloperationen, relativ wenig Löschvorgänge, vorzugsweise auf Schlüsselwerten basierende Änderungen und Einfügungen in nur ein paar bestimmte Tabellen durch. Die MyISAM-Basiskonfiguration von MySQL ist für solche Zwecke hervorragend geeignet.

Die Tabellensperrung in MySQL schließt ein Deadlock bei Speicher-Engines aus, die Sperren auf Tabellenebene verwenden. Die Deadlock-Vermeidung wird verwaltet, indem zu Anfang einer Abfrage immer alle erforderlichen Sperren auf einmal angefordert und die Tabellen immer in derselben Reihenfolge gesperrt werden.

MySQL gewährt Tabellenschreibsperren folgendermaßen:

  1. Wenn keine Sperre für die Tabelle vorhanden ist, wird eine Schreibsperre verhängt.

  2. Andernfalls wird die Sperranforderung in die Warteschlange für Schreibsperranforderungen gesetzt.

MySQL gewährt Tabellenlesesperren folgendermaßen:

  1. Wenn keine Schreibsperre für die Tabelle vorhanden ist, wird eine Lesesperre verhängt.

  2. Andernfalls wird die Sperranforderung in die Warteschlange für Lesesperranforderungen gesetzt.

Tabellenaktualisierungen werden höhere Priorität als Tabellen-Retrievals gegeben. Wird eine Sperre freigegeben, wird die Sperre daher verfügbar für die Anfragen in der Schreibsperrwarteschlange und danach für die Anfragen in der Lesesperrwarteschlange. Dies stellt sicher, dass Tabellenaktualisierungen nicht „verhungern“, auch wenn es starke SELECT-Aktivitäten für die Tabelle gibt. Wenn Sie viele Aktualisierungen für eine Tabelle haben, warten SELECT-Anweisungen allerdings, bis es keine mehr Updates gibt.

Information über das Ändern der Priorität von Leseoperationen und Schreiboperationen erhalten Sie unter Abschnitt 4.3.2, „Tabellensperrprobleme“.

Sie können die Tabellensperrenkonkurrenz auf Ihrem System analysieren, indem Sie die Statusvariablen Table_locks_waited und Table_locks_immediate überprüfen, die die Häufigkeit, dass Anfragen auf Tabellensperren sofort erfüllt werden konnten, und die Zahl derjenigen, die jeweils warten mussten, anzeigen:

mysql> SHOW STATUS LIKE 'Table%';
+-----------------------+---------+
| Variable_name         | Value   |
+-----------------------+---------+
| Table_locks_immediate | 1151552 |
| Table_locks_waited    | 15324   |
+-----------------------+---------+

Die MyISAM-Speicher-Engine unterstützt gleichzeitige Einfügeoperationen, um Konkurrenzbetrieb zwischen Lesevorgängen und Schreibvorgängen für eine bestimmte Tabelle zu reduzieren: Wenn eine MyISAM-Tabelle keine freien Blöcke in der Mitte der Datendatei hat, werden Zeilen immer am Ende der Datendatei eingefügt. In diesem Fall können Sie gleichzeitige INSERT- und SELECT-Anweisungen für eine MyISAM-Tabelle ohne Sperren frei mischen. Sie können also Datensätze in eine MyISAM-Tabelle einfügen, während andere Clients zur selben Zeit daraus lesen. Löcher können aus Datensätzen resultieren, die in der Mitte der Tabelle gelöscht oder aktualisiert wurden. Wenn es Löcher gibt, werden gleichzeitige Einfügeoperationen deaktiviert. Sie werden automatisch wieder aktiviert, wenn alle Löcher mit neuen Daten gefüllt worden sind. Dieses Verhalten wird mit der Systemvariablen concurrent_insertverändert. Siehe auch Abschnitt 4.3.3, „Gleichzeitige Einfügeoperationen“.

Wenn Sie eine Tabellensperre explizit mit LOCK TABLES erwerben, können Sie eine READ LOCAL-Sperre statt einer READ-Sperre anfordern, damit andere Sitzungen gleichzeitige Einfügeoperationen ausführen können, während Sie die Tabelle gesperrt haben.

Um viele INSERT- und SELECT-Operationen auf einer real_table-Tabelle auszuführen, wenn gleichzeitige Einfügeoperationen nicht möglich sind, können Sie Datensätze in eine temporäre Tabelle temp_table einfügen und die wirkliche Tabelle mit den Datensätzen der temporären Tabelle periodisch aktualisieren. Dies ist etwa mit dem folgenden Code möglich:

mysql> LOCK TABLES real_table WRITE, temp_table WRITE;
mysql> INSERT INTO real_table SELECT * FROM temp_table;
mysql> DELETE FROM temp_table;
mysql> UNLOCK TABLES;

InnoDB verwendet Sperren auf Datensatzebene. Deadlocks sind bei InnoDB möglich, weil automatisch während der Verarbeitung von SQL-Anweisungen, und nicht am Anfang der Transaktion, Sperren angelegt werden.

Vorteile der Sperrung auf Datensatzebene:

  • Weniger Sperrkonflikte, wenn unterschiedliche Sitzungen auf unterschiedliche Datensätze zugreifen

  • Weniger Änderungen für Rollback

  • Ein einzelner Datensatz kann für eine lange Zeit gesperrt werden

Nachteile der Sperrung auf Datensatzebene:

  • Erfordert mehr Speicher als Sperren auf Tabellenebene

  • Langsamer als Sperren auf Tabellenebene, wenn auf einem großen Teil der Tabelle angewendet, da viel mehr Sperren nötig sind

  • Langsamer als andere Sperren, wenn Sie oft GROUP BY-Operationen auf einem großen Teil der Daten ausführen oder wenn Sie häufig die ganze Tabelle scannen müssen

Im Allgemeinen sind Tabellensperren Sperren auf Datensatzebene in den folgenden Fällen überlegen:

  • Die meisten Anweisungen für die Tabelle sind Leseoperationen

  • Anweisungen für die Tabelle sind eine Mischung aus Lese- und Schreiboperationen, wobei Schreiboperationen Updates oder Löschungen eines einzelnen DAtensatzes sind, die mit einem Schlüssellesevorgang geholt werden können:

    UPDATE tbl_name SET column=value WHERE unique_key_col=key_value;
    DELETE FROM tbl_name WHERE unique_key_col=key_value;
    
  • SELECT kombiniert mit gleichzeitigen INSERT-Anweisungen und sehr wenigen UPDATE- oder DELETE-Anweisungen

  • Viele Scans oder GROUP BY-Operationen auf der ganzen Tabelle ohne Schreibvorgänge

Bei Sperren höherer Ebene können Sie Anwendungen einfacher optimieren, indem Sie Sperren verschiedener Typen unterstützen, weil der Overhead wesentlich geringer ist als bei Sperren auf Datensatzebene.

Andere Möglichkeiten als Sperrung auf Datensatzebene:

  • Versionierung (wie sie beispielsweise in MySQL für nebenläufige Einfügeoperationen verwendet wird). Hierbei können ein Schreiber und mehrere Leser nebeneinander arbeiten. Dies bedeutet, dass die Datenbank oder Tabelle verschiedene Views der Daten abhängig vom Zeitpunkt des Zugriffsbeginns unterstützt. Andere gängige Bezeichnungen hierfür sind „Zeitreise“, „Copy on Write“ (Kopieren beim Schreiben) und „Copy on Demand“ (Kopieren bei Bedarf).

  • Copy on Demand ist der Sperrung auf Seiten- oder Datensatzebene in vielen Fällen überlegen. Schlimmstenfalls kann sie jedoch wesentlich mehr Speicher beanspruchen als normale Sperren.

  • Anstelle von Sperren auf Datensatzebene können Sie auch Sperren auf Anwendungsebene verwenden – in MySQL etwa GET_LOCK() und RELEASE_LOCK(). Diese sind Richtsperren, daher funktionieren sie nur mit Programmen, die miteinander kooperieren. Siehe auch Abschnitt 7.11.4, „Sonstige Funktionen“.

4.3.2. Tabellensperrprobleme

Um eine sehr hohe Sperrgeschwindigkeit zu erreichen, verwendet MySQL Sperren auf Tabellenebene (anstatt auf Seiten-, datensatz- oder Spaltenebene) für alle Speicher-Engines außer InnoDB und NDBCLUSTER.

Bei InnoDB-Tabellen verwendet MySQL Sperren auf Tabellenebene nur, wenn Sie explizit die Tabelle mit LOCK TABLES sperren. Für diese Speicher-Engine sollten Sie überhaupt LOCK TABLES vollständig vermeiden, weil InnoDB automatische Sperren auf Datensatzebene verwendet, um Transaktionsisolation zu sichern.

Bei großen Tabellen ist eine Sperre auf Tabellenebene oft besser als auf Datensatzebene, aber es gibt einige Nachteile:

  • Eine Sperre auf Tabellenebene ermöglicht es vielen Sitzungen, gleichzeitig aus einer Tabelle zu lesen. Wenn aber eine Sitzung in eine Tabelle schreiben will, muss sie zuerst exklusiven Zugriff bekommen. Während der Aktualisierung müssen alle anderen Sitzungen, die auf diese Tabelle zugreifen wollen, auf den Abschluss der Aktualisierung warten.

  • Die Tabellensperre kann beispielsweise Probleme verursachen, wenn eine Sitzung wartet, weil die Festplatte voll ist und erst freier Speicher benötigt wird, damit sie fortgesetzt werden kann. In diesem Fall werden alle Sitzungen, die auf die problematische Tabelle zugreifen wollen, ebenfalls in einen Wartezustand versetzt, bis wieder genug Festplattenkapazität verfügbar ist.

Die Tabellensperre ist auch in folgendem Szenario nachteilig:

  • Eine Sitzung setzt eine SELECT-Anweisung ab, deren Ausführung sehr lange dauert.

  • Eine andere Sitzung gibt dann eine UPDATE-Anweisung auf der gleichen Tabelle aus. Diese Sitzung wartet, bis die SELECT-Anweisung beendet wird.

  • Eine andere Sitzung gibt eine andere SELECT-Anweisung auf der gleichen Tabelle aus. Weil UPDATE höhere Priorität hat als SELECT, wartet diese SELECT-Anweisung, bis die UPDATE-Anweisung abgeschlossen ist und danach darauf, dass die erste SELECT-Anweisung abgeschlossen ist.

Die folgenden Punkte beschreiben einige Möglichkeiten, um den konkurrierenden Zugriff, der durch Tabellensperren verursacht werden kann, zu vermeiden oder zumindest zu verringern:

  • Versuchen Sie die Ausführung der SELECT-Anweisungen zu beschleunigen, sodass die Tabellensperren verkürzt werden. Zu diesem Zweck müssen Sie unter Umständen einige Zusammenfassungstabellen erstellen.

  • Starten Sie mysqld mit der Option --low-priority-updates. Für Speicher-Engines, die nur Sperren auf Tabellenebene verwenden (MyISAM, MEMORY, MERGE), gibt dies allen Anweisungen, die eine Tabelle aktualisieren (modifizieren), eine geringere Priorität als SELECT-Anweisungen. In diesem Fall würde die zweite SELECT-Anweisung in obigem Beispiel vor der UPDATE-Anweisung ausgeführt werden, und Sie müssten nicht warten, bis die erste SELECT-Anweisung abgeschlossen ist.

  • Sie können mit der Anweisung SET LOW_PRIORITY_UPDATES=1 festlegen, dass alle Aktualisierungen, die über eine bestimmte Verbindung erfolgen, mit niedrigerer Priorität verarbeitet werden sollen. Siehe auch Server System Variables.

  • Um einer bestimmten INSERT-, UPDATE- oder DELETE-Anweisung niedrigere Priorität zu geben, verwenden Sie das Attribut LOW_PRIORITY.

  • Um einer bestimmten SELECT-Anweisung höhere Priorität zu geben, verwenden Sie das Attribut HIGH_PRIORITY. Siehe auch Abschnitt 8.2.8, „SELECT.

  • Starten Sie mysqld mit einem niedrigen Wert für die Systemvariable max_write_lock_count, um MySQL zu zwingen, die Priorität aller SELECT-Anweisungen, die auf eine Tabelle warten, zu senken, nachdem eine bestimmte Anzahl von Einfügeoperationen in die Tabelle stattgefunden hat. Dies gibt zu, dass READ blockiert, nachdem eine gewisse Anzahl von WRITE blockiert hat.

  • Falls Sie Probleme mit SELECT verbunden mit INSERT haben, sollten Sie überlegen, ob Sie auf MyISAM-Tabellen wechseln, die gleichzeitige SELECT- und INSERT-Anweisungen unterstützen. (Siehe auch Abschnitt 4.3.3, „Gleichzeitige Einfügeoperationen“.)

  • Mischen Sie Einfüge- und Löschoperationen in derselben Tabelle, dann kann INSERT DELAYED sehr hilfreich sein. Siehe auch Abschnitt 8.2.5.2, „INSERT DELAYED.

  • Falls Sie Probleme mit gemischten SELECT- und DELETE-Anweisungen haben, kann die OptionLIMIT für DELETE helfen. Siehe auch Abschnitt 8.2.2, „DELETE.

  • Die Verwendung von SQL_BUFFER_RESULT bei SELECT-Anweisungen kann dabei helfen, die Dauer der Tabellensperren zu verkürzen. Siehe auch Abschnitt 8.2.8, „SELECT.

  • Sie können den Sperrcode in mysys/thr_lock.c so abändern, dass nur eine einzelne Warteschlange verwendet wird. In diesem Fall hätten Schreib- und Lesesperren dieselbe Priorität, was bei einigen Anwendungen von Nutzen sein kann.

Hier noch ein paar Tipps zu Tabellensperren in MySQL:

  • Gleichzeitige Benutzer stellen kein Problem dar, wenn Sie Update- nicht mit Auswahloperationen mischen, die viele Datensätze in derselben Tabelle untersuchen müssen.

  • Sie können mit LOCK TABLES die Geschwindigkeit erhöhen, weil viele Updates innerhalb einer einzelnen Sperre wesentlich schneller erfolgen als die Durchführung von Updates ohne Sperre. Auch das Aufteilen des Tabelleninhalts auf mehrere Tabellen kann hilfreich sein.

  • Wenn Sie auf geschwindigkeitsspezifische Probleme in Verbindung mit Tabellensperren bei MySQL treffen, können Sie die Leistung möglicherweise durch Konvertierung einiger Ihrer Tabellen in InnoDB-Tabellen verbessern. Siehe auch Kapitel 9, Die InnoDB-Speicher-Engine.

4.3.3. Gleichzeitige Einfügeoperationen

Die MyISAM-Speicher-Engine unterstützt gleichzeitige Einfügeoperationen, um Konkurrenzbetrieb zwischen Lesevorgängen und Schreibvorgängen für eine bestimmte Tabelle zu reduzieren: Wenn eine MyISAM-Tabelle keine Löcher in der Datendatei hat (gelöschte Zeilen in der Mitte), kann eine INSERT-Anweisung ausgeführt werden, um am Ende der Tabelle Zeilen hinzuzufügen, während gleichzeitig SELECT-Anweisungen Datensätze aus der Tabelle lesen. Wenn es mehrere INSERT-Anweisungen gibt, werden sie in eine Warteschlange gestellt und nacheinander gleichzeitig mit den SELECT-Anweisungen ausgeführt.

Die Systemvariable concurrent_insert kann gesetzt werden, um die Verarbeitung gleichzeitiger Einfügeoperationen zu modifizieren. Standardmäßig wird die Variable auf 1 gesetzt und gleichzeitige Einfügeoperationen werden wie gerade beschrieben gehandhabt. Wenn concurrent_insert auf 0 gesetzt wird, werden gleichzeitige Einfügeoperationen deaktiviert. Wenn die Variable auf 2 gesetzt wird, werden gleichzeitige Einfügeoperationen am Ende der Tabelle sogar für Tabellen erlaubt, die gelöschte Zeilen enthalten. Siehe auch die Beschreibung der Systemvariablenconcurrent_insert.

Unter Umständen, bei denen gleichzeitige Einfügeoperationen verwendet werden können, ist es nur sehr selten notwendig, den Modifizierer DELAYED für INSERT-Anweisungen zu verwenden. Siehe auch Abschnitt 8.2.5.2, „INSERT DELAYED.

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. Siehe auch The Binary Log. Außerdem wird bei jenen Anweisungen eine Lesesperre auf der Tabelle gesetzt, aus der selektiert wird, damit Einfügeoperationen in jener Tabelle gesperrt sind. Die Wirkung ist, dass gleichzeitige Einfügeoperationen für jene Tabelle auch warten müssen.

Bei LOAD DATA INFILE können, wenn Sie CONCURRENT bei einer MyISAM-Tabelle angeben, die die Bedingungen für gleichzeitige Einfügeoperationen erfüllt (d. h. keine freien Blöcke in der Mitte enthält), andere Sitzungen Daten aus der Tabelle abrufen, während LOAD DATA ausgeführt wird. Die Verwendung der CONCURRENT-Option wirkt sich auch dann auf die Leistung von LOAD DATA ein bisschen aus, wenn keine andere Sitzung gleichzeitig die Tabelle verwendet.

Wenn Sie HIGH_PRIORITY angeben, setzt es die Auswirkungen der Option --low-priority-updates außer Kraft, sofern der Server mit dieser Option gestartet worden war. Außerdem sind auch hier gleichzeitige Einfügeoperationen nicht möglich.

Bei LOCK TABLE ist der Unterschied zwischen READ LOCAL und READ, dass READ LOCAL im nicht im Konflikt stehende INSERT-Anweisungen (gleichzeitige Einfügeoperationen) zulässt, während die Sperre gehalten wird. Allerdings kann dies nicht verwendet werden, wenn Sie die Datenbank mit Prozessen bearbeiten, die nicht vom Server gesteuert werden, während Sie die Sperre halten.

4.3.4. Externe Sperren

Externes Sperren ist die Verwendung von Dateisystemsperren, um Konkurrenzbetrieb für Datenbanktabellen durch mehrere Prozesse zu verwalten. Externes Sperren wird in Situationen verwendet, in denen man nicht annehmen kann, dass ein einzelner Prozess wie der MySQL-Server der einzige Prozess ist, der Zugriff auf die Tabellen benötigt. Hier ein paar Beispiele:

  • Wenn Sie mehrere Server ausführen, die das gleiche Datenbankverzeichnis verwenden (nicht empfohlen), muss jeder Server die externe Sperrung aktiviert haben.

  • Wenn Sie myisamchk verwenden, um Tabellenwartungsarbeiten auf MyISAM-Tabellen auszuführen, müssen Sie entweder sicherstellen dass der Server nicht läuft oder dass der Server externe Sperrung aktiviert hat, so dass er Tabellendateien sperrt, wie es notwendig ist, um mit myisamchk den Zugriff auf die Tabellen zu koordinieren. Das gleiche gilt für die Verwendung von myisampack zum Packen von MyISAM-Tabellen.

    Wenn der Server mit aktivierter externer Sperrung ausgeführt wird, können Sie myisamchk jederzeit für Leseoperationen verwenden, z. B. für die Überprüfung von Tabellen. Wenn der Server versucht, eine Tabelle zu aktualisieren, die myisamchk verwendet, wird der Server in diesem Fall warten, bis myisamchk beendet ist, bevor er fortfährt.

    Wenn Sie myisamchk für Schreibvorgänge verwenden, z. B. um Tabellen zu reparieren oder zu optimieren, oder wenn Sie myisampack verwenden, um Tabellen zu packen, müssen Sie immer sicherstellen, dass der mysqld-Server die Tabelle nicht verwendet. 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.

Ist externe Sperrung wirksam, erwirbt jeder Prozess, der Zugriff auf eine Tabelle benötigt, eine Dateisystemsperre für die Tabellendateien, bevor er auf die Tabelle zugreift. Wenn alle notwendigen Sperren nicht erworben werden können, wird der Prozess gehindert, auf die Tabelle zuzugreifen, bis die Sperren erhalten werden können (nachdem sie der Prozess, der gegenwärtig die Sperren hält, diese freigegeben hat).

Externe Sperrung wirkt sich auf Serverleistung aus, weil der Server manchmal auf andere Prozesse warten muss, bevor er auf Tabellen zugreifen kann.

Externe Sperrung ist unnötig, wenn Sie einen einzelnen Server auf ein bestimmtes Datenverzeichnis zugreifen lassen (was der übliche Fall ist) und wenn keine anderen Programme wie myisamchk Tabellen modifizieren müssen, während der Server läuft. Wenn Sie Tabellen mit anderen Programmen nur lesen, wird externe Sperre nicht benötigt, obwohl myisamchk Warnungen melden könnte, wenn der Server Tabellen ändert, während myisamchk sie liest.

Ist die externer Sperre deaktiviert, um myisamchk zu verwenden, müssen Sie entweder den Server stoppen, während myisamchk läuft oder sonst die Tabellen sperren und leeren, bevor Sie myisamchk ausführen. (Siehe auch Abschnitt 4.5.2, „Systemfaktoren und Startup-Parameter-Tuning“.) Um diese Anforderung zu umgehen, verwenden Sie die Anweisungen CHECK TABLE und REPAIR TABLE zur Überprüfung und Reparatur von MyISAM-Tabellen.

Bei mysqld wird externe Sperrung vom Wert der Systemvariablen skip_external_locking kontrolliert. Wenn diese Variable aktiviert wird, ist externe Sperrung deaktiviert, und umgekehrt. Ab MySQL 4.0 wird externe Sperrung standardmäßig deaktiviert. Vor MySQL 4.0 wird externe Sperrung unter Linux oder wenn MySQL konfiguriert wird, MIT-pthreads zu verwenden, standardmäßig aktiviert.

Die Verwendung der externen Sperrung kann bei Serverstart unter Verwendung von der Option --external-locking oder --skip-external-locking gesteuert werden.

Wenn Sie die externe Sperroption verwenden, um Aktualisierungen an MyISAM-Tabellen von vielen MySQL-Prozessen zu aktivieren, müssen Sie sicherstellen, dass den folgenden Bedingungen entsprochen wird:

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

  • Sie sollten den Server nicht mit der Option --delay-key-write=ALLstarten oder die Tabellenoption DELAY_KEY_WRITE=1 für gemeinsam genutzte Tabellen verwenden. Sonst kann Indexverfälschung auftreten.

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.)

4.4. Optimieren der Datenbank-Struktur

4.4.1. Machen Sie Ihre Daten so klein wie möglich

Eine der einfacheren Optimierungen besteht darin, Ihre Tabellen so zu implementieren, dass sie möglichst wenig Platz auf der Festplatte einnehmen. Dies kann erhebliche Verbesserungen zur Folge haben, weil die Lesevorgänge von der Festplatte schneller erfolgen und kleinere Tabellen normalerweise weniger Hauptspeicher benötigen, während ihre Inhalte bei der Abfrageausführung aktiv verarbeitet werden. Auch die Indizierung ist weniger ressourcenbeanspruchend, wenn sie an schmaleren Spalten vorgenommen wird.

MySQL unterstützt viele verschiedene Speicher-Engines (Tabellentypen) und Datensatzformate. Für jede Tabelle können Sie neu entscheiden, welche Speicher- und Indizierungsmethode verwendet werden soll. Die Auswahl des für Ihre Anwendung geeigneten Tabellenformats kann Ihnen einen erheblichen Performancezuwachs bringen. Siehe auch Storage Engines.

Sie können die Leistungsfähigkeit Ihrer Tabellen optimieren und den Speicherbedarf minimieren, indem Sie die folgenden Methoden benutzen:

  • Verwenden Sie den jeweils effizientesten (d. h. kleinstmöglichen) Datentyp. MySQL bietet viele Spezialtypen, mit denen sich Festplatten- und Arbeitsspeicher einsparen lassen. Setzen Sie beispielsweise möglichst die kleineren Integer-Typen ein, um kleinere Tabellen zu erhalten. MEDIUMINT ist häufig besser geeignet als INT, weil eine MEDIUMINT-Spalte 25 Prozent weniger Platz benötigt.

  • Wenn möglich, deklarieren Sie Spalten als NOT NULL. Hierdurch wird alles schneller, und Sie sparen ein Bit je Spalte. Wenn Sie NULL in Ihrer Anwendung wirklich benötigen, sollten Sie es natürlich benutzen; Sie sollten lediglich verhindern, dass alle Spalten vorgabeseitig so eingestellt sind.

  • Wenn Ihre MyISAM-Tabellen keine Spalten variabler Länge (VARCHAR, TEXT oder BLOB) enthalten, wird ein festes Datensatzformat verwendet. Dieses ist schneller, kann allerdings mehr Platz beanspruchen. Siehe auch MyISAM Table Storage Formats. Sie können mit der Option ROW_FORMAT=FIXED für CREATE TABLE angeben, dass Sie Datensätze fester Länge verwenden wollen, auch wenn VARCHAR-Spalten vorhanden sind.

  • InnoDB-Tabellen verwenden ein kompaktes Speicherformat. In Versionen vor MySQL 5.0.3 enthalten InnoDB-Datensätze einige redundante Informationen, z. B. die Anzahl und die Längen der einzelnen Spalten (und zwar auch bei Spalten fester Größe). Standardmäßig werden Tabellen im kompakten Format erstellt (ROW_FORMAT=COMPACT). Wenn Sie ein Downgrade auf eine ältere MySQL-Version durchführen wollen, können Sie das alte Format mit ROW_FORMAT=REDUNDANT anfordern.

    Die Anwesenheit des kompakten Zeilenformats vermindert Zeilenspeicherplatz um ungefähr 20 % auf Kosten der gesteigerten CPU-Nutzung bei einigen Operationen. Wenn Ihre Auslastung eine typische ist, die von Cachetrefferquoten und Plattendrehzahl beschränkt wird, ist dies wahrscheinlich schneller. In dem seltenen Fall, der von der CPU-Geschwindigkeit beschränkt wird, könnte es langsamer sein.

    Das kompakte InnoDB-Format ändert auch die Art der Speicherung der CHAR-Spalten, die UTF-8-Daten enthalten. Bei ROW_FORMAT=REDUNDANT belegt eine Spalte CHAR(N) im UTF-8-Format 3 N Byte (davon ausgehend, dass die maximale Länge eines UTF-8-kodierten Zeichens drei Byte beträgt). Viele Sprachen können vorwiegend mit UTF-8-Zeichen geschrieben werden, die nur ein Byte umfassen, weswegen eine feste Speicherlänge häufig Platzverschwendung ist. Beim ROW_FORMAT=COMPACT-Format reserviert InnoDB eine variable Speichermenge im Bereich zwischen N und 3 N Byte für diese Spalten, indem Leerzeichen am Ende nach Bedarf abgeschnitten werden. Die Mindestspeichergröße wird als N Byte vermerkt, um in typischen Fällen interne Updates durchführen zu können.

  • Der Primärindex einer Tabelle sollte so kurz wie möglich sein. Dies macht die Identifizierung eines Datensatzes einfach und effizient.

  • Erstellen Sie nur Indizes, die Sie auch wirklich benötigen. Indizes sind praktisch, um Daten abzurufen, aber von Nachteil, wenn Sie Daten schnell speichern müssen. Wenn Sie auf eine Tabelle in erster Linie durch das Durchsuchen einer Kombination von Spalten zugreifen, dann erstellen Sie für diese Kombination einen Index. Der erste Teil des Indexes sollte die meistverwendete Spalte sein. Wenn Sie immer viele Spalten bei der Auswahl aus einer Tabelle verwenden, sollte die erste Spalte im Index die mit den meisten Duplikaten sein, um bessere Komprimierung des Indexes zu erhalten.

  • Wenn es sehr wahrscheinlich ist, dass eine Stringspalte einen eindeutigen Präfix auf den ersten Zeichen hat, ist es besser, nur diesen Präfix zu indizieren und dabei den MySQL-Support für das Erstellen eines Indexes auf dem linken Teil der Spalte zu nutzen (siehe Abschnitt 8.1.13, „CREATE INDEX). Kürzere Indizes sind nicht nur deswegen schneller, weil sie weniger Festplattenkapazität benötigen, sondern auch, weil sie auf diese Weise mehr Treffer im Index-Cache erhalten (d. h., es sind weniger Suchvorgänge auf der Festplatte erforderlich). Siehe auch Abschnitt 4.5.3, „Tuning der Server-Parameter“.

  • Unter manchen Umständen kann es von Vorteil sein, eine Tabelle, die sehr häufig gescannt wird, in zwei Tabellen aufzutrennen. Dies gilt insbesondere, wenn es sich um eine Tabelle im dynamischen Format handelt und es möglich ist, dass eine kleinere statische Tabelle entsteht, die beim Scannen der Tabelle zum Auffinden der gewünschten Datensätze benutzt werden kann.

4.4.2. Spaltenindizes

Alle MySQL-Datentypen lassen sich indizieren. Die Verwendung von Indizes der relevanten Spalten ist die beste Möglichkeit, die Leistung von SELECT-Operationen zu optimieren.

Die maximale Anzahl von Indizes pro Tabelle und die maximale Indexlänge werden durch die verwendete Speicher-Engine bestimmt. Siehe auch Storage Engines. Alle Speicher-Engines unterstützen mindestens 16 Indizes pro Tabelle und eine Indexgesamtlänge von mindestens 256 Byte. Bei den meisten Speicher-Engines liegen die Grenzen höher.

Mit der Syntax col_name(N) in einer Indexdefinition können Sie einen Index erstellen, der nur die ersten N Zeichen einer String-Spalte verwendet. Wenn Sie auf diese Weise nur ein Präfix der Spaltenwerte indizieren, kann dies die Indexdatei erheblich kleiner machen. Bei der Indizierung einer BLOB- oder TEXT-Spalte müssen Sie eine Präfixlänge für den Index angeben. Ein Beispiel:

CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));

Präfixe können bis 1.000 Byte lang sein (767 Byte bei InnoDB-Tabellen). Beachten Sie, dass Präfixbeschränkungen in Byte angegeben werden, wohingegen die Präfixlänge in CREATE TABLE-Anweisungen als Anzahl der Zeichen interpretiert wird. Dies muss bei der Angabe einer Präfixlänge für eine Spalte, die einen Multibytezeichensatz verwendet, in jedem Fall berücksichtigt werden.

Sie können außerdem FULLTEXT-Indizes erstellen. Diese werden für die Volltextsuche verwendet. Nur die MyISAM-Speicher-Engine unterstützt FULLTEXT-Indizes, und auch nur für CHAR-, VARCHAR- und TEXT-Spalten. Die Indizierung erfolgt stets über die gesamte Spalte – eine Spaltenpräfixindizierung wird nicht unterstützt. Detaillierte Informationen finden Sie in Abschnitt 7.8, „Volltextsuchfunktionen“.

Sie können auch Indizes für raumbezogene Typen erstellen. Derzeit unterstützt nur MyISAM R-Tree-Indizes für raumbezogene Typen. Andere Speicher-Engines verwenden B-Trees zur Indizierung raumbezogener Typen. (Ausnahmen sind lediglich ARCHIVE und NDBCLUSTER, die überhaupt keine raumbezogene Indizierung unterstützen.)

Die MEMORY-Engine verwendet standardmäßig HASH-Indizes, unterstützt aber auch BTREE-Indizes.

4.4.3. Mehrfachspaltenindizes

MySQL kann zusammengesetzte Indizes erstellen (d. h. Indizes über mehrere Spalten). Ein Index kann aus bis 16 Spalten bestehen. Bei bestimmten Datentypen können Sie ein Präfix der Spalte indizieren (siehe Abschnitt 4.4.2, „Spaltenindizes“).

Ein mehrspaltiger Index kann als sortiertes Array betrachtet werden, das Werte enthält, die durch Verkettung der Werte der indizierten Spalten entstanden sind.

MySQL verwendet mehrspaltige Indizes derart, dass Abfragen schnell sind, wenn Sie einen bekannten Teil der ersten Spalte des Indexes in einer WHERE-Klausel angeben – und zwar auch dann, wenn Sie keine Werte für andere Spalten angeben.

Angenommen, eine Tabelle habe die folgende Spezifikation:

CREATE TABLE test (
    id         INT NOT NULL,
    last_name  CHAR(30) NOT NULL,
    first_name CHAR(30) NOT NULL,
    PRIMARY KEY (id),
    INDEX name (last_name,first_name)
);

Der Index name ist ein Index über die Spalten last_name und first_name. Der Index kann für Abfragen, die Werte in einem bekannten Bereich für last_name angeben, oder sowohl für last_name als auch für first_name verwendet werden. Aus diesem Grund wird der Index name in den folgenden Abfragen benutzt:

SELECT * FROM test WHERE last_name='Widenius';
SELECT * FROM test
  WHERE last_name='Widenius' AND first_name='Michael';
SELECT * FROM test
  WHERE last_name='Widenius'
  AND (first_name='Michael' OR first_name='Monty');
SELECT * FROM test
  WHERE last_name='Widenius'
  AND first_name >='M' AND first_name < 'N';

Im Gegensatz dazu wird der Index name in den folgenden Abfragen nicht benutzt:

SELECT * FROM test WHERE first_name='Michael';
SELECT * FROM test
  WHERE last_name='Widenius' OR first_name='Michael';

Die Art und Weise, wie MySQL Indizes zur Verbesserung der Abfrageleistung verwendet, wird in Abschnitt 4.4.4, „So verwendet MySQL Indizes“, näher beschrieben.

4.4.4. So verwendet MySQL Indizes

Indizes werden verwendet, um schnell Datensätze mit bestimmten Spaltenwerten zu finden. Ohne Index müsste MySQL mit der Suche beim ersten Datensatz beginnen und dann die gesamte Tabelle nach passenden Datensätzen durchforsten. Je größer die Tabelle, desto höher sind die Kosten dafür. Wenn die Tabelle einen Index für die fraglichen Spalten aufweist, kann MySQL die Position in der Mitte der Datendatei, an der die Suche beginnen soll, schnell bestimmen, ohne alle Daten in der Datei überprüfen zu müssen. Wenn eine Tabelle 1.000 Datensätze hat, ist dies mindestens hundertmal schneller als ein sequenzielles Lesen. Wenn Sie hingegen auf die meisten Datensätze zugreifen müssen, ist das sequenzielle Lesen schneller, weil die Anzahl der Festplattenzugriffe geringer ist.

Die meisten MySQL-Indizes (PRIMARY KEY, UNIQUE, INDEX und FULLTEXT) sind in B-Trees gespeichert. Zu erwähnende Ausnahmen sind, dass Indizes für raumbezogene Datentypen R-Typen verwenden und MEMORY-Tabellen auch Hash-Indizes unterstützen.

Strings werden automatisch präfixkomprimiert; Gleiches gilt für Leerzeichen am Ende des Strings. Siehe auch Abschnitt 8.1.13, „CREATE INDEX.

Generell werden Indizes wie nachfolgend beschrieben verwendet. Die spezifischen Eigenschaften von Hash-Indizes, die in Verbindung mit MEMORY-Tabellen verwendet werden, werden am Ende dieses Abschnitts erläutert.

MySQL verwendet Indizes für die folgenden Operationen:

  • Zum schnellen Auffinden von Datensätzen, die der WHERE-Klausel entsprechen.

  • Zum Ignorieren bestimmter Datensätze. Wenn mehrere Indizes vorhanden sind, verwendet MySQL normalerweise denjenigen, der die kleinste Anzahl von Datensätzen findet.

  • Zum Abrufen von Datensätzen aus anderen Tabellen bei der Durchführung von Joins. MySQL kann Indizes auf Spalten effizienter verwenden, wenn sie mit dem gleichen Typ und der gleichen Größe deklariert werden. In diesem Zusammenhang werden VARCHAR und CHAR als gleich erachtet, wenn sie mit der gleichen Größe deklariert werden. Zum Beispiel haben VARCHAR(10) und CHAR(10) die gleiche Größe, aber VARCHAR(10) und CHAR(15) nicht.

    Der Vergleich unterschiedlicher Spalten kann die Verwendung von Indizes verhindern, wenn Werte nicht direkt ohne Konvertierung verglichen werden können. Angenommen, eine numerische Spalte wird mit einer Stringspalte verglichen. Für einen gegebenen Wert wie1 in der numerischen Spalte könnte der Vergleich eine Gleichheit mit einer Anzahl von Werten in der Stringspalte ergeben, z. B. '1', ' 1', '00001' oder '01.e1'. Dies schließt Verwendung von Indizes für die Stringspalte aus.

  • Zum Auffinden des MIN()- oder MAX()-Werts für eine bestimmte indizierte Spalte key_col. Dies wird mit einem Vorprozessor optimiert, der überprüft, ob Sie WHERE key_part_N = constant für alle Schlüsselteile verwenden, die im Index vor key_col erscheinen. In diesem Fall führt MySQL eine einfache Schlüsselsuche nach jedem MIN()- oder MAX()-Ausdruck durch und ersetzt ihn durch eine Konstante. Wenn alle Ausdrücke durch Konstanten ersetzt werden konnten, wird die Abfrage umgehend abgeschlossen. Ein Beispiel:

    SELECT MIN(key_part2),MAX(key_part2)
      FROM tbl_name WHERE key_part1=10;
    
  • Zum Sortieren oder Gruppieren einer Tabelle, sofern das Sortieren bzw. Gruppieren auf der Basis des linken Präfixes eines verwendbaren Schlüssels erfolgt (z. B. ORDER BY key_part1, key_part2). Wenn auf alle Schlüsselteile DESC folgt, wird der Schlüssel in umgekehrter Reihenfolge gelesen. Siehe auch Abschnitt 4.2.13, „ORDER BY-Optimierung“, und Abschnitt 4.2.14, „GROUP BY-Optimierung“.

  • In manchen Fällen kann eine Abfrage so optimiert werden, dass sie Werte abruft, ohne die eigentlichen Datensätze zu untersuchen. Wenn eine Abfrage nur Spalten einer Tabelle verwendet, die numerisch sind und bei einem Schlüssel ein linkes Präfix bilden, dann können die ausgewählten Werte auch aus dem Indexbaum abgerufen werden, was deutlich schneller ist:

    SELECT key_part3 FROM tbl_name
      WHERE key_part1=1
    

Nehmen wir an, dass Sie folgende SELECT-Anweisung absetzen:

mysql> SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;

Wenn für col1 und col2 ein mehrspaltiger Index vorhanden ist, können die entsprechenden Datensätze direkt abgerufen werden. Sind separate einspaltige Indizes für col1 und col2 vorhanden, dann versucht der Optimierer, die Index Merge-Optimierung zu verwenden (sieheAbschnitt 4.2.6, „Index-Merge-Optimierung“), oder versucht, den restriktivsten Index zu finden, indem er entscheidet, welcher Index weniger Datensätze findet, und dann jenen Index verwendet, um die Datensätze zu holen.

Wenn die Tabelle einen mehrspaltigen Index aufweist, kann ein beliebiges linkes Präfix des Indexes vom Optimierer zum Suchen von Datensätzen verwendet werden. Haben Sie beispielsweise einen dreispaltigen Index für (col1, col2, col3), dann bietet dieser Suchfunktionalität für (col1), (col1, col2) und (col1, col2, col3).

MySQL kann keinen Index verwenden, wenn die Spalten kein linkes Präfix für den Index bilden. Betrachten Sie einmal die folgenden SELECT-Anweisungen:

SELECT * FROM tbl_name WHERE col1=val1;
SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;
SELECT * FROM tbl_name WHERE col2=val2;
SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3;

Wenn ein Index für (col1, col2, col3) vorhanden ist, verwenden diese nur die ersten beiden Abfragen. Die dritte und die vierte Abfrage beziehen sich zwar auf indizierte Spalten, aber (col2) und (col2, col3) sind keine linken Präfixe von (col1, col2, col3).

Ein B-Tree-Index kann für Spaltenvergleiche in Ausdrücken benutzt werden, die die Operatoren =, >, >=, <, <= oder BETWEEN verwenden. Der Index kann auch für LIKE-Vergleiche benutzt werden, wenn das Argument zu LIKE ein Konstanten-String ist, der nicht mit einem Jokerzeichen beginnt. Die folgenden SELECT-Anweisungen verwenden beispielsweise Indizes:

SELECT * FROM tbl_name WHERE key_col LIKE 'Patrick%';
SELECT * FROM tbl_name WHERE key_col LIKE 'Pat%_ck%';

In der ersten Anweisung werden nur Datensätze mit 'Patrick' <= key_col< 'Patricl' berücksichtigt. In der zweiten Anweisung werden nur Datensätze mit 'Pat' <= key_col< 'Pau' berücksichtigt.

Die folgenden SELECT-Anweisungen verwenden keine Indizes:

SELECT * FROM tbl_name WHERE key_col LIKE '%Patrick%';
SELECT * FROM tbl_name WHERE key_col LIKE other_col;

In der ersten Anweisung beginnt der Wert LIKE mit einem Jokerzeichen. In der zweiten Anweisung ist der LIKE-Wert keine Konstante.

Wenn Sie LIKE '%string%' verwenden und string mehr als drei Zeichen umfasst, verwendet MySQL den Turbo-Boyer-Moore-Algorithmus zur Initialisierung des Musters für den String; mit diesem Muster wird die Suche dann schneller durchgeführt.

Eine Suche unter Verwendung von col_name IS NULL setzt Indizes ein, wenn col_name indiziert ist.

Ein Index, der nicht alle AND-Ebenen in der WHERE-Klausel einbezieht, wird nicht zur Optimierung der Abfrage benutzt. Um also einen Index verwenden zu können, muss in jeder AND-Gruppe ein Präfix des Indexes benutzt werden.

Die folgenden WHERE-Klauseln verwenden Indizes:

... WHERE index_part1=1 AND index_part2=2 AND other_column=3
    /* index = 1 OR index = 2 */
... WHERE index=1 OR A=10 AND index=2
    /* optimized like "index_part1='hello'" */
... WHERE index_part1='hello' AND index_part3=5
    /* Can use index on index1 but not on index2 or index3 */
... WHERE index1=1 AND index2=2 OR index1=3 AND index3=3;

Die folgenden WHERE-Klauseln verwenden Indizes nicht:

    /* index_part1 is not used */
... WHERE index_part2=1 AND index_part3=2
    /*  Index is not used in both parts of the WHERE clause  */
... WHERE index=1 OR A=10
    /* No index spans all rows  */
... WHERE index_part1=1 OR index_part2=10

Manchmal verwendet MySQL auch dann keinen Index, wenn ein solcher vorhanden ist. Ein Umstand, unter dem dies geschieht, liegt vor, wenn der Optimierer der Ansicht ist, dass MySQL bei Verwendung eines Indexes auf einen sehr großen Anteil der Datensätze in der Tabelle zugreifen muss. (In diesem Fall ist ein Tabellenscan mit hoher Wahrscheinlichkeit schneller, weil weniger Suchvorgänge erforderlich sind.) Wenn eine solche Abfrage jedoch dank einer LIMIT-Klausel nur ein paar Datensätze abruft, verwendet MySQL trotzdem einen Index, da sich die Datensätze, die zum Ergebnis gehören, auf diese Weise schneller finden lassen.

Hash-Indizes weisen etwas andere Eigenschaften auf als die soeben beschriebenen:

  • Sie werden nur zu Vergleichen verwendet, die die Operatoren = oder <=> benutzen (aber sie sind extrem schnell). Nicht verwendet werden sie für Vergleiche mit <, bei denen ein Wertebereich gefunden wird.

  • Der Optimierer kann einen Hash-Index nicht zur Beschleunigung von ORDER BY-Operationen verwenden. (Dieser Indextyp kann nicht zur Suche nach dem nächsten Eintrag in der Reihenfolge benutzt werden.)

  • MySQL kann nicht näherungsweise bestimmen, wie viele Datensätze zwischen zwei Werten vorhanden sind (diese Angabe verwendet der Bereichsoptimierer für die Entscheidung, welchen Index er verwenden soll). Dies kann sich auf einige Abfragen auswirken, wenn Sie eine MyISAM-Tabelle in eine MEMORY-Tabelle mit einem Hash-Index konvertieren.

  • Nur vollständige Schlüssel können zur Suche nach einem Datensatz benutzt werden. (Bei einem B-Tree-Index kann dagegen ein beliebiges linkes Präfix des Schlüssels zum Suchen von Datensätzen eingesetzt werden.)

4.4.5. Der MyISAM-Schlüsselcache

Um die Festplattenzugriffe zu minimieren, verwendet die MyISAM-Speicher-Engine eine Strategie, auf der zahlreiche Datenbanksysteme basieren. Sie benutzt einen Cache-Mechanismus, um die am häufigsten abgerufenen Tabellenblöcke im Speicher zu halten:

  • Für Indexblöcke wird eine spezielle Struktur namens Schlüssel-Cache (oder Schlüsselpuffer) implementiert. Diese Struktur enthält eine Anzahl von Blockpuffern, in denen die meistverwendeten Indexblöcke abgelegt werden.

  • Für Datenblöcke verwendet MySQL keinen speziellen Cache. Stattdessen wird der Dateisystem-Cache des nativen Betriebssystems benutzt.

Dieser Abschnitt beschreibt zunächst den grundlegenden Betrieb des MyISAM-Schlüssel-Caches. Nachfolgend werden Funktionen erläutert, die die Leistungsfähigkeit des Schlüssel-Caches optimieren und mit denen Sie den Cache-Betrieb besser steuern können:

  • Mehrere Sitzungen können gleichzeitig auf den Cache zugreifen.

  • Sie können mehrere Schlüssel-Caches einrichten und Tabellenindizes speziellen Caches zuweisen.

Die Größe des Schlüssel-Caches stellen Sie mit der Systemvariablen key_buffer_size ein. Wenn diese Variable auf null gesetzt ist, wird kein Cache verwendet. Der Schlüssel-Cache wird ferner nicht benutzt, wenn der Wert key_buffer_size zu klein ist, um die Mindestanzahl von Blockpuffern (8) zu reservieren.

Wenn der Schlüssel-Cache nicht betriebsbereit ist, erfolgt der Zugriff auf Indexdateien nur über die Puffer des nativen Dateisystems, die vom Betriebssystem bereitgestellt werden. (Anders gesagt, wird auf Tabellenindexblöcke unter Verwendung derselben Methode zugegriffen wie auf Tabellendatenblöcke.)

Ein Indexblock ist eine zusammenhängende Zugriffseinheit für MyISAM-Indexdateien. Normalerweise entspricht die Größe eines Indexblocks der Größe der Knoten des B-Trees. (Indizes werden auf der Festplatte mit einer B-Tree-Datenstruktur dargestellt. Knoten unten am Baum sind Blattknoten. Knoten über den Blattknoten sind nonleaf-Knoten.)

Alle Blockpuffer in einer Schlüssel-Cache-Struktur haben dieselbe Größe. Diese Größe kann der Größe eines Tabellenindexblocks entsprechen, sie kann aber auch höher oder niedriger sein. Normalerweise ist einer dieser beiden Werte ein Vielfaches des anderen.

Wenn ein Zugriff auf Daten aus einem Tabellenindexblock erfolgen muss, dann überprüft der Server zunächst, ob er in einem Blockpuffer des Schlüssel-Caches vorhanden ist. Ist dies der Fall, dann greift der Server auf die Daten im Schlüssel-Cache statt auf der Festplatte zu: Er liest aus und/oder schreibt in den Cache statt auf die Festplatte. Andernfalls wählt der Server einen Cache-Blockpuffer, der einen oder mehrere andere Tabellenindexblöcke enthält, und ersetzt die dortigen Daten durch eine Kopie des erforderlichen Tabellenindexblocks. Sobald der neue Indexblock sich im Cache befindet, kann auf die Indexdaten zugegriffen werden.

Sollte ein für den Ersatz selektierter Block verändert worden sein, wird der Block als „unbereinigt“ erachtet. In diesem Fall wird sein Inhalt vor dem Ersatz in den Tabellenindex geleert, aus dem er kam.

Üblicherweise folgt der Server einer LRU (Least Recently Used)-Strategie: Bei der Auswahl eines Block für den Ersatz wird der zuletzt verwendete Indexblock selektiert. Um die Auswahl zu erleichtern, unterhält das Schlüssel-Cache-Modul eine spezielle Warteschlange (die LRU-Kette) mit allen verwendeten Blöcken. Wenn auf einen Block zugegriffen wird, wird er ans Ende der Warteschlange gesetzt. Müssen Blöcke ersetzt werden, dann sind die Blöcke am Anfang der Warteschlange die am längsten nicht verwendeten und werden infolgedessen als Erste geräumt.

4.4.5.1. Gemeinschaftlicher Schlüsselcachezugriff

Threads können gleichzeitig auf Schlüssel-Cache-Puffer zugreifen. Dabei ist Folgendes zu beachten:

  • Ein Puffer kann von mehreren Sitzungen benutzt werden, sofern er derzeit nicht aktualisiert wird.

  • Wenn ein Puffer gerade aktualisiert wird, müssen Sitzungen, die ihn verwenden wollen, warten, bis das Update abgeschlossen ist.

  • Mehrere Sitzungen können Anfragen erzeugen, die zu Ersetzungen im Cache-Block führen können, solange sie sich nicht gegenseitig stören (d. h. solange sie verschiedene Indexblöcke benötigen und insofern auch verschiedene Cache-Blöcke ersetzt werden).

Der gemeinsame Zugriff auf den Schlüssel-Cache ermöglicht dem Server eine erhebliche Verbesserung des Durchsatzes. Mehrfache Index-Caches

4.4.5.2. Mehrfach-Schlüssel-Caches

Der gemeinsame Zugriff auf den Schlüssel-Cache verbessert die Leistung, beseitigt das Problem des gleichzeitigen Zugriffs durch mehrere Sitzungen aber nicht vollständig. Diese wetteifern weiterhin um Steuerstrukturen, mit denen der Zugriff auf die Schlüssel-Cache-Puffer verwaltet wird. Um also die Rivalität um den Schlüssel-Cache-Zugriff weiter zu verringern, stellt MySQL zusätzlich mehrere Schlüssel-Caches bereit. Diese Funktion erlaubt es Ihnen, verschiedenen Schlüssel-Caches unterschiedliche Tabellenindizes zuzuweisen.

Wenn mehrere Schlüssel-Caches vorhanden sind, muss der Server wissen, welchen Cache er bei der Verarbeitung von Abfragen für eine gegebene MyISAM-Tabelle verwenden soll. Standardmäßig werden alle MyISAM-Tabellenindizes im vorgabeseitigen Schlüssel-Cache zwischengespeichert. Um Tabellenindizes einem bestimmten Schlüssel-Cache zuzuweisen, verwenden Sie die Anweisung CACHE INDEX (siehe Abschnitt 8.5.6.2, „CACHE INDEX). Die folgende Anweisung beispielsweise weist Indizes der Tabellen t1, t2 und t3 dem Schlüssel-Cache namens hot_cache zu:

mysql> CACHE INDEX t1, t2, t3 IN hot_cache;
+---------+--------------------+----------+----------+
| Table   | Op                 | Msg_type | Msg_text |
+---------+--------------------+----------+----------+
| test.t1 | assign_to_keycache | status   | OK       |
| test.t2 | assign_to_keycache | status   | OK       |
| test.t3 | assign_to_keycache | status   | OK       |
+---------+--------------------+----------+----------+

Der in der CACHE INDEX-Anweisung referenzierte Schlüssel-Cache kann erstellt werden, indem seine Größe mit einer SET GLOBAL-Anweisung zur Parametereinstellung oder in den Startoptionen des Servers angegeben wird. Ein Beispiel:

mysql> SET GLOBAL keycache1.key_buffer_size=128*1024;

Um einen Schlüssel-Cache zu beseitigen, setzen Sie seine Größe auf null:

mysql> SET GLOBAL keycache1.key_buffer_size=0;

Beachten Sie, dass Sie den vorgabeseitigen Schlüssel-Cache nicht zerstören können. Alle diesbezüglichen Versuche werden ignoriert:

mysql> SET GLOBAL key_buffer_size = 0;
mysql> SHOW VARIABLES LIKE 'key_buffer_size';
+-----------------+---------+
| Variable_name   | Value   |
+-----------------+---------+
| key_buffer_size | 8384512 |
+-----------------+---------+

Schlüssel-Cache-Variablen sind strukturierte Systemvariablen, die einen Namen und Komponenten aufweisen. Bei keycache1.key_buffer_size etwa ist keycache1 der Cache-Variablenname und key_buffer_size die Cache-Komponente. Eine Beschreibung der Syntax zur Referenzierung strukturierter Systemvariablen für den Schlüssel-Cache finden Sie in Structured System Variables.

Standardmäßig werden Tabellenindizes dem (vorgabeseitigen) Hauptschlüssel-Cache zugewiesen, der beim Serverstart erstellt wird. Wird ein Schlüssel-Cache zerstört, dann werden alle ihm zugewiesenen Indizes wieder dem Standard-Schlüssel-Cache zugewiesen.

Für einen beschäftigten Server können Sie eine Strategie verwenden, die drei Schlüsselcaches enthält:

  • Ein „heißer“ Schlüssel-Cache, der 20 Prozent des für alle Schlüssel-Caches reservierten Speichers verwendet. Diesen setzen Sie für Tabellen ein, in denen sehr viele Suchvorgänge, aber keine Änderungen erfolgen.

  • Ein „kalter“ Schlüssel-Cache, der weitere 20 Prozent des für alle Schlüssel-Caches reservierten Speichers verwendet. Dieser Cache unterstützt mittelgroße, häufig geänderte Tabellen (z. B. Temporärtabellen).

  • Ein „warmer“ Schlüssel-Cache, der die verbleibenden 60 Prozent des Schlüssel-Cache-Speichers belegt. Diesen verwenden Sie als vorgabeseitigen Schlüssel-Cache, der standardmäßig von allen anderen Tabellen benutzt wird.

Ein Grund dafür, warum die Verwendung dreier Schlüssel-Caches von Vorteil ist, besteht darin, dass der Zugriff auf eine Schlüssel-Cache-Struktur den Zugriff auf die anderen nicht behindert. Anweisungen, die auf Tabellen zugreifen, die dem einen Cache zugewiesen sind, konkurrieren nicht mit Anweisungen, deren referenzierte Tabellen auf einen anderen Cache zugreifen. Ein Leistungsgewinn wird aber auch aus anderen Gründen erzielt:

  • Der heiße Cache wird nur für anfordernde Abfragen verwendet, d. h., sein Inhalt ändert sich nicht. Dies bedeutet, dass, wann immer ein Indexblock von der Festplatte abgerufen werden muss, der Inhalt des für die Ersetzung gewählten Cache-Blocks nicht zuerst synchronisiert werden muss.

  • Ist ein Index dem heißen Cache zugewiesen, dann ist, wenn keine Abfragen kommen, die einen Indexscan erfordern, die Wahrscheinlichkeit hoch, dass die Indexblöcke, die den Nichtblattknoten des B-Trees entsprechen, im Cache verbleiben.

  • Ein Updatevorgang, wie er am häufigsten für Temporärtabellen vorgenommen wird, wird wesentlich schneller durchgeführt, wenn der geänderte Knoten sich im Cache befindet und nicht erst von der Festplatte gelesen werden muss. Wenn die Größe der Indizes der Temporärtabellen mit der Größe des kalten Schlüssel-Caches vergleichbar ist, dann ist die Wahrscheinlichkeit, dass der aktualisierte Knoten sich im Cache befindet, extrem hoch.

CACHE INDEX richtet eine Verknüpfung zwischen einer Tabelle und einem Schlüssel-Cache ein, die jedoch nur bis zum nächsten Serverneustart bestehen bleibt. Wenn die Zuordnung jedes Mal wirksam werden soll, wenn der Server gestartet wird, können Sie das mit einer Optionsdatei erreichen: Schließen Sie Variableneinstellungen ein, die Ihre Schlüsselcaches konfigurieren, und eine init-file-Option, die eine Datei benennt, die auszuführende CACHE INDEX-Anweisungen enthält. Ein Beispiel:

key_buffer_size = 4G
hot_cache.key_buffer_size = 2G
cold_cache.key_buffer_size = 2G
init_file=/path/to/data-directory/mysqld_init.sql

Die Anweisungen in mysqld_init.sql werden bei jedem Start des Servers ausgeführt. Die Datei sollte eine SQL-Anweisung pro Zeile enthalten. Das folgende Beispiel weist verschiedene Tabellen jeweils hot_cache und cold_cache zu:

CACHE INDEX db1.t1, db1.t2, db2.t3 IN hot_cache
CACHE INDEX db1.t4, db2.t5, db2.t6 IN cold_cache

4.4.5.3. Mittelpunkteinfügestrategie

Standardmäßig verwendet das System zur Schlüssel-Cache-Verwaltung die LRU-Strategie zur Auswahl der zu räumenden Schlüssel-Cache-Blöcke, unterstützt aber auch eine komplexere Methode namens Strategie des Einfügens am Mittelpunkt.

Wenn man die Mittelpunkteinfügestrategie verwendet, wird die LRU-Kette in zwei Teile geteilt: eine heiße Unterkette und eine warme Unterkette. Der Unterteilungspunkt zwischen zwei Teilen ist dabei nicht fest, sondern das Schlüsselcachemanagementsystem sorgt dafür, dass der warme Teil nicht „zu kurz“ ist und immer mindestens key_cache_division_limit Prozent der Schlüsselcacheblöcke enthält. key_cache_division_limit ist ein Bestandteil der strukturierten Schlüsselcachevariablen, also ist der Wert ein Parameter, der für jeden einzelnen Cache gesetzt werden kann.

Wenn ein Indexblock aus einer Tabelle in den Schlüssel-Cache eingelesen wird, wird er an das Ende der warmen Unterkette gesetzt. Nach einer bestimmten Anzahl von Treffern (d. h. von Zugriffen auf den Block) wird er in die heiße Unterkette hochgestuft. Zurzeit ist die Anzahl der für das Hochstufen eines Blocks erforderlichen Treffer für alle Indexblöcke gleich (nämlich 3).

Ein Block, der in die heiße Unterkette hochgestuft wurde, wird an das Ende der Kette gesetzt. Der Block kreist dann innerhalb dieser Unterkette. Bleibt der Block lang genug am Anfang der Unterkette, dann wird er in die warme Unterkette zurückgestuft. Der Zeitpunkt wird vom Wert der Schlüssel-Cache-Komponente key_cache_age_threshold bestimmt.

Der Schwellwert definiert, dass bei einem Schlüssel-Cache mit N Blöcken der am Anfang der heißen Unterkette stehende Block an den Anfang der warmen Unterkette gesetzt wird, sofern er nicht innerhalb der letzten N key_cache_age_threshold / 100 Treffer aufgerufen wurde. Er wird dann erster Anwärter auf die Räumung, weil für die Ersetzung vorgesehene Blöcke am Anfang der warmen Unterkette entfernt werden.

Die Strategie des Einfügens am Mittelpunkt gestattet Ihnen, Blöcke, die offensichtlich wichtig sind, immer im Cache zu behalten. Wenn Sie die direkte LRU-Strategie bevorzugen, belassen Sie den Wert von key_cache_division_limit auf der Vorgabe von 100.

Die Strategie des Einfügens am Mittelpunkt ist hilfreich zur Leistungssteigerung, wenn die Ausführung einer Abfrage einen Indexscan erfordert und so im Endeffekt all diejenigen Indexblöcke aus dem Cache wirft, die wichtigen B-Tree-Knoten entsprechen. Um dies zu vermeiden, müssen Sie eine Mittelpunkteinfügestrategie verwenden, wobei key_cache_division_limit auf sehr viel weniger als 100 gesetzt wird. Dann werden wertvolle, häufig getroffene Knoten ebenso in der heißen Unterkette während einer Indexscanoperation bewahrt.

4.4.5.4. Index-Vorabladen

Die Blöcke wenn es genug Blöcke in einem Schlüsselcache gibt, um Blöcke eines ganzen Indexes zu halten, oder mindestens seinen Nichtblattknoten entsprechend, lässt es zu Vorlast den Schlüsselcache mit Indexblöcken abfühlen, bevor man anfängt, es zu verwenden. Dieses Vorabladen gestattet es Ihnen, die Tabellenindexblöcke auf effizienteste Art und Weise in einem Schlüssel-Cache-Puffer abzulegen – nämlich durch sequenzielles Lesen der Indexblöcke von der Festplatte.

Ohne Vorabladen werden die Blöcke so im Schlüssel-Cache abgelegt, wie sie von den Abfragen benötigt werden. Zwar bleiben die Blöcke dann im Cache, weil genug Puffer für sie alle vorhanden sind, aber sie werden dann nicht sequenziell, sondern in zufälliger Abfolge von der Festplatte abgerufen.

Um einen Index vorab in einen Cache zu laden, verwenden Sie die Anweisung LOAD INDEX INTO CACHE. Die folgende Anweisung beispielsweise lädt Knoten (Indexblöcke) mit Indizes der Tabellen t1 und t2:

mysql> LOAD INDEX INTO CACHE t1, t2 IGNORE LEAVES;
+---------+--------------+----------+----------+
| Table   | Op           | Msg_type | Msg_text |
+---------+--------------+----------+----------+
| test.t1 | preload_keys | status   | OK       |
| test.t2 | preload_keys | status   | OK       |
+---------+--------------+----------+----------+

Der Modifizierer IGNORE LEAVES bewirkt, dass nur Blöcke für Indexknoten, die nicht Endknoten (Blätter) sind, geladen werden. Auf diese Weise lädt die gezeigte Anweisung alle Indexblöcke von t1, von t2 hingegen nur Blöcke für die Nichtblattknoten.

Wenn ein Index mit einer CACHE INDEX-Anweisung einem Schlüssel-Cache zugewiesen wurde, platziert das Vorabladen die Indexblöcke in diesem Cache. Andernfalls wird der Index in den vorgabeseitigen Schlüssel-Cache geladen.

4.4.5.5. Schlüsselcacheblockgröße

Mit der Variablen key_cache_block_size ist es möglich, die Größe von Blockpuffern für einen einzelnen Schlüssel-Cache anzugeben. Auf diese Weise können Sie die Leistung von I/O-Operationen für Indexdateien optimieren.

Die beste Leistung für I/O-Operationen erhalten Sie, wenn die Größe der Lesepuffer der Größe der I/O-Puffer des nativen Betriebssystems entspricht. Allerdings gewährleistet das Einstellen der Schlüsselknotengröße auf die Größe der I/O-Puffer nicht immer die beste Gesamtperformance. Wenn der Server die großen Blattknoten ausliest, ruft er eine Menge unnötiger Daten ab, wodurch im Endeffekt das Lesen anderer Blattknoten verhindert wird.

Um die Größe der Blöcken in der .MYI-Indexdatei der MyISAM-Tabellen zu steuern, verwenden Sie die Option --myisam-block-size beim Serverstart.

4.4.5.6. Umstrukturieren eines Schlüsselcaches

Ein Schlüssel-Cache kann jederzeit durch Änderung seiner Parameterwerte umstrukturiert werden. Ein Beispiel:

mysql> SET GLOBAL cold_cache.key_buffer_size=4*1024*1024;

Wenn Sie den Schlüssel-Cache-Komponenten key_buffer_size oder key_cache_block_size einen anderen als den aktuellen Wert zuweisen, zerstört der Server die alte Struktur des Caches und erstellt eine neue, die auf den geänderten Werten basiert. Wenn der Cache unbereinigte Blöcke enthält, speichert der Server sie auf der Festplatte, bevor er den Cache zerstört und neu erstellt. Eine Umstrukturierung findet hingegen nicht statt, wenn Sie andere Schlüssel-Cache-Parameter ändern.

Wenn Sie einen Schlüssel-Cache umstrukturieren, synchronisiert der Server zunächst die Inhalte unbereinigter Puffer (soweit vorhanden) auf die Festplatte. Danach ist der Inhalt des Caches nicht mehr verfügbar. Allerdings blockiert die Umstrukturierung keine Abfragen, die dem Cache zugewiesene Indizes verwenden müssen. Stattdessen greift der Server in diesem Fall über das native Dateisystem-Caching direkt auf die Tabellenindizes zu. Das Dateisystem-Caching ist nicht so effizient wie ein Schlüssel-Cache, d. h., die Abfragen werden zwar ausgeführt, aber Sie können von Geschwindigkeitseinbußen ausgehen. Nachdem der Cache umstrukturiert wurde, werden ihm zugewiesene Indizes dort wieder zwischengespeichert, und das Dateisystem-Caching wird nicht mehr für die Indizes verwendet.

4.4.6. MyISAM-Indexstatistiksammlung

Speicher-Engines sammeln tabellenspezifische Statistiken, die der Optimierer verwenden kann. Tabellenstatistiken basieren auf Wertegruppen. Eine Wertegruppe ist eine Menge von Datensätzen mit demselben Schlüsselpräfixwert. Eine wichtige Statistik für Optimiererzwecke ist die Durchschnittswertgruppengröße.

MySQL verwendet die Durchschnittswertgruppengröße auf folgende Weisen:

  • um zu bestimmen, wie viele Datensätze für jeden ref-Zugriff gelesen werden müssen,

  • um einzuschätzen, wie viele Datensätze ein Teil-Join – oder, genauer, eine Operation der folgenden Form – erzeugt:

    (...) JOIN tbl_name ON tbl_name.key = expr
    

Wenn die Durchschnittswertgruppengröße für einen Index anwächst, ist der Index weniger nützlich für jene beiden Zwecke, weil die durchschnittliche Anzahl der Datensätze pro Anfrage anwächst: Damit der Index für Optimierungszwecke gut ist, sollte am besten jeder Indexwert auf eine kleine Anzahl von Datensätzen in der Tabelle zielen. Hat ein gegebener Indexwert eine hohe Zahl von Datensätzen zum Ergebnis, dann ist sein Nutzen eingeschränkt, und die Wahrscheinlichkeit, dass MySQL ihn verwendet, ist geringer.

Die durchschnittliche Wertegruppengröße bezieht sich auf die Kardinalität der Tabelle, d. h. die Anzahl der Wertegruppen. Die SHOW INDEX-Anweisung zeigt einen Kardinalitätswert basierend auf N ÷ S an, wobei N die Anzahl der Datensätze in der Tabelle und S die durchschnittliche Wertegruppengröße darstellt. Dieses Verhältnis gibt einen Näherungswert für die Anzahl der Wertegruppen in der Tabelle an.

Beruht ein Join auf dem Vergleichsoperator <=> wird NULL nicht anders als andere Werte behandelt: NULL <=> NULL genau wie N <=> N für ein beliebiges N.

Beruht ein Join allerdings auf dem Vergleichsoperator = unterscheidet sich NULL von Nicht-NULL-Werten: als expr1 = expr2 ist nicht wahr, wenn expr1 oder expr2 (oder beide) NULL sind. Das betrifft ref-Zugriffe bei Vergleichen der Form tbl_name.key = expr : MySQL wird nicht auf die Tabelle zugreifen, wenn der gegenwärtige Wert von expr NULL ist, weil der Vergleich nicht wahr sein kann.

Bei =-Vergleichen spielt es keine Rolle, wie viele NULL-Werte in der Tabelle vorhanden sind. Der für Optimierungszwecke relevante Wert ist die Durchschnittsgröße der Gruppe von Nicht-NULL-Werten. Allerdings gestattet MySQL derzeit keine Ermittlung oder Verwendung dieser Durchschnittsgröße.

Bei MyISAM-Tabellen haben Sie mit der Systemvariablen myisam_stats_method in eingeschränktem Maße Kontrolle über die Ermittlung der Tabellenstatistiken. Diese Variable hat drei mögliche Werte, die sich wie folgt voneinander unterscheiden:

  • Wennmyisam_stats_method ist nulls_equal, werden alle NULL Werte als identisch behandelt (das heißt, sie alle bilden eine Einzelwertgruppe).

    Wenn die NULL-Wertegruppe wesentlich größer ist als die Durchschnittsgröße der Gruppe der Nicht-NULL-Werte, dann erhöht diese Methode die durchschnittliche Wertegruppengröße. Aufgrund dessen erscheint der Index dem Optimierer weniger nützlich, als er es für Joins, die nach Nicht-NULL-Werten suchen, tatsächlich ist. Im Ergebnis kann die nulls_equal-Methode also dazu führen, dass der Optimierer den Index für ref nicht verwendet, obwohl er es sollte.

  • Wenn myisam_stats_method nulls_unequal ist, werden NULL-Werte nicht als identisch betrachtet. Stattdessen bildet jeder NULL-Wert eine separate Wertegruppe der Größe 1.

    Wenn Sie viele NULL-Werte haben, verschiebt diese Methode den Durchschnittswert für die Wertegruppengröße nach unten. Ist der Durchschnittswert der Gruppe der Nicht-NULL-Werte hoch, dann kann dieses Verhalten dazu führen, dass der Optimierer den Wert des Indexes für Joins überschätzt, die nach Nicht-NULL-Werten suchen. Aufgrund dessen kann der nulls_unequal-Ansatz dazu führen, dass der Optimierer diesen Index für ref-Suchvorgänge verwendet, obwohl andere Methoden besser geeignet wären.

  • Wenn myisam_stats_method nulls_ignored ist, werden NULL-Werte ignoriert.

Wenn Sie häufig viele Joins benutzen, die <=> statt = verwenden, dann werden NULL-Werte in Vergleichen nicht gesondert betrachtet, sondern ein NULL-Wert entspricht dem anderen. In diesem Fall ist nulls_equal die passende Statistikmethode.

Die Systemvariable myisam_stats_method hat globale und sitzungsbezogene Werte. Das Einstellen des globalen Werts wirkt sich auf die MyISAM-Statistikermittlung bei allen MyISAM-Tabellen aus. Im Gegensatz dazu wirkt der Sitzungswert nur auf Statistiken zur aktuellen Clientverbindung. Sie können also, indem Sie den Sitzungswert von myisam_stats_method einstellen, die Neuerstellung der Statistiken zu einer Tabelle mit einer gegebenen Methode erzwingen, ohne dass andere Clients hiervon beeinträchtigt würden.

Zur Neuerstellung der Tabellenstatistiken können Sie eine der folgenden Methoden benutzen:

  • Führen Sie myisamchk --stats_method=method_name --analyze aus.

  • Ändern Sie die Tabelle so ab, dass die Statistiken veralten (indem Sie beispielsweise einen Datensatz einfügen und ihn dann löschen), stellen Sie myisam_stats_method ein und setzen Sie eine ANALYZE TABLE-Anweisung ab.

Die Verwendung von myisam_stats_method hat auch ein paar Nachteile:

  • Sie können die Ermittlung von Tabellenstatistiken wie gerade beschrieben erzwingen. Allerdings kann MySQL die Statistiken auch automatisch sammeln. Wenn beispielsweise während der Ausführung von Anweisungen für eine Tabelle einige dieser Anweisungen die Tabelle ändern, ermittelt MySQL unter Umständen Statistiken. (Dies kann etwa bei Masseneinfüge- oder -löschoperationen oder bei bestimmten ALTER TABLE-Anweisungen der Fall sein.) Wenn dies geschieht, werden die Statistiken ohne Berücksichtigung des aktuellen Werts von myisam_stats_method gesammelt. Wenn Sie also Statistiken mit einer bestimmten Methode ermitteln, aber myisam_stats_method bei einer späteren automatischen Statistiksammlung auf eine andere Methode gesetzt wird, dann wird diese andere Methode verwendet.

  • Es gibt keine Möglichkeit, festzustellen, welche Methode zur Erzeugung von Statistiken für eine gegebene MyISAM-Tabelle verwendet wurde.

  • myisam_stats_method gilt nur für MyISAM-Tabellen. Die übrigen Speicher-Engines haben jeweils eigene Methoden zur Ermittlung von Tabellenstatistiken. Diese ähneln der Methode nulls_equal.

4.4.7. So öffnet und schließt MySQL Tabellen

Wenn Sie einen mysqladmin status-Befehl ausführen, sollten Sie etwa folgendes Ergebnis erhalten:

Uptime: 426 Running threads: 1 Questions: 11082
Reloads: 1 Open tables: 12

Der Open tables-Wert von 12 kann etwas verwirrend sein, wenn Sie nur sechs Tabellen haben.

MySQL arbeitet mit mehreren Threads, d. h., mehrere Clients setzen unter Umständen gleichzeitig Abfragen für eine gegebene Tabelle ab. Um das Problem mit mehreren Client-Sitzungen, die unterschiedliche Zustände bezüglich derselben Tabelle haben, zu minimieren, wird die Tabelle von allen nebenläufigen Sitzungen unabhängig geöffnet. Zwar wird hierdurch mehr Speicher verbraucht, aber in der Regel wird die Leistung verbessert. Bei MyISAM-Tabellen ist pro Client, der eine Tabelle geöffnet hält, ein zusätzlicher Dateideskriptor für die Datendatei erforderlich. (Dies steht im Gegensatz zum Indexdateideskriptor, der von allen Sitzungen gemeinsam verwendet wird.)

Anmerkung

table_open_cache war früher als table_cache in MySQL 5.1.2 und früher bekannt.

Die Systemvariablen table_open_cache, max_connections und max_tmp_tables bestimmen die maximale Anzahl der Dateien, die der Server geöffnet hält. Wenn Sie einen oder mehrere dieser Werte erhöhen, stoßen Sie unter Umständen auf ein Limit, das Ihr Betriebssystem bezüglich der prozessbezogenen Anzahl offener Dateideskriptoren setzt. Viele Betriebssysteme erlauben Ihnen eine Anhebung der Beschränkung für offene Dateien, auch wenn sich die jeweilige Methode von Betriebssystem zu Betriebssystem unterscheidet. Informationen dazu, ob und wie es möglich ist, diesen Wert anzuheben, entnehmen Sie der Dokumentation zu Ihrem Betriebssystem.

table_open_cache bezieht sich auf max_connections. So sollten Sie etwa für 200 gleichzeitig laufende Verbindungen einen Tabellen-Cache mit einer Größe von mindestens 200 N haben, wobei N die maximale Anzahl von Tabellen pro Join in einer beliebigen von Ihnen ausgeführten Abfrage ist. Sie müssen ferner einige zusätzliche Dateideskriptoren für Temporärtabellen und -dateien reservieren.

Stellen Sie sicher, dass Ihr Betriebssystem die Anzahl der mit der Einstellung von table_open_cache verbundenen Deskriptoren für offene Dateien verarbeiten kann. Wenn für table_open_cache ein zu hoher Wert eingestellt ist, stehen für MySQL irgendwann unter Umständen keine Dateideskriptoren mehr zur Verfügung: Sie müssen ferner berücksichtigen, dass die MyISAM-Speicher-Engine zwei Dateideskriptoren für jede offene Tabelle benötigt. Sie können die Anzahl der MySQL zur Verfügung stehenden Dateideskriptoren mit der Startoption --open-files-limit für mysqld erhöhen. Siehe auch 'File' Not Found and Similar Errors.

Der Cache für die offenen Tabellen wird auf einem Niveau von table_open_cache Einträgen gehalten. Der Standardwert beträgt 64, kann aber mit der Option --table_open_cache für mysqld geändert werden. Beachten Sie, dass MySQL zur Ausführung von Abfragen vorübergehend auch mehr Tabellen öffnen kann.

MySQL schließt nicht verwendete Tabellen und entfernt sie aus dem Tabellen-Cache, wenn

  • der Cache voll ist und ein Thread eine Tabelle zu öffnen versucht, die nicht im Cache enthalten ist,

  • der Cache mehr als table_open_cache Einträge enthält und eine Tabelle im Cache von keinem Thread mehr verwendet wird,

  • die Tabelle synchronisiert wird. Dies passiert, wenn jemand eine FLUSH TABLES-Anweisung absetzt oder einen der Befehle mysqladmin flush-tables oder mysqladmin refresh ausführt.

Wenn der Tabellen-Cache Einträge enthält, ermittelt der Server einen zu verwendenden Cache-Eintrag wie folgt:

  • Tabellen, die zurzeit nicht verwendet werden, werden freigegeben. Hierbei wird mit der Tabelle begonnen, die am längsten nicht verwendet wurde.

  • Wenn eine neue Tabelle geöffnet werden muss, der Cache aber voll ist und keine Tabelle freigegeben werden kann, dann wird der Cache vorübergehend nach Bedarf erweitert. Ist der Cache vorübergehend erweitert und eine Tabelle erhält den Status nicht verwendet, dann wird diese Tabelle geschlossen und aus dem Cache entfernt.

Eine MyISAM-Tabelle wird für jeden gleichzeitigen Zugriff geöffnet. Das bedeutet, dass die Tabelle zweimal geöffnet werden muss, wenn zwei Threads auf dieselbe Tabelle zugreifen oder ein Thread die Tabelle zweimal in derselben Abfrage referenziert (beispielsweise beim Join einer Tabelle mit sich selbst). Jeder gleichzeitige Öffnungsvorgang erfordert einen Eintrag im Tabellen-Cache. Der erste Öffnungsvorgang einer MyISAM-Tabelle nimmt zwei Dateideskriptoren entgegen, nämlich je einen für die Daten- und die Indexdatei. Jede zusätzliche Verwendung der Tabelle benötigt nur einen Deskriptor für die Datendatei. Der Deskriptor für die Indexdateien wird von allen Threads gemeinsam verwendet.

Wenn Sie eine Tabelle mit der Anweisung HANDLER tbl_name OPEN öffnen, wird für den Thread ein dediziertes Tabellenobjekt reserviert. Dieses Tabellenobjekt wird nicht mit anderen Threads gemeinsam genutzt und wird erst geschlossen, wenn der Thread HANDLER tbl_name CLOSE aufruft oder beendet wird. In diesem Fall wird die Tabelle in den Tabellen-Cache zurückgeführt (sofern dieser nicht voll ist). Siehe auch Abschnitt 8.2.4, „HANDLER.

Sie können festlegen, ob Ihr Tabellen-Cache zu klein ist, indem Sie die mysqld-Statusvariable Opened_tables überprüfen, die die Anzahl der Tabellenöffnungoperationen seit dem Serverstart angibt:

mysql> SHOW GLOBAL STATUS LIKE 'Opened_tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Opened_tables | 2741  |
+---------------+-------+

Wenn der Wert sehr groß ist oder rasch anwächst, sollten Sie - auch wenn Sie nicht viele FLUSH TABLES-Anweisungen ausgegeben haben - die Tabellen-Cache-Größe erhöhen. Siehe auch Server System Variables, und Server Status Variables.

4.4.8. Nachteile durch das Erstellen vieler Tabellen in der gleichen Datenbank

Wenn sich viele MyISAM-Tabellen im selben Datenbankverzeichnis befinden, verlaufen Operationen wie das Öffnen, Schließen und Erstellen von Tabellen sehr langsam. Führen Sie SELECT-Anweisungen für viele verschiedene Tabellen aus, dann tritt eine geringe Mehrbelastung auf, wenn der Tabellen-Cache voll ist, weil für jede Tabelle, die geöffnet wird, eine andere geschlossen werden muss. Sie können diesen Aufwand reduzieren, indem Sie die Anzahl von erlaubten Einträgen im Tabellen-Cache erhöhen.

4.5. Optimieren des MySQL-Servers

4.5.1. So wirken sich Kompilieren und Verknüpfen auf die Geschwindigkeit von MySQL aus

Die meisten der folgenden Tests wurden unter Linux mit den MySQL-Benchmarks durchgeführt, sie sollten aber trotzdem ausreichend aussagekräftig auch für andere Betriebssysteme und Belastungsbereiche sein.

Sie erhalten die schnellsten ausführbaren Dateien, indem Sie mit der Option -static verknüpfen.

Unter Linux kompilieren Sie den Server am besten mit pgcc und -O3. Sie benötigen etwa 200 Mbyte Speicher zur Kompilierung von sql_yacc.cc mit diesen Optionen, weil gcc oder pgcc eine Menge Speicher benötigt, um alle Funktionen zu integrieren. Ferner sollten Sie bei der Konfiguration von MySQL CXX=gcc einstellen, um die Miteinbeziehung der Bibliothek libstdc++ zu vermeiden, denn diese wird nicht benötigt. Beachten Sie, dass bei einigen Versionen von pgcc die resultierende Binärdatei nur auf echten Pentium-Prozessoren läuft, auch wenn Sie eine Compileroption verwendet haben, mit der Sie angeben wollten, dass der Ergebniscode auf allen x586-Prozessoren (z. B. AMD) laufen soll.

Sie können eine Geschwindigkeitszunahme von 10 bis 30 Prozent erzielen, indem Sie einen besseren Compiler und geeignetere Kompilierungsoptionen verwenden. Dies ist besonders wichtig, wenn Sie den MySQL Server selbst kompilieren.

Als wir die Cygnus CodeFusion- und Fujitsu-Compiler testeten, stellte sich heraus, dass keiner von diesen ausreichend wenig Bugs aufwies, um MySQL mit aktivierten Optimierungen zu kompilieren.

MySQL-Standarddistributionen werden mit der Unterstützung für alle Zeichensätze kompiliert. Wenn Sie MySQL selbst kompilieren, sollten Sie die Unterstützung nur für diejenigen Zeichensätze integrieren, die Sie tatsächlich verwenden werden. Dies wird mit der Option --with-charset für configure gesteuert.

Es folgt eine Liste einiger Maßnahmen, die wir vorgenommen haben:

  • Wenn Sie pgcc verwenden und alles mit -O6 kompilieren, ist der Server mysqld um ein Prozent schneller als mit gcc 2.95.2.

  • Wenn Sie dynamisch verknüpfen (also ohne -static), ist das Ergebnis unter Linux um 13 Prozent langsamer. Beachten Sie, dass Sie eine dynamisch verknüpfte MySQL-Bibliothek weiterhin für Ihre Clientanwendungen benutzen können. Es ist der Server, der für die Leistungsfähigkeit die kritischste Komponente darstellt.

  • Bei einer Verbindung von einem Client zu einem Server, der auf demselben Host läuft, ist die Leistung um 7,5 Prozent geringer, wenn Sie die Verbindung über TCP/IP statt über eine Unix-Socketdatei herstellen. (Unter Unix verwendet MySQL, wenn Sie die Verbindung zum Hostnamen localhost herstellen, standardmäßig eine Socketdatei.)

  • TCP/IP-Verbindungen von einem Client mit einem Server sind um 8 bis 11 Prozent langsamer, wenn der Server auf einem entfernten System liegt, als bei Verbindung mit einem Server auf demselben Host (und zwar auch bei Verbindungen schneller als 100Mb/s Ethernet).

  • Bei Ausführung unserer Benchmark-Tests über sichere Verbindungen (d. h., alle Daten wurden durch die interne SSL-Unterstützung verschlüsselt) war die Leistung um 55 Prozent geringer als bei unverschlüsselten Verbindungen.

  • Wenn Sie mit --with-debug=full kompilieren, sind die meisten Abfragen 20 Prozent langsamer. Einige Abfragen können deutlich länger benötigen; so laufen die MySQL-Benchmarks um 35 Prozent langsamer. Wenn Sie --with-debug (ohne =full) angeben, liegt der Geschwindigkeitsverlust lediglich bei 15 Prozent. Bei einer Version von mysqld, die mit --with-debug=full kompiliert wurde, können Sie die Speicherüberprüfung zur Laufzeit abschalten, indem Sie sie mit der Option --skip-safemalloc starten. Die Ausführungsgeschwindigkeit sollte in diesem Fall nicht allzu weit unter derjenigen liegen, die sich bei einer Konfiguration mit --with-debug erzielen lässt.

  • Auf einem Sun UltraSPARC-IIe ist ein mit Forte 5.0 kompilierter Server 4 Prozent schneller als ein mit gcc 3.2 kompilierter Server.

  • Auf einem Sun UltraSPARC-IIe ist ein mit Forte 5.0 kompilierter Server im 32-Bit-Modus 4 Prozent schneller als im 64-Bit-Modus.

  • Die Kompilierung mit gcc 2.95.2 für UltraSPARC mit den Optionen -mcpu=v8 -Wa, -xarch=v8plusa bietet einen Leistungszuwachs von 4 Prozent.

  • Auf Solaris 2.5.1 ist MIT-pthreads 8 bis 12 Prozent langsamer als native Solaris-Threads auf einem einzelnen Prozessor. Bei hoher Belastung oder mehr Prozessoren sollte der Unterschied noch größer sein.

  • Die Kompilierung auf Linux-x86 mit gcc ohne Frame-Zeiger (-fomit-frame-pointer oder -fomit-frame-pointer -ffixed-ebp) macht mysqld 1 bis 4 Prozent schneller.

Binäre MySQL-Distributionen für Linux, für die von uns bereitgestellt werden, wurden normalerweise mit pgcc kompiliert. Aufgrund eines Bugs in pgcc, der dazu führte, dass die erzeugten Binärdateien nicht auf AMD-Prozessoren liefen, mussten wir jedoch zu gcc zurückkehren. Wir werden gcc weiterhin verwenden, bis dieser Bug behoben ist. In der Zwischenzeit können Sie, wenn Sie kein AMD-System haben, durch Kompilierung mit pgcc eine schnellere Binärdatei erstellen. Die MySQL-Standardbinärdatei für Linux ist statisch verknüpft, um Geschwindigkeit und Portabilität zu optimieren.

4.5.2. Systemfaktoren und Startup-Parameter-Tuning

Wir beginnen mit den Faktoren auf der Systemebene, weil einige dieser Entscheidungen sehr früh getroffen werden müssen, um einen beträchtlichen Leistungszugewinn zu erzielen. In anderen Fällen kann ein kurzer Blick in diesen Abschnitt ausreichen. Allerdings kann es immer praktisch sein, ein Gespür dafür zu entwickeln, welcher Zugewinn sich durch Änderung von Faktoren auf dieser Ebene erzielen lässt.

Das Betriebssystem, welches verwendet werden soll, ist ein wesentlicher Faktor. Um aus Mehrprozessorrechnern die optimale Leistung zu erzielen, sollten Sie Solaris (aufgrund seiner gut funktionierenden Thread-Implementierung) oder Linux verwenden (weil der Kernel der Versionen 2.4 und höher eine gute SMP-Unterstützung bietet). Beachten Sie, dass ältere Linux-Kernels standardmäßig eine Dateigrößenbeschränkung auf 2 Gbyte aufweisen. Wenn Sie einen solchen Kernel verwenden, Ihre Dateien aber größer werden könnten als 2 Gbyte, dann sollten Sie sich den LFS-Patch (Large File Support) für das ext2-Dateisystem besorgen. Andere Dateisysteme wie ReiserFS und XFS haben diese 2GB-Begrenzung nicht.

Bevor Sie MySQL in die Produktion nehmen, sollten Sie es auf der vorgesehenen Plattform testen.

Weitere Tipps:

  • Wenn Sie genug RAM haben, können Sie in Betracht ziehen, alle Auslagerungsgeräte zu entfernen. Einige Betriebssysteme verwenden unter bestimmten Umständen ein Auslagerungsgerät auch dann, wenn freier Speicher vorhanden ist.

  • Vermeiden Sie externe Sperren. Seit MySQL 4.0 ist die externe Sperrung standardmäßig auf allen Systemen deaktiviert. Mit den Optionen --external-locking und --skip-external-locking können Sie externe Sperren explizit aktivieren bzw. deaktivieren.

    Beachten Sie, dass die Deaktivierung externer Sperren die Funktionalität von MySQL nicht beeinträchtigt, solange Sie nur einen einzelnen Server ausführen. Denken Sie aber immer daran, den Server abzuschalten (oder die relevanten Tabellen zu sperren und zu synchronisieren), bevor Sie myisamchk ausführen. Auf einigen Systemen ist die Deaktivierung externer Sperren obligatorisch, weil sie dort ohnehin nicht funktionieren.

    Der einzige Fall, in dem Sie die externe Sperrung nicht deaktivieren können, liegt vor, wenn Sie mehrere MySQL Server (nicht Clients) mit demselben Datenbestand betreiben, oder wenn Sie mit myisamchk eine Tabelle überprüfen (nicht reparieren), ohne den Server zuvor angewiesen zu haben, die Tabellen zuerst zu sperren und zu synchronisieren. Beachten Sie, dass von der Verwendung mehrerer MySQL Server für den gleichzeitigen Zugriff auf dieselben Daten generell abzuraten ist, sofern Sie nicht MySQL Cluster verwenden.

    Die Anweisungen LOCK TABLES und UNLOCK TABLES verwenden interne Sperren, d. h., Sie können sie auch bei deaktivierter externer Sperrung verwenden.

4.5.3. Tuning der Server-Parameter

Mit dem folgenden Befehl können Sie die standardmäßigen Puffergrößen festlegen, die der Server mysqld verwendet:

shell> mysqld --verbose --help

Dieser Befehl erzeugt eine Liste aller mysqld-Optionen und konfigurierbarer Systemvariablen. Die Ausgabe enthält die Standardwerte der Variablen und sieht etwa so aus:

abort-slave-event-count           0
allow-suspicious-udfs             FALSE
auto-increment-increment          1
auto-increment-offset             1
automatic-sp-privileges           TRUE
back_log                          50
basedir                           /home/jon/bin/mysql-5.1/
bind-address                      (No default value)
binlog-row-event-max-size         1024
binlog_cache_size                 32768
binlog_format                     (No default value)
bulk_insert_buffer_size           8388608
character-set-client-handshake    TRUE
character-set-filesystem          binary
character-set-server              latin1
character-sets-dir                /home/jon/bin/mysql-5.1/share/mysql/charsets/
chroot                            (No default value)
collation-server                  latin1_swedish_ci
completion-type                   0
concurrent-insert                 1
connect_timeout                   10
console                           FALSE
datadir                           .
datetime_format                   %Y-%m-%d %H:%i:%s
date_format                       %Y-%m-%d
default-character-set             latin1
default-collation                 latin1_swedish_ci
default-storage-engine            MyISAM
default-table-type                MyISAM
default-time-zone                 (No default value)
default_week_format               0
delayed_insert_limit              100
delayed_insert_timeout            300
delayed_queue_size                1000
disconnect-slave-event-count      0
div_precision_increment           4
enable-locking                    FALSE
engine-condition-pushdown         TRUE
expire_logs_days                  0
external-locking                  FALSE
flush_time                        0
ft_max_word_len                   84
ft_min_word_len                   4
ft_query_expansion_limit          20
ft_stopword_file                  (No default value)
gdb                               FALSE
general_log                       FALSE
general_log_file                  (No default value)
group_concat_max_len              1024
help                              TRUE
init-connect                      (No default value)
init-file                         (No default value)
init-slave                        (No default value)
innodb                            TRUE
innodb-adaptive-hash-index        TRUE
innodb-additional-mem-pool-size   1048576
innodb-autoextend-increment       8
innodb-autoinc-lock-mode          1
innodb-buffer-pool-size           8388608
innodb-checksums                  TRUE
innodb-commit-concurrency         0
innodb-concurrency-tickets        500
innodb-data-file-path             (No default value)
innodb-data-home-dir              (No default value)
innodb-doublewrite                TRUE
innodb-fast-shutdown              1
innodb-file-io-threads            4
innodb-file-per-table             FALSE
innodb-flush-log-at-trx-commit    1
innodb-flush-method               (No default value)
innodb-force-recovery             0
innodb-lock-wait-timeout          50
innodb-locks-unsafe-for-binlog    FALSE
innodb-log-buffer-size            1048576
innodb-log-file-size              5242880
innodb-log-files-in-group         2
innodb-log-group-home-dir         (No default value)
innodb-max-dirty-pages-pct        90
innodb-max-purge-lag              0
innodb-mirrored-log-groups        1
innodb-open-files                 300
innodb-rollback-on-timeout        FALSE
innodb-stats-on-metadata          TRUE
innodb-status-file                FALSE
innodb-support-xa                 TRUE
innodb-sync-spin-loops            20
innodb-table-locks                TRUE
innodb-thread-concurrency         8
innodb-thread-sleep-delay         10000
interactive_timeout               28800
join_buffer_size                  131072
keep_files_on_create              FALSE
key_buffer_size                   8384512
key_cache_age_threshold           300
key_cache_block_size              1024
key_cache_division_limit          100
language                          /home/jon/bin/mysql-5.1/share/mysql/english/
large-pages                       FALSE
lc-time-names                     en_US
local-infile                      TRUE
log                               (No default value)
log-bin                           (No default value)
log-bin-index                     (No default value)
log-bin-trust-function-creators   FALSE
log-bin-trust-routine-creators    FALSE
log-error
log-isam                          myisam.log
log-output                        FILE
log-queries-not-using-indexes     FALSE
log-short-format                  FALSE
log-slave-updates                 FALSE
log-slow-admin-statements         FALSE
log-slow-slave-statements         FALSE
log-tc                            tc.log
log-tc-size                       24576
log-update                        (No default value)
log-warnings                      1
log_slow_queries                  (No default value)
long_query_time                   10
low-priority-updates              FALSE
lower_case_table_names            0
master-connect-retry              60
master-host                       (No default value)
master-info-file                  master.info
master-password                   (No default value)
master-port                       3306
master-retry-count                86400
master-ssl                        FALSE
master-ssl-ca                     (No default value)
master-ssl-capath                 (No default value)
master-ssl-cert                   (No default value)
master-ssl-cipher                 (No default value)
master-ssl-key                    (No default value)
master-user                       test
max-binlog-dump-events            0
max_allowed_packet                1048576
max_binlog_cache_size             18446744073709547520
max_binlog_size                   1073741824
max_connections                   151
max_connect_errors                10
max_delayed_threads               20
max_error_count                   64
max_heap_table_size               16777216
max_join_size                     18446744073709551615
max_length_for_sort_data          1024
max_prepared_stmt_count           16382
max_relay_log_size                0
max_seeks_for_key                 18446744073709551615
max_sort_length                   1024
max_sp_recursion_depth            0
max_tmp_tables                    32
max_user_connections              0
max_write_lock_count              18446744073709551615
memlock                           FALSE
min_examined_row_limit            0
multi_range_count                 256
myisam-recover                    OFF
myisam_block_size                 1024
myisam_data_pointer_size          6
myisam_max_extra_sort_file_size   2147483648
myisam_max_sort_file_size         9223372036853727232
myisam_repair_threads             1
myisam_sort_buffer_size           8388608
myisam_stats_method               nulls_unequal
myisam_use_mmap                   FALSE
ndb-autoincrement-prefetch-sz     1
ndb-cache-check-time              0
ndb-connectstring                 (No default value)
ndb-extra-logging                 0
ndb-force-send                    TRUE
ndb-index-stat-enable             FALSE
ndb-mgmd-host                     (No default value)
ndb-nodeid                        0
ndb-optimized-node-selection      TRUE
ndb-report-thresh-binlog-epoch-slip 3
ndb-report-thresh-binlog-mem-usage 10
ndb-shm                           FALSE
ndb-use-copying-alter-table       FALSE
ndb-use-exact-count               TRUE
ndb-use-transactions              TRUE
ndb_force_send                    TRUE
ndb_use_exact_count               TRUE
ndb_use_transactions              TRUE
net_buffer_length                 16384
net_read_timeout                  30
net_retry_count                   10
net_write_timeout                 60
new                               FALSE
old                               FALSE
old-alter-table                   FALSE
old-passwords                     FALSE
old-style-user-limits             FALSE
open_files_limit                  1024
optimizer_prune_level             1
optimizer_search_depth            62
pid-file                          /home/jon/bin/mysql-5.1/var/tonfisk.pid
plugin-load                       (No default value)
plugin_dir                        /home/jon/bin/mysql-5.1/lib/mysql/plugin
port                              3306
port-open-timeout                 0
preload_buffer_size               32768
profiling_history_size            15
query_alloc_block_size            8192
query_cache_limit                 1048576
query_cache_min_res_unit          4096
query_cache_size                  0
query_cache_type                  1
query_cache_wlock_invalidate      FALSE
query_prealloc_size               8192
range_alloc_block_size            4096
read_buffer_size                  131072
read_only                         FALSE
read_rnd_buffer_size              262144
record_buffer                     131072
relay-log                         (No default value)
relay-log-index                   (No default value)
relay-log-info-file               relay-log.info
relay_log_purge                   TRUE
relay_log_space_limit             0
replicate-same-server-id          FALSE
report-host                       (No default value)
report-password                   (No default value)
report-port                       3306
report-user                       (No default value)
rpl-recovery-rank                 0
safe-user-create                  FALSE
secure-auth                       FALSE
secure-file-priv                  (No default value)
server-id                         0
show-slave-auth-info              FALSE
skip-grant-tables                 FALSE
skip-slave-start                  FALSE
slave-exec-mode                   STRICT
slave-load-tmpdir                 /tmp
slave_compressed_protocol         FALSE
slave_net_timeout                 3600
slave_transaction_retries         10
slow-query-log                    FALSE
slow_launch_time                  2
slow_query_log_file               (No default value)
socket                            /tmp/mysql.sock
sort_buffer_size                  2097144
sporadic-binlog-dump-fail         FALSE
sql-mode                          OFF
symbolic-links                    TRUE
sync-binlog                       0
sync-frm                          TRUE
sysdate-is-now                    FALSE
table_cache                       64
table_definition_cache            256
table_lock_wait_timeout           50
table_open_cache                  64
tc-heuristic-recover              (No default value)
temp-pool                         TRUE
thread_cache_size                 0
thread_concurrency                10
thread_stack                      262144
timed_mutexes                     FALSE
time_format                       %H:%i:%s
tmpdir                            (No default value)
tmp_table_size                    16777216
transaction_alloc_block_size      8192
transaction_prealloc_size         4096
updatable_views_with_limit        1
use-symbolic-links                TRUE
verbose                           TRUE
wait_timeout                      28800
warnings                          1

Wird gerade ein mysqld-Server ausgeführt, dann können Sie die aktuellen Werte seiner Systemvariablen anzeigen, indem Sie eine Verbindung mit ihm herstellen und die folgende Anweisung absetzen:

mysql> SHOW VARIABLES;

Mit der folgenden Anweisung können Sie statistische Informationen und Statusangaben für einen laufenden Server abrufen:

mysql> SHOW STATUS;

Angaben zu Systemvariablen und Status erhalten Sie auch mit mysqladmin:

shell> mysqladmin variables
shell> mysqladmin extended-status

Eine vollständige Beschreibung aller System- und Statusvariablen finden Sie in Server System Variables und Server Status Variables.

MySQL verwendet Algorithmen, die sehr gut skalierbar sind, d. h., Sie können MySQL gewöhnlich mit sehr wenig Speicher ausführen. Andererseits erhalten Sie eine umso bessere Performance, je mehr Speicher Sie MySQL zugestehen.

Wenn Sie einen MySQL Server optimieren, dann sind die beiden wichtigsten zu konfigurierenden Variablen key_buffer_size und table_open_cache. Sie sollten erst ganz sicher sein, dass Sie für diese Variablen geeignete Werte eingestellt haben, bevor Sie andere Variablen zu ändern versuchen.

Die folgenden Beispiele zeigen einige typische Variablenwerte für verschiedene Laufzeitkonfigurationen.

  • Wenn Sie mindestens 256 Mbyte Speicher und viele Tabellen haben und für eine moderate Anzahl von Clients die optimale Leistung erzielen wollen, sollten Sie einmal Folgendes probieren:

    shell> mysqld_safe --key_buffer_size=64M --table_open_cache=256 \
               --sort_buffer_size=4M --read_buffer_size=1M &
    
  • Haben Sie nur 128 Mbyte Speicher und nur ein paar Tabellen, die aber häufig sortiert werden müssen, dann können Sie Folgendes ausprobieren:

    shell> mysqld_safe --key_buffer_size=16M --sort_buffer_size=1M
    

    Wenn es sehr viele simultane Verbindungen gibt, können Auslagerungsprobleme auftreten, außer wenn mysqld so konfiguriert worden ist, dass es sehr wenig Speicher für jede Verbindung nutzt. mysqld funktioniert besser, wenn Sie genug Speicher für alle Verbindungen haben.

  • Bei sehr wenig Speicher und vielen Verbindungen verwenden Sie Folgendes:

    shell> mysqld_safe --key_buffer_size=512K --sort_buffer_size=100K \
               --read_buffer_size=100K &
    

    Oder sogar Folgendes:

    shell> mysqld_safe --key_buffer_size=512K --sort_buffer_size=16K \
               --table_open_cache=32 --read_buffer_size=8K \
               --net_buffer_length=1K &
    

Wenn Sie GROUP BY- oder ORDER BY-Operationen an Tabellen durchführen, die wesentlich größer sind als der verfügbare Speicher, dann sollten Sie den Wert von read_rnd_buffer_size erhöhen, um nach Durchführung von Sortieroperationen das Auslesen von Datensätzen zu beschleunigen.

Sie können auch die Beispieloptionsdateien verwenden, die zum Umfang Ihrer MySQL-Distribution gehören, siehe Preconfigured Option Files.

Wenn Sie für mysqld oder mysqld_safe eine Option auf der Befehlszeile angeben, ist diese nur für den betreffenden Aufruf des Servers gültig. Um diese Option jedes Mal bei Ausführung des Servers zu verwenden, müssen Sie sie in einer Optionsdatei ablegen.

Um die Wirkung einer Parameteränderung zu prüfen, können Sie Folgendes tun:

shell> mysqld --key_buffer_size=32M --verbose --help

Die Variablenwerte sind kurz vor Ende der Ausgabe aufgeführt. Vergewissern Sie sich, dass die Optionen --verbose und --help am Ende stehen. Andernfalls werden die Auswirkungen von Optionen, die nach diesen beiden Optionen auf der Befehlszeile angegeben wurden, in der Ausgabe nicht berücksichtigt.

Informationen zur Optimierung der InnoDB-Speicher-Engine finden Sie in Abschnitt 9.13.1, „Tipps zum InnoDB-Leistungs-Tuning“.

4.5.4. Steuern der Abfrageoptimiererleistung

Die Aufgabe des Abfrageoptimierers besteht darin, einen optimalen Plan für die Ausführung einer SQL-Abfrage zu entwickeln. Da der Unterschied zwischen „gut“ und „schlecht“ aus leistungstechnischer Sicht mehrere Größenordnungen betragen kann (d. h. Sekunden im Vergleich zu Stunden oder sogar Tagen), führten die meisten Abfrageoptimierer (einschließlich des MySQL-Optimierers) unter allen möglichen Plänen zur Abfragebewertung eine mehr oder minder umfangreiche Suche nach dem optimalen Plan durch. Bei Join-Abfragen wächst die Anzahl möglicher Pläne, die vom MySQL-Optimierer untersucht werden, exponentiell mit der Anzahl der Tabellen, die in einer Abfrage referenziert werden. Bei einer kleinen Anzahl von Tabellen (etwa 7 bis 10) ist dies unproblematisch. Werden hingegen größere Abfragen abgesetzt, dann kann die für die Abfrageoptimierung erforderliche Zeit schnell zum Engpass für die Leistung des Servers werden.

Eine flexiblere Methode zur Abfrageoptimierung gewährt dem Benutzer Kontrolle darüber, wie erschöpfend der Optimierer bei der Suche nach einem optimalen Abfragebewertungsplan vorgeht. Hintergedanke ist, dass umso weniger Zeit für die Kompilierung einer Abfrage aufgewendet wird, je weniger Pläne vom Optimierer untersucht werden. Andererseits kann es sein, dass der Optimierer, weil er einige Pläne überspringt, den optimalen Plan übersieht.

Das Verhalten des Optimierers in Bezug auf die Anzahl der Pläne, die er bewertet, kann über zwei Systemvariablen gesteuert werden:

  • Die Variable optimizer_prune_level weist den Optimierer an, bestimmte Pläne basierend auf der geschätzten Anzahl der Datensätze, auf die pro Tabelle zugegriffen wird, zu übergehen. Unsere Erfahrung zeigt, dass diese Art der „begründeten Annahme“ optimale Pläne nur in sehr seltenen Fällen verfehlt. Aus diesem Grund ist die Option standardmäßig aktiviert (optimizer_prune_level=1). Wenn Sie allerdings das Gefühl haben, dass der Optimierer einen besseren Abfrageplan hätte finden können, dann können Sie die Option auch abschalten (optimizer_prune_level=0); allerdings besteht dann das Risiko, dass die Abfragekompilierung deutlich länger dauert. Beachten Sie, dass der Optimierer auch bei Verwendung dieser Heuristik eine grob exponentielle Anzahl von Plänen untersucht.

  • Die Variable optimizer_search_depth sagt dem Optimierer, wie weit er bei unvollständigen Plänen „vorausschauen“ soll, um einzuschätzen, ob ein Plan erweitert werden soll. Niedrige Werte für optimizer_search_depth führen zu um mehrere Größenordnungen kürzeren Abfragekompilierungszeiten. So kann die Kompilierung von Abfragen mit 12, 13 oder mehr Tabellen leicht Stunden oder sogar Tage dauern, wenn optimizer_search_depth einen Wert hat, der annähernd der Anzahl der Tabellen in der Abfrage entspricht. Umgekehrt benötigt der Optimierer für dieselbe Abfrage noch nicht einmal eine Minute, wenn optimizer_search_depth den Wert 3 oder 4 hat. Wenn Sie nicht sicher sind, welcher Wert für optimizer_search_depth sinnvoll sein könnte, können Sie ihn auf 0 setzen; so weisen Sie den Optimierer an, den Wert automatisch zu ermitteln.

4.5.5. Der MySQL-Abfragen-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 Abfragen-Cache wird unter Sitzungen aufgeteilt, daher kann eine von einem Clienten generierte Ergebnismenge als Antwort auf die gleiche von einem anderen Clienten herausgegebene Abfrage geschickt werden.

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.

Der Abfrage-Cache gibt keine veralteten Daten zurück. Wenn Tabellen modifiziert werden, werden alle entsprechenden Einträge im Abfrage-Cache synchronisiert.

Anmerkung

Der Abfrage-Cache funktioniert nicht in Umgebungen, in denen mehrere mysqld-Server dieselben MyISAM-Tabellen aktualisieren.

Anmerkung

Ab MySQL 5.1.17 wird der Abfragen-Cache für vorbereitete Anweisungen unter den Bedingungen verwendet, die unterAbschnitt 4.5.5.1, „So funktioniert der Abfrage-Cache“ beschrieben werden. Vor 5.1.17 wird der Abfragen-Cache nicht für vorbereitete Anweisungen verwendet.

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 Abfragen-Cache beim Serverstart zu deaktivieren, setzen Sie die Systemvariable query_cache_size auf 0. Durch Deaktivierenn des Abfragen-Cache-Codes gibt es keine merklichen Mehraufwand. 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.

Der Abfragen-Cache bietet das Potential für substanzielle Leistungsverbesserung, aber Sie sollten nicht annehmen, dass er unter allen Umständen hilft. Bei einigen Abfragen-Cache-Konfigurationen oder Serverbelastungen könnten Sie tatsächlich eine Leistungsverminderung sehen:

  • Achten Sie darauf, den Abfragen-Cache nicht übermäßig zu bemessen, was den Mehraufwand für die cache-Pflege möglicherweise über den Nutzen seiner Aktivierung hinaus erhöht. Größen in Zehnern von Megabytes sind üblicherweise nützlich. Größen in den Hunderten von Megabytes möglicherweise nicht mehr.

  • Die Serverbelastung hat eine bedeutende Wirkung auf die Abfrage-Cache-Effizienz. Eine Abfragemischung, die fast gänzlich aus einer festen Menge von SELECT-Anweisungen besteht, profitiert wahrscheinlich viel mehr von der Aktivierung des Cache als eine Mischung, in der häufige INSERT-Anweisungen die Ergebnissen im Cache ständig ungültig machen. In einigen Fällen besteht ein Workaround in der Verwendung der Option SQL_NO_CACHE, die es verhindert, dass Ergebnisse von SELECT-Anweisungen, die häufig modifizierte Tabellen nutzen, überhaupt in den Cache gelangen. (Siehe auch Abschnitt 4.5.5.2, „Abfragen-Cache-SELECT-Optionen“.)

Um zu überprüfen, wie nützlich es ist, den Abfragen-Cache zu aktivieren, testen Sie die Operation Ihres MySQL-Servers mit aktiviertem und deaktiviertem Cache. Dann testen Sie regelmäßig erneut, weil die Abfrage-Cache-Effizienz sich mit der Serverbelastungsänderung ändern kann.

4.5.5.1. So funktioniert der Abfrage-Cache

Dieser Abschnitt beschreibt, wie der Abfrage-Cache funktioniert, wenn er betriebsbereit ist. Abschnitt 4.5.5.3, „Abfragen-Cache-Konfiguration“, 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.

Der Cache wird nicht für Abfragen der folgenden Typen verwendet:

  • Abfragen, die eine Unterabfrage einer äußeren Abfrage sind

  • Innerhalb des Hauptteils von einer gespeicherten Funktion, eines Trigger oder Ereignisses ausgeführte Abfragen

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 4.5.5.4, „Abfragen-Cache-Status und Pflege“.

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.

Der Abfragen-Cache funktioniert auch innerhalb von Transaktionen, wenn man InnoDB-Tabellen verwendet.

In MySQL 5.1 wird das Ergebnis einerSELECT Abfrage auf einer Ansicht zwischengespeichert.

Der Abfragen-Cache funktioniert für SELECT SQL_CALC_FOUND_ROWS...-Abfragen und speichert einen Wert, der von einer folgenden SELECT FOUND_ROWS()-Abfrage zurückgegeben wird. 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. Die SELECT FOUND_ROWS()-Abfrage selbst kann nicht zwischengespeichert werden.

Vor MySQL 5.1.17 verwenden vorbereitete Anweisungen den Abfragen-Cache nicht. Ab 5.1.17 verwenden vorbereitete Anweisungen den Abfragen-Cache unter gewissen Bedingungen, die sich je nach Vorbereitungsmethode unterscheiden:

  • Anweisungen, die über das binäre Protokoll mitmysql_stmt_prepare() und mysql_stmt_execute() ausgegeben werden. Siehe auch C API Prepared Statements.

    Bei einer vorbereiteten Anweisung, die über das binäre Protokoll ausgeführt wird, basiert der Vergleich mit den Anweisungen im Abfragen-Cache auf dem Text der Anweisung nach Expansion der ?-Parametermarker. Die Anweisung wird nur mit anderen zwischengespeicherten Anweisungen verglichen, die über das binäre Protokoll ausgeführt wurden. Das heißt, für Abfragen-Cache-Zwecke unterscheiden sich über das binäre Protokoll ausgegebene Anweisungen von über das Textprotokoll ausgegebenen Anweisungen.

  • Anweisungen, die mit PREPARE und EXECUTEüber das Textprotokoll (nicht binär) ausgegeben werden. Siehe auch Abschnitt 8.7, „SQL-Syntax für vorbereitete Anweisungen“. Diese werden hier als SQL PS-Anweisungen angegeben.

    Vor MySQL 5.1.21 wird eine überPREPARE und EXECUTE ausgeführte vorbereitete Anweisung nicht gezwischenspeichert, wenn sie einen ?-Parametermarker enthält. In diesem Fall enthält die Anweisung nach Parametererweiterung Referenzen zu Benutzervariablen, was die Zwischenspeicherung auch für nichtvorbereitete Anweisungen verhindert. Wenn die Anweisung keine Parametermarker enthält, wird die Anweisung mit den Anweisungen im Abfragen-Cache verglichen, die über das Textprotokoll ausgeführt wurden (das heißt, sie wird mit anderen SQL PS-Anweisungen und nichtvorbereiteten Anweisungen verglichen). Ab MySQL 5.1.21 wird diese Beschränkung aufgehoben und vorbereitete Anweisungen, die Parametermarker enthalten, können gezwischenspeichert werden, weil die Expansion direkt die Benutzervariablenwerte ersetzt.

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()CONVERT_TZ()
CURDATE()CURRENT_DATE()CURRENT_TIME()
CURRENT_TIMESTAMP()CURTIME()DATABASE()
ENCRYPT() mit genau einem ParameterFOUND_ROWS()GET_LOCK()
LAST_INSERT_ID()LOAD_FILE()MASTER_POS_WAIT()
NOW()RAND()RELEASE_LOCK()
SLEEP()SYSDATE()UNIX_TIMESTAMP() ohne Parameter
USER()UUID()UUID_SHORT()

Auch unter den folgenden Bedingungen wird eine Abfrage nicht im Abfrage-Cache gespeichert:

  • Sie verweist auf benutzer-definierte Funktionen (UDFs) oder Stored-Funktionen.

  • Sie verweist auf Benutzervariablen oder lokal gespeicherte Programmvariablen.

  • Sie verweist auf Tabellen in der mysql- oder INFORMATION_SCHEMA-Systemdatenbank.

  • Sie hat eine der folgenden Formen:

    SELECT ... LOCK 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 MyODBC-Abschnitt von Connectors and APIs.

    Anweisungen innerhalb von Transaktionen, die das SERIALIZABLE-Isolationsniveau verwenden, können auch nicht zwischengespeichert werden, weil sie LOCK IN SHARE MODE-Sperren verwenden.

  • Sie verwendet TEMPORARY-Tabellen.

  • Sie verwendet überhaupt keine Tabellen.

  • Sie generiert Warnungen.

  • Der Benutzer hat eine Berechtigung auf Spaltenebene für eine der betreffenden Tabellen.

4.5.5.2. Abfragen-Cache-SELECT-Optionen

In SELECT-Anweisungen können zwei für den Abfrage-Cache spezifische Optionen angegeben werden:

  • SQL_CACHE

    Das Abfrageergebnis wird gezwischenspeichert, wenn es zwischenspeicherbar ist und der Wert der Systemvariablen query_cache_type auf ON oder DEMAND gesetzt 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;

4.5.5.3. Abfragen-Cache-Konfiguration

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 Server System Variables, 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.

Anmerkung

Verwenden Sie den Windows-Konfigurationsassistenten, um MySQL zu installieren oder zu konfigurieren, wird der Standardwert für query_cache_size basierend auf den unterschiedlichen verfügbaren Konfigurationstypen automatisch für Sie konfiguriert. Wenn Sie den Windows-Konfigurationsassistenten verwenden, kann der Abfragen-Cache auf Grund der selektierten Konfiguration aktiviert werden (das heißt auf einen Wert ungleich Null gesetzt werden). Der Abfragen-Cache wird auch von der Einstellung der Variablenquery_cache_type gesteuert. Sie sollten die Werte dieser Variablen in Ihrer my.ini-Datei überprüfen, nachdem Konfiguration stattgefunden hat.

Wenn Sie query_cache_size auf einen Wert ungleich Null setzen, denken Sie daran, dass der Abfragen-Cache eine Mindestgröße von etwa 40KB 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 |
+------------------+-------+

Damit der Abfragen-Cache tatsächlich Abfrageergebnisse halten kann, muss seine Größe größer gesetzt werden:

mysql> SET GLOBAL query_cache_size = 1000000;
Query OK, 0 rows affected (0.04 sec)
mysql> SHOW VARIABLES LIKE 'query_cache_size';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| query_cache_size | 999424 |
+------------------+--------+
1 row in set (0.00 sec)

Der Wert query_cache_size wird am nächsten 1024 Byte-Block ausgerichtet. Der gemeldete Wert kann deswegen anders als der von Ihnen zugewiesene Wert sein.

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;

Wenn Sie query_cache_type bei Serverstart setzen (und nicht bei Laufzeit mit einer SET-Anweisung), sind nur numerische Werte zulässig.

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 Standardwert ist 1MB.

Anmerkung

Sie können die maximale Größe setzen, die für den Abfragen-Cache bei Laufzeit mit der SET-Anweisung angegeben werden kann, indem Sie die Option --maximum-query_cache_size=32M auf der Befehlszeile oder in der Konfigurationsdatei verwenden.

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).

4.5.5.4. Abfragen-Cache-Status und Pflege

Um zu überprüfen, ob der Abfragen-Cache in Ihrem MySQL-Server vorhanden ist, verwenden Sie die folgende Anweisung:

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 Server Status Variables. 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 4.5.5.3, „Abfragen-Cache-Konfiguration“.

4.5.6. Prüfen der Thread-Informationen

Wenn Sie versuchen festzustellen, was Ihr MySQL-Server ausführt, kann es hilfreich sein, die Prozessliste zu prüfen, die die Menge von Threads ist, die gegenwärtig auf dem Server ausgeführt werden. Prozesslisteninformationen sind aus diesen Quellen verfügbar:

Sie können sich immer Informationen über Ihre eigenen Threads ansehen. Um Information über Threads anzusehen, die für andere Konten ausgeführt werden, müssen Sie die PROCESS-Berechtigung haben.

Jeder Prozesslisteneintrag enthält einige Informationsstücke:

  • Id ist der Verbindungsbezeichner für den sich mit dem Thread verbindenden Client.

  • user und host zeigen das sich mit dem Thread verbindende Konto an.

  • db ist die Standarddatenbank für den Thread, oder NULL, wenn keine ausgewählt ist.

  • Command und State zeigen, was der Thread ausführt.

    Die meisten Zustände entsprechen sehr schnellen Operationen. Wenn ein Thread in einem bestimmten Zustand über viele Sekunden verbleibt, könnte es ein Problem geben, das untersucht werden muss.

  • Time zeigt, wie lange der Thread in seinem gegewärtigen Zustand gewesen ist. Die Angabe der gegenwärtigen Zeit des Threads kann in einigen Fällen verändert werden: Der Thread kann die Zeit mit SET TIMESTAMP =Wert verändern. Bei einem auf einem Slave ausgeführten Thread, der Ereignisse vom Master bearbeitet, wird die Thread-Zeit auf die in den Ereignissen gefundene Zeit gesetzt und gibt damit die aktuelle Zeit auf dem Master und nicht dem Slave wieder.

  • Info enthält den Text der vom Thread ausgeführten Anweisung oder NULL, wenn er keine ausführt. Standardmäßig enthält dieser Wert nur die ersten 100 Zeichen der Anweisung. Um die vollständigen Anweisungen zu sehen, verwenden Sie SHOW FULL PROCESSLIST.

Die folgenden Abschnitte listen die möglichen Command-Werte und State-Werte nach Kategorie gruppiert auf. Die Bedeutung einiger dieser Werte ist offensichtlich. Für andere wird für eine zusätzliche Beschreibung geliefert.

4.5.6.1. Thread-Befehlswerte

Ein Thread kann einen der folgenden Command-Werte haben:

  • Binlog Dump

    Dies ist ein Thread auf einem Masterserver, der Inhalte über ein binäres Protokoll an einen Slave-Server sendet.

  • Change user

    Der Thread führt eine Benutzeränderungsperation aus.

  • Close stmt

    Der Thread schließt eine vorbereitete Anweisung.

  • Connect

    Ein Replikations-Slave wird an seinen Master angeschlossen.

  • Connect Out

    Ein Replikationsslave stellt eine Verbindung zum Master her.

  • Create DB

    Der Thread führt eine Datenbankeinrichtungsoperation aus.

  • Daemon

    Dies ist ein server-interner Thread, kein Thread, der eine Clientverbindung bedient.

  • Debug

    Der Thread generiert Debuginformationen.

  • Delayed insert

    Der Thread ist ein delayed-insert-Handler.

  • Drop DB

    Der Thread führt eine Drop-Database-Operation aus.

  • Error

  • Execute

    Der Thread führt eine vorbereitete Anweisung aus.

  • Fetch

    Der Thread holt die Ergebnisse der Ausführung einer vorbereiteten Anweisung.

  • Field List

    Der Thread holt Information für Tabellenspalten.

  • Init DB

    Der Thread selektiert eine Standarddatenbank.

  • Kill

    Der Thread beendet einen anderen Thread.

  • Long Data

    Der Thread holt lange Daten aus dem Ergebnis der Ausführung einer vorbereiteten Anweisung.

  • Ping

    Der Thread behandelt eine server-ping-Anfrage.

  • Prepare

    Der Thread bereitet eine vorbereitete Anweisung vor.

  • Processlist

    Der Thread erzeugt Informationen über Server-Threads.

  • Query

    Der Thread führt eine Anweisung aus.

  • Quit

    Der Thread wird beendet.

  • Refresh

    Der Thread leert eine Tabelle, die Protokolle oder den Cache oder setzt die Statusvariable oder Replikationsserverinformationen zurück.

  • Register Slave

    Der Thread meldet einen Slave-Server an.

  • Reset stmt

    Der Thread setzt eine vorbereitete Anweisung zurück.

  • Set option

    Der Thread setzt eine Clientanweisungsausführungsoption oder setzt sie zurück.

  • Shutdown

    Der Thread fährt den Server herunter.

  • Sleep

    Der Thread wartet darauf, dass der Client eine neue Anweisung an ihn sendet.

  • Statistics

    Der Thread erzeugt Serverstatusinformationen.

  • Table Dump

    Der Thread schickt Tabelleninhalte an einen Slave-Server.

  • Time

    Nicht verwendet.

4.5.6.2. Allgemeine Thread-Zustände

Die folgende Liste beschreibt State-Werte von Threads, die sich auf allgemeine Abfrageverarbeitung beziehen, und nicht auf spezialisiertere Aktivitäten wie Replikation. Viele dieser sind nur für die Fehlersuche auf dem Server nützlich.

  • After create

    Dieser tritt auf, wenn der Thread eine Tabelle (einschließlich interner temporärer Tabellen) am Ende der Funktion erstellt, die die Tabelle erstellt. Dieser Zustand wird verwendet, auch wenn die Tabelle auf Grund eines Fehlers nicht erstellt werden könnte.

  • Analyzing

    Der Thread berechnet eine MyISAM-Tabellenschlüsselverteilung (zum Beispiel für ANALYZE TABLE).

  • checking permissions

    Der Thread überprüft, ob der Server die benötigten Berechtigungen hat, um die Anweisung auszuführen.

  • Checking table

    Der Thread führt eine Tabellenprüfung durch.

  • cleaning up

    Der Thread hat einen Befehl bearbeitet und bereitet sich darauf vor, Speicher freizugeben und bestimmte Zustandsvariablen zurückzusetzen.

  • closing tables

    Der Thread leert die veränderten Tabellendaten auf die Festplatte und schließt die verwendeten Tabellen. Dies sollte ein sehr schneller Vorgang sein. Andernfalls sollten Sie überprüfen, ob Ihre Festplatte nicht voll ist oder stark frequentiert wird.

  • converting HEAP to MyISAM

    Der Thread konvertiert eine innere temporäre Tabelle von einer MEMORY-Tabelle in eine MyISAM-Tabelle auf der Festplatte.

  • copy to tmp table

    Der Thread bearbeitet eine ALTER TABLE-Anweisung. Dieser Zustand tritt auf, nachdem die Tabelle mit der neuen Struktur eingerichtet worden ist, aber bevor Datensätze hineinkopiert werden.

  • Copying to group table

    Wenn eine Anweisung unterschiedliche ORDER BY- und GROUP BY-Kriterien hat, werden die Zeilen nach Gruppen sortiert und in eine temporäre Tabelle kopiert.

  • Copying to tmp table

    Der Server kopiert Daten in eine Temporärtabelle im Speicher.

  • Copying to tmp table on disk

    Der Server kopiert Daten in eine Temporärtabelle auf die Festplatte. Die temporäre Ergebnismenge war größer als tmp_table_size, und der Thread stellt die Temporärtabelle deswegen vom speicherresidenten in das festplattenbasierte Format um, um Speicher zu sparen.

  • Creating index

    Der Thread bearbeitet ALTER TABLE ... ENABLE KEYS für eine MyISAM-Tabelle.

  • Creating sort index

    Der Thread bearbeitet eine SELECT-Anweisung, die mit einer inneren temporären Tabelle gelöst wird.

  • creating table

    Der Thread erstellt eine Tabelle. Dies schließt die Erstellung temporärer Tabellen ein.

  • Creating tmp table

    Der Thread erstellt eine temporäre Tabelle im Speicher oder auf der Festplatte. Wenn die Tabelle im Arbeitsspeicher erstellt, aber später in eine Tabelle auf der Festplatte konvertiert wird, ändert sich der Zustand während jener Operation auf Copying to tmp table on disk.

  • deleting from main table

    Der Server führt den ersten Teil eines Löschvorgangs über mehrere Tabellen aus. Der Löschvorgang erfolgt nur in der ersten Tabelle und speichert Spalten und Offsets, die zum Löschen aus anderen (Referenz-)Tabellen benutzt werden.

  • deleting from reference tables

    Der Server führt den zweiten Teil eines Löschvorgangs über mehrere Tabellen aus und löscht die entsprechenden Datensätze aus anderen Tabellen.

  • discard_or_import_tablespace

    Der Thread bearbeitet eine ALTER TABLE ... DISCARD TABLESPACE- oder ALTER TABLE ... IMPORT TABLESPACE-Anweisung.

  • end

    Dies tritt am Ende der Anweisungen ALTER TABLE, CREATE VIEW, DELETE, INSERT, SELECT oder UPDATE, aber vor der Bereinigung auf.

  • executing

    Der Thread hat mit der Ausführung einer Anweisung begonnen.

  • Execution of init_command

    Der Thread führt Anweisungen im Wert der Systemvariableninit_command aus.

  • freeing items

    Der Thread hat einen Befehl ausgeführt. Auf diesen Zustand folgt üblicherweise ein cleaning up.

  • Flushing tables

    Der Thread führt FLUSH TABLES aus und wartet, bis alle Threads ihre Tabellen geschlossen haben.

  • FULLTEXT initialization

    Der Server bereitet die Ausführung einer natursprachlichen Volltextsuche vor.

  • init

    Dies tritt vor der Initialisierung der Anweisungen ALTER TABLE, DELETE, INSERT, SELECT oder UPDATE auf.

  • Killed

    Jemand hat eine KILL-Anweisung an den Thread abgesetzt. Der Thread wird abgebrochen, wenn beim nächsten Mal das Terminierungs-Flag gesetzt wird. Dieses Flag wird in jeder größeren Schleife in MySQL gesetzt. Trotzdem kann es unter Umständen einen Moment dauern, bis der Thread terminiert ist. Ist der Thread durch einen anderen Thread gesperrt, dann erfolgt die Terminierung erst, wenn der andere Thread die Sperre aufgehoben hat.

  • Locked

    Die Abfrage wird durch eine andere Abfrage gesperrt.

  • logging slow query

    Der Thread schreibt eine Anweisung in das Langsamabfrageprotokoll.

  • NULL

    Dieser Zustand wird für den SHOW PROCESSLIST-Zustand verwendet.

  • login

    Der Anfangsstatus für einen Verbindungs-Thread, bis der Client erfolgreich authentisiert worden ist.

  • Opening tables, Opening table

    Der Thread versucht, eine Tabelle zu öffnen. Dies sollte ein sehr schneller Vorgang sein, sofern das Öffnen nicht durch irgendeinen Umstand verhindert wird. So kann beispielsweise eine ALTER TABLE- oder eine LOCK TABLE-Anweisung das Öffnen einer Tabelle bis zum Abschluss der Anweisung unterbinden.

  • preparing

    Dieser Zustand tritt während Abfrageoptimierung auf.

  • Purging old relay logs

    Der Thread beseitigt unbenötigte Relaylogdateien.

  • query end

    Dieser Zustand tritt nach der Bearbeitung einer Abfrage, aber vor dem Zustand freeing items auf.

  • Reading from net

    Der Server liest ein Paket aus dem Netzwerk.

  • Removing duplicates

    The query was using SELECT DISTINCT in such a way that MySQL could not optimize away the distinct operation at an early stage. Aus diesem Grund erfordert MySQL eine zusätzliche Phase, um alle duplizierten Datensätze zu entfernen, bevor das Ergebnis an den Client gesendet wird.

  • removing tmp table

    Der Thread beseitigt eine innere temporäre Tabelle, nachdem er eine SELECT-Anweisung bearbeitet hat. Dieser Zustand wird nicht verwendet, wenn keine temporäre Tabelle erstellt wurde.

  • rename

    Der Thread benennt eine Tabelle um.

  • rename result table

    Der Thread bearbeitet eine ALTER TABLE-Anweisung, hat die neue Tabelle erstellt und benennt sie um, um die ursprüngliche Tabelle zu ersetzen.

  • Reopen tables

    Der Thread hat eine Sperre für die Tabelle erwirkt, danach aber festgestellt, dass die zugrunde liegende Tabellenstruktur sich geändert hat. Der Thread hat die Sperre dann aufgehoben und die Tabelle geschlossen und versucht nun, sie wieder zu öffnen.

  • Repair by sorting

    Der Reparaturcode verwendet einen Sortiervorgang zur Erstellung der Indizes.

  • Repair done

    Der Thread hat eine Multithread-Reparatur für eine MyISAM-Tabelle abgeschlossen.

  • Repair with keycache

    Der Reparaturcode erstellt einen Schlüssel nach dem anderen über den Schlüssel-Cache. Dies ist wesentlich langsamer als Repair by sorting.

  • Rolling back

    Der Thread rollt eine Transaktion zurück.

  • Saving state

    Für MyISAM-Tabellenoperationen wie Reparatur oder Analyse speichert der Thread den neuen Tabellenzustand in den .MYI-Dateiheader. Zustand schließt Informationen wie die Anzahl der Zeilen, den AUTO_INCREMENT-Zähler und Schlüsselverteilungen ein.

  • Searching rows for update

    Der Thread durchläuft die erste Phase zur Suche nach passenden Datensätzen, bevor er sie aktualisiert. Dies muss getan werden, wenn UPDATE den Index ändert, der für die Suche nach den betreffenden Datensätzen verwendet wird.

  • Sending data

    Der Thread verarbeitet Datensätze für eine SELECT-Anweisung und sendet zudem Daten an den Client.

  • setup

    Der Thread fängt eine ALTER TABLE-Operation an.

  • Sorting for group

    Der Thread führt eine Sortierung infolge einer GROUP BY-Klausel durch.

  • Sorting for order

    Der Thread führt eine Sortierung infolge einer ORDER BY-Klausel durch.

  • Sorting index

    Der Thread sortiert Indexseiten für den effizienteren Zugriff während einer MyISAM-Tabellenoptimierungsoperation.

  • Sorting result

    Bei einer SELECT-Anweisungentspricht dies Creating sort index, außer bei nicht temporären Tabellen.

  • statistics

    Der Server berechnet Statistiken zur Entwicklung eines Abfrageausführungsplans.

  • System lock

    Der Thread stellt eine Anfrage oder wartet auf eine innere oder externe Systemsperre für die Tabelle. Wenn dieser Zustand durch eine Anfrage auf externe Sperren verursacht wird und Sie nicht mehrere mysqld-Server verwenden, die auf die gleichen Tabellen zugreifen, können Sie externe Systemsperren mit der Option --skip-external-locking deaktivieren. Allerdings wird externe Sperrung standardmäßig deaktiviert, daher hat diese Option wahrscheinlich keine Wirkung.

  • Table lock

    Der nächste Thread-Zustand nach System lock. Der Thread hat eine externe Sperre erhalten und wird eine interne Tabellensperre anfordern.

  • Updating

    Der Thread sucht nach zu aktualisierenden Datensätzen und aktualisiert diese dann.

  • updating main table

    Der Server führt den ersten Teil eines Änderungsvorgangs über mehrere Tabellen aus. Er führt Änderungen nur in der ersten Tabelle aus und speichert Spalten und Offsets, die zur Aktualisierung anderer (Referenz-)Tabellen benutzt werden.

  • updating reference tables

    Der Server führt den zweiten Teil eines Änderungsvorgangs über mehrere Tabellen aus und aktualisiert die entsprechenden Datensätze in den anderen Tabellen.

  • User lock

    Der Thread startet eine Anfrage oder wartet auf eine Richtsperre, die mit einem GET_LOCK()-Aufruf angefordert wird. Bei SHOW PROFILE bedeutet dieser Zustand, dass der Thread die Sperre anfordert (und nicht darauf wartet).

  • Waiting for tables, Waiting for table

    Der Thread hat eine Mitteilung erhalten, dass die einer Tabelle zugrunde liegende Struktur sich geändert hat und er die Tabelle neu öffnen muss, um die neue Struktur zu erhalten. Um die Tabelle allerdings neu öffnen zu können, muss er warten, bis alle anderen Threads die fragliche Tabelle geschlossen haben.

    Diese Benachrichtigung erfolgt, wenn ein anderer Thread FLUSH TABLES oder eine der folgenden Anweisungen für die betreffende Tabelle verwendet hat: FLUSH TABLES tbl_name, ALTER TABLE, RENAME TABLE, REPAIR TABLE, ANALYZE TABLE oder OPTIMIZE TABLE.

  • Waiting on cond

    Ein generischer Zustand, in dem der Thread darauf wartet, dass eine Bedingung wahr wird. Es ist keine spezifische Zustandsinformation verfügbar.

  • Writing to net

    Der Server schreibt ein Paket in das Netzwerk.

4.5.6.3. Thread-Zustände bei verzögerter Einfügeoperation

Diese Thread-Zustände gehören zur Verarbeitung von DELAYED-Einfügeoperationen (siehe Abschnitt 8.2.5.2, „INSERT DELAYED). Einige Zustände gehören zu Verbindungs-Threads, die INSERT DELAYED-Anweisungen von Clients bearbeiten. Andere Zustände gehören zu Handler-Threads für verzögerte Einfügeoperationen, die Datensätze einfügen. Es gibt einen Handler-Thread für verzögerte Einfügeoperationen für jede Tabelle, für die INSERT DELAYED-Anweisungen ausgegeben werden.

Zustände in Verbindung mit einem Verbindungs-Thread, der eine INSERT DELAYED-Anweisung vom Client bearbeitet:

  • allocating local table

    Der Thread bereitet sich vor, Datensätze an den Handler-Thread für verzögerte Einfügeoperationen zu liefern.

  • Creating delayed handler

    Der Thread erstellt einen Handler für DELAYED-Einfügeoperationen.

  • got handler lock

    Dies tritt vor dem Zustand allocating local table und nach dem Zustand waiting for handler lock auf, wenn der Verbindungs-Thread Zugriff auf den Handler-Thread für verzögerte Einfügeoperationen bekommt.

  • got old table

    Dies tritt nach dem Zustand waiting for handler open auf. Der Handler-Thread für verzögerte Einfügeoperationen hat signalisiert, dass er seine Initialisierungsphase beendet hat, was das Öffnen der Tabelle für verzögerte Einfügeoperationen einschließt.

  • storing row into queue

    Der Thread fügt einen neuen Datensatz der Liste von Datensätzen hinzu, die der Handler-Thread für verzögerte Einfügeoperationen einfügen muss.

  • update

  • waiting for delay_list

    Dies tritt während der Initialisierungsphase auf, wenn der Thread versucht, den Handler-Thread für verzögerte Einfügeoperationen für die Tabelle zu finden, bevor er versucht, Zugriff auf die Liste der verzögerten Einfügeoperations-Threads zu erhalten.

  • waiting for handler insert

    Ein INSERT DELAYED-Handler hat alle anstehenden Einfügeoperationen bearbeitet und wartet auf neue.

  • waiting for handler lock

    Dies tritt vor dem Zustand allocating local table auf, wenn der Verbindungs-Thread auf Zugriff auf den Handler-Thread für verzögerte Einfügeoperationen wartet.

  • waiting for handler open

    Dies nach tritt dem Zustand Creating delayed handler und vor dem Zustand got old table auf. Der Handler-Thread für verzögerte Einfügeoperationen ist gerade gestartet worden und der Verbindungs-Thread wartet auf seine Initialisierung.

Zustände eines Handler-Threads für verzögerte Einfügeoperationen, der Datensätze einfügt:

  • insert

    Der Zustand, der direkt vor dem Einfügen der Datensätze in die Tabelle auftritt.

  • reschedule

    Nachdem er eine Anzahl von Datensätzen eingefügt hat, schläft der Handler-Thread für verzögerte Einfügeoperationen, um andere Threads arbeiten zu lassen.

  • upgrading lock

    Ein Handler für verzögerte Einfügeoperationen versucht, eine Sperre für die Tabelle zu bekommen, um Zeilen einzufügen.

  • Waiting for INSERT

    Ein Handler für verzögerte Einfügeoperationen wartet, dass ein Verbindungs-Thread der Warteschlange Datensätze hinzufügt (siehe storing row into queue).

4.5.6.4. Replikations-Master-Thread-Zustände

Die folgende Liste zeigt die häufigsten Zustände in der Spalte State für den Binlog Dump-Thread des Masters. Wenn keine Binlog Dump-Threads auf einem Master vorhanden sind, bedeutet dies, dass die Replikation nicht ausgeführt wird, d. h., es sind derzeit keine Slaves angebunden.

  • Sending binlog event to slave

    Binärlogs enthalten Ereignisse, wobei ein Ereignis normalerweise eine Änderung sowie zugehörige Informationen umfasst. Der Thread hat ein Ereignis aus dem Binärlog gelesen und sendet dieses nun an den Slave.

  • Finished reading one binlog; switching to next binlog

    Der Thread hat das Lesen einer Binärlogdatei beendet und öffnet die nächste, um sie an den Slave zu senden.

  • Has sent all binlog to slave; waiting for binlog to be updated

    Der Thread hat alle anhängigen Updates aus den Binärlogs gelesen und an den Slave gesendet. Er ist nun untätig und wartet auf neue Ereignisse, die aufgrund von Änderungen am Master in das Binärlog geschrieben werden.

  • Waiting to finalize termination

    Eine nur ganz kurz angezeigte Statusangabe, die besagt, dass der Thread gerade beendet wird.

4.5.6.5. Replikations-Slave-E/A-Thread-Zustände

Die folgende Liste zeigt die häufigsten Statusangaben, die in der Spalte State für den I/O-Thread auf dem Slave-Server erscheinen können. Dieser Zustand erscheint auch in der von SHOW SLAVE STATUS gezeigten Slave_IO_State-Spalte, damit Sie mit dieser Anweisung einen guten Überblick darüber erhalten, was geschieht.

  • Waiting for master update

    Der Anfangszustand vor Connecting to master.

  • Connecting to master

    Der Thread versucht, eine Verbindung zum Master herzustellen.

  • Checking master version

    Eine Statusangabe, die nur ganz kurz angezeigt wird, nachdem die Verbindung zum Master erfolgreich hergestellt werden konnte.

  • Registering slave on master

    Eine Statusangabe, die nur ganz kurz angezeigt wird, nachdem die Verbindung zum Master erfolgreich hergestellt werden konnte.

  • Requesting binlog dump

    Eine Statusangabe, die nur ganz kurz angezeigt wird, nachdem die Verbindung zum Master erfolgreich hergestellt werden konnte. Der Thread fordert vom Master den Inhalt seiner Binär-Logs an, beginnend mit dem angeforderten Binär-Log-Dateinamen und der angeforderten Position.

  • Waiting to reconnect after a failed binlog dump request

    Wenn die Anforderung des Binärlogs fehlgeschlagen ist (etwa aufgrund eines Verbindungsabbruchs), dann wechselt der Thread in diesen Status, solange er schläft, versucht aber in regelmäßigen Abständen, die Verbindung wiederherzustellen. Der Abstand zwischen Wiederholungen kann bei der Verwendung der CHANGE MASTER TO-Anweisung oder der Option --master-connect-retry angegeben werden.

  • Reconnecting after a failed binlog dump request

    Der Thread versucht, erneut eine Verbindung zum Master herzustellen.

  • Waiting for master to send event

    Der Thread hat die Verbindung zum Master hergestellt und wartet auf das Eintreffen von Binärlogereignissen. Dies kann recht lange dauern, wenn der Master untätig ist. Wenn die Wartezeit slave_net_timeout Sekunden lang dauert, tritt eine Zeitüberschreitung auf. Der Thread geht dann davon aus, dass die Verbindung abgebrochen ist, und versucht, sie neu herzustellen.

  • Queueing master event to the relay log

    Der Thread hat ein Ereignis gelesen und kopiert es in sein Relay-Log, damit der SQL-Thread es verarbeiten kann.

  • Waiting to reconnect after a failed master event read

    Ein Lesefehler ist aufgetreten (aufgrund eines Verbindungsabbruchs). Der Thread schläft für die Anzahl von Sekunden, die von der Anweisung CHANGE MASTER TO oder der Option -- master-connect-retry gesetzt wird (Voreinstellung 60), bevor er eine erneute Verbindung versucht.

  • Reconnecting after a failed master event read

    Der Thread versucht, erneut eine Verbindung zum Master herzustellen. Wenn die Verbindung wiederhergestellt werden konnte, wechselt der Status zu Waiting for master to send event.

  • Waiting for the slave SQL thread to free enough relay log space

    Sie verwenden einen Wertrelay_log_space_limit ungleich Null und die Relaylogs sind so groß geworden, dass ihre kombinierte Größe diesen Wert überschreitet. Der I/O-Thread wartet, bis der SQL-Thread durch die Verarbeitung von Relay-Log-Inhalten genug Speicher freigegeben hat, sodass Relay-Logs gelöscht werden können.

  • Waiting for slave mutex on exit

    Eine Statusangabe, die beim Beenden des Threads ganz kurz angezeigt wird.

4.5.6.6. Replikations-Slave-SQL-Thread-Zustände

Die folgende Liste zeigt die häufigsten Statusangaben, die in der Spalte State für den SQL-Thread auf dem Slave-Server erscheinen können.

  • Waiting for the next event in relay log

    Der Anfangsstatus vor Reading event from the relay log.

  • Reading event from the relay log

    Der Thread hat ein Ereignis aus dem Relay-Log gelesen, sodass dieses Ereignis verarbeitet werden kann.

  • Has read all relay log; waiting for the slave I/O thread to update it

    Der Thread hat alle Ereignisse in den Relay-Log-Dateien verarbeitet und wartet nun darauf, dass der I/O-Thread neue Ereignisse in das Relay-Log schreibt.

  • Making temp file

    Der Thread führt eine LOAD DATA INFILE-Anweisung aus und erstellt eine temporäre Datei, die die Daten enthält, aus denen der Slave Datensätze lesen wird.

  • Waiting for slave mutex on exit

    Eine nur ganz kurz angezeigte Statusangabe, die besagt, dass der Thread gerade beendet wird.

Die Spalte State für den I/O-Thread kann auch den Text einer Anweisung anzeigen. Das bedeutet, dass der Thread ein Ereignis aus dem Relay-Log gelesen und die Anweisung daraus extrahiert hat und diese nun ausführt.

4.5.6.7. Replikations-Slave-Verbindungs-Thread-Zustände

Diese Thread-Zustände treten auf einem Replikations-Slave auf, gehören aber zu Verbindungs-Threads, nicht E/A- oder SQL-Threads.

  • Changing master

    Der Thread bearbeitet eine CHANGE MASTER TO-Anweisung.

  • Creating table from master dump

    Der Slave erstellt eine Tabelle mit der Anweisung CREATE TABLE, die im Dump vom Master enthalten ist. Wird für LOAD TABLE FROM MASTER und LOAD DATA FROM MASTER verwendet.

  • Killing slave

    Der Thread bearbeitet eine SLAVE STOP-Anweisung.

  • Opening master dump table

    Dieser Zustand tritt nach Creating table from master dump auf.

  • Reading master dump table data

    Dieser Zustand tritt nach Opening master dump table auf.

  • Rebuilding the index on master dump table

    Dieser Zustand tritt nach Reading master dump table data auf.

  • starting slave

    Der Thread startet die Slave-Threads nach der erfolgreichen Ladeoperation LOAD DATA FROM MASTER.

4.5.6.8. MySQL Cluster-Thread-Zustände

  • Committing events to binlog

  • Opening mysql.ndb_apply_status

  • Processing events

    Der Thread bearbeitet Ereignisse für binäres Loggen.

  • Processing events from schema table

    Der Thread führt die Arbeit der Schemareplikation aus.

  • Shutting down

  • Syncing ndb table schema operation and binlog

    Dies wird verwendet, um ein richtiges Binär-Log der Schemaoperationen für NDB zu haben.

  • Waiting for event from ndbcluster

    Der Server handelt als ein SQL-Knoten in einem MySQL Cluster, und wird an einen Cluster-Managementkonten angeschlossen.

  • Waiting for first event from ndbcluster

  • Waiting for ndbcluster binlog update to reach current position

  • Waiting for ndbcluster to start

  • Waiting for schema epoch

    Der Thread wartet auf eine Schemaepoche (das heißt einen globalen Prüfpunkt).

4.5.6.9. Event-Scheduler-Thread-Zustände

Diese Zustände treten auf für den Event Scheduler-Thread, für Threads, die eingerichtet werden, um geplante Ereignisse auszuführen, oder für Threads, die den Scheduler beenden.

  • Clearing

    Der Scheduler-Thread oder ein Thread, der ein Ereignis ausführte, wird beendet.

  • Initialized

    Der Scheduler-Thread oder ein Thread, das ein Ereignis ausführen wird, ist initialisiert worden.

  • Waiting for next activation

    Der Scheduler hat eine nichtleere Ereigniswarteschlange, aber die nächste Aktivierung liegt in der Zukunft.

  • Waiting for scheduler to stop

    Der Thread gab SET GLOBAL event_scheduler=OFF aus und wartet, dass der Scheduler aufhört.

  • Waiting on empty queue

    Die Ereigniswarteschlange des Schedulers ist leer und er schläft.

4.5.7. So verwendet MySQL Threads für Clientverbindungen

Verbindungs-Manager-Threads behandeln Clientverbindungsanfragen auf den Netzschnittstellen, die der Server überwacht. Auf allen Plattformen behandelt ein Manager-Thread TCP/IP-Verbindungswünsche. Auf Unix behandelt dieser Manager-Thread auch Unix-Socket-Dateiverbindungswünsche. Auf Windows behandelt ein Manager-Thread Anfragen für Verbindungen mit gemeinsam genutztem Speicher und ein anderer behandelt Named-Pipe-Verbindungsanfragen. Der Server richtet keine Threads für die Verwaltung von Schnittstellen ein, die er nicht überwacht. Zum Beispiel richtet ein Windows-Server, der keinen Support für Named-Pipe-Verbindungen aktiviert hat, keinen Thread ein, um diese zu bedienen.

Verbindungs-Manager-Threads weisen jede Clientverbindung einem speziellen Thread zu, der Authentifizierungs- und Anfragenverarbeitung für jene Verbindung handhabt. Manager-Threads richten bei Bedarf einen neuen Thread, versuchen das aber zu vermeiden, indem sie zuerst den Thread-Cache konsultieren, um zu erkennen, ob er einen Thread enthält, der für die Verbindung verwendet werden kann. Wenn eine Verbindung endet, wird sein Thread an den Thread-Cache zurückgegeben, wenn der Cache nicht voll ist.

In diesem Verbindungs-Thread-Modell gibt es ebenso viele Threads wie gegenwärtig verbundene Clients, was einige Nachteile hat, wenn die Serverbelastung muss skaliert werden muss, um eine Vielzahl von Verbindungen zu behandeln. Zum Beispiel wird die Thread-Einrichtung und -Beseitigung aufwendig. Auch benötigt jeder Thread Server- und Kern-Ressourcen, z. B. Stapelspeicherplatz. Um eine Vielzahl simultaner Verbindungen zu ermöglichen, muss die Stapelspeichergröße pro Thread klein gehalten werden, was zu einer Situation führt, bei der sie entweder zu klein ist oder der Server große Mengen an Speicher verbraucht. Es kann auch zu einer Erschöpfung anderer Ressourcen kommen, damit wird die Aufwandszeitplanung signifikant.

Mehrere System- und Statusvariablen sind relevant für die Steuerung und Überwachung des Servers beim Management der Threads, die Clientverbindungen behandeln. (Siehe auch Server System Variables, und Server Status Variables.)

Der Thread-Cache hat eine von der Systemvariablenthread_cache_size bestimmte Größe. Der Standardwert ist 0 (kein Zwischenspeichern), wodurch für jede neue Verbindung ein Thread erstellt und wieder beseitigt wird, wenn die Verbindung beendet wird. Setzen Sie thread_cache_size auf N, damit N inaktive Verbindungs-Threads im Cache gehalten werden. thread_cache_size kann beim Serverstart gesetzt oder geändert werden, während der Server läuft. Ein Verbindungs-Thread wird inaktiv, wenn die Clientverbindung, zu der er gehört, beendet wird.

Um die Anzahl der Threads im Cache und die Anzhal der Threads, die erstellt wurde, weil kein Thread aus dem Cache genommen werden könnte, zu überwachen, überprüfen Sie die Statusvariablen threads_cached und threads_created überwachen.

Sie können max_connections beim Serverstart oder zur Laufzeit setzen, um die maximale Anzahl von Clients zu kontrollieren, die gleichzeitig verbinden können.

Wenn der Thread-Stapelspeicher zu klein ist, beschränkt dies die Komplexität von den SQL-Anweisungen, die der Server bedienen kann, der Rekursionstiefe von Stored Procedures und anderer speicherintensiver Aktionen. Um eine Stapelspeichergröße von N Bytes für jeden Thread zu setzen, starten Sie den Server mit --thread_stack=N.

4.5.8. So verwendet MySQL Speicher

Die folgende Liste gibt einige Möglichkeiten an, wie der mysqld-Server Speicher verwendet. Sofern anwendbar, wird der Name der Systemvariablen angegeben, die für die Speichernutzung relevant ist:

  • Der Schlüsselpuffer wird von allen Threads gemeinsam genutzt. Seine Größe wird mit der Variablenkey_buffer_size festgelegt. Andere vom Server verwendete Puffer werden bei Bedarf zugewiesen. Siehe auch Abschnitt 4.5.3, „Tuning der Server-Parameter“.

  • Jeder für das Verwalten von Clientverbindungen verwendete Thread belegt etwas threadspezifischen Platz. Die folgende Liste zeigt diesen und die Variablen, die seine Größe kontrollieren, an:

    • einen Stapel (standardmäßig 192 Kbyte groß, Variable thread_stack)

    • einen Verbindungspuffer (Variable net_buffer_length)

    • einen Ergebnispuffer (Variable net_buffer_length)

    Der Verbindungspuffer und der Ergebnispuffer haben anfangs beide eine von net_buffer_length angegebene Größe, werden aber dynamisch bei Bedarf bis auf max_allowed_packet Bytes vergrößert. Der Ergebnispuffer schrumpft nach jeder SQL-Anweisung auf net_buffer_length. Während eine Anweisung läuft, wird auch eine Kopie des gegenwärtigen Anweisungsstrings zugewiesen.

  • Alle Threads verwenden denselben Basisspeicher.

  • Wird ein Thread nicht mehr benötigt, wird der ihm zugewiesene Speicher freigegeben und dem System zurückgegeben, außer wenn der Thread in den Thread-Cache zurückgeht. In diesem Fall bleibt der Speicher zugewiesen.

  • Vor MySQL 5.1.4 wurden nur für komprimierte MyISAM-Tabellen Speicher zugeordnet. Seit MySQL 5.1.4 lässt sich die Systemvariable myisam_use_mmap auf 1 setzen, um die Speicherzuordnung für alle MyISAM-Tabellen zu aktivieren.

  • Jede Anforderung, die einen sequenziellen Scan einer Tabelle durchführt, reserviert einen Lesepuffer (Variable read_buffer_size).

  • Beim Lesen von Datensätzen in willkürlicher Folge (z. B. nach einer Sortierung) kann ein Zufallslesepuffer reserviert werden, um Festplattenzugriffe zu umgehen (Variable read_rnd_buffer_size).

  • Alle Joins werden in einem einzigen Durchlauf ausgeführt, und die meisten Joins können sogar ohne Temporärtabelle erledigt werden. Die meisten Temporärtabellen sind speicherbasierte Hash-Tabellen. Temporärtabellen mit einer großen Datensatzlänge (berechnet als Summe aller Spaltenlängen) oder solche, die BLOB-Spalten enthalten, werden auf der Festplatte gespeichert.

    Wenn eine interne HEAP-Tabelle die durch tmp_table_size angegebene Größe überschreitet, macht MySQL die HEAP-Tabelle im Speicher nach Bedarf automatisch zu einer festplattenbasierten MyISAM-Tabelle. Sie können auch die Größe der Temporärtabelle erhöhen, indem Sie die mysqld-Option tmp_table_size oder die SQL-Option SQL_BIG_TABLES im Clientprogramm einstellen. Siehe auch Server System Variables.

  • Die meisten Anforderungen, die eine Sortierung durchführen, reservieren einen Sortierpuffer und abhängig von der Größe der Ergebnismenge null bis zwei Temporärdateien. Siehe auch Where MySQL Stores Temporary Files.

  • Praktisch die gesamte Analyse und Berechnung erfolgt in einem lokalen Speicherbereich. Bei kleinen Elementen ist keine Speichermehrbelastung gegeben, d. h., die normale langsame Speicherreservierung und -freigabe werden umgangen. Bei kleinen Elementen ist keine Speichermehrbelastung gegeben, d. h., die normale langsame Speicherreservierung und -freigabe werden umgangen.Speicher wird nur für unerwartet große Strings reserviert. Dies wird mit malloc() und free() bewerkstelligt.

  • Für jede MyISAM-Tabelle, die geöffnet wird, wird die Indexdatei einmal geöffnet. Die Datendatei wird für jeden gleichzeitig laufenden Thread einmal geöffnet. Für jeden nebenläufigen Thread werden eine Tabellenstruktur, Spaltenstrukturen für jede Spalte und ein Puffer der Größe 3 N reserviert. (Hierbei ist N die maximale Datensatzlänge abzüglich vorhandener BLOB-Spalten.) Eine BLOB-Spalte erfordert fünf bis acht Byte zuzüglich der Länge der BLOB-Daten. Die MyISAM-Speicher-Engine unterhält einen zusätzlichen Puffer zur internen Verwendung.

  • Bei Tabellen mit BLOB-Spalten wird ein Puffer dynamisch vergrößert, um größere BLOB-Werte einlesen zu können. Wenn Sie eine Tabelle scannen, wird ein Puffer reserviert, der so groß ist wie der größte BLOB-Wert.

  • Handler-Strukturen für alle in Verwendung befindlichen Tabellen werden in einem Cache gespeichert und als FIFO verwaltet. Standardmäßig hat der Cache 64 Einträge. Wenn eine Tabelle von zwei laufenden Threads gleichzeitig verwendet wurde, enthält der Cache zwei Einträge für die Tabelle. Siehe auch Abschnitt 4.4.7, „So öffnet und schließt MySQL Tabellen“.

  • Eine FLUSH TABLES-Anweisung oder der Befehl mysqladmin flush-tables schließt alle Tabellen, die gerade nicht verwendet werden, und kennzeichnet alle in Verwendung befindlichen Tabellen, damit diese geschlossen werden, sobald der ausführende Thread endet. Hierdurch wird der größte Teil des in Verwendung befindlichen Speichers freigegeben. FLUSH TABLES wird erst abgeschlossen, wenn alle Tabellen geschlossen wurden.

  • Der Server speichert Informationen im Arbeitsspeicher als ein Ergebnis der Anweisungen GRANT, CREATE USER, INSTALL PLUGIN und CREATE SERVER. Dieser Speicher wird nicht von den entsprechenden Anweisungen REVOKE, DROP USER, DROP SERVER und UNINSTALL PLUGIN freigegeben, daher wird es bei einem Server, der viele Instanzen der Anweisungen ausführt, die Caching verursachen, es eine Zunahme der Speicherverwendung geben. Dieser Cache-Speicher kann mit FLUSH PRIVILEGES freigegeben werden.

ps und andere Systemstatusprogramme melden unter Umständen, dass mysqld viel Speicher benötigt. Dies kann von Thread-Stapeln an verschiedenen Speicheradressen verursacht werden. Die Solaris-Version von ps beispielsweise zählt die Menge des nicht verwendeten Speichers zwischen den Stapeln als verwendeten Speicher. Um dies zu überprüfen, prüfen Sie den verfügbaren Swap mit swap -s. Wir testen mysqld mit verschiedenen Speicherleckdetektoren (sowohl kommerzieller als auch freier Herkunft), d. h., es sollten keine Speicherlecks vorhanden sein.

4.5.9. Aktivierung der Unterstützung großer Seiten

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.

In MySQL können große Seiten von InnoDB verwendet werden, um seinem Pufferpool und zusätzlichem Speicherpool Speicher zuzuweisen.

Gegenwärtig unterstützt MySQL nur die Linux-Implementierung der Unterstützung großer Seiten (der HugeTLB in Linux genannt wird).

Bevor große Seiten auf Linux verwendet werden können, müssen Sie ihre Unterstützung durch den Kern aktivieren und den HugeTLB-Speicherpool konfigurieren. Die HugeTBL-API wird in der Datei Documentation/vm/hugetlbpage.txt Ihrer Linux-Quellen dokumentiert.

Es scheint, dass der Kern einiger neuerer Systeme wie Red Hat Enterprise Linux die Großseitenfunktion standardmäßig aktiviert hat. Um für Ihren Kern zu überprüfen, ob dies wahr ist, verwenden Sie den folgenden Befehl und suchen nach Ausgabezeilen, die „huge“ enthalten:

shell> cat /proc/meminfo | grep -i huge
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       4096 kB

Die nichtleere Befehlsausgabe zeigt, dass die Unterstützung großer Seiten vorhanden ist, aber Nullwerte zeigen, dass keine Seiten für die Verwendung konfiguriert wurden.

Wenn Ihr Kern neukonfiguriert werden muss, um große Seiten zu unterstützen, finden Sie eine Anleitung in hugetlbpage.txt.

Angenommen Ihr Linux-Kern hat die Unterstützung großer Seiten aktiviert, dann konfigurieren Sie ihn mit den folgenden Befehlen für Verwendung durch MySQL. Normalerweise stellen Sie diese in eine rc-Datei oder gleichwertiger Startdatei, die während der Systembootsequenz ausgeführt wird, so dass die Befehle jedes Mal bei Systemstart ausgeführt werden. Die Befehle sollten früh in der Bootsequenz ausgeführt werden, bevor der MySQL-Server startet. Vergewissern Sie sich, dass die Zuweisungsnummern und die Gruppennummer für Ihr System geeignet sind.

# Set the number of pages to be used.
# Each page is normally 2MB, so a value of 20 = 40MB.
# This command actually allocates memory, so this much
# memory must be available.
echo 20 > /proc/sys/vm/nr_hugepages
# Set the group number that is allowed to access this
# memory (102 in this case). The mysql user must be a
# member of this group.
echo 102 > /proc/sys/vm/hugetlb_shm_group
# Increase the amount of shmem allowed per segment
# (12G in this case).
echo 1560281088 > /proc/sys/kernel/shmmax
# Increase total amount of shared memory.  The value
# is the number of pages. At 4KB/page, 4194304 = 16GB.
echo 4194304 > /proc/sys/kernel/shmall

Für MySQL-Gebrauch sollten Sie normalerweise den Wert von shmmax ähnlich wie shmall setzen.

Um die Konfiguration großer Seiten zu überprüfen, prüfen Sie erneut /proc/meminfo wie oben beschrieben. Jetzt sollten Sie einige Werte ungleich Null sehen:

shell> cat /proc/meminfo | grep -i huge
HugePages_Total:      20
HugePages_Free:       20
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       4096 kB

Der letzte Schritt für die Nutzung der hugetlb_shm_group ist die Zuweisung des Werts „unlimited“ für die Memlock-Grenze für den Benutzer mysql. Das geschieht entweder durch das Editieren von /etc/security/limits.conf oder durch Hinzufügen des folgenden Befehls zu Ihrem mysqld_safe-Skript:

ulimit -l unlimited

Das Hinzufügen des Befehls ulimit zu mysqld_safe bewirkt, dass der Benutzer root die Memlock-Grenze auf unlimited setzt, bevor er auf den Benutzer mysql wechselt. (Dies setzt voraus, dass mysqld_safe von root gestartet wird.)

Die Unterstützung großer Seiten ist in MySQL standardmäßig deaktiviert. Um sie zu aktivieren, starten Sie den Server mit der Option --large-pages. Zum Beispiel können Sie die folgenden Zeilen in der Datei my.cnf Ihres Servers verwenden:

[mysqld]
large-pages

Mit dieser Option verwendet InnoDB automatisch große Seiten für seinen Pufferpool und zusätzlichen Speicherpool. Ist das nicht möglich fällt InnoDB auf die Nutzung traditionellen Speichers zurück und schreibt eine Warnung in das Fehlerprotokoll: Warning: Using conventional memory pool

Um zu überprüfen, dass große Seiten verwendet werden, prüfen Sie erneut /proc/meminfo:

shell> cat /proc/meminfo | grep -i huge
HugePages_Total:      20
HugePages_Free:       20
HugePages_Rsvd:        2
HugePages_Surp:        0
Hugepagesize:       4096 kB

4.5.10. So verwendet MySQL interne temporäre Tabellen

In einigen Fällen erstellt der Server interne temporäre Tabellen, während er Abfragen bearbeitet. Eine temporäre Tabelle kann im Speicher gehalten und von der MEMORY-Speicher-Engine bearbeitet, oder auf Festplatte gespeichert und von der MyISAM-Speicher-Engine bearbeitet werden. Temporäre Tabellen können unter Bedingungen wie diesen erstellt werden:

  • Wenn eine ORDER BY- und eine davon unterschiedliche GROUP BY-Klausel vorhanden sind, oder wenn ORDER BY oder GROUP BY Spalten aus anderen als der ersten Tabelle in der Join-Warteschlange enthalten, dann wird eine Temporärtabelle erstellt.

  • Wenn Sie die Option SQL_SMALL_RESULT verwenden, dann benutzt MySQL eine speicherresidente Temporärtabelle.

  • DISTINCT kombiniert mitORDER BY kann eine temporäre Tabelle erforderlich machen.

Um zu erkennen, ob eine Abfrage eine temporäre Tabelle benötigt, verwenden Sie EXPLAIN und überprüfen die Spalte Extra, um zu erkennen, ob sie Using temporary enthält. Siehe auch Abschnitt 4.2.1, „Abfragen mit EXPLAIN optimieren“.

Einige Bedingungen verhindern die Verwendung einer MEMORY-Temporärtabelle, in welchem Fall der Server statt dessen eine MyISAM-Tabelle verwendet:

  • Vorhandensein einer TEXT- oder BLOB-Spalte in der Tabelle

  • Vorhandensein einer Spalte in einer GROUP BY- oder DISTINCT-Klausel größer als 512 Byte

  • Vorhandensein einer Spalte größer als 512 Byte in der SELECT-Liste, wenn UNION oder UNION ALL verwendet wird

Eine temporäre Tabelle, die anfänglich als eine MEMORY-Tabelle erstellt wird, könnte in eine MyISAM-Tabelle konvertiert und auf Festplatte gespeichert werden, wenn sie zu groß wird. Die Systemvariablemax_heap_table_size entscheidet, wie groß MEMORY-Tabellen werden dürfen. Sie bezieht sich auf alle MEMORY-Tabellen, einschließlich jener, die mit CREATE TABLEerstellt wurden. Allerdings wird die tatsächliche Maximalgröße für interne MEMORY-Tabellen von max_heap_table_size in Kombination mit tmp_table_size bestimmt: Der jeweils kleinere Wert gilt. Wenn die Größe einer internen MEMORY-Tabelle die Grenze überschreitet, konvertiert MySQL sie automatisch in eine auf der Festplatte gespeicherte MyISAM-Tabelle.

4.5.11. So verwendet MySQL DNS

Wenn ein neuer Client eine Verbindung mit mysqld herstellt, dann erzeugt mysqld einen neuen Thread, um die Anforderung zu bearbeiten. Dieser Thread überprüft zuerst, ob der Hostname sich im Hostnamenscache befindet. Wenn nicht, versucht der Thread, den Hostnamen aufzulösen:

  • Der Thread nimmt die IP-Adresse und löst sie mit gethostbyaddr() zu einem Hostnamen auf. Es nimmt dann den Hostnamen und löst ihn zurück zur IP-Adresse (unter Verwendung von gethostbyname()) und vergleicht dabei, ob es sich um die ursprüngliche IP-Adresse handelt.

  • Wenn das Betriebssystem die Thread-sicheren Aufrufe gethostbyaddr_r() und gethostbyname_r() unterstützt, führt der Thread unter ihrer Verwendung die Hostnamensauflösung durch.

  • Unterstützt das Betriebssystem die Thread-sicheren Aufrufe nicht, dann sperrt der Thread ein Mutex und ruft stattdessen gethostbyaddr() und gethostbyname() auf. In diesem Fall kann ein anderer Thread Hostnamen, die nicht im Hostnamens-Cache vorhanden sind, erst auflösen, wenn der erste Thread das Mutex wieder aufgehoben hat.

Sie können DNS-Lookups für Hostnamen deaktivieren, indem Sie mysqld mit der Option --skip-name-resolve starten. Allerdings können Sie in diesem Fall nur IP-Adressen in den MySQL-Grant-Tabellen verwenden.

Wenn Ihr DNS sehr langsam ist und Sie viele Hosts haben, können Sie die Leistung steigern, indem Sie entweder DNS-Lookups mit --skip-name-resolve deaktivieren oder den HOST_CACHE_SIZE-Wert (Standard: 128) erhöhen und mysqld neu kompilieren.

Sie können den Hostnamens-Cache deaktivieren, indem Sie den Server mit der Option --skip-host-cache starten. Um den Hostnamenscache zu löschen, geben Sie eine FLUSH HOSTS-Anweisung aus oder führen den Befehl mysqladmin flush-hosts aus.

Um TCP/IP-Verbindungen gänzlich zu verweigern, starten Sie mysqld mit der Option --skip-networking.

4.6. Festplattenprobleme

  • Suchvorgänge auf der Festplatte stellen einen für die Leistung beträchtlichen Engpass dar. Dieses Problem wird in dem Moment umso offensichtlicher, wenn die Datenmengen so groß werden, dass ein effizientes Caching unmöglich wird. Bei großen Datenbanken, bei denen der Datenzugriff mehr oder weniger zufällig erfolgt, können Sie sich darauf verlassen, dass Sie mindestens einen Lese- und mehrere Suchvorgänge benötigen, um Daten zu schreiben. Um dieses Problem zu verringern, sollten Sie Festplatten mit schnellen Zugriffszeiten verwenden.

  • Erhöhen Sie die Anzahl der verfügbaren Festplattenspindeln (und verringern Sie dadurch die Suchbelastung), indem Sie entweder Dateien auf anderen Festplatten symbolisch verknüpfen oder das Striping verwenden:

    • Symbolische Verknüpfungen

      Sie verknüpfen die Index- und Datendateien von MyISAM-Tabellen von ihren normalen Positionen im Datenverzeichnis aus auf eine andere Festplatte (für die zudem das Striping angewendet werden kann). Hierdurch werden Such- und Lesezeiten verkürzt (vorausgesetzt, die Festplatte wird nicht noch für andere Zwecke verwendet). Siehe auch Abschnitt 4.6.1, „Symbolische Verknüpfungen“.

    • Striping

      Striping bedeutet, dass Sie viele Festplatten haben und den ersten Block auf der ersten Festplatte, den zweiten Block auf der zweiten und den N-ten Block auf der Festplatte mit der Nummer N MOD number_of_disks ablegen. Wenn Ihre normale Datengröße also geringer ist als die Stripe-Größe (oder perfekt angepasst ist), dann erhalten Sie eine wesentlich bessere Performance. Das Striping hängt sehr stark vom Betriebssystem und der Stripe-Größe ab. Insofern sollten Sie Benchmark-Tests Ihrer Anwendung mit verschiedenen Stripe-Größen durchführen. Siehe auch Abschnitt 4.1.5, „Ihre eigenen Benchmarks verwenden“.

      Der Geschwindigkeitsunterschied für das Striping hängt in erheblichem Maße von den Parametern ab. Je nachdem, wie Sie Ihre Striping-Parameter einstellen und über wie viel Festplatten Sie verfügen, können die Unterschiede mehrere Größenordnungen betragen. Sie müssen sich entscheiden, ob Sie die Optimierung für den wahlfreien oder den sequenziellen Zugriff durchführen wollen.

  • Aus Gründen der Zuverlässigkeit sollten Sie RAID 0+1 (Striping plus Spiegelung) verwenden, allerdings benötigen Sie in diesem Fall 2 N Laufwerke, um N Laufwerke mit Daten aufzunehmen. Dies ist die wahrscheinlich beste Option, sofern Sie über das nötige Kleingeld verfügen. Allerdings müssen Sie unter Umständen in eine Volumeverwaltungssoftware investieren, um ein solches Setup effizient steuern zu können.

  • Empfehlenswert ist auch der Ansatz, den RAID-Level entsprechend der Wichtigkeit der Daten zu variieren. So können Sie etwa Daten moderater Wichtigkeit, die sich wiederherstellen lassen, auf einer RAID-0-Festplatte speichern, wirklich wichtige Daten (z. B. Hostinformationen und Logdateien) hingegen auf einer RAID 0+1- oder einer RAID-N-Festplatte ablegen. RAID N kann problematisch werden, wenn Sie viele Schreibvorgänge haben, da die Aktualisierung der Paritätsbits zeitaufwändig werden kann.

  • Unter Linux können Sie deutlich mehr Leistung erzielen, indem Sie die Schnittstelle Ihrer Festplatte mit hdparm konfigurieren. (Bis zu 100 Prozent unter Last sind nicht ungewöhnlich.) Die folgenden hdparm-Optionen sollten für MySQL – und auch für viele andere Anwendungen – recht gut geeignet sein:

    hdparm -m 16 -d 1
    

    Beachten Sie, dass, wenn Sie diesen Befehl verwenden, Leistung und Zuverlässigkeit von Ihrer Hardware abhängen; aus diesem Grund empfehlen wir Ihnen dringend, Ihr System nach der Verwendung von hdparm umfassend zu testen. Weitere Informationen entnehmen Sie der hdparm-Manpage. Wenn hdparm nicht klug verwendet wird, kann sich eine Dateisystemverfälschung ergeben, führen Sie daher ein Backup von allem durch, bevor Sie experimentieren!

  • Sie können auch die Parameter für das Dateisystem setzen, das die Datenbank verwendet:

    Wenn Sie nicht wissen müssen, wann zuletzt auf die Dateien zugegriffen wurde (was bei einem Datenbankserver eigentlich auch nicht wichtig ist), dann können Sie Ihre Dateisysteme mit der Option -o noatime einbinden. Hierdurch werden Updates bis zum letzten Zugriffszeitpunkt in Inoden auf dem Dateisystem übersprungen, wodurch einige Suchvorgänge auf der Festplatte unnötig werden.

    Bei vielen Betriebssystemen können Sie für ein Dateisystem eine asynchrone Aktualisierung konfigurieren; hierzu binden Sie es mit der Option -o async ein. Wenn Ihr Computer ausreichend stabil ist, sollten Sie auf diese Weise mehr Performance erhalten, ohne zu viel Zuverlässigkeit zu opfern. (Unter Linux ist dieses Flag standardmäßig aktiv.)

4.6.1. Symbolische Verknüpfungen

Sie können Tabellen und Datenbanken aus dem Datenbankverzeichnis an andere Positionen verschieben und sie durch symbolische Verknüpfungen auf diese neuen Positionen ersetzen. Sie könnten dies beispielsweise tun, um eine Datenbank auf ein Dateisystem mit mehr freiem Speicher zu verschieben oder die Geschwindigkeit Ihres Systems durch Verteilen Ihrer Tabellen auf verschiedene Festplatten zu erhöhen.

Die empfohlene Vorgehensweise hierfür besteht schlicht darin, für Datenbanken symbolische Verknüpfungen auf eine andere Festplatte zu erstellen. Symbolische Verknüpfungen für Tabellen sollten hingegen nur als letzter Ausweg verwendet werden.

4.6.1.1. Verwenden symbolischer Verknüpfungen für Datenbanken unter Unix

Unter Unix erstellen Sie eine symbolische Verknüpfung mit einer Datenbank, indem Sie zuerst ein Verzeichnis auf einer Festplatte erstellen, auf der sich genug freier Speicher befindet, und dann eine symbolische Verknüpfung zu diesem Verzeichnis aus dem MySQL-Datenverzeichnis einrichten.

shell> mkdir /dr1/databases/test
shell> ln -s /dr1/databases/test /path/to/datadir

MySQL unterstützt Verknüpfungen von einem Verzeichnis auf mehrere Datenbanken nicht. Das Ersetzen eines Datenbankverzeichnisses durch eine symbolische Verknüpfung funktioniert, solange Sie keine symbolischen Verknüpfungen zwischen Datenbanken erstellen. Angenommen, Sie haben eine Datenbank db1 im MySQL-Datenverzeichnis und erstellen dann eine symbolische Verknüpfung db2, die auf db1 zeigt:

shell> cd /path/to/datadir
shell> ln -s db1 db2

Im Ergebnis scheint für jede Tabelle tbl_a in db1 offenbar auch eine Tabelle tbl_a in db2 vorhanden zu sein. Wenn ein Client db1.tbl_a und ein anderer Client db2.tbl_a aktualisiert, sind Probleme vorprogrammiert.

Wenn Sie dies aber wirklich tun müssen, ist es möglich, indem Sie die Quelldatei mysys/my_symlink.c ändern. Suchen Sie dort nach folgender Anweisung:

if (!(MyFlags & MY_RESOLVE_LINK) ||
    (!lstat(filename,&stat_buff) && S_ISLNK(stat_buff.st_mode)))

Ändern Sie diese wie folgt ab:

if (1)

4.6.1.2. Verwenden symbolischer Verknüpfungen für Tabellen unter Unix

Auf Systemen, die keinen vollständig funktionsfähigen realpath()-Aufruf aufweisen, sollten Sie Tabellen nicht symbolisch verknüpfen. (Linux und Solaris unterstützen realpath().) Sie können überprüfen, ob Ihr System symbolische Verknüpfungen unterstützt, indem Sie eine SHOW VARIABLES LIKE 'have_symlink'-Anweisung absetzen.

Symbolische Verknüpfungen werden nur bei MyISAM-Tabellen vollständig unterstützt. Bei Dateien, die von auf anderen Speicher-Engines basierenden Tabellen verwendet werden, werden Sie seltsame Probleme bekommen, wenn Sie versuchen, symbolische Verknüpfungen zu verwenden.

Die Verarbeitung symbolischer Verknüpfungen für MyISAM-Tabellen funktioniert wie folgt:

  • Im Datenverzeichnis befinden sich immer die Tabellenformatdatei (.frm-Datei), die Datendatei (.MYD-Datei) und die Indexdatei (.MYI-Datei). Die Daten- und die Indexdatei können an eine andere Position verschoben und durch symbolische Verknüpfungen im Datenverzeichnis ersetzt werden. Für die Formatdatei ist dies nicht möglich.

  • Sie können die Daten- und die Indexdatei separat in verschiedene Verzeichnisse verschieben und durch Verknüpfungen ersetzen.

  • Sie können einen laufenden MySQL Server anweisen, die symbolischen Verknüpfungen mithilfe der Optionen DATA DIRECTORY und INDEX DIRECTORY für CREATE TABLE zu erstellen. Siehe auch Abschnitt 8.1.17, „CREATE TABLE. Alternativ können die Verknüpfungen mithilfe von ln -s auch manuell über die Befehlszeile eingerichtet werden, wenn mysqld nicht ausgeführt wird.

    Anmerkung

    Ab MySQL 5.1.24 dürfen der mit den Optionen DATA DIRECTORY und INDEX DIRECTORY verwendete Pfad das data-Verzeichnis von MySQL nicht einschließen. (Bug#32167)

  • myisamchk ersetzt einen Symlink nicht durch die Datendatei oder Indexdatei. Er bearbeitet direkt die Datei, auf die der Symlink zeigt. Temporärdateien werden in dem Verzeichnis erstellt, in dem sich die Daten- bzw. Indexdatei befindet. Das gleiche gilt für die Anweisungen ALTER TABLE, OPTIMIZE TABLE und REPAIR TABLE.

  • Anmerkung

    Wenn Sie eine Tabelle löschen, die symbolische Verknüpfungen erstellt, dann werden sowohl die Verknüpfung als auch die Datei, auf die die Verknüpfung verweist, gelöscht. Dies ist ein ausgesprochen triftiger Grund, warum Sie mysqld nicht als root des Systems ausführen oder Benutzern Schreibzugriff auf die MySQL-Datenbankverzeichnisse gewähren sollten.

  • Wenn Sie eine Tabelle mit ALTER TABLE ... RENAME oder RENAME TABLE umbenennen und sie nicht in einer Datenbank verschieben, werden die symbolischen Verknüpfungen im Datenbankverzeichnis auf die neuen Namen umgestellt und die Daten- und Indexdatei entsprechend umbenannt.

  • Wenn Sie ALTER TABLE ... RENAME oder RENAME TABLE verwenden, um eine Tabelle in eine andere Datenbank zu verschieben, wird die Tabelle in das andere Datenbankverzeichnis verschoben. Hat sich der Tabellenname geändert, werden die symbolischen Verknüpfungen im neuen Datenbankverzeichnis auf die neuen Namen umbenannt und die Datendatei und die Indexdatei werden dementsprechend umbenannt.

  • Wenn Sie keine symbolischen Verknüpfungen verwenden, sollten Sie die Option --skip-symbolic-links für mysqld einsetzen, um zu gewährleisten, dass niemand mit mysqld eine Datei außerhalb des Datenverzeichnisses löschen oder umbenennen kann.

Die folgenden tabellenbezogenen Operationen in Verbindung mit symbolischen Verknüpfungen werden noch nicht unterstützt:

  • ALTER TABLE ignoriert die Tabellenoptionen DATA DIRECTORY und INDEX DIRECTORY.

  • BACKUP TABLE und RESTORE TABLE beachten symbolische Verknüpfungen nicht.

  • Die .frm-Datei darf niemals eine symbolische Verknüpfung sein (wie oben bereits angemerkt; nur Daten- und Indexdateien dürfen symbolische Verknüpfungen sein). Wenn Sie dies trotzdem versuchen (um beispielsweise Synonyme zu erstellen), dann erhalten Sie falsche Ergebnisse. Angenommen, Sie haben eine Datenbank db1 im MySQL-Datenverzeichnis und eine Tabelle tbl1 in dieser Datenbank. Nun erstellen Sie im Verzeichnis db1 eine symbolische Verknüpfung tbl2, die auf tbl1 verweist:

    shell> cd /path/to/datadir/db1
    shell> ln -s tbl1.frm tbl2.frm
    shell> ln -s tbl1.MYD tbl2.MYD
    shell> ln -s tbl1.MYI tbl2.MYI
    

    Probleme treten auf, wenn ein Thread db1.tbl1 liest und ein anderer db1.tbl2 aktualisiert:

    • Der Abfrage-Cache wird „hintergangen“ (denn er kann nicht wissen, dass tbl1 nicht geändert wurde, und gibt aufgrund dessen veraltete Ergebnisse zurück).

    • ALTER-Anweisungen auf tbl2 scheitern.

4.6.1.3. Verwenden symbolischer Verknüpfungen für Datenbanken unter Windows

Symbolische Verknüpfungen sind standardmäßig auf allen Windows-Servern aktiv. Auf diese Weise können Sie ein Datenbankverzeichnis auf eine andere Festplatte verschieben, indem Sie eine Verknüpfung darauf erstellen. Dies ähnelt der Art und Weise, wie symbolische Verknüpfungen unter Unix funktionieren, auch wenn die Vorgehensweise zur Einrichtung der Verknüpfung eine andere ist. Wenn Sie keine symbolischen Verknüpfungen benötigen, können Sie sie mit der Option --skip-symbolic-links deaktivieren.

Unter Windows erstellen Sie eine Verknüpfung mit einer MySQL-Datenbank, indem Sie eine Datei im Datenverzeichnis anlegen, die den Pfad zum Zielverzeichnis enthält. Diese Datei sollte db_name.sym heißen, wobei db_name der Name der Datenbank ist.

Angenommen, das MySQL-Datenverzeichnis heißt C:\mysql\data. Nun wollen Sie, dass die Datenbank foo auf D:\data\foo abgelegt wird. Gehen Sie wie folgt vor, um eine symbolische Verknüpfung zu erstellen:

  1. Vergewissern Sie sich, dass das Verzeichnis D:\data\foo vorhanden ist (andernfalls müssen Sie es erstellen). Wenn sich in Ihrem Datenverzeichnis bereits ein Datenbankverzeichnis namens foo befindet, sollten Sie es nach D:\data verschieben. Andernfalls wird die Verknüpfung unbrauchbar sein. Um Probleme zu vermeiden, stellen Sie sicher, dass der Server beim Verschieben des Datenbankverzeichnisses nicht ausgeführt wird.

  2. Erstellen Sie eine Textdatei C:\mysql\data\foo.sym, die den Pfadnamen D:\data\foo\ enthält.

    Anmerkung

    Der Pfadname zur neuen Datenbank und den Tabellen sollte absolut sein. Wenn Sie einen relativen Pfad angeben, wird der Standort relativ zur foo.sym-Datei sein.

Danach werden alle Tabellen, die Sie in der Datenbank foo anlegen, in D:\data\foo erstellt.

Die folgenden Beschränkungen beziehen sich auf die Verwendung von der .sym-Dateien für symbolische Datenbankverknüpfung unter Windows:

  • Der symbolische Link wird nicht verwendet, wenn ein Dateiverzeichnis mit dem gleichen Namen wie die Datenbank im MySQL-Datenverzeichnis existiert.

  • Die --innodb_file_per_table-Option kann nicht verwendet werden.

  • Wenn Sie mysqld als ein Dienst ausführen, können Sie ein verknüpftes Laufwerk zu einem entfernten Server nicht als der Bestimmungsort des symbolischen Links verwenden. Als einen Workaround können Sie den vollständigen Pfad verwenden (\\servername\path\).

Kapitel 5. Sprachstruktur

Dieses Kapitel erläutert die Notationsregeln für die folgenden Elemente von SQL-Anweisungen bei der Verwendung von MySQL:

  • literale Werte wie etwa Strings und Zahlen

  • Bezeichner wie Datenbank-, Tabellen- und Spaltennamen

  • reservierte Wörter

  • benutzerdefinierte und Systemvariablen

  • Kommentare

5.1. Literalwerte

In diesem Abschnitt wird erläutert, wie literale Werte in MySQL geschrieben werden. Hierzu gehören Strings, Zahlen, Hexadezimalwerte, boolesche Werte und NULL. Ferner behandeln wir hier die verschiedenen Nuancen und Fallstricke, auf die Sie beim Umgang mit diesen Grundtypen in MySQL treffen können.„

5.1.1. Strings

Ein String ist eine Abfolge von Bytes oder Zeichen, die in einfache („'“) oder doppelte Anführungszeichen („"“) gesetzt sind. Ein paar Beispiele:

'a string'
"another string"

In Anführungszeichen gesetzte nebeneinander platzierte Strings werden zu einem einzigen String verkettet. Die folgenden Zeilen sind gleichwertig:

'a string'
'a' ' ' 'string'

Wenn der ANSI_QUOTES-SQL-Modus aktiviert ist, können String-Literale nur in einfache Anführungszeichen gesetzt werden, weil ein in doppelten Anführungszeichen gesetzter String als ein Bezeichner interpretiert wird.

Ein binärer String ist ein String, für den kein Zeichensatz und keine Sortierung definiert ist. Ein nichtbinärer String hingegen ist ein String, für den Zeichensatz und Sortierung definiert sind. Bei beiden String-Typen basieren Vergleiche auf den numerischen Werten der String-Einheit. Für Binärstrings ist die Einheit das Byte. Für nichtbinäre Strings ist die Einheit das Zeichen. Einige Zeichensätze erlauben Multibytezeichen. Die Zeichenwertsortierung ist eine Funktion der Stringsortierung.

String-Literale weisen unter Umständen eine optionale Zeichensatzeinführung und eine COLLATE-Klausel auf:

[_charset_name]'string' [COLLATE collation_name]

Ein paar Beispiele:

SELECT _latin1'string';
SELECT _latin1'string' COLLATE latin1_danish_ci;

Sie können mit N'literal' (oder n'literal') einen String im Nationalzeichensatz erstellen. Diese Anweisungen sind gleichwertig:

SELECT N'some text';
SELECT n'some text';
SELECT _utf8'some text';

Weitere Informationen zu diesen Syntaxtypen für Strings finden Sie unter Character String Literal Character Set and Collation und National Character Set.

Innerhalb eines Strings haben gewisse Sequenzen eine Sonderbedeutung, es sei denn, der NO_BACKSLASH_ESCAPES-SQL-Modus ist aktiviert. Jede dieser Sequenzen beginnt mit einem Backslash („\“). Dieser wird häufig als Escape-Zeichen bezeichnet. MySQL erkennt die folgenden Escape-Sequenzen.

\0 Ein ASCII-NUL-Zeichen (0x00).
\' Ein einfaches Anführungszeichen („'“).
\" Ein doppeltes Anführungszeichen („"“).
\b Ein Rückschrittzeichen.
\n Ein Zeilenwechsel- oder Zeilenvorschubzeichen.
\r Ein Absatzschaltungszeichen.
\t Ein Tabulatorzeichen.
\Z ASCII 26 (Strg+Z). Siehe Anmerkung nach dieser Tabelle.
\\ Ein Backslash-Zeichen („\“).
\% Ein Jokerzeichen („%“). Siehe Anmerkung nach dieser Tabelle.
\_ Ein Jokerzeichen („_“). Siehe Anmerkung nach dieser Tabelle.

Bei allen anderen Escape-Sequenzen wird der Backslash ignoriert. Das bedeutet, dass das gekennzeichnete Zeichen als nicht gekennzeichnetes interpretiert wird. So ist etwa „\x“ identisch mit „x“.

Diese Sequenzen unterscheiden die Groß-/Kleinschreibung. So wird etwa „\b“ als Rückschritt, „\B“ hingegen als „B interpretiert“.

Das ASCII-Zeichen 26 kann als „\Z kodiert werden; hierdurch umgehen Sie Probleme mit der Tatsache, dass dieses Zeichen unter Windows als Dateiende interpretiert wird. “ Das ASCII-Zeichen 26 verursacht in einer Datei Probleme, wenn Sie mysql db_name< file_name verwenden.

Die Escape-Verarbeitung wird entsprechend dem von der character_set_connection-Systemvariablen angezeigten Zeichensatz ausgeführt. Dies gilt sogar für Strings, die durch ein Einführungszeichen eingeleitet werden, das einen unterschiedlichen Zeichensatz, wie in Character String Literal Character Set and Collation diskutiert, anzeigt.

Die Sequenzen „\%“ und „\_“ erlauben die Suche nach literalen Instanzen von „%“ und „_“ in Mustervergleichskontexten, in denen sie andernfalls als Jokerzeichen interpretiert würden. Details finden Sie in der Beschreibung zum Operator LIKE in Abschnitt 7.4.1, „String-Vergleichsfunktionen“. Wenn Sie „\%“ oder „\_“ in Kontexten ohne Mustervergleich verwenden, werden diese als Strings „\%“ und „\_“ und nicht als „%“ und „_“ ausgewertet.

Es gibt mehrere Möglichkeiten, Anführungszeichen in einen String zu setzen:

  • Ein „'“ in einem String, der in „'“ gesetzt ist, kann als „''“ geschrieben werden.

  • Ein „"“ in einem String, der in „"“ gesetzt ist, kann als „"''“ geschrieben werden.

  • Stellen Sie dem Anführungszeichen ein Escape-Zeichen („\“) voran.

  • Ein „'“ in einem String, der in „"“ gesetzt ist, erfordert keine spezielle Behandlung und muss weder verdoppelt noch mit einem Escape-Zeichen versehen werden. Ebenso erfordert ein „"“ in einem String, der in „'“ gesetzt ist, keine Sonderbehandlung.

Die folgenden SELECT-Anweisungen veranschaulichen die Verwendung von Anführungs- und Escape-Zeichen:

mysql> SELECT 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello';
+-------+---------+-----------+--------+--------+
| hello | "hello" | ""hello"" | hel'lo | 'hello |
+-------+---------+-----------+--------+--------+
mysql> SELECT "hello", "'hello'", "''hello''", "hel""lo", "\"hello";
+-------+---------+-----------+--------+--------+
| hello | 'hello' | ''hello'' | hel"lo | "hello |
+-------+---------+-----------+--------+--------+
mysql> SELECT 'This\nIs\nFour\nLines';
+--------------------+
| This
Is
Four
Lines |
+--------------------+
mysql> SELECT 'disappearing\ backslash';
+------------------------+
| disappearing backslash |
+------------------------+

Wenn Sie Binärdaten in eine String-Spalte (z. B. eine BLOB-Spalte) einfügen wollen, müssen die folgenden Zeichen durch Escape-Sequenzen dargestellt werden.

NULNUL-Byte (0x00). Dieses Zeichen wird mit „\0“ (einem Backslash gefolgt vom Zeichen ASCII „0) dargestellt.
\Backslash (ASCII 92). Stellen Sie dieses Zeichen als „\\“ dar.
'Einfaches Anführungszeichen (ASCII 39). Stellen Sie dieses Zeichen als „\'“ dar.
"Doppeltes Anführungszeichen (ASCII 34). Stellen Sie dieses Zeichen als „\"“ dar.

Wenn Sie Anwendungsprogramme schreiben, muss jeder String, der eines dieser Sonderzeichen enthalten kann, korrekt gekennzeichnet werden, bevor er als Datenwert in einer SQL-Anweisung verwendet wird, die an den MySQL Server gesendet wird. Dies lässt sich auf zweierlei Weise realisieren:

  • Sie verarbeiten den String mit einer Funktion, die die Sonderzeichen entsprechend kennzeichnet. In einem C-Programm können Sie die C-API-Funktion mysql_real_escape_string() zur Kennzeichnung von Sonderzeichen verwenden. So bietet etwa die C-API eine Anzahl von Funktionsaufrufen, die eine API für vorbereitete Anweisungen darstellen. Siehe auch mysql_real_escape_string(). Die Perl-DBI-Schnittstelle stellt eine Methode quote zur Konvertierung von Sonderzeichen in die entsprechenden Escape-Sequenzen bereit. So bietet etwa die C-API eine Anzahl von Funktionsaufrufen, die eine API für vorbereitete Anweisungen darstellen. Siehe auch MySQL Perl API. Andere Spracheschnittstellen bieten unter Umständen ähnliche Funktionalitäten.

  • Eine Alternative zur expliziten Kennzeichnung von Sonderzeichen stellt die Platzhalterfunktion dar, die von vielen MySQL-APIs geboten wird. Sie erlaubt Ihnen das Einfügen spezieller Markierungen in einen Anweisungs-String und das nachfolgende Binden der Datenwerte an diese Markierungen beim Absetzen der Anweisung. In diesem Fall nimmt Ihnen die API die Kennzeichnung der Sonderzeichen in den Werten ab.

5.1.2. Zahlen

Integer-Zahlen werden als Abfolge von Ziffern dargestellt. Fließkommazahlen verwenden den Punkt („.“) als Dezimaltrennzeichen. Bei allen Zahlentypen werden durch ein vorangestelltes „-“- oder „+“-Zeichen negative bzw. positive Werte angezeigt.

Beispiele gültiger Integers:

1221
0
-32

Beispiele gültiger Fließkommazahlen:

294.42
-32032.6809e+10
148.00

Ein Integer kann durchaus in einem Fließkommakontext angegeben werden. Er wird dann als die entsprechende Fließkommazahl interpretiert.

5.1.3. Hexadezimalwerte

MySQL unterstützt Hexadezimalwerte, die in den Formaten X'val', x'val' oder 0xval geschrieben werden (wobei val für Hexadezimalziffern steht (0..9, A..F). Die Schreibweise der Ziffern ist nicht wichtig. Für die Werte im Format X'val' oder x'val' muss val eine gerade Ziffernanzahl enthalten. Für Werte in der Formatsyntax 0xval werden Werte, die eine ungerade Ziffernanzahl enthalten, so behandelt, als hätten sie eine zusätzliche führende 0. Beispiel: 0x0a und 0xaaa werden interpretiert wie 0x0a und 0x0aaa.

In numerischen Kontexten verhalten sich Hexadezimalwerte wie Integers (mit 64-Bit-Präzision). In String-Kontexten hingegen agieren sie als binäre Strings, wobei jedes Hexadezimalziffernpaar in ein Zeichen umgewandelt wird:

mysql> SELECT X'4D7953514C';
        -> 'MySQL'
mysql> SELECT 0x0a+0;
        -> 10
mysql> SELECT 0x5061756c;
        -> 'Paul'

Der Standardtyp eines Hexadezimalwerts ist ein String. Wenn Sie gewährleisten wollen, dass der Wert als Zahl behandelt wird, können Sie CAST(... AS UNSIGNED) verwenden:

mysql> SELECT 0x41, CAST(0x41 AS UNSIGNED);
        -> 'A', 65

Die Syntax X'hexstring' basiert auf Standard-SQL. Die Syntax 0x basiert auf ODBC. Hexadezimal-Strings werden von ODBC häufig zur Angabe von Werten für BLOB-Spalten verwendet.

Sie können mit der Funktion HEX() einen String oder eine Zahl in einen String im Hexadezimalformat umwandeln:

mysql> SELECT HEX('cat');
        -> '636174'
mysql> SELECT 0x636174;
        -> 'cat'

5.1.4. Boolesche Werte

Die Konstanten TRUE und FALSE werden als 1 bzw. 0 ausgewertet. Bei den Konstantennamen wird die Groß-/Kleinschreibung nicht unterschieden.

mysql> SELECT TRUE, true, FALSE, false;
        -> 1, 1, 0, 0

5.1.5. Bit-Feldwerte

Bit-Feldwerte können im Format b'value' oder 0bvalue geschrieben werden. value ist ein binärer Wert, der mit Nullen und Einsen geschrieben wird.

Die Bitfeldnotation ist zur Angabe von Werten nützlich, die BIT-Spalten zugewiesen werden sollen:

mysql> CREATE TABLE t (b BIT(8));
mysql> INSERT INTO t SET b = b'11111111';
mysql> INSERT INTO t SET b = b'1010';
mysql> INSERT INTO t SET b = b'0101';

Bitwerte werden als binäre Werte zurückgegeben. Um sie in druckfertiger Form anzuzeigen, fügen Sie 0 hinzu oder verwenden Sie eine Konvertierungsfunktion wie BIN(). Hochwertige 0-Bits werden nicht im konvertierten Wert angezeigt.

mysql> SELECT b+0, BIN(b+0), OCT(b+0), HEX(b+0) FROM t;
+------+----------+----------+----------+
| b+0  | BIN(b+0) | OCT(b+0) | HEX(b+0) |
+------+----------+----------+----------+
|  255 | 11111111 | 377      | FF       |
|   10 | 1010     | 12       | A        |
|    5 | 101      | 5        | 5        |
+------+----------+----------+----------+

Benutzervariablen zugewiesene Bitwerte werden als Binärstrings behandelt. Um einen Bitwert einer Benutzervariablen als Zahl zuzuweisen, verwenden Sie CAST() oder +0:

mysql> SET @v1 = 0b1000001;
mysql> SET @v2 = CAST(0b1000001 AS UNSIGNED), @v3 = 0b1000001+0;
mysql> SELECT @v1, @v2, @v3;
+------+------+------+
| @v1  | @v2  | @v3  |
+------+------+------+
| A    |   65 |   65 |
+------+------+------+

5.1.6. NULL-Werte

Der NULL-Wert bedeutet „keine Daten“. NULL kann in jeder Schreibweise geschrieben werden. Ein Synonym ist \N (Beachtung der Groß-/Kleinschreibung).

Für Textdatei-Import- oder Exportoperationen mit LOAD DATA INFILE oder SELECT... INTO OUTFILE wird NULL durch die \N-Sequenz repräsentiert. Siehe auch Abschnitt 8.2.6, „LOAD DATA INFILE.

Beachten Sie, dass der NULL-Wert sich von Werten wie 0 für numerische Typen oder vom Leer-String für String-Typen unterscheidet. Weitere Informationen siehe Problems with NULL Values.

5.2. Schema-Objektnamen

Gewisse Objekte in MySQL, einschließlich Datenbank-, Tabellen-, Index-, Spalten-, Alias-, Stored Procedure-, Partitions-, Tablespace- und andere Objektnamen, werden Bezeichner genannt. Dieser Abschnitt beschreibt die für Bezeichner in MySQL zulässige Syntax. Abschnitt 5.2.2, „Beachtung der Groß-/Kleinschreibung bei Bezeichnern“ beschreibt, bei welchen Arten von Bezeichnern die Groß-/Kleinschreibung beachtet wird und unter welchen Bedingungen dies geschieht.

Ein Bezeichner kann mit und ohne Anführungszeichen geschrieben werden. Wenn ein Bezeichner Sonderzeichen enthält oder ein reserviertes Wort ist, müssen Sie ihn in Anführungszeichen setzen, wann immer Sie diesen referenzieren. Die alphanumerischen Zeichen des aktuellen Zeichensatzes, „_“ sowie „$“ sind keine Sonderzeichen. Reservierte Wörter werden unter Abschnitt 5.3, „Reservierte Wörter“aufgelistet. (Ausnahme: Ein reserviertes Wort, das einem Punkt in einem qualifizierten Namen folgt, muss ein Bezeichner sein. Es muss daher nicht in Anführungszeichen gesetzt werden.)

Das Bezeichner-Anführungszeichen ist das rückwärts gerichtete Anführungszeichen („'“):

mysql> SELECT * FROM `select` WHERE `select`.id > 100;

Wenn der SQL-Modus ANSI_QUOTES aktiviert ist, können Sie Bezeichner auch in doppelte Anführungszeichen setzen:

mysql> CREATE TABLE "test" (col INT);
ERROR 1064: You have an error in your SQL syntax...
mysql> SET sql_mode='ANSI_QUOTES';
mysql> CREATE TABLE "test" (col INT);
Query OK, 0 rows affected (0.00 sec)

Der ANSI_QUOTES-Modus führt dazu, dass der Server in doppelte Anführungszeichen gesetzte Strings als Bezeichner interpretiert. Wenn dieser Modus aktiviert ist, müssen String-Literale folglich innerhalb einfacher Anführungszeichen eingeschlossen werden. Sie können nicht innerhalb doppelter Anführungszeichen eingeschlossen werden. Wie der SQL-Modus des Servers gesteuert wird, entnehmen Sie Server SQL Modes.

Anführungszeichen für Bezeichner können in einem Bezeichner enthalten sein, wenn Sie den Bezeichner in Anführungszeichen setzen. Wenn das im Bezeichner enthaltene Zeichen dasselbe ist, mit dem auch der Bezeichner selbst umschlossen ist, dann müssen Sie das Zeichen im Bezeichner verdoppeln. Die folgende Anweisung erstellt eine Tabelle namens a`b, die eine Spalte namens c"d enthält:

mysql> CREATE TABLE `a``b` (`c"d` INT);

Alias-Namen können entweder als Bezeichner oder als Strings in Anführungszeichen gesetzt werden:

mysql> SELECT 1 AS `one`, 2 AS 'two';
+-----+-----+
| one | two |
+-----+-----+
|   1 |   2 |
+-----+-----+

Bezeichner können mit einer Ziffer anfangen, aber dürfen - außer wenn sie in Anführungszeichen gesetzt werden - nicht allein aus Ziffern bestehen.

Es empfiehlt sich, keine Namen zu verwenden, die mit Me oder MeN anfangen, wo M und N Integer sind. Vermeiden Sie zum Beispiel, 1e als Bezeichner zu verwenden, weil ein Ausdruck wie 1e+3 mehrdeutig ist. Abhängig vom Kontext kann er als Ausdruck 1e + 3 oder als Zahl 1e+3 interpretiert werden.

Seien Sie vorsichtig, wenn Sie mit MD5() Tabellennamen erstellen, da hiermit Namen in unzulässigen oder mehrdeutigen Formaten (so, wie gerade beschrieben) erzeugt werden können.

Eine Benutzervariable kann nicht direkt in einer SQL-Anweisung als ein Bezeichner oder als Teil eines Bezeichners verwendet werden. Mehr Informationen und Beispiele für Workarounds finden Sie unter Abschnitt 5.4, „Benutzerdefinierte Variablen“.

Es gibt einige Beschränkungen auf die Zeichen, die in Bezeichnern erscheinen können:

  • Kein Bezeichner darf ASCII NUL enthalten (0x00).

  • Datenbank-, Tabellen- und Spaltennamen sollten nicht mit Leerzeichen enden.

  • Vor MySQL 5.1.6 dürfen Datenbank- und Tabellennamen nicht die folgenden Zeichen enthalten: „/“, „\“, „.“ oder Zeichen, die nicht in Dateinamen erlaubt sind.

Ab MySQL 5.1.6 werden Sonderzeichen in Datenbank- und Tabellennamen in den entsprechenden Dateisystemnamen, wie unter Abschnitt 5.2.3, „Abbilden von Bezeichnern auf Dateinamen“ beschrieben, verschlüsselt. Wenn Sie Datenbanken oder Tabellen aus einer älteren MySQL-Version haben, die Sonderzeichen enthalten und für die die zu Grunde liegenden Verzeichnisnamen oder Dateinamen nicht aktualisiert worden sind, damit sie die neue Verschlüsselung verwenden, zeigt der Server ihre Namen mit dem Präfix #mysql50# an. Weitere Informationen darüber, wie solche Namen referenziert oder in die neuere Verschlüsselung konvertiert werden, finden Sie in diesem Abschnitt.

Die folgende Tabelle beschreibt die Maximallänge für jeden Bezeichnertyp.

BezeichnerMaximallänge (Zeichen)
Database64
Tabelle64
Spalte64
Index64
Constraint64
Gespeicherte Funktion oder Prozedur64
Trigger64
Ansicht64
Event64
Tablespace64
Logdatei-Gruppe64
Alias256 (siehe Ausnahme nach Tabelle)

Ab MySQL 5.1.23 werden Alias-Namen für Spaltennamen in CREATE VIEW-Anweisungen gegen die maximale Spaltenlänge von 64 Zeichen überprüft (nicht die maximale Alias-Länge von 256 Zeichen).

Bezeichner werden im Unicode-Format (UTF-8) gespeichert. Dies gilt für Bezeichner in Tabellendefinitionen, die in .frm-Dateien gespeichert sind, ebenso wie für solche in den Berechtigungstabellen der Datenbank mysql. Die Größen der Bezeichnerstring-Spalten in den Berechtigungstabellen werden in Zeichen gemessen. Sie können Mehrbyte-Zeichen verwenden, ohne die Anzahl von Zeichen zu reduzieren, die für die in diesen Spalten gespeicherten Werten erlaubt ist. Dies war vor MySQL 4.1 nicht zulässig. Die zulässigen Unicode-Zeichen sind Basic Multilingual Plane (BMP)-Zeichen. Zusätzliche Zeichen sind nicht erlaubt.

5.2.1. Bezeichner-Kennzeichner

MySQL unterstützt Namen, die aus einem oder mehreren Bezeichnern bestehen. Die Bestandteile eines mehrteiligen Namens sollten durch Punkte („.“) getrennt werden. Die ersten Bestandteile eines mehrteiligen Namens agieren als Qualifikationsmerkmal, das den Kontext beeinflusst, in dem der endgültige Bezeichner interpretiert wird.

Bei MySQL können Sie eine Tabellenspalte auf jede der folgenden Weisen referenzieren.

SpaltenreferenzierungBedeutung
col_nameDie Spalte col_name einer in der Anweisung verwendeten Tabelle hat diesen Namen.
tbl_name.col_nameDie Spalte col_name der Tabelle tbl_name aus der Standarddatenbank.
db_name.tbl_name.col_nameDie Spalte col_name der Tabelle tbl_name aus der Datenbank db_name.

Wenn Bestandteile eines mehrteiligen Namens Anführungszeichen erfordern, müssen Sie diese Bestandteile einzeln (statt des gesamten Namens) in Anführungszeichen setzen. Schreiben Sie zum Beispiel `my-table`.`my-column`, nicht `my-table.my-column`.

Ein reserviertes Wort, das einem Punkt in einem qualifizierten Namen folgt, muss ein Bezeichner sein. Es muss daher in diesem Kontext in Anführungszeichen gesetzt werden.

Sie müssen das Präfix tbl_name oder db_name.tbl_name für eine Spaltenreferenzierung in einer Anweisung nicht angeben, sofern die Referenzierung eindeutig ist. Angenommen, die Tabellen t1 und t2 enthalten jeweils eine Spalte c. Nun wollen Sie c in einer SELECT-Anweisung abrufen, die sowohl t1 als auch t2 verwendet. In diesem Fall ist c unklar, weil es in Bezug auf die in der Anweisung angegebenen Tabellen nicht eindeutig ist. Sie müssen es mit einem Tabellennamen wie t1.c bzw. t2.c qualifizieren, um anzugeben, welche Tabelle Sie meinen. Analog müssen Sie, um Spaltenwerte aus einer Tabelle t in der Datenbank db1 und einer Tabelle t in der Datenbank db2 in einer Anweisung abzurufen, Spalten in diesen Tabellen als db1.t.col_name und db2.t.col_name referenzieren.

Die Syntax .tbl_name bezeichnet die Tabelle tbl_name in der Standarddatenbank. Diese Syntax wird aus Gründen der ODBC-Kompatibilität akzeptiert, weil einige ODBC-Programme Tabellennamen das Zeichen „.“ voranstellen.

5.2.2. Beachtung der Groß-/Kleinschreibung bei Bezeichnern

Bei MySQL entsprechen Datenbanken den Verzeichnissen im Datenverzeichnis. Jede Tabelle in einer Datenbank entspricht mindestens einer Datei (abhängig von der Speicher-Engine möglicherweise auch mehreren) im Datenbankverzeichnis. Trigger entsprechen auch Dateien. Hieraus folgt, dass die Beachtung der Groß-/Kleinschreibung des zugrunde liegenden Betriebssystems eine Rolle bei der Beachtung der Groß-/Kleinschreibung von Datenbank- und Tabellennamen spielt. Dies heißt, dass bei Datenbank-, Tabellen- und Triggernamen in Windows die Groß-/Kleinschreibung nicht beachtet wird, in den meisten Derivaten von Unix wird die Groß-/Kleinschreibung jedoch beachtet. Eine beachtenswerte Ausnahme ist Mac OS X, welches zwar auf Unix basiert, standardmäßig aber einen Dateisystemtyp verwendet, der die Groß-/Kleinschreibung nicht beachtet. Allerdings unterstützt Mac OS X auch UFS-Volumes, die wie bei Unix üblich die Groß-/Kleinschreibung unterscheiden. So bietet etwa die C-API eine Anzahl von Funktionsaufrufen, die eine API für vorbereitete Anweisungen darstellen. Siehe auch MySQL Extensions to Standard SQL. Die Systemvariable lower_case_table_names beeinflusst ebenfalls die Vorgehensweise des Servers in Bezug auf die Groß-/Kleinschreibung bei Bezeichnern. Weitere Informationen hierzu folgen in diesem Abschnitt.

Anmerkung

Zwar wird die Groß-/Kleinschreibung bei Datenbank-, Tabellen- und Triggernamen auf manchen Plattformen nicht unterschieden, aber Sie sollten eine gegebene Datenbank, Tabelle oder einen Trigger auch nicht mit unterschiedlichen Schreibweisen innerhalb derselben Anweisung referenzieren. Die folgende Anweisung würde nicht funktionieren, weil sie eine Tabelle sowohl als my_table als auch als MY_TABLE referenziert:

mysql> SELECT * FROM my_table WHERE MY_TABLE.col=1;

Bei Namen von Spalten, Indizes, gespeicherten Routinen und Ereignissen wird die Groß-/Kleinschreibung auf keiner Plattform unterschieden. Gleiches gilt für Spaltenaliase.

Allerdings wird für die Namen von Triggern und Logdatei-Gruppen die Groß-/Kleinschreibung beachtet. Dies unterscheidet sich von standardmäßigem SQL.

Standardmäßig wird die Groß-/Kleinschreibung bei Tabellenalias-Namen unter Unix, nicht aber unter Windows oder Mac OS X unterschieden. Die folgende Anweisung würde unter Unix nicht funktionieren, da sie einen Alias sowohl als a als auch als A referenziert:

mysql> SELECT col_name FROM tbl_name AS a
    -> WHERE a.col_name = 1 OR A.col_name = 2;

Unter Windows hingegen ist diese Anweisung zulässig. Damit Sie Probleme, die sich aus diesen Unterschieden ergeben, möglichst vermeiden, sollten Sie am besten eine konsistente Benennungskonvention verwenden, in der Datenbanken und Tabellen immer mit aus Kleinbuchstaben bestehenden Namen erstellt und referenziert werden. Eine solche Konvention wird im Sinne maximaler Portabilität und Benutzerfreundlichkeit empfohlen.

Wie Tabellen- und Datenbanknamen auf der Festplatte gespeichert und in MySQL verwendet werden, wird von der lower_case_table_names-Systemvariablen beeinflusst, die Sie setzen können, wenn Sie mysqld starten. lower_case_table_names kann die in der folgenden Tabelle gezeigten Werte annehmen. Diese Variable wirkt sich nicht auf die Beachtung der Groß-/Kleinschreibung von Triggerbezeichnern aus. Auf Unix ist der Standardwert von lower_case_table_names 0. Unter Windows ist der Standardwert 1. Auf Mac OS X ist der Standardwert 2.

WertBedeutung
0Tabellen- und Datenbanknamen werden in der Schreibweise auf Festplatte gespeichert, die in der CREATE TABLE- bzw. CREATE DATABASE-Anweisung angegeben wurde. Beim Namensvergleich wird die Groß-/Kleinschreibung unterschieden. Beachten Sie, dass, wenn Sie diese Variable auf einem Dateisystem ohne Unterscheidung der Groß-/Kleinschreibung mit --lower-case-table-names= 0 explizit auf 0 setzen und dann MyISAM-Tabellen mit Namen in anderer Schreibung aufrufen, dies zu einer Beschädigung der Indizes führen kann.
1Tabellennamen werden in Kleinbuchstaben auf Festplatte gespeichert. Beim Namensvergleich wird die Groß-/Kleinschreibung nicht unterschieden. MySQL konvertiert beim Speichern und Abrufen alle Tabellennamen in Kleinbuchstaben. Dieses Verhalten gilt auch für Datenbanknamen und Tabellenaliase.
2Tabellen- und Datenbanknamen werden in der Schreibweise auf Festplatte gespeichert, die in der CREATE TABLE- bzw. CREATE DATABASE-Anweisung angegeben wurde; beim Nachschlagen konvertiert MySQL sie jedoch in Kleinbuchstaben. Beim Namensvergleich wird die Groß-/Kleinschreibung nicht unterschieden. Dies funktioniert nur auf Dateisystemen, die die Groß-/Kleinschreibung nicht unterscheiden! InnoDB-Tabellennamen werden in Kleinbuchstaben (wie bei lower_case_table_names=1) gespeichert.

Wenn Sie MySQL nur auf einer Plattform verwenden, dann müssen Sie die Variable lower_case_table_names normalerweise nicht vom Standardwert abweichen lassen. Allerdings kann es zu Problemen kommen, wenn Sie Tabellen auf andere Plattformen mit unterschiedlicher Behandlung der Groß-/Kleinschreibung portieren wollen. So können Sie unter Unix beispielsweise zwei verschiedene Tabellen mit den Namen my_table und MY_TABLE verwenden; unter Windows jedoch werden diese beiden Namen als identisch betrachtet. Um Transferprobleme aufgrund der Schreibweise von Datenbank- oder Tabellennamen zu vermeiden, haben Sie zwei Optionen:

  • Sie verwenden lower_case_table_names=1 auf allen Systemen. Der wesentliche Nachteil besteht hierbei darin, dass Sie, wenn Sie SHOW TABLES bzw. SHOW DATABASES verwenden, die Namen nicht in der ursprünglichen Schreibweise angezeigt bekommen.

  • Sie verwenden unter Unix lower_case_table_names=0 und unter Windows lower_case_table_names=2. Hierdurch wird die Schreibweise von Datenbank- und Tabellennamen beibehalten. Allerdings müssen Sie in diesem Fall gewährleisten, dass Ihre Anweisungen unter Windows die korrekte Schreibweise für Datenbank- und Tabellennamen enthalten. Wenn Sie Ihre Anweisungen dann auf Unix übertragen, wo die Groß-/Kleinschreibung unterschieden wird, dann funktionieren sie aufgrund der falschen Schreibweise nicht mehr.

    Ausnahme: Wenn Sie InnoDB-Tabellen verwenden und Sie versuchen, diese Datenübertragungsprobleme zu vermeiden, sollten Sie lower_case_table_names auf allen Plattformen auf 1 setzen, um in Kleinbuchstaben zu konvertierende Namen zu erzwingen.

Wenn Sie die Systemvariable lower_case_table_names unter Unix auf 1 setzen wollen, müssen Sie zunächst Ihre alten Datenbank- und Tabellennamen in die Kleinschreibung konvertieren, bevor Sie mysqld stoppen und mit der neuen Variableneinstellung neu starten.

Objektnamen können für Duplikate gehalten werden, wenn ihre großgeschriebenen Formen gemäß einer binären Sortierung gleich sind. Das trifft für Namen von Cursorn, Bedingungen, Funktionen, Prozeduren, Savepoints, Stored-Routine-Parameter, gespeicherte programmlokale Variablen und Plug-Ins zu. Es trifft nicht für Namen von Spalten, Constraints, Datenbanken, Partitionen, mit PREPARE vorbereiteten Anweisungen, Tabellen, Triggern, Benutzern und benutzerdefinierten Variablen zu.

5.2.3. Abbilden von Bezeichnern auf Dateinamen

Es gibt eine Übereinstimmung zwischen Datenbank- und Tabellenbezeichnern und Namen im Dateisystem. Für die Grundstruktur stellt MySQL jede Datenbank als ein Verzeichnis im Datenverzeichnis und jede Tabelle durch eine oder mehrere Dateien im entsprechenden Datenbankverzeichnis dar. Für das Tabellenformat (.FRM) werden die Daten immer in dieser Struktur und an diesem Standort gespeichert.

Für die Daten- und Indexdateien ist die genaue Darstellung auf Festplatte Speicher-Engine-spezifisch. Diese Dateien können am gleichen Standort wie die FRM-Dateien gespeichert werden, oder die Informationen werden in eine gesonderte Datei geschrieben. InnoDB-Daten werden in den InnoDB-Datendateien gespeichert. Wenn Sie Tablespaces mit InnoDB verwenden, werden die spezifischen Tablespace-Dateien, die Sie einrichten, stattdessen verwendet.

Vor MySQL 5.1.6 gibt es einige Begrenzungen auf die Zeichen, die in Bezeichnern für Datenbankobjekte verwendet werden können, die Dateisystemobjekten entsprechen. Zum Beispiel werden Pfadnamenstrennzeichen verweigert. Auch der „.“ wird verweigert, weil er als Anfangszeichen der Erweiterung für Tabellendateien dient.

Ab MySQL 5.1.6 ist jedes Zeichen in Datenbank- oder Tabellenbezeichnern außer ASCII NUL (0x00) legal. MySQL verschlüsselt Zeichen, die in den entsprechenden Dateisystemobjekten problematisch sind, wenn es Datenbankverzeichnisse oder Tabellendateien einrichtet:

  • Basic Latin-Buchstaben (a..zA..Z) und Ziffern (0..9) werden wie gehabt verschlüsselt. Folglich hängt ihre Beachtung der Groß-/Kleinschreibung direkt von Dateisystemfunktionen ab.

  • Alle anderen nationalen Buchstaben von Alphabeten, die eine Groß-/Kleinschreibungszuordnung haben, werden folgendermaßen verschlüsselt:

    Code range Pattern            Number   Used Unused  Blocks
    -----------------------------------------------------------------------------
    00C0..017F [@][0..4][g..z] 5*20= 100   97     3  Latin1 Supplement + Ext A
    0370..03FF [@][5..9][g..z] 5*20= 100   88    12  Greek + Coptic
    0400..052F [@][g..z][0..6] 20*7= 140  140   137  Cyrillic
    0530..058F [@][g..z][7..8] 20*2=  40   38     2  Armenian
    2160..217F [@][g..z][9]    20*1=  20   16     4  Number Forms
    0180..02AF [@][g..z][a..k] 28*11=220  203    17  Latin Ext B + IPA
    1E00..0EFF [@][g..z][l..r] 20*7= 140  136     4  Latin Additional Extended
    1F00..1FFF [@][g..z][s..z] 20*8= 160  144    16  Greek Extended
    ....  .... [@][a..f][g..z] 6*20= 120    0   120  RESERVED
    24B6..24E9 [@][@][a..z]           26   26     0  Enclosed Alphanumerics
    FF21..FF5A [@][a..z][@]           26   26     0  Full Width forms
    

    Eines der Byte in der Sequenz verschlüsselt die Schreibweise. Beispiel: LATIN CAPITAL LETTER A WITH GRAVE wird als @0G verschlüsselt, während LATIN SMALL LETTER A WITH GRAVE als @0g verschlüsselt wird. Hier zeigt das dritte Byte (G oder g) die Schreibweise an. (Auf einem schreibweisenunabhängigen Dateisystem werden beide Buchstaben gleich behandelt.)

    Für einige Blöcke, wie Kyrillisch, bestimmt das zweite Byte die Schreibweise. Für andere Blöcke, wie Latin1 Supplement, bestimmt das dritte Byte die Schreibweise. Wenn zwei Byte in der Sequenz Buchstaben sind (wie in Erweitertem Griechisch), steht das linke Buchstabenzeichen für die Schreibweise. Alle anderen Buchstabenbyte müssen in Kleinbuchstaben sein.

  • Alle Nichtbuchstabenzeichen, ebenso wie Buchstaben von Alphabeten, die keine Groß-/Kleinschreibungszuordnung haben (wie Hebräisch), werden unter Verwendung hexadezimaler Darstellungen mit Kleinbuchstaben für Hex-Ziffern a..f verschlüsselt:

    0x003F -> @003f
    0xFFFF -> @ffff
    

    Die Hexadezimalwerte entsprechen Zeichenwerten im ucs2-Doppelbytezeichensatz.

Unter Windows können einige Namen wie nul, prn und aux nicht als Dateinamen verwendet werden, weil sie als Gerätenamen belegt sind. Ab MySQL 5.1.10 sind sie zulässige Namen in MySQL. Sie werden verschlüsselt, indem @@@ an den Namen angehängt wird, wenn der Server die entsprechende Datei oder das Verzeichnis einrichtet. Dies tritt auf allen Plattformen zur Portabilität des entsprechenden Datenbankobjekts zwischen Plattformen auf.

Wenn Sie Datenbanken oder Tabellen einer MySQL-Version vor 5.1.6 haben, die Sonderzeichen enthalten und für die die zu Grunde liegenden Verzeichnisnamen oder Dateinamen nicht aktualisiert worden sind, damit sie die neue Verschlüsselung verwenden, zeigt der Server ihre Namen mit dem Präfix #mysql50# in der Ausgabe von INFORMATION_SCHEMA-Tabellen oder SHOW-Anweisungen an. Wenn Sie zum Beispiel eine Tabelle a@b haben und ihre Namenverschlüsselung nicht aktualisiert wurde, zeigt SHOW TABLES sie so an:

mysql> SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| #mysql50#a@b   |
+----------------+

Um sich auf solch einen Namen zu beziehen, für den die Verschlüsselung nicht aktualisiert worden ist, müssen Sie das #mysql50#-Präfix angeben:

mysql> SHOW COLUMNS FROM `a@b`;
ERROR 1146 (42S02): Table 'test.a@b' doesn't exist
mysql> SHOW COLUMNS FROM `#mysql50#a@b`;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| i     | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+

Um alte Namen zu aktualisieren, damit Sie das besondere Präfix nicht verwenden müssen, um sie zu referenzieren, verschlüsseln Sie sie erneut mit mysqlcheck. Der folgende Befehl aktualisiert alle Namen auf die neue Verschlüsselung:

shell> mysqlcheck --check-upgrade --fix-db-names --fix-table-names --all-databases

Um nur spezifische Datenbanken oder Tabellen zu überprüfen, lassen Sie --all-databases weg und liefern Sie die entsprechenden Datenbank- oder Tabellenargumente. Weitere Informationen über die mysqlcheck-Aufrufsyntax finden Sie unter