MySQLのテーブルロックの問題(一)

5495 ワード


mysqlマニュアルにはlock tablesの文法について説明されています.
LOCK TABLES
    tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}
    [, tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}] ...
UNLOCK TABLES

READ
テーブルにWRITE書き込みロックが存在する場合にはREADリードロックが実行され、この状態では現在のスレッドは修正(insert,update,delete)することができず、他のスレッドの修正操作はキューに入る、現在のスレッドがロックを解除すると、他のスレッドの修正が実行される.
READ LOCAL
READ LOCALとREADの違いは、READ LOCALがロックが保持されている間に、非衝突INSERT文(同時に挿入)を実行することを可能にすることである.ただし、MySQLの外部でデータベース・ファイルを操作しながらロックしている場合は、READ LOCALは使用できません.InnoDBテーブルの場合、READ LOCALはREADと同じです.
WRITE
現在のユーザがロックされたテーブルの読み取りと変更を許可されているほか、他のユーザのすべてのアクセスは完全にブロックされている.なお、現在のスレッドにおいてWRITEが実行する場合、READが加算されてもキャンセルすることはない.
LOW_PRIORITY WRITE
優先度を下げるWRITEは、デフォルトのWRITEの優先度がREADより高い.現在のスレッドのLOW_PRIORITY WRITE列の中で、実行しない前に他のスレッドがREADを転送して、それではLOW_PRIORITY WRITEは待ち続けます.
LOCK TABLESを使用する場合は、クエリーで使用するすべてのテーブルをロックする必要があります.LOCK TABLES文を使用して得られたロックは依然として有効ですが、この文にロックされていないテーブルにはアクセスできません.また、ロックされたテーブルを1回のクエリで複数回使用することはできません.別名を使用する代わりに、各別名に対するロックを個別に取得する必要があります.
マニュアルでは、次の例を示します.
mysql> LOCK TABLE t WRITE, t AS t1 WRITE;#         t      t1
mysql> INSERT INTO t SELECT * FROM t;#     2 t 
ERROR 1100: Table 't' was not locked with LOCK TABLES
mysql> INSERT INTO t SELECT * FROM t AS t1;
 
  
mysql> LOCK TABLE t READ;
mysql> SELECT * FROM t AS myalias;#                  ,      myalias    
ERROR 1100: Table 'myalias' was not locked with LOCK TABLES
 
  
mysql> LOCK TABLE t AS myalias READ;
mysql> SELECT * FROM t;#       
ERROR 1100: Table 't' was not locked with LOCK TABLES
mysql> SELECT * FROM t AS myalias;

LOCK TABLESは、以下のように実行される.
1.ロックするすべてのテーブルを内部定義の順序で分類します.この順序は、ユーザーの観点から定義されていません.
2.1つの読み込みと1つの書き込みロックを使用して1つのテーブルをロックする場合は、書き込みロックを読み込みロックの前に配置します.
3.スレッドがすべてロックされるまで、テーブルを一度にロックします.
この場合、INSERTは別のスレッドによって実行されるため、INSERT DELAYEDを使用して使用しているテーブルをロックすることはできません.一部のMyISAM操作がLOCK TABLESの下でより速いのは、UNLOCK TABLEが呼び出されるまで、MySQLがテーブルをロックしたキーキャッシュを空にしないためです.通常、各SQL文はキーが存在した後にクリアされます.
 
  MyISAM   Concurrent Inserts,         .
          MyISAM            ,         ,    .
MyISAM           Concurrent Inserts
 my.cnf      Concurrent Inserts  ,   1
    :
concurrent inserts=1,           delete update     ,     select         insert  ,          ,  
   insert       .
      :
If a MyISAM table has no holes in the data file (deleted rows in the middle), an INSERT statement can be executed to add rows to 
the end of the table at the same time that SELECT statements are reading rows from the table. If there are multiple INSERT 
statements, they are queued and performed in sequence, concurrently with the SELECT statements.
 :     update,  deleted rows in the middle     ,     text                      ,        ,   
       ,  Concurrent Inserts        )
concurrent inserts=0,         ,Concurrent Inserts     .
concurrent inserts=2,         ,Concurrent Inserts     .
 binarylog  Concurrent Inserts        insert  
         :

With LOAD DATA INFILE , if you specify CONCURRENT with a MyISAM table that satisfies the condition for concurrent inserts (that is, it contains no free blocks in the middle), other sessions can retrieve data from the table while LOAD DATA is executing. Use of the CONCURRENT option affects the performance of LOAD DATA a bit, even if no other session is using the table at the same time.
If you specify HIGH_PRIORITY , it overrides the effect of the --low-priority-updates option if the server was started with that option. It also causes concurrent inserts not to be used.
For LOCK TABLE , the difference between READ LOCAL and READ is that READ LOCAL allows nonconflicting INSERT statements (concurrent inserts) to execute while the lock is held. However, this cannot be used if you are going to manipulate the database using processes external to the server while you hold the lock
 
使用可能
mysql> show status like "table_lock%"; +-----------------------+-------+ | Variable_name         | Value | +-----------------------+-------+ | Table_locks_immediate | 81204 | | Table_locks_waited    | 2128  |
 
mysqlのテーブルロック競合の表示
Table_locks_immediateは、待ち時間なしにテーブルロックを取得する回数を示す.
Table_locks_waitedは、テーブルを取得するために待機する回数を表します.