Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 27.1Mb
PDF (A4) - 27.2Mb
HTML Download (TGZ) - 7.2Mb
HTML Download (Zip) - 7.2Mb


13.3.5.3 テーブルロックの制限と条件

テーブルロックを待機しているセッションを終了するために、KILL を安全に使用できます。セクション13.7.6.4「KILL 構文」を参照してください。

INSERT DELAYED で使用しているテーブルはロックしないでください。挿入は、ロックを保持するセッションではなく、別のスレッドによって処理される必要があるため、この場合の INSERT DELAYED はエラーになります。

LOCK TABLES および UNLOCK TABLES は、ストアドプログラム内では使用できません。

performance_schema データベース内のテーブルは、setup_xxx テーブルを除き、LOCK TABLES ではロックできません。

LOCK TABLES ステートメントが有効になっている間、次のステートメントは禁止されます。CREATE TABLECREATE TABLE ... LIKECREATE VIEWDROP VIEW、およびストアドファンクション、ストアドプロシージャー、イベントでの DDL ステートメント。

一部の操作では、mysql データベース内のシステムテーブルにアクセスする必要があります。たとえば、HELP ステートメントにはサーバー側のヘルプテーブルの内容が必要であり、また CONVERT_TZ() はタイムゾーンテーブルの読み取りが必要になる可能性があります。サーバーは、ユーザーが明示的にロックしなくても済むように、必要に応じてシステムテーブルを読み取りに対して暗黙的にロックします。次のテーブルは、今説明したように処理されます。

mysql.help_category
mysql.help_keyword
mysql.help_relation
mysql.help_topic
mysql.proc
mysql.time_zone
mysql.time_zone_leap_second
mysql.time_zone_name
mysql.time_zone_transition
mysql.time_zone_transition_type

これらのテーブルのいずれかに対する WRITE ロックを LOCK TABLES ステートメントで明示的に設定する場合は、そのテーブルがロックされる唯一のテーブルである必要があります。ほかのどのテーブルも、同じステートメントではロックできません。

1 つの UPDATE ステートメントはすべてアトミックであるため、通常、テーブルをロックする必要はありません。現在実行中の SQL ステートメントを、ほかのどのセッションも妨げることはできません。ただし、テーブルのロックによって利点が得られる可能性のある場合がいくつかあります。

  • 一連の MyISAM テーブルに対して多くの操作を実行しようとしている場合は、使用しようとしているテーブルをロックする方がはるかに高速です。MyISAM テーブルをロックすると、MySQL はロックされたテーブルのキーキャッシュを UNLOCK TABLES が呼び出されるまでフラッシュしないため、そのテーブルに対する挿入、更新、または削除が高速化されます。通常、キーキャッシュは各 SQL ステートメントのあとでフラッシュされます。

    テーブルロックのマイナス面は、READ によってロックされたテーブルをどのセッションも更新できず (ロックを保持しているセッションを含む)、ロックを保持しているセッションを除き、WRITE によってロックされたテーブルにどのセッションもアクセスできない点です。

  • 非トランザクションストレージエンジンに対してテーブルを使用している場合、SELECTUPDATE の間にテーブルがほかのセッションによって変更されないようにするには、LOCK TABLES を使用する必要があります。次に示す例では、安全に実行するために LOCK TABLES が必要です。

    LOCK TABLES trans READ, customer WRITE;
    SELECT SUM(value) FROM trans WHERE customer_id=some_id;
    UPDATE customer
      SET total_value=sum_from_previous_statement
      WHERE customer_id=some_id;
    UNLOCK TABLES;

    LOCK TABLES を使用しない場合は、SELECT ステートメントと UPDATE ステートメントの実行の間に、別のセッションによって trans テーブルに新しい行が挿入される可能性があります。

多くの場合は、相対的な更新 (UPDATE customer SET value=value+new_value) または LAST_INSERT_ID() 関数を使用することによって LOCK TABLES の使用を回避できます。セクション1.8.2.3「トランザクションおよびアトミック操作の違い」を参照してください。

場合によっては、ユーザーレベルのアドバイザリロック関数 GET_LOCK() および RELEASE_LOCK() を使用してテーブルのロックを回避することもできます。高速化のために、これらのロックはサーバーのハッシュテーブル内に保存され、pthread_mutex_lock()pthread_mutex_unlock() で実装されます。セクション12.18「その他の関数」を参照してください。

ロックポリシーの詳細は、セクション8.10.1「内部ロック方法」を参照してください。


User Comments
Sign Up Login You must be logged in to post a comment.