Prevent transaction deadlocks in DownloadsCounter #3414
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
While analyzing the behavior of
DownloadsCounter
(introduced in #3413) in production, we noticed that there were a few cases of transaction deadlocks tonight in the background thread persisting the download counts.I did some investigation on the cause of this and came up with this fix. As recommended by the PostgreSQL docs, to avoid deadlocks when multiple transactions affect multiple rows in a table, the affected keys needs to be modified in a consistent order across the transactions. We implement that by sorting by
version_id
the items we're going to insert.Local reproduction instructions
The exact error we saw in production can be reproduced by opening two instances of
psql
locally and running those two set of queries in eachpsql
(without runningCOMMIT
):Then, once the commands are sent to both instances of
psql
, sending these other commands will cause the deadlock:Instead, if both transactions try to insert first
1
and then2
the firstpsql
will work fine, and the secondpsql
will wait for the firstpsql
toCOMMIT
before applying the changes. That's the behavior we want and it's the one this PR implements.r? @jtgeibel