Mysqlロックテーブル/ロック解除構文


6.7.2 LOCK TABLES/UNLOCK TABLES構文
LOCK TABLES tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}
[, tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE} ...]
...
UNLOCK TABLES
LOCK TABLESは、現在のスレッドロックテーブルです.UNLOCK TABLESは、現在のスレッドが所有するすべてのロックを解放します.スレッドが別のLOCK TABLESを発行するか、サーバとの接続が閉じられると、現在のスレッドによってロックされているすべてのテーブルが自動的にロック解除されます.
MySQL 4.0.2でLOCK TABLESを使用するには、グローバルなLOCK TABLES権限と関連テーブル上のSELECT権限が必要です.MySQL 3.23では、このテーブルにはSELECTinsertDELETEUPDATELOCK TABLESの権限が必要です.READを使用する主な理由は、トランザクションを模倣したり、テーブルを更新したりする際により高速になるためです.後でもっと詳しく説明します.
1つのスレッドが1つのテーブルにWRITEロックを取得した場合、スレッド(および他のすべてのスレッド)はテーブルからのみ読み出されます.1つのスレッドが1つのテーブルにREAD LOCALロックを得た場合、このロックを有するスレッドのみがテーブルからテーブルを読み取り、書き込みすることができる.他のスレッドがブロックされています.READREAD LOCALの違いは、ロックがロードされると、INSERTが非衝突(non-conflicting)LOCK TABLES文の実行を許可することである.ロックをロードしている間にMySQLの外部からデータベースファイルを操作すると、まだ使用できません.WRITEを使用する場合は、使用するすべてのテーブルをロックし、クエリーで使用する別名と同じ名前を使用する必要があります.クエリーでテーブル(別名)を複数回使用する場合は、別名ごとにロックを取得する必要があります.READロックは、READロックよりも高い権限を有することによって、更新が迅速に処理されることを保証する.これは、1つのスレッドがWRITEロックを取得し、同時に別のスレッドがREADロックを要求する場合、同時のWRITEロック要求はLOW_PRIORITY WRITEスレッドがロックされ、解放されるまで待機することを意味する.WRITEロックを使用して、スレッドがREADロックを待っている間に、他のスレッドがLOW_PRIORITY WRITEロックを取得することを許可します.READロックのみを使用する必要があります.これが最後になると確信したら、スレッドがないとLOCK TABLESロックがあります.LOW_PRIORITY WRITEは次のように動作します.
  • は、ロックされたすべてのテーブルを内部定義の順序でソートする(ユーザの立場から言えば、この順序は明確ではない).
  • テーブルが1つのリードロックと1つのライトロックでロックされている場合、ライトロックはリードロックの前に置かれます.
  • は一度に1つのテーブルのみをロックし、スレッドにのみすべてのロックを取得します.

  • このスキームは、テーブルロックのデッドロックが解放されることを確認するためです.このモードについては、まだ他のことを知っておく必要があります.
    テーブルに対してREADロックを使用すると、これは、スレッドがWRITEロックを要求しないまでMySQLがこのロックを待つことを意味します.スレッドがWRITEロックされ、ロックテーブルリスト内の次のテーブルのロックが取得されるのを待つと、他のすべてのスレッドはKILLロックが解放されるのを待つ.これがアプリケーションで深刻な問題を引き起こす場合は、いくつかのテーブルをトランザクション・セキュリティ・テーブルに変換することを考慮する必要があります.KILLを使用して、テーブルがロックされているスレッドを安全に殺すことができます.章4.5.5 INSERT DELAYED構文を参照してください.INSERTを使用しているテーブルをロックするべきではありません.これは、この場合、UPDATEが個別のスレッドによって完了するためである.
    通常、すべての単一READ文が原子であるため、テーブルをロックする必要はありません.他のスレッドは、現在実行されているSQL文に干渉できません.どうしてもテーブルをロックしたい場合は、次のような場合があります.
  • 多くの操作を1つのテーブルで実行している場合は、使用するテーブルをロックすると、より速くなります.もちろん、他のスレッドは、WRITEロックのテーブルを更新することができず、LOCK TABLESロックのテーブルを読み取る他のスレッドはありません.UNLOCK TABLESでは、いくつかのことがより速く実行される理由は、MySQLがMyISAMが呼び出されるまでロックされたテーブル・キー・キャッシュをダンプ・パージしないためです(通常、キー・キャッシュはSQL文ごとにダンプ・パージされます).これにより、SELECTテーブルでの挿入、更新、削除が加速します.
  • MySQLでトランザクションをサポートしないストレージエンジンを使用している場合は、UPDATELOCK TABLESの間に他のスレッドが表示されないことを確認したい場合は、LOCK TABLESを使用する必要があります.次の例は、安全に実行するために、ここではLOCK TABLES:
    mysql> LOCK TABLES trans READ, customer WRITE;
    mysql> SELECT SUM(value) FROM trans WHERE customer_id=some_id;
    mysql> UPDATE customer SET total_value=sum_from_previous_statement
    -> WHERE customer_id=some_id;
    mysql> UNLOCK TABLES;
    が必要であり、SELECT文およびUPDATE文の実行中に、trans表に新しいレコードを挿入する別のスレッドが発生する可能性があることを示している.

  • 増分更新(UPDATE customer SET value=value+new_value)またはLAST_INSERT_ID()関数を使用すると、LOCK TABLESの使用を避けることができます.
    ユーザー・レベルのロック関数GET_LOCK()およびRELEASE_LOCK()を使用して、サーバ上のハッシュ・テーブルに保存され、pthread_mutex_lock()およびpthread_mutex_unlock()で実装され、高速度を得ることもできます.章6.3.6.2補助機能関数を参照してください.
    ロックスキームの詳細については、セクション5.3.1 MySQLは表をロックする方法を参照してください.FLUSH TABLES WITH READ LOCKコマンドを使用して、すべてのデータベース内のすべてのテーブルを読み込みロックできます.章4.5.3 FLUSH構文を参照してください.Veritasなどのファイルスナップショットをタイムリーに確立できるファイルシステムがあれば、バックアップを得るのに非常に便利です.
    注:LOCK TABLESはトランザクションが安全ではありません.テーブルをロックしようとする前に、すべてのアクティブなトランザクションが自動的にコミットされます.