l&T0bGffpbn 3ﰐkQ=!SA7Q`Y՘ y ~GsgFrʊ}"(14cʴ|,]]0Yoa">Ѻ \[ń?NF|oW5:Be࿬]LƱ &|aoB#*Y*w-;UQ "m&QZ w35Et1'gv}ٖJm󐐩ɉvUϢ#:iT㇪b8AP|R,uvtn>@v\?,(Ph(H(m{~`*֣ؐ쥡k"KH %Y-ԃ/ĬEQ[kΪ@Vyo(|>I|7V}'X/ ot(lmqhT-6e追yoc(L`bU?J.9ywRJ3G<-!TIBJnPrg*gĿ3Qw8v`ﰃLx`֧m_Hk{m:j ւd[7H*T Wh̔?wF"v"=q g;>w].yqZ׆QQed/RVR榺q3LNfAٯ A?8m,+?P $W-_<`,+d=YiKi;aG}GxgS lkF]=d"dp%65}j [ĖF;xG WMڼ gP ګ`";'@DG`Ei*:Ӈz8xs1 EVʶ+ OI1XɩT~Ld{h&Tij{7hS$]n^ӝR S;E>O8ɢF wrr-@iyDag(mZꏨ/zE^6Yʻ,%U,pƘS?D*XjPS|W;z dn\ЊkEe!%2y;KS&nug'[mò,RwMW Wv1N/xwK]Hvj|N^\̚z [bnq~bS, \8&{tYARKCNvb.q3,c5EsuR O/шm9Tu)1ӎ*BY,{xd2*C+Wxtíjl4gM6e!{'6U L#+>+mgYj[v^9QmLS$F7ེ{3ߓ0bgoFܼcWt EыA{iϚ^uM9CXکX;Pp4*e>@q`F4w]MXx9!OcU'\z}$5£MOQ8*3f^:>:d1xuCCXJ ڝcn,he8&βwW_nB(]|mExf5qIrJl./ŸQXg/t\*<Kmъg#J*Qկ^ԙaD 6OƎ>Ńbg[_&ϳ@ ׳E<.w92<@Ǿ"#T!-7aףrjeyTgG@4ɹՕzL}$:;#Бc7̮r>~/W,('3$q?M6_R=IpoO1{#t^{j.L,Z(~ϳ=TiwdY/*Jy{f lbHM(_A%+H -dZi*$l=t{)"&RaQ&bwPҡU;] rBëN釬@o930Ǵ9FUcrj_]奶1'sR5%9U?fnMXmWz].㋉pzyCz!oJ%lML^Jj79Tnݯ8Cm08[WV;,l5)k"-: W)U[,P E_Q:k,UmV" ?Ycq.Uk fW ]!ָ38O֔!2l|PiR MaG9 aQՒϗf&}*UEt# zUSOɯR1/P< TLAZ诱[0 0ʭ6hOU hsk[PKA7͍LYP!΄(y" U,ֻ~z0O b܇zBםo-I 2uOKxۭ)P3n6u-.$hj ~ET㥥Kͫ;?dlAk^xWz*xhTtrP^Zk/>;x-ޗ:}5&Sx@vW;B7 ngxj'Q]'h $)R_ kgHqE=+K,os mb`'#{ݾۧ0s$!FCjUuE, E/0$h,r %nQ) B؊ćGw]#XHV;#+/g7%kQ78\[RGI}\蚃n6jhŝF<{/#ڋI]C~B[|ն;N->;:,P-n'4ba;@̒݃v3iMa ? Ay ?uaD$@OCtR̓e3Az{(a:j*2]/~u+Wuz8Ă0gdrG X!!&E4%DᫌEubKUTuY;g^CJs빡;cД UI]F.ZHӣ`͞ H=ѡs]Ei_%& ; _#g -AS-Ӎ__*_t =l0k&\jK/>

MySQL- das offizielle Handbuch



Subscribe to the monthly
MySQL Newsletter!

7.7.2 LOCK TABLES/UNLOCK TABLES-Syntax

LOCK TABLES tabelle [AS alias] {READ | [READ LOCAL] | [LOW_PRIORITY] WRITE}
            [, tabelle {READ | [LOW_PRIORITY] WRITE} ...]
...
UNLOCK TABLES

LOCK TABLES sperrt Tabellen fr den aktuellen Thread. UNLOCK TABLES hebt alle Sperren auf, die vom aktuellen Thread veranlasst wurden. Alle Tabellen, die durch den aktuellen Thread gesperrt sind, werden automatisch entsperrt, wenn der Thread ein weiteres LOCK TABLES absetzt oder wenn die Verbindung zum Server geschlossen wird.

Die wichtigsten Grnde fr die Benutzung von LOCK TABLES sind die Emulation von Transaktionen oder um mehr Geschwindigkeit bei der Aktualisierung von Tabellen zu erhalten. Das wird spter detaillierter erlutert.

Wenn ein Thread eine READ-Sperre auf eine Tabelle erlangt, kann dieser Thread (und alle anderen Threads) nur aus der Tabelle lesen. Wenn ein Thread eine WRITE-Sperre auf eine Tabelle erlangt, kann nur der Thread, der die Sperre veranlasst hat, READ oder WRITE auf der Tabelle durchfhren. Andere Threads werden blockiert.

Der Unterschied zwischen READ LOCAL und READ ist, dass READ LOCAL nicht kollidierende INSERT-Statements whrend der Dauer der Sperre zult. Das kann jedoch nicht benutzt werden, wenn Sie Datenbankdateien ausserhalb von MySQL bearbeiten, whrend die Sperre aktiv ist.

Wenn Sie LOCK TABLES benutzen, mssen Sie alle Tabellen sperren, die Sie benutzen werden, und Sie mssen denselben Alias benutzen, den Sie in Ihren Anfragen benutzen werden! Wenn Sie eine Tabelle in einer Anfrage mehrfach (mit Aliasen) benutzen, mssen Sie fr jeden Alias eine Sperre machen!

WRITE-Sperren haben normalerweise hhere Prioritt als READ-Sperren, um sicherzustellen, dass Aktualisierungen so frh wie mglich bearbeitet werden. Dass heit, wenn ein Thread eine READ-Sperre erlangt und dann ein anderer Thread eine WRITE-Sperre verlangt, dass nachfolgende READ-Sperrenanfragen warten, bis der WRITE-Thread die Sperre erhalten und freigegeben hat. Sie knnen LOW_PRIORITY WRITE-Sperren benutzen, um anderen Threads zu gestatten, READ-Sperren zu erlangen, whrend der Thread auf die WRITE-Sperre wartet. Sie sollten nur dann LOW_PRIORITY WRITE-Sperren benutzen, wenn Sie sicher sind, dass es irgendwann eine Zeit gibt, in der kein anderer Thread eine READ-Sperre haben wird.

LOCK TABLES funktioniert wie folgt:

  1. Sortiert alle Tabellen, die gesperrt werden sollen, in einer intern definierten Reihenfolge (aus Benutzersicht ist die Reihenfolge undefiniert).
  2. Wenn eine Tabelle mit einer Lese- und einer Schreibsperre gesperrt ist, wird die Schreibsperre vor die Lesesperre platziert.
  3. Sperrt eine Tabelle nach der anderen, bis der Thread alle Sperren erhalten hat.

Diese Methode stellt sicher, dass Tabellensperren blockierungsfrei ist. Bei diesem Schema gibt es jedoch ein paar weitere Dinge, derer man sich bewusst sein muss:

Wenn Sie eine LOW_PRIORITY_WRITE-Sperre fr eine Tabelle benutzen, heit das, dass MySQL auf diese bestimmte Sperre wartet, bis es keinen Thread gibt, der eine READ-Sperre will. Wenn der Thread die WRITE-Sperre erhalten hat und darauf wartet, die Sperre fr die nchste Tabelle in der Tabellensperrliste zu erhalten, warten alle anderen Threads darauf, dass die WRITE-Sperre aufgehoben wird. Wenn das bei Ihrer Applikation zu ernsthaften Problemen fhrt, sollten Sie in Betracht ziehen, einige Ihrer Tabelle in transaktionssichere Tabelle umzuwandeln.

Es ist sicher, einen Thread mit KILL zu killen, der auf eine Tabellensperre wartet. See section 5.5.4 KILL-Syntax.

Beachten Sie, dass Sie NICHT irgend welche Tabellen sperren sollten, die Sie mit INSERT DELAYED benutzen. Das liegt darin, dass in diesem Fall das INSERT von einem separaten Thread durchgefhrt wird.

Normalerweise mssen Sie Tabellen nicht sperren, weil alle einzelnen UPDATE-Statements atomisch sind. Kein anderer Thread kann mit einem aktuell ausgefhrten SQL-Statement in die Quere kommen. Es gibt dennoch einige Fllen, in denen es wnschenswert sein kann, Tabellen zu sperren:

  • Wenn Sie viele Operationen auf einer groen Zahl von Tabellen laufen lassen wollen, ist es viel schneller, die Tabellen zu sperren, die Sie benutzen werden. Der Nachteil besteht natrlich darin, dass kein anderer Thread eine READ-gesperrte Tabelle aktualisieren und kein anderer Thread eine WRITE-gesperrte Tabelle lesen kann. Der Grund, dass einiges mit LOCK TABLES schneller geht, liegt darin, dass MySQL den Schlssel-Cache fr die gesperrten Tabellen nicht auf Platte zurckschreibt (flush), bis UNLOCK TABLES aufgerufen wird (normalerweise wird der Schlssel-Cache nach jedem SQL-Statement auf Platte zurckgeschrieben). Das erhht die Geschwindigkeit bei den Operationen INSERT / UPDATE / DELETE bei MyISAM-Tabellen.
  • Wenn Sie einen Tabellen-Handler in MySQL benutzen, der keine Transaktionen untersttzt, mssen Sie LOCK TABLES benutzen, wenn Sie sicherstellen wollen, dass kann anderer Thread zwischen einem SELECT und einem UPDATE dazwischen kommen kann. Das unten stehende Beispiel erfordert LOCK TABLES, um sicher ausgefhrt zu werden:
    mysql> LOCK TABLES trans READ, kunde WRITE;
    mysql> select sum(wert) from trans where kunde_id=irgendeine_id;
    mysql> update kunde set gesamt_wert=summe_aus_vorherigem_statement
               where kunde_id=irgendeine_id;
    mysql> UNLOCK TABLES;
    
    Ohne LOCK TABLES besteht die Mglichkeit, dass ein anderer Thread eine neue Zeile in die trans-Tabelle einfgt, zwischen der Ausfhrung des SELECT- und des UPDATE-Statements.

Wenn Sie inkrementelle Updates (UPDATE kunde SET wert=wert+neuer_wert) oder die LAST_INSERT_ID()-Funktion benutzen, knnen Sie LOCK TABLES in vielen Fllen vermeiden.

Einige Problemflle knnen Sie auch lsen, indem Sie die Sperrfunktionen auf Benutzerebene GET_LOCK() und RELEASE_LOCK() benutzen. Diese Sperren werden in einer Hash-Tabelle im Server gespeichert und sind mit pThread_mutex_lock() und pThread_mutex_unlock() fr die Erzielung hherer Geschwindigkeit implementiert. See section 7.3.5.2 Verschiedene Funktionen.

Siehe section 6.3.1 Wie MySQL Tabellen sperrt wegen weiterer Informationen ber Sperrmethoden.

Sie knnen alle Tabellen in allen Datenbanken mit Lesesperren sperren, und zwar mit dem FLUSH TABLES WITH READ LOCK-Befehl. See section 5.5.3 FLUSH-Syntax. Das ist eine sehr bequeme Mglichkeit, Datensicherungen zu erhalten, wenn Sie ein Dateisystem wie Veritas haben, dass Schnappschsse im Zeitverlauf aufnehmen kann.

HINWEIS: LOCK TABLES ist nicht transaktionssicher und schickt automatisch jegliche aktiven Transaktionen ab (Commit), bevor es versucht, die Tabellen zu sperren.


User Comments

Posted by Warren Dew on November 21 2003 11:05pm[Delete] [Edit]

When the manual says a user needs global lock tables permission to lock tables, they mean global. While the permissions system also tracks lock tables permission at the database level, that permission does not appear to actually let the user lock tables. So when granting the permissions, if using a database, you need to do this:

grant lock tables on *.* to <user>

not this:

grant lock tables on * to <user>

At least, that's how it seemed to work for me.

Add your own comment.

Top / /