“致命:剩余连接槽保留用于非复制超级用户连接”,尽管关闭了连接仍会触发

问题描述 投票:0回答:1

我创建了一个简单的程序,它重复创建与数据库的连接,然后关闭该连接。程序在第六次或第七次迭代时产生错误。如果我在每次迭代之间将程序暂停五秒钟,则程序在第三次迭代时会产生错误。 打印出连接状态表明它们已成功关闭,因此不应发生连接泄漏。我的连接是通过 HikariCP 和 Google Cloud 的 IAM 身份验证建立的。

package Tester;

import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import InstanceCreator.InstanceCreator;

public class Tester {

    public static void main(String[] args) throws SQLException, InterruptedException {

        int i = 1;
        while (true) {
            System.out.println("Starting loop: " + i);
            i++;
            Thread.sleep(5000);
            DataSource dataSource = InstanceCreator.createConnectionPool();
            Connection connection = null;
            try {
                connection = dataSource.getConnection();

            } catch (SQLException e) {
                e.printStackTrace();
            } 
            finally {
                connection.close();
            }
        }
    }
}


package InstanceCreator;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;

public class InstanceCreator {

      private static final String INSTANCE_CONNECTION_NAME = "mycreds";
      private static final String DB_IAM_USER = "mycreds";
      private static final String DB_NAME = "mycreds";

      public static DataSource createConnectionPool() {

        HikariConfig config = new HikariConfig();

        config.setJdbcUrl(String.format("jdbc:postgresql:///%s", DB_NAME));

        config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.postgres.SocketFactory");
        config.addDataSourceProperty("cloudSqlInstance", INSTANCE_CONNECTION_NAME);
        config.addDataSourceProperty("enableIamAuth", "true");
        config.addDataSourceProperty("user", DB_IAM_USER);
        config.addDataSourceProperty("password", "password");
        config.addDataSourceProperty("sslmode", "disable");

        return new HikariDataSource(config);
      }
    }


Starting loop: 1
SLF4J(W): No SLF4J providers were found.
SLF4J(W): Defaulting to no-operation (NOP) logger implementation
SLF4J(W): See https://www.slf4j.org/codes.html#noProviders for further details.
Starting loop: 2
Starting loop: 3
Starting loop: 4
Starting loop: 5
Starting loop: 6
Starting loop: 7
Exception in thread "main" com.zaxxer.hikari.pool.HikariPool$PoolInitializationException: Failed to initialize pool: FATAL: remaining connection slots are reserved for non-replication superuser connections
    at com.zaxxer.hikari.pool.HikariPool.throwPoolInitializationException(HikariPool.java:596)
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:582)
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
    at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:81)
    at InstanceCreator.InstanceCreator.createConnectionPool(InstanceCreator.java:27)
    at Tester.Tester.main(Tester.java:17)
Caused by: org.postgresql.util.PSQLException: FATAL: remaining connection slots are reserved for non-replication superuser connections
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2676)
    at org.postgresql.core.v3.QueryExecutorImpl.readStartupMessages(QueryExecutorImpl.java:2788)
    at org.postgresql.core.v3.QueryExecutorImpl.<init>(QueryExecutorImpl.java:174)
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:313)
    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:54)
    at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:253)
    at org.postgresql.Driver.makeConnection(Driver.java:434)
    at org.postgresql.Driver.connect(Driver.java:291)
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:121)
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364)
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476)
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
    ... 4 more

java database google-cloud-sql hikaricp
1个回答
0
投票

每次在循环中,您创建的不是一个连接,而是一个连接池。默认情况下,一个 HikariCP 池打开 10 个到数据库的连接,因此在第六次迭代时有 60 个活动连接,而在第七次迭代时已经有 70 个。任何 DBMS 都对最大连接数有限制;在 PostgreSQL 中默认为 100。创建大量连接后,您很快就耗尽了此限制并收到错误 org.postgresql.util.PSQLException: FATAL: 剩余连接槽保留用于非复制超级用户连接。 PostgreSQL 保留三个连接用于管理目的,以便主管即使在连接限制耗尽时也可以连接到 DBMS。不要这样做,谨慎使用连接。

© www.soinside.com 2019 - 2024. All rights reserved.