INSERT DELAYED ...
Die Option DELAYED
für die
INSERT
-Anweisung ist eine MySQL-Erweiterung
zum SQL-Standard, die sehr praktisch ist, wenn Sie Clients
haben, die nicht auf den Abschluss der
INSERT
-Anweisung warten können oder
müssen. Eine solche Situation liegt häufig vor, wenn Sie
MySQL zum Loggen verwenden und zudem regelmäßig
SELECT
- und
UPDATE
-Anweisungen ausführen, deren
Fertigstellung sehr lange dauert.
Wenn ein Client INSERT DELAYED
verwendet,
wird diese Anweisung vom Server sofort angenommen und der
Datensatz in einer Warteschlange abgelegt. Sobald die Tabelle
von keinem anderen Thread mehr verwendet wird, wird der
Datensatz dann aus der Warteschlange eingefügt.
Ein weiterer wesentlicher Vorteil von INSERT
DELAYED
besteht darin, dass Einfügeoperationen
mehrerer Clients gebündelt und dann in einem Block
geschrieben werden. Dies ist bedeutend schneller als die
Durchführung vieler separater Einfügeoperationen.
Beachten Sie, dass INSERT DELAYED
, sofern
die Tabelle gerade nicht anderweitig verwendet wird, langsamer
als eine normale INSERT
-Anweisung ist. Auch
liegt die Serverbelastung etwas höher, weil der Server für
jede Tabelle, für die verzögerte Datensätze vorhanden sind,
einen separaten Thread verwalten muss. Insofern sollten Sie
INSERT DELAYED
nur verwenden, wenn Sie
wirklich sicher sind, dass Sie die Funktionalität benötigen.
Die Datensätze in der Warteschlange verbleiben nur solange im
Speicher, bis sie in die Tabelle eingefügt wurden. Aufgrund
dessen gehen, wenn Sie mysqld – etwa mit
kill -9
– terminieren oder
mysqld unerwartet abstürzt, alle
Datensätze in der Warteschlange, die noch nicht auf
Festplatte geschrieben wurden, verloren!
Für die Verwendung von DELAYED
gelten
einige Einschränkungen:
INSERT DELAYED
funktioniert nur bei
MyISAM
-, MEMORY
- und
ARCHIVE
-Tabellen. Siehe auch
Abschnitt 14.1, „Die MyISAM
-Speicher-Engine“,
Abschnitt 14.4, „Die MEMORY
-Speicher-Engine“ und
Abschnitt 14.8, „Die ARCHIVE
-Speicher-Engine“.
Bei MyISAM
-Tabellen werden, wenn keine
freien Blöcke in der Mitte der Datendatei vorhanden sind,
gleichzeitige SELECT
- und
INSERT
-Anweisung unterstützt. Unter
diesen Umständen müssen Sie INSERT
DELAYED
bei MyISAM
nur in
sehr seltenen Fällen verwenden.
INSERT DELAYED
sollte nur für
INSERT
-Anweisungen eingesetzt werden,
die Wertelisten angeben. Bei INSERT DELAYED ...
SELECT
-Anweisungen ignoriert der Server das
DELAYED
.
Ebenso ignoriert der Server das DELAYED
bei INSERT ... SELECT
- oder
INSERT ... ON DUPLICATE KEY
UPDATE
-Anweisungen.
Weil die INSERT DELAYED
-Anweisung aus
Clientsicht abgeschlossen wird, bevor die Datensätze
tatsächlich eingefügt werden, können Sie den von der
Anweisung erstellten
AUTO_INCREMENT
-Wert nicht mit
LAST_INSERT_ID()
abrufen.
Verzögerte Datensätze werden für
SELECT
-Anweisungen erst sichtbar, wenn
sie tatsächlich eingefügt wurden.
DELAYED
wird auf
Slave-Replikationsservern ignoriert, weil andernfalls auf
dem Slave andere Daten vorhanden sein könnten als auf dem
Master.
Nachfolgend wird ausführlich beschrieben, was geschieht, wenn
Sie die Option DELAYED
für
INSERT
oder REPLACE
einsetzen. In dieser Beschreibung ist „Thread“
der Thread, der eine INSERT
DELAYED
-Anweisung empfangen hat, und
„Handler“ der Thread, der alle INSERT
DELAYED
-Anweisungen der betreffenden Tabelle
verwaltet.
Wenn ein Thread eine DELAYED
-Anweisung
für eine Tabelle ausführt, wird – sofern nicht bereits
vorhanden – ein Handler-Thread erzeugt, um alle
DELAYED
-Anweisungen für die Tabelle zu
verarbeiten.
Der Thread überprüft, ob der Handler zuvor bereits eine
DELAYED
-Sperre erwirkt hat, und weist
den Handler andernfalls dazu an. Die
DELAYED
-Sperre kann auch dann erwirkt
werden, wenn andere Threads eine READ
-
oder WRITE
-Sperre für die Tabelle
halten. Allerdings wartet der Handler, bis alle
ALTER TABLE
-Sperren aufgehoben und
FLUSH TABLES
-Anweisungen abgeschlossen
sind, um zu gewährleisten, dass die Tabellenstruktur
aktuell ist.
Der Thread führt die INSERT
-Anweisung
aus, schreibt den Datensatz aber nicht in die Tabelle,
sondern setzt eine Kopie des endgültigen Datensatzes in
eine Warteschlange, die vom Handler verwaltet wird.
Syntaxfehler werden vom Thread bemerkt und an das
Clientprogramm zurückgemeldet.
Der Client kann die Anzahl doppelter Datensätze oder den
AUTO_INCREMENT
-Wert des resultierenden
Datensatzes nicht beim Server erfragen, weil die
INSERT
-Anweisung vor Durchführung der
eigentlichen Einfügeoperation bereits abgeschlossen wird.
(Wenn Sie die C-API verwenden, dann gibt die Funktion
mysql_info()
aus demselben Grund nur
irrelevante Angaben zurück.)
Das Binärlog wird vom Handler-Thread aktualisiert, sobald der Datensatz in die Tabelle eingefügt wurde. Im Falle des Einfügens mehrerer Datensätze wird das Binärlog aktualisiert, wenn der erste Datensatz eingefügt wird.
Jedes Mal, wenn delayed_insert_limit
Datensätze geschrieben wurden, überprüft der Handler,
ob noch weitere SELECT
-Anweisungen
anhängig sind. Ist dies der Fall, so gestattet er deren
Ausführung, bevor er fortfährt.
Wenn der Handler keine Datensätze mehr in der
Warteschlange hat, wird die Tabelle entsperrt. Werden
innerhalb des durch
delayed_insert_timeout
(in Sekunden)
angegebenen Zeitraums keine neuen INSERT
DELAYED
-Anweisungen empfangen, dann wird der
Handler beendet.
Sind mehr als delayed_queue_size
Datensätze in einer bestimmten Handler-Warteschlange
anhängig, dann fordert der Thread INSERT
DELAYED
auf, zu warten, bis wieder Platz in der
Warteschlange ist. Hierdurch soll gewährleistet werden,
dass mysqld nicht den gesamten Speicher
für die Warteschlange mit den verzögerten Datensätzen
verwendet.
Der Handler-Thread erscheint in der MySQL-Prozessliste als
delayed_insert
in der Spalte
Command
. Er wird terminiert, wenn Sie
eine FLUSH TABLES
-Anweisung absetzen
oder KILL
ausführen.
Allerdings speichert er vor der Terminierung alle in der
Warteschlange vorhandenen Datensätze in die Tabelle,
bevor er beendet wird. In diesem Zeitraum werden keine
neuen thread_id
INSERT
-Anweisungen anderer
Threads angenommen. Wenn Sie nachfolgend eine
INSERT DELAYED
-Anweisung ausführen,
wird ein neuer Handler-Thread erstellt.
Beachten Sie, dass dies bedeutet, dass INSERT
DELAYED
-Anweisungen Vorrang vor normalen
INSERT
-Anweisungen haben, wenn ein
INSERT DELAYED
-Handler ausgeführt
wird. Andere Änderungsanweisungen müssen warten, bis die
INSERT DELAYED
-Warteschlange leer ist
oder jemand den Handler-Thread (mit KILL
) terminiert
oder eine thread_id
FLUSH TABLES
-Anweisung
ausführt.
Die folgenden Statusvariablen machen Angaben zu
INSERT DELAYED
-Anweisungen:
Statusvariable | Bedeutung |
Delayed_insert_threads |
Anzahl der Handler-Threads |
Delayed_writes |
Anzahl der mit INSERT DELAYED geschriebenen
Datensätze |
Not_flushed_delayed_rows |
Anzahl der Datensätze, die noch geschrieben werden müssen |
Sie können diese Variablen anzeigen, indem Sie eine
SHOW STATUS
-Anweisung absetzen oder den
Befehl mysqladmin extended-status
ausführen.
Dies ist eine Übersetzung des MySQL-Referenzhandbuchs, das sich auf dev.mysql.com befindet. Das ursprüngliche Referenzhandbuch ist auf Englisch, und diese Übersetzung ist nicht notwendigerweise so aktuell wie die englische Ausgabe. Das vorliegende deutschsprachige Handbuch behandelt MySQL bis zur Version 5.1.