Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Lock] MySQL reports deadlocks which are difficult to investigate #57906

Open
@sylfabre

Description

@sylfabre

Symfony version(s) affected

6.4.6 but I guess it happens with newest ones too as there are no changes according to the changelog

Description

MySQL reports deadlocks like this one when using the Lock component:

------------------------
LATEST DETECTED DEADLOCK
------------------------
2024-08-02 02:42:39 125380545455680
*** (1) TRANSACTION:
TRANSACTION 2755326397, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1128, 2 row lock(s)
MySQL thread id 610443, OS thread handle 125380125038144, query id 23603665462 10.10.13.8 app-read-write update
INSERT INTO lock_keys (key_id, key_token, key_expiration) VALUES ('c0c39cdb26e264f91ea3628f2ab2c87b04cee54fa6dc5bc2e75a499d022110a9', 'iyNOnmWrqJBjkAh5C77LMZjFKFDBQIBEntYf+RmzDVY=', UNIX_TIMESTAMP() + 300)

*** (1) HOLDS THE LOCK(S):
RECORD LOCKS space id 191 page no 180 n bits 192 index PRIMARY of table `bbwzm3n4u`.`lock_keys` trx id 2755326397 lock mode S locks rec but not gap
Record lock, heap no 63 PHYSICAL RECORD: n_fields 5; compact format; info bits 32
 0: len 30; hex 633063333963646232366532363466393165613336323866326162326338; asc c0c39cdb26e264f91ea3628f2ab2c8; (total 64 bytes);
 1: len 6; hex 0000a43af1bc; asc    :  ;;
 2: len 7; hex 01000054532ef0; asc    TS. ;;
 3: len 30; hex 77556d4f3542534134744e6c417766436445397a6c727863467a666b4c4d; asc wUmO5BSA4tNlAwfCdE9zlrxcFzfkLM; (total 44 bytes);
 4: len 4; hex 66ac48cb; asc f H ;;


*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 191 page no 180 n bits 192 index PRIMARY of table `bbwzm3n4u`.`lock_keys` trx id 2755326397 lock_mode X locks rec but not gap waiting
Record lock, heap no 63 PHYSICAL RECORD: n_fields 5; compact format; info bits 32
 0: len 30; hex 633063333963646232366532363466393165613336323866326162326338; asc c0c39cdb26e264f91ea3628f2ab2c8; (total 64 bytes);
 1: len 6; hex 0000a43af1bc; asc    :  ;;
 2: len 7; hex 01000054532ef0; asc    TS. ;;
 3: len 30; hex 77556d4f3542534134744e6c417766436445397a6c727863467a666b4c4d; asc wUmO5BSA4tNlAwfCdE9zlrxcFzfkLM; (total 44 bytes);
 4: len 4; hex 66ac48cb; asc f H ;;


*** (2) TRANSACTION:
TRANSACTION 2755326398, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1128, 2 row lock(s)
MySQL thread id 624364, OS thread handle 125379871249984, query id 23603665471 10.10.13.10 app-read-write update
INSERT INTO lock_keys (key_id, key_token, key_expiration) VALUES ('c0c39cdb26e264f91ea3628f2ab2c87b04cee54fa6dc5bc2e75a499d022110a9', 'bT4yW/bpDThzAgHWxqjc0IEzJA7oCofHoKXqrTac808=', UNIX_TIMESTAMP() + 300)

*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 191 page no 180 n bits 192 index PRIMARY of table `bbwzm3n4u`.`lock_keys` trx id 2755326398 lock mode S locks rec but not gap
Record lock, heap no 63 PHYSICAL RECORD: n_fields 5; compact format; info bits 32
 0: len 30; hex 633063333963646232366532363466393165613336323866326162326338; asc c0c39cdb26e264f91ea3628f2ab2c8; (total 64 bytes);
 1: len 6; hex 0000a43af1bc; asc    :  ;;
 2: len 7; hex 01000054532ef0; asc    TS. ;;
 3: len 30; hex 77556d4f3542534134744e6c417766436445397a6c727863467a666b4c4d; asc wUmO5BSA4tNlAwfCdE9zlrxcFzfkLM; (total 44 bytes);
 4: len 4; hex 66ac48cb; asc f H ;;


*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 191 page no 180 n bits 192 index PRIMARY of table `bbwzm3n4u`.`lock_keys` trx id 2755326398 lock_mode X locks rec but not gap waiting
Record lock, heap no 63 PHYSICAL RECORD: n_fields 5; compact format; info bits 32
 0: len 30; hex 633063333963646232366532363466393165613336323866326162326338; asc c0c39cdb26e264f91ea3628f2ab2c8; (total 64 bytes);
 1: len 6; hex 0000a43af1bc; asc    :  ;;
 2: len 7; hex 01000054532ef0; asc    TS. ;;
 3: len 30; hex 77556d4f3542534134744e6c417766436445397a6c727863467a666b4c4d; asc wUmO5BSA4tNlAwfCdE9zlrxcFzfkLM; (total 44 bytes);
 4: len 4; hex 66ac48cb; asc f H ;;

*** WE ROLL BACK TRANSACTION (2)

How to reproduce

I don't know how to reproduce it because I don't know which key my application is trying to lock.

My understanding is that, somehow, the lock component first MySQL-wise locks the record with a SELECT statement before the INSERT statement.

That shared lock would come from a call to the PersistingStoreInterface::exists() method from a call to the Lock::isAcquired() method.

Possible Solution

This bug is about investigating what lock usage is causing this in my application.

Right now, it is difficult because lock_id obfuscates the locked key:
image

It comes from \Symfony\Component\Lock\Store\DatabaseTableTrait::getHashedKey() that hashes the key.

I understand this hash is useful when the key is longer than 64 chars.

An alternative may be

private function getHashedKey(Key $key): string
{
	$keyAsString = (string) $key;
	if (64 <= strlen($keyAsString)) {
		return $keyAsString;
	}
	return hash('sha256', $keyAsString);
}

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions