🔒Sperren und Deadlocks
MVCC regelt das Lesen. Beim Schreiben (und beim sperrenden Lesen) braucht InnoDB Sperren – und zwar nicht nur auf Datensätzen, sondern auch auf den Lücken dazwischen.
📏Sperren-Labor: Index als Zahlengerade
Tabelle t mit Primärschlüssel id und den Zeilen 10, 20, 30. Wähle eine Sperre von Sitzung A und eine Anweisung von Sitzung B.
Sitzung A hält …
Sitzung B versucht …
Insert-Intention auf 20 kollidiert mit gehaltener Next-Key X → Sitzung B wartet.
💡 Record-Lock
Sperrt genau einen Indexeintrag. Andere Datensätze und Lücken bleiben frei.
💡 Gap-Lock
Sperrt nur die Lücke vor einem Eintrag – gegen Einfügungen. Zwei Gap-Locks auf dieselbe Lücke vertragen sich.
💡 Next-Key-Lock
Record + Lücke davor, also (vorheriger, dieser]. Standard unter REPEATABLE READ – verhindert Phantome beim sperrenden Lesen.
💡 Insert-Intention
Ein INSERT kündigt an, in eine Lücke zu schreiben. Mehrere Einfügungen in dieselbe Lücke (an verschiedenen Stellen) warten nicht aufeinander.
🧮Konfliktmatrix
Zeilensperren auf demselben Datensatz – muss die Anforderung warten?
| angefordert ↓ / gehalten → | Record S | Record X | Gap S | Gap X | Next-Key S | Next-Key X | Insert-Intention |
|---|---|---|---|---|---|---|---|
| Record S | ✔ | wartet | ✔ | ✔ | ✔ | wartet | ✔ |
| Record X | wartet | wartet | ✔ | ✔ | wartet | wartet | ✔ |
| Gap S | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| Gap X | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| Next-Key S | ✔ | wartet | ✔ | ✔ | ✔ | wartet | ✔ |
| Next-Key X | wartet | wartet | ✔ | ✔ | wartet | wartet | ✔ |
| Insert-Intention | ✔ | ✔ | wartet | wartet | wartet | wartet | ✔ |
Berechnet mit den Regeln aus lock_rec_has_to_wait(): Gap-Sperren blockieren nur Einfügungen (Insert-Intention), nie andere Sperren.
Tabellensperren (Intention Locks)
| IS | IX | S | X | |
|---|---|---|---|---|
| IS | ✔ | ✔ | ✔ | ✘ |
| IX | ✔ | ✔ | ✘ | ✘ |
| S | ✔ | ✘ | ✔ | ✘ |
| X | ✘ | ✘ | ✘ | ✘ |
Vor jeder Zeilensperre setzt InnoDB auf der Tabelle IS (für S) bzw. IX (für X). So erkennt ein LOCK TABLES … WRITE sofort, dass Zeilen gesperrt sind.
💀Deadlock im Wartegraphen
Zwei Transaktionen sperren dieselben Zeilen in umgekehrter Reihenfolge.
Schritt 1 / 6 · Tasten ← →
Zwei Überweisungen laufen gleichzeitig: A bucht von Konto 1 auf Konto 2, B von Konto 2 auf Konto 1.
A hält: –
B hält: –
✅ Vermeiden
Zeilen immer in derselben Reihenfolge sperren (z. B. nach id sortiert), Transaktionen kurz halten, passende Indizes – ohne Index sperrt ein UPDATE viel mehr Einträge.
💡 Lock Wait Timeout
Ohne Zyklus wartet eine Anweisung bis
innodb_lock_wait_timeout (Standard 50 s) und endet dann mit ERROR 1205. MariaDB kennt zusätzlich SELECT … FOR UPDATE WAIT n und NOWAIT.💡 Wer wartet gerade?
information_schema.INNODB_LOCK_WAITS, INNODB_TRX und SHOW ENGINE INNODB STATUS\G.