Opened 2 years ago

Last modified 4 months ago

#23326 new Bug

DatabaseCache must implement incr to guarantee atomic increment

Reported by: Vinay Anantharaman Owned by:
Component: Core (Cache system) Version: 1.6
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

django.core.cache.backends.db.DatabaseCache uses BasesCache's incr which does a get followed by a set. If the application uses multiple servers the increments will get clobbered. Furthermore, the current implementation overwrites the expiry time of a key to the default value instead of using the value which was initially set.

Change History (6)

comment:1 Changed 2 years ago by Russell Keith-Magee

Easy pickings: set
Triage Stage: UnreviewedAccepted

You are correct that the implementation of incr on the DB cache backend will be subject to race conditions, so we should fix that.

However, I'd also say that if you're using the database cache backend for a count where there is heavy traffic, You're Doing It Wrong(TM). You should be using Redis, or at least Memcached.

comment:2 Changed 2 years ago by Tim Graham

Easy pickings: unset

comment:3 Changed 2 years ago by Vinay Anantharaman

I am not doing it wrong necessarily because our DB is very small with a limited number of users. The table should basically live in InnoDB's buffer pool. It's not unreasonable to just use the DB as a cache for values.

comment:4 Changed 2 years ago by Michael Manfre

Has patch: set
Owner: changed from nobody to Michael Manfre
Status: newassigned

comment:5 Changed 2 years ago by Michael Manfre

Patch needs improvement: set

My initial patch and pull request will not work as desired. Wrapping the get/set in an atomic block will only work for database isolation levels higher than Postgresql's default. There are two possible ways of ensuring an atomic incr, (1) control the locking from python, or (2) use select_for_update. Select_for_update would be the ideal solution, except DatabaseCache doesn't use the ORM and would need to expose an API for each database backend to provide SQL.

comment:6 Changed 4 months ago by Tim Graham

Owner: Michael Manfre deleted
Status: assignednew
Note: See TracTickets for help on using tickets.
Back to Top