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), anINSERT
statement can be executed to add rows tothe end of the table at the same time that
SELECT
statements are reading rows from the table. If there are multipleINSERT
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
:
WithLOAD DATA INFILE
, if you specifyCONCURRENT
with aMyISAM
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 whileLOAD DATA
is executing. Use of theCONCURRENT
option affects the performance ofLOAD DATA
a bit, even if no other session is using the table at the same time.
If you specifyHIGH_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.
ForLOCK TABLE
, the difference betweenREAD LOCAL
andREAD
is thatREAD LOCAL
allows nonconflictingINSERT
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は、テーブルを取得するために待機する回数を表します.