価値のあることとして、このロックは次のことに限定されませんREAD-UNCOMMITTED
。
mysql1> show variables like '%isolation%';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
mysql1> BEGIN;
mysql1> SET @x := (SELECT x FROM foo LIMIT 1);
mysql2> UPDATE foo SET x = x+1;
[gets a lock wait]
mysql3> SHOW ENGINE INNODB STATUS;
...
---TRANSACTION 228746, ACTIVE 22 sec
2 lock struct(s), heap size 360, 1 row lock(s)
MySQL thread id 58, OS thread handle 0x7fc262a1c700, query id 8163
192.168.56.1 root cleaning up
TABLE LOCK table `test`.`foo` trx id 228746 lock mode IS
RECORD LOCKS space id 801 page no 3 n bits 80 index `PRIMARY`
of table `test`.`foo` trx id 228746 lock mode S
...
あなたがログに記録したバグで説明されているように、バグ #67452 選択から変数を設定すると、 read uncommitted を使用するとロックが取得されます。この動作はおそらく設計によるものです。SELECT
次のケースのように、結果がデータの変更に使用されるステートメントと同じカテゴリに分類されるようです。
http://dev.mysql.com/doc/refman/5.6/en/innodb-locks-set.html
コンストラクトREPLACE INTO t SELECT ... FROM s WHERE ...
またはで SELECT が使用されるとUPDATE t ... WHERE col IN (SELECT ... FROM s ...)
、 InnoDB は table の行に共有次キー ロックを設定しますs
。
次のキー ロックの理由は、SELECT
結果をより安定させるためです。つまり、またはその他のデータ変更ステートメントSELECT
に使用されている間に、 によって一致する行が変更されることは望ましくありません。UPDATE
tx_isolation がであっても、これは重要です。 InnoDB はforステートメントが の一部として実行されるときにREPEATABLE-READ
サポートしないためです。REPEATABLE-READ
SELECT
UPDATE
あなたのコメントについて:
ドキュメントに関係なく、次のことが起こります。
プレーンSELECT
ステートメントを実行すると、 InnoDB は、 を除くトランザクション分離で何もロックしませんSERIALIZABLE
。
SELECT ... LOCK IN SHARE MODE
またはを実行するSELECT ... FOR UPDATE
と、もちろんロックされます。
ただしSELECT
、データ変更ステートメントの一部としてINSERT INTO...SELECT
または のサブクエリで実行する場合、UPDATE
または で見つかったようにSET @variable := (SELECT...)
、共有ロックを使用して、更新の進行中にデータが変更されないようにします。
ドキュメントは不完全な場合があります。テストしたほうがいいです。