Question

When profiling (on the database side) the communication between a client using Npgsql and our Postgres server, I see some additional statements being run during every transaction.

A sample log:

    LOG:  statement: select 'Npgsql155171'
    LOG:  duration: 0.136 ms
    LOG:  statement: BEGIN; SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
    LOG:  duration: 0.060 ms
    ...
    LOG:  statement: unlisten *
    LOG:  duration: 0.049 ms

The two statements in question are the initial "select 'Npgsql155171'" and the "unlisten *".

Are these two statements absolutely necessary? Does anyone know what they do?

Edit:

Every transaction appears to query a different string. None of which I can find defined anywhere. Nor are they sequential.

The next two transactions after this ran these statements:

LOG:  statement: select 'Npgsql213141'
...
LOG:  statement: select 'Npgsql223203'
Was it helpful?

Solution

Unlisten is sent to clear the connection from any previous notifications which may have been set before returning the connection to the pool.

The select Npgsql is sent to test if the connection is still valid when getting one from the pool. You can find the code here: https://github.com/npgsql/Npgsql/blob/e7913234bd1a406dc6288147fb24b52c041abd26/Npgsql/Npgsql/NpgsqlConnector.cs#L372

It used to be a simple " select 1" but we started to receive reports that the connection being returned was broken and we thought the cause was that a broken connection with a value of "1" was being put in the pool and when Npgsql read the response of the query, it was in fact reading this left value and returning a false positive. That's when we decided to use a random value for the test. But performance wise, I'm open for suggestions about any better way to make this simple validation test. Maybe use some other type of signature?

I hope it helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top