There is a request that is executed in parallel by multiple threads in its own transactions:
SELECT `account_id` FROM `accounts` WHERE `request_mts` < :request_mts ORDER BY `request_mts` ASC LIMIT 1 FOR UPDATE ... where "account_id" is the primary key, and ": request_mts" is the number of milliseconds.
This query often leads to deadlocks:
Trying to get lock; try restarting transaction
QMYSQL3: Unable to store statement results
The problem, as we found out, is related to the sorting of the sample. If the sorting is removed from the query, then the deadlocks no longer occur:
SELECT `account_id` FROM `accounts` WHERE `request_mts` < :request_mts LIMIT 1 FOR UPDATE Is there a way to save the sort, but avoid the deadlocks?
Updated
After the selection (if a suitable account_id was found), there is a request to update the request_mts column in the same transaction as the sample. After that, the transaction is closed.
UPDATE `accounts` SET `request_mts` = :request_mts WHERE `account_id` = :account_id
READ COMMITTED. The presence of a covering index can also help. - Akinaupdate, which updates therequest_mtsif the previousaccount_idwas found in the previous step. Can you tell a little more about this: "distributing records for processing streams by the remainder of dividing mts by the number of streams"? - alexis031182READ COMMITTED. What is a covering index? - alexis031182request_mts < :request_mts and request_mts % ΠΊΠΎΠ»-Π²ΠΎ-ΠΏΠΎΡΠΎΠΊΠΎΠ² = Π½ΠΎΠΌΠ΅Ρ-ΠΏΠΎΡΠΎΠΊΠ°conditionrequest_mts < :request_mts and request_mts % ΠΊΠΎΠ»-Π²ΠΎ-ΠΏΠΎΡΠΎΠΊΠΎΠ² = Π½ΠΎΠΌΠ΅Ρ-ΠΏΠΎΡΠΎΠΊΠ°then two threads will not physically be able to receive the same record, because their numbers are different. at the same time, the records for the streams will be distributed more or less evenly (unless of course you have the same number in milliseconds constantly) - Mike