-
-
Notifications
You must be signed in to change notification settings - Fork 313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Occasional deadlocks on DB #1675
Comments
The signal-cli database implementation started the first point, i.e. get a new connection for each operation. Then when implementing the storage sync it was extended to use existing connections so reading from storage could be done in a single transaction to prevent partial updates in case of failures. I'd be interested to see your changes. |
So, I spent some time working with code and I think I got rid of these errors. Also, from my logs it seems that they might have been a reason for some integrity issues which I experienced (not being able to exchange contact information between devices or even decrypt messages). Together with this change: #1690 it made situation way better for me. So, what did I change with DB:
|
Posting a patch file with a code to my previous comment to give a general feeling of what I did. |
Thank you for deeper investigation, caught 11 deadlocks in like an hour |
Sooo...
After submitting this PR #1674 I looked at the code and it seems there are more issues of this nature.
The problem is that sometimes code that holds an open connection to the DB calls another component that tries to open another connection.
As an example:
AccountRecordProcessor
is constructed with a Connection, yet in a call toStorageSyncModels.localToRemoteRecord
it passesaccount.getConfigurationStore()
, which will try to create a new Connection withkeyValueStore
.This particular example might not be critical but there are more issues like that and under load they produce errors while working with storage now and then.
For us, it leads to complete session degradation within a week with the client being completely unable to decrypt incoming messages from known contacts.
I modifier
Database.getConnection
and found some more deadlocks (basically, SQLBUSY exceptions on store modifications):There are many ways to address the issue, e.g.
account
but rather pass it around to all methods that require access to DB (to avoid cluttering the code we can pass some other useful things in that context, like loggers, account itself etc). Then when we need an ad-hoc connection, there's acontext.withConnection(c -> { ...})
method and if we want to do multiple operations wetry (var ctx = ctx.connect()) {}
which produces a context of the same type but with an already opened connection. This will allow to have functions, components, stores and helpers that can access DB but are unaware in which context they are called (with or without opened connection). So the code will be really simple and safe.The text was updated successfully, but these errors were encountered: