Dient dem Errichten und Freigeben von Tabellensperren.
virtual THR_LOCK_DATA ** store_lock
( |
thd, | |
to, | ||
lock_type) ; |
THD * | thd ; |
THR_LOCK_DATA ** | to ; |
enum thr_lock_type | lock_type ; |
Dies ist die Methode store_lock
.
Der Methode handler::store_lock()
liegt
folgende Idee zugrunde:
Die Anweisung entscheidet darüber, welche Sperren auf einer Tabelle erforderlich sind. Für Updates/Deletes/Inserts bekommen wir WRITE-Sperren und für SELECTs usw. Lesesperren.
Bevor die Sperre dem Tabellensperren-Handler übergeben wird,
ruft mysqld die Funktion
store_lock
mit den erforderlichen Sperren
auf. Diese Funktion kann die Sperrebene modifizieren, etwa den
blockierenden Schreibmodus in einen nichtblockierenden
umwandeln, die Sperre ignorieren (wenn wir die
MySQL-Tabellensperren gar nicht einsetzen möchten) oder Sperren
für viele Tabellen hinzufügen (zum Beispiel bei Verwendung
eines MERGE-Handlers).
Berkeley DB stuft beispielsweise blockierende Tabellensperren vom Typ TL_WRITE zu nichtblockierenden TL_WRITE_ALLOW_WRITE-Sperren herab (ein Zeichen dafür, dass wir zwar Schreiboperationen vornehmen, aber dennoch andere Lese- und Schreibvorgänge zulassen).
store_lock()
wird auch bei der Freigabe von
Sperren aufgerufen. In diesem Fall muss normalerweise nichts
weiter getan werden.
Wenn store_lock()
das Argument
TL_IGNORE
bekommt, so bedeutet dies, dass
MySQL den Handler dasselbe Ausmaß der Sperrung wie beim letzten
Mal speichern lässt.
Wird von lock.cc
durch
get_lock_data()
aufgerufen.
thd
to
lock_type
Keine Rückgabewerte.
Das folgende Beispiel stammt von der Speicher-Engine
ARCHIVE
:
/* Das folgende Beispiel zeigt die Einrichtung von Zeilensperren. */ THR_LOCK_DATA **ha_archive::store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type) { if (lock_type == TL_WRITE_DELAYED) delayed_insert= TRUE; else delayed_insert= FALSE; if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) { /* Hier kommen wir zum Kern der Zeilensperre. Wenn TL_UNLOCK gesetzt ist Wenn kein LOCK TABLE oder DISCARD/IMPORT TABLESPACE erfolgt, dann sollen mehrere Schreib-Threads zulässig sein */ if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && lock_type <= TL_WRITE) && !thd->in_lock_tables && !thd->tablespace_op) lock_type = TL_WRITE_ALLOW_WRITE; /* In Anfragen wie INSERT INTO t1 SELECT ... FROM t2 ... würde MySQL die Sperre TL_READ_NO_INSERT für t2 verwenden und dies würde mit der Sperre TL_WRITE_ALLOW_WRITE in Konflikt treten, da alle Inserts in t2 blockiert werden. Also konvertieren wir die Sperre in eine normale Lesesperre, um nebenläufige Einfügungen in t2 zuzulassen. */ if (lock_type == TL_READ_NO_INSERT && !thd->in_lock_tables) lock_type = TL_READ; lock.type=lock_type; } *to++= &lock; return to; }
Im Folgenden sehen Sie die Minimalimplementierung für eine Speicher-Engine, die keine Sperren herabstufen muss:
THR_LOCK_DATA **ha_tina::store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type) { /* Achtung: Wenn die Sperre den Typ TL_IGNORE hat, wird lock.type nicht aktualisiert, sondern die vorherige Ebene beibehalten*/ if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) lock.type=lock_type; /* Das Herz der Methode store_lock() und ihr Daseinszweck: das (möglicherweise geänderte) Ausmaß der Sperrung im zugewiesenen Speicher festzuhalten */ *to++= &lock; return to; }
Komplexere Implementierungen finden Sie unter
ha_berkeley::store_lock()
und
ha_myisammrg::store_lock()
.
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.