#31419: Django Postgres memory leak
-------------------------------------+-------------------------------------
Reporter: pinkynrg | Owner: nobody
Type: Bug | Status: new
Component: Database | Version: 3.0
layer (models, ORM) | Keywords: postgresl memory-
Severity: Normal | leak
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
Note: I also wrote the detailed issue here:
[https://stackoverflow.com/questions/60972577/django-postgres-memory-leak]
I have a custom Django (v 2.0.0) command to start background job executers
in a multi-threaded fashion which seems to give me memory leak issues.
The command can be started like so:
{{{
./manage.py start_job_executer --thread=1
}}}
Each thread has a while True loop that picks up jobs from a PostgreSQL
table.
In order to pick up the job and change the status atomically I used
transactions:
{{{
# atomic transaction to temporary lock the db access and to
# get the most recent job from db with column status = pending
with transaction.atomic():
job = Job.objects.select_for_update() \
.filter(status=Job.STATUS['pending']) \
.order_by('created_at').first()
if job:
job.status = Job.STATUS['executing']
job.save()
}}}
Il looks like the allocated memory by this Django custom command keeps
growing.
Using tracemalloc I tried to find what is causing the memory leak by
creating a background thread that checks the memory allocation:
{{{
def check_memory(self):
while True:
s1 = tracemalloc.take_snapshot()
sleep(10)
s2 = tracemalloc.take_snapshot()
for alog in s2.compare_to(s1, 'lineno')[:10]:
log.info(alog)
}}}
Finding out the following log:
{{{
01.04.20 13:50:06 operations.py:222: size=23.7 KiB (+23.7 KiB), count=66
(+66), average=367 B
01.04.20 13:50:36 operations.py:222: size=127 KiB (+43.7 KiB), count=353
(+122), average=367 B
01.04.20 13:51:04 operations.py:222: size=251 KiB (+66.7 KiB), count=699
(+186), average=367 B
01.04.20 13:51:31 operations.py:222: size=379 KiB (+68.9 KiB),
count=1056 (+192), average=367 B
01.04.20 13:51:57 operations.py:222: size=495 KiB (+60.3 KiB),
count=1380 (+168), average=367 B
}}}
Looks like /usr/local/lib/python3.5/dist-
packages/django/db/backends/postgresql/operations.py:222 does not release
memory
The leakage is slow for 1 thread but if I use 8 threads the memory leak is
worse:
{{{
01.04.20 13:07:51 operations.py:222: size=68.3 KiB (+68.3 KiB),
count=191 (+191), average=366 B
01.04.20 13:08:56 operations.py:222: size=770 KiB (+140 KiB), count=2151
(+390), average=367 B
01.04.20 13:10:07 operations.py:222: size=1476 KiB (+138 KiB),
count=4122 (+386), average=367 B
01.04.20 13:36:22 operations.py:222: size=17.3 MiB (+138 KiB),
count=49506 (+385), average=367 B
01.04.20 13:48:16 operations.py:222: size=24.5 MiB (+136 KiB),
count=69993 (+379), average=367 B
}}}
This is the code at line 222 in /usr/local/lib/python3.5/dist-
packages/django/db/backends/postgresql/operations.py:222:
{{{
def last_executed_query(self, cursor, sql, params):
# http://initd.org/psycopg/docs/cursor.html#cursor.query
# The query attribute is a Psycopg extension to the DB API 2.0.
if cursor.query is not None:
return cursor.query.decode() # this is line 222!
return None
}}}
I have no clue how to attack this problem. Any ideas at all?
Thanks in advance
**UPDATE**
I was using Django 2.0 and I thought to update to Django 3.0.5 (latest
stable release), but unfortunately the problem is still there.
Below the new logs:
{{{
01.04.20 20:15:06 operations.py:235: size=977 KiB (+53.9 KiB),
count=2750 (+152), average=364 B
01.04.20 20:15:28 operations.py:235: size=1070 KiB (+50.1 KiB),
count=3012 (+141), average=364 B
01.04.20 20:15:53 operations.py:235: size=1156 KiB (+43.7 KiB),
count=3255 (+123), average=364 B
01.04.20 20:16:19 operations.py:235: size=1245 KiB (+44.7 KiB),
count=3507 (+126), average=364 B
01.04.20 20:20:23 operations.py:235: size=2154 KiB (+44.3 KiB),
count=6065 (+125), average=364 B
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31419>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/051.fad15bdb83aa52b2c05d2ed35fb5fa1a%40djangoproject.com.