Rolf B: mysql show processlist

Beitrag lesen

Hallo norbert,

das Statement sieht harmlos aus, aber:

  • ist es InnoDB?
  • wieviel Rows hat die Table?
  • ist ls_num eine Indexierte Spalte?
  • gibt es Trigger, die ggf. Folgeaktivitäten auslösen können?
  • Sind die geänderten Spalten ggf. foreign Keys, die mit Update Cascade definiert sind?

Wieviel Last ist auf der Webseite? Viele User gleichzeitig? Wenn es dann Transaktionen gibt, können zwei Requeste, die zuerst Sätze lesen und dann einen Updaten, sich gegenseitig festfressen. Voraussetzung sind Isolation Levels in den Transaktionen, die Lesesperren hervorrufen. Zum Beispiel Repeatable Read.

Request 1: Liest Sätze 1-10 und setzt für sie einen s-lock (Shared Lock) Request 2: Liest Sätze 1-10 und setzt ebenfalls einen s-lock

Zwei s-locks auf einen Satz sind erlaubt. Alles prima.

Request 1: Möchte Satz 4 Updaten und bestellt bei MySQL einen Upgrade des s-lock von Satz 4 auf einen x-lock (Exclusive lock). Diese Bestellung geht in die Warteschlange, weil Request 2 ebenfalls einen s-lock hält. Ein x-lock will allein sein.

Request 2: Möchte Satz 7 Updaten und bestellt bei MySQL einen Upgrade seines s-lock auf Satz 7 auf einen x-lock. Aber Request 1 hält bereits einen s-lock, darum geht auch diese Bestellung in die Warteschlange.

Dum di dum di dum...

Irgendwann gibt's einen Deadlock-Timeout.

In einer Transaktion erst zu lesen und dann zu schreiben ist bei Multiuserbetrieb kritisch. Hier gibt's eine Abhandlung zum Thema.

Statt vorab zu sperren (pessimistic locking) gibt's auch die Möglichkeit, gar nicht zu sperren und beim Schreiben zu prüfen, ob das immer noch der Satz ist den man gelesen hat (optimistic locking). Dazu braucht es einen Update-Timestamp oder einen Updatecounter pro Row, der man bei jedem Update ändert. Das ist natürlich Programmierarbeit.

Rolf

--
sumpsi - posui - obstruxi