pgjdbc-ng icon indicating copy to clipboard operation
pgjdbc-ng copied to clipboard

Connection leak when timing out connection attempts

Open lloydyellowbrick opened this issue 2 years ago • 0 comments

Hi there 😄 We have been noticing a leaked connection under certain circumstances when connecting to a PG database with this driver.

Here is the simple program I am connecting with:

import java.util.Properties;
import java.sql.*;

public class Main {

  public static void main(String[] args) {
      Properties props = new Properties();
      props.put("user", "{username}");
      props.put("password", "{password}");

      String url = "jdbc:pgsql:{database}?unixsocket=/tmp/.s.PGSQL.5432";
      DriverManager.setLoginTimeout(30);

      try (Connection conn = DriverManager.getConnection(url, props)) {
          try (Statement stmt = conn.createStatement()) {
                stmt.execute("drop table if exists bar;");
                stmt.execute("create table bar(i int);");
          }
      } catch (Exception e) {
          e.printStackTrace();
          try {
            Thread.sleep(10000000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
      }
  }
}

To repro the issue:

  • Inject a delay in the initialisation of a Postgres Backend (we injected it in InitPostgres() with post_auth_delay), such that the driver login timeout fires, but there may be other ways to do so depending on your Postgres set up
  • Observe that the postgres backend stays connected, and is unable to detect that the other end has exited (waiting forever in the ServerLoop, never receiving EOF on the unix domain socket as I would expect)

Observations:

  • If this program exits, the socket is closed properly - the leak only exists for long-running clients that timeout
  • This does appear to reproduce for TCP sockets as well

lloydyellowbrick avatar Feb 08 '23 12:02 lloydyellowbrick