MySQL のテーブルロックコードはデッドロックフリーです。
        MySQL は、InnoDB テーブルと
        BDB
        テーブルを除くすべてのテーブル型にテーブルロックを使用して、非常に高速なロックを実現します。大型のテーブルの場合、ほとんどのアプリケーションで行ロックと比較してテーブルロックのほうがはるかに優れていますが、これには危険もあります。
      
        InnoDB テーブルと BDB
        テーブルの場合は、MySQL で LOCK
        TABLES
        によって明示的テーブルをロックした場合のみテーブルロックが使用されます。
        InnoDB
        は自動行レベルロックを使用し、BDB
        はページレベルロックを使用してトランザクションの独立を確実にするため、これらのテーブル型には、LOCK
        TABLES
        をまったく使用しないように推奨します。
      
        MySQL バージョン 3.23.7
        以降は、MyISAM
        テーブルへのレコードの挿入を、他のスレッドが同一テーブルから読み取りを行うのと同時に実行できるようになりました。現在のところ、挿入実行時にテーブルのレコード削除後のホールがない場合にのみ、この機能が使用可能になるため注意が必要です。すべてのホールに新規のデータが入力されると、同時挿入が自動的に再度可能になります。
      
テーブルロックにより、同時に多数のスレッドがテーブルからの読み取りを行うことができますが、あるスレッドがテーブルへの書き込みを行うときは、まず排他処理をする必要があります。更新時は、特定のテーブルにアクセスしようとする他のすべてのスレッドが、更新の準備ができるまで待機します。
        一般にテーブルの更新は SELECT
        より重要だと見なされるため、テーブルを更新するステートメントはすべて、テーブルから情報を取り出すステートメントより優先度が高くなります。これにより、更新では特定のテーブルに対して大量の重いクエリが使用されるため、更新が
        '資源枯渇'
        にさらされないことが確実になります(これは、更新を実行するステートメントを
        LOW_PRIORITY
        とともに使用するか、SELECT
        ステートメントとともに
        HIGH_PRIORITY
        を使用することで変更できます)。
      
        MySQL バージョン 3.23.7
        以降は、max_write_lock_count
        変数を使用して、テーブルに対する挿入が一定数行われた後に、MySQL
        によってテーブルの使用を待機している
        SELECT
        ステートメントのすべてに高い優先度を強制的に設定できるようになりました。
      
ただし、テーブルロックは以下のシナリオには適していません。
            クライアントが実行に長時間かかる
            SELECT を使用する。
          
            その後、別のクライアントが使用テーブルに対して
            UPDATE
            を使用する。このクライアントは
            SELECT
            が完了するまで待機が必要になる。
          
            別のクライアントが同一テーブルに対してさらに
            SELECT
            ステートメントを使用する。UPDATE
            は SELECT
            より優先度が高いため、この
            SELECT は UPDATE
            が完了するまで待機が必要になる。また、最初の
            SELECT
            の完了を待つ必要もある。
          
            full disk
            などによってスレッドが待機中の場合、そのテーブルへのアクセスが必要なすべてのスレッドが追加のディスク容量が使用可能になるまで待機状態に置かれる。
          
この問題に対応する解決策は以下のとおりです。
            SELECT
            ステートメントの実行の高速化を試行する。これにはサマリテーブルの作成が必要な場合もある。
          
            --low-priority-updates
            のオプションで mysqld
            を開始する。これは、テーブルを更新(変更)するすべてのステートメントの優先度を
            SELECT
            ステートメントの優先度より低くする。この場合、前のシナリオの最後の
            SELECT ステートメントが
            INSERT
            ステートメントより前に実行されることになる。
          
            LOW_PRIORITY
            属性を使用して、特定の
            INSERT、UPDATE、または
            DELETE
            ステートメントの優先度を低く設定できる。
          
            max_write_lock_count
            の値を低くして mysqld
            を開始し、一定数の WRITE
            ロックの後に READ
            ロックを設定する。
          
            SQL コマンド SET
            LOW_PRIORITY_UPDATES=1
            を使用すると、特定のスレッドからの更新すべてが低い優先度で実行されるように指定できる。
            See 項5.5.6. 「SET 構文」。
          
            HIGH_PRIORITY
            属性を使用すると、特定の
            SELECT
            の重要度を高く指定できる。 See
            項6.4.1. 「SELECT 構文」。
          
            SELECT と結合した
            INSERT
            に問題がある場合は、SELECT
            ステートメントと INSERT
            ステートメントの同時サポートが可能になるため、新規の
            MyISAM
            テーブルを使用するように切り替える。
          
            INSERT ステートメントと
            SELECT
            ステートメントの混在が多い場合、INSERT
            の DELAYED
            属性によって問題が解決される確率が高い。
            See 項6.4.3. 「INSERT 構文」。
          
            SELECT と DELETE
            に問題がある場合、DELETE に
            LIMIT
            オプションを使用すると解決できる場合がある。
            See 項6.4.5. 「DELETE 構文」。
          
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.

