Skip to content
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

AccessLog update causes deadlock #909

Open
m-lang opened this issue Jul 29, 2022 · 1 comment
Open

AccessLog update causes deadlock #909

m-lang opened this issue Jul 29, 2022 · 1 comment

Comments

@m-lang
Copy link

m-lang commented Jul 29, 2022

In user_logged_out function of handler/database.py there is an update() call:

AccessLog.objects.filter(
  username=username, logout_time__isnull=True
).update(logout_time=request.axes_attempt_time)

There are two problems with this update:

  1. If the same user logs into the system from multiple places then at logout the AXES Django module tries to update ALL rows that has logout time NULL for the user. That means that the first logout will trigger all records belonging to the user to be updated, which is not correct. The system must update only the record that was created for the current session (and do not touch the other records).

  2. The second problem is because the first problem exists. During update the database puts locks on the rows and when the logout takes place simultaneously from two places and the update is run simultaneously and there are multiple logins, then it is not guaranteed that the order of the rows will be tha same during update and that might result in a deadlock.
    See this StachExchange article:
    https://dba.stackexchange.com/questions/257217/why-am-i-getting-a-deadlock-for-a-single-update-query

The quick and dirty fix for the deadlock would be to sort the rows by ID. If the new rows are guaranteed to have higher ID than the old ones, then the UPDATE will never deadlock, because at every run the system will lock in the same order.

The real fix would be to save the ACCESSLOG row ID in the session and update the corresponding row when logout takes place.

@aleksihakli
Copy link
Member

aleksihakli commented Aug 17, 2022

Thanks for reporting this.

Quick and dirty fix can not unfortunately be guaranteed to work with all the database backends as row IDs are not always-incrementing on all database engines.

Would somebody be interested in exploring linking sessions to the AccessLog records or fixing the deadlock by other means?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants