私は次のクエリを持っている:MySQLの自己結合デッドロック
UPDATE messages QM JOIN (SELECT id FROM messages WHERE name = 'name'
AND state = 0 ORDER BY priority DESC, timestamp DESC LIMIT 1) AS QM2
ON QM.name ='name' AND QM.id = QM2.id SET QM.weight = QM.weight + 1;
複合インデックスがあり
(簡単な更新と、ORDER BYのインデックスを使用することができないのmysqlので、私は自己結合ここで必要) (name, state, priority, timestamp)
の列にあります。上記のクエリと完全に一致します。
私の問題は、デッドロックの膨大な量であるとき、クエリ率> 80のRPS:
------------------------
LATEST DETECTED DEADLOCK
------------------------
2017-05-15 12:04:49 7f7992119b00
*** (1) TRANSACTION:
TRANSACTION 3923289, ACTIVE 0 sec starting index read
mysql tables in use 2, locked 2
LOCK WAIT 4 lock struct(s), heap size 1184, 4 row lock(s)
MySQL thread id 992, OS thread handle 0x7f7958b5eb00, query id 1325283 172.17.0.1 facade Sending data
UPDATE queue_messages m1 JOIN
(SELECT id FROM queue_messages WHERE queue_name = ? AND state = 0 ORDER BY priority DESC, message_timestamp DESC LIMIT ?)
AS m2 ON m1.queue_name = ? AND m1.id = m2.id SET m1.state = 1, m1.transient_token = ?, m1.transient_token_expiration_timestamp = ?, m1.retry_count = retry_count + 1
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1772 page no 2464 n bits 304 index `QUEUE_NAME_STATE_PRIORITY_MESSAGE_TIMESTAMP_INDEX` of table `actionmq_data`.`queue_messages` trx table locks 1 total table locks 4 trx id 3923289 lock mode S waiting lock hold time 0 wait time before grant 0
*** (2) TRANSACTION:
TRANSACTION 3923243, ACTIVE 0 sec updating or deleting
mysql tables in use 2, locked 2
9 lock struct(s), heap size 2936, 9 row lock(s), undo log entries 1
MySQL thread id 975, OS thread handle 0x7f7992119b00, query id 1325044 172.17.0.1 facade updating reference tables
UPDATE queue_messages m1 JOIN
(SELECT id FROM queue_messages WHERE queue_name = ? AND state = 0 ORDER BY priority DESC, message_timestamp DESC LIMIT ?)
AS m2 ON m1.queue_name = ? AND m1.id = m2.id SET m1.state = 1, m1.transient_token = ?, m1.transient_token_expiration_timestamp = ?, m1.retry_count = retry_count + 1
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 1772 page no 2464 n bits 304 index `QUEUE_NAME_STATE_PRIORITY_MESSAGE_TIMESTAMP_INDEX` of table `actionmq_data`.`queue_messages` trx table locks 2 total table locks 4 trx id 3923243 lock_mode X locks rec but not gap lock hold time 0 wait time before grant 0
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1772 page no 2469 n bits 168 index `QUEUE_NAME_STATE_PRIORITY_MESSAGE_TIMESTAMP_INDEX` of table `actionmq_data`.`queue_messages` trx table locks 2 total table locks 4 trx id 3923243 lock_mode X locks gap before rec insert intention waiting lock hold time 0 wait time before grant 0
*** WE ROLL BACK TRANSACTION (1)
私はそれを解決することができますか?
こんにちは。残念ながら、私はこのアプローチに次のようなエラーがあります。 'テーブル 'QM'は、 'UPDATE'のターゲットとデータの別のソースの両方として2回指定されます。 –
これを試してください: ' UPDATE messages QM SET QM.weight =(QM .weight + 1)WHERE QM.id =(select id from FROMメッセージWHERE name = 'name' AND state = 0 ORDER BY優先度DESC、タイムスタンプDESC LIMIT 1)m) –