Git Product home page Git Product logo

Comments (10)

vonzshik avatar vonzshik commented on September 25, 2024 2

OK, I think I finally understand what's going on.
For the leak to happen you have to:

  1. Send LISTEN query
  2. Send NOTIFY query
  3. Send a query with extended query protocol with a parameter written as binary (and not text, like what psql does)

What's leaking is the array for parameter's OID (and in some cases, a string for the query) because they're allocated in TopMemoryContext instead of MessageContext how they're supposed to.

Now what's happening: is

  1. MessageContext is set after NOTIFY query is done
  2. notifyInterruptPending flag is set because there is a notification, so pg has to send notification
  3. Afterwards ProcessIncomingNotify is called, which starts a transaction and changes the current memory context to CurTransactionContext
  4. When transaction is commited it calls AtCommit_Memory, which changes current context to TopMemoryContext (instead of MessageContext in which we've started)
  5. This makes it so all of the allocations for Parse command (at the very least in postgres.c) are going to happen in TopMemoryContext, which is going to stay until pg process is destroyed.

Now, I'm afraid I'm going to be busy with other stuff for at least the next few weeks, so I wouldn't be able to notify pg's maintainers. If anyone is interested in raising this with pg folks and potentially fixing it themselves, please feel free to do so.

from npgsql.

vonzshik avatar vonzshik commented on September 25, 2024 1

Can also be reproed with psql:

  1. Change client encoding to a different one from pg (SET client_encoding = 'LATIN1')
  2. Subscribe to a channel (LISTEN any_channel)
  3. Do NOTIFY/SELECT 1 loop

This way it leaks query text string and in my case it's 80 bytes per loop.

image

from npgsql.

WizardBrony avatar WizardBrony commented on September 25, 2024 1

I filed a Postgres bug report for this. Here is a link to the development thread:

https://www.postgresql.org/message-id/3478884.1718656625%40sss.pgh.pa.us

Tom, if you're reading this, next time I'll submit bug details instead of linking to a GitHub page, sorry about that.

Thanks everyone for your help.

from npgsql.

vonzshik avatar vonzshik commented on September 25, 2024 1

@WizardBrony great, thank you!

from npgsql.

roji avatar roji commented on September 25, 2024

@WizardBrony just to be sure, what makes you think there's a leak here (where memory continues to be referenced), rather than Npgsql simply allocating memory that will be garbage-collected eventually? If a real leak is involved, program memory should continuously always grow, and eventually cause an OutOfMemoryException; is that really what you're seeing?

from npgsql.

WizardBrony avatar WizardBrony commented on September 25, 2024

@WizardBrony just to be sure, what makes you think there's a leak here (where memory continues to be referenced), rather than Npgsql simply allocating memory that will be garbage-collected eventually? If a real leak is involved, program memory should continuously always grow, and eventually cause an OutOfMemoryException; is that really what you're seeing?

Just to clarify, I'm seeing the actual Postgres backend process leak memory, not Npgsql, which means this could in fact be a bug in Postgres itself. However, I do not know the details of the LISTEN/NOTIFY or command parameter protocols nor Npgsql's implementation of them to know for a fact that it's not an issue in Npgsql, so I wanted to bring the issue up here first.

from npgsql.

roji avatar roji commented on September 25, 2024

Yeah, sorry - @vonzshik and @NinoFloris pointed that out to me offline. @vonzshik is taking a look at it, but as you say, this is most likely an issue in PG rather than Npgsql.

from npgsql.

WizardBrony avatar WizardBrony commented on September 25, 2024

Sounds good, thanks for looking into it. I appreciate it.

from npgsql.

tlewis-ba avatar tlewis-ba commented on September 25, 2024

Is there a usage pattern which npgsql could adopt which would avoid this pg leakage?

from npgsql.

vonzshik avatar vonzshik commented on September 25, 2024

Is there a usage pattern which npgsql could adopt which would avoid this pg leakage?

You could try sending SELECT 1 query after each NOTIFY, and as long as there is no encoding mismatch between frontend (npgsql) and backend (pg) it should help. But from the example above, this can be easily reproduced with psql, and that means that leak can happen with any pg provider as long as they have different encodings or they're using extended query protocol.

from npgsql.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.