MagicStack / MagicStack/asyncpg

Asyncpg does not seem to clear memory allocated to Pool object after db.disconnect() (possible memory leak)

オープン
#929 コメント 1 件 リアクション 5 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

主要言語
Python
スター
8.1k
フォーク
468
PR マージ指標
30日以内にマージされた PR はありません

説明

  • asyncpg version: 0.25.0 (tried with 0.23.0 and 0.24.0)
  • PostgreSQL version: 11.16
  • Do you use a PostgreSQL SaaS? If so, which? Can you reproduce
    the issue with a local PostgreSQL install?
    : No, using the postgres:11.16 docker image directrly
  • Python version: 3.10.5 (+ latest 3.9 and 3.8)
  • Platform: Ubuntu 64 and docker
  • Do you use pgbouncer?: No
  • Did you install asyncpg with pip?: Yes
  • If you built asyncpg locally, which version of Cython did you use?: N/A
  • Can the issue be reproduced under both asyncio and
    uvloop?
    : I only tried asyncio

We observed PODs running out of memory.
They are reading from a queue constantly and calling this function

async def process_request(message, db : ):
    await db.connect()
    # do_something(message, db)
    await db.disconnect()

I am confident this is related to asyncpg as here are some of the objects that are created in memory with every iteration of connect/disconnect.

  asyncpg.pgproto.pgproto.ReadBuffer |        1000 |    132.81 KB
             collections.OrderedDict |        1000 |    125.00 KB
   asyncpg.pool.PoolConnectionHolder |        1000 |    117.19 KB
          asyncio.events.TimerHandle |        1001 |    109.48 KB

I have tried:

  • waiting for the TimerHandle to expire (60s)
  • calling engine.dispose() manually
  • calling the garbage collector manually

Sometime in the past we encountered a problem that made 10000s of connections in a few seconds (crashing the DB) that was fixed by abandoning this connect/disconnect pattern, so maybe these two are related.

The db is initialised as such

databases.Database(db_uri)

This problem does not exists in the sqlite driver.

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

まず、asyncpg 0.25.0、PostgreSQL 11.16、Python 3.10.5、および Docker イメージ postgres:11.16 で説明されている、db.connect() と db.disconnect() の反復パターンを再現します。切断とガベージコレクションの後も、asyncpg.pgproto.pgproto.ReadBuffer、OrderedDict、PoolConnectionHolder、asyncio.events.TimerHandle オブジェクトが残るかどうかを調べます。sqlite ドライバーと動作を比較し、保持された割り当てがリークを表しているかどうかを判断します。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
postgresql, python
領域
backend, databases
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
説明が足りない
初心者へのやさしさ
25/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。