org.postgresql.util.PSQLException: FATAL: извините, уже слишком много клиентов


93

Я пытаюсь подключиться к базе данных Postgresql, получаю следующую ошибку:

Ошибка: org.postgresql.util.PSQLException: FATAL: извините, уже слишком много клиентов

Что означает ошибка и как ее исправить?

Мой server.propertiesфайл следующий:

serverPortData=9042
serverPortCommand=9078
trackConnectionURL=jdbc:postgresql://127.0.0.1:5432/vTrack?user=postgres password=postgres
dst=1
DatabaseName=vTrack
ServerName=127.0.0.1
User=postgres
Password=admin
MaxConnections=90
InitialConnections=80
PoolSize=100
MaxPoolSize=100
KeepAliveTime=100
TrackPoolSize=120
TrackMaxPoolSize=120
TrackKeepAliveTime=100
PortNumber=5432
Logging=1

Ответы:


38

Мы не знаем, что это за файл server.properties , мы также не знаем, что означает SimocoPoolSize (а вы?)

Предположим, вы используете какой-то настраиваемый пул подключений к базе данных. Тогда, я полагаю, проблема в том, что ваш пул настроен на открытие 100 или 120 соединений, но ваш сервер Postgresql настроен на прием MaxConnections=90. Эти настройки кажутся противоречивыми. Попробуйте увеличить MaxConnections=120.

Но сначала вы должны понять свою инфраструктуру уровня БД, знать, какой пул вы используете, если вам действительно нужно так много открытых соединений в пуле. И, особенно, если вы изящно возвращаете открытые соединения в пул


168

Объяснение следующей ошибки:

org.postgresql.util.PSQLException: FATAL: sorry, too many clients already.

Резюме:

Вы открыли больше разрешенного лимита подключений к базе данных. Вы запустили что-то вроде этого: Connection conn = myconn.Open();внутри цикла и забыли запустить conn.close();. Просто потому, что ваш класс уничтожен, а сборщик мусора не освобождает соединение с базой данных. Самый быстрый способ исправить это - убедиться, что у вас есть следующий код с любым классом, который создает соединение:

protected void finalize() throws Throwable  
{  
    try { your_connection.close(); } 
    catch (SQLException e) { 
        e.printStackTrace();
    }
    super.finalize();  
}  

Поместите этот код в любой класс, в котором вы создаете соединение. Затем, когда ваш класс будет собран сборщиком мусора, ваше соединение будет освобождено.

Запустите этот SQL, чтобы увидеть разрешенные соединения postgresql:

show max_connections;

По умолчанию - 100. PostgreSQL на хорошем оборудовании может поддерживать несколько сотен подключений одновременно. Если вы хотите иметь тысячи, вам следует подумать об использовании программного обеспечения для пула подключений, чтобы уменьшить накладные расходы на подключение.

Посмотрите, кто / что / когда / где держит ваши связи открытыми:

SELECT * FROM pg_stat_activity;

Количество используемых в настоящее время соединений:

SELECT COUNT(*) from pg_stat_activity;

Стратегия отладки

  1. Вы можете дать разные имена пользователей / пароли программам, которые могут не освобождать соединения, чтобы узнать, какое это, а затем заглянуть в pg_stat_activity, чтобы узнать, какая из них не очищает себя.

  2. Выполните полную трассировку стека исключений, когда соединения не могут быть созданы, и следуйте за кодом до того места, где вы создаете новое Connection, убедитесь, что каждая строка кода, в которой вы создаете соединение, заканчиваетсяconnection.close();

Как установить max_connections выше:

max_connections в postgresql.conf устанавливает максимальное количество одновременных подключений к серверу базы данных.

  1. Сначала найдите свой файл postgresql.conf
  2. Если вы не знаете, где он находится, запросите базу данных с помощью sql: SHOW config_file;
  3. Мой находится в: /var/lib/pgsql/data/postgresql.conf
  4. Войдите как root и отредактируйте этот файл.
  5. Найдите строку: «max_connections».
  6. Вы увидите строку с надписью max_connections=100.
  7. Установите это число больше, проверьте лимит для вашей версии postgresql.
  8. Перезапустите базу данных postgresql, чтобы изменения вступили в силу.

Какое максимальное количество max_connections?

Используйте этот запрос:

select min_val, max_val from pg_settings where name='max_connections';

Я понимаю ценность 8388607, теоретически это максимум, что вам разрешено иметь, но затем неконтролируемый процесс может съесть тысячи соединений, и, что удивительно, ваша база данных не отвечает до перезагрузки. Если бы у вас было разумное max_connections, такое как 100. Программа-нарушитель не могла бы установить новое соединение.


4
почему некоторые люди забывают ';' после операторов SQL ?!
Копирует

@codervince Обратите внимание. Я бы даже сказал, что вам следует транскрибировать команды, а не копировать + вставлять.
AVProgrammer

4

Нет необходимости увеличивать MaxConnections и InitialConnections. Просто закройте свои связи после того, как поработаете. Например, если вы создаете соединение:

try {
     connection = DriverManager.getConnection(
                    "jdbc:postgresql://127.0.0.1/"+dbname,user,pass);

   } catch (SQLException e) {
    e.printStackTrace();
    return;
}

После выполнения работы закройте соединение:

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

11
Всегда закрывайте соединения в блоке finally! В противном случае соединение останется открытым при возникновении ошибки.
tine2k 02

1

Оскорбительные строки следующие:

MaxConnections=90
InitialConnections=80

Вы можете увеличить значения, чтобы разрешить больше подключений.


4
И если у вас будет больше подключений, можно также настроить параметры памяти, чтобы они соответствовали увеличению количества подключений.
Kuberchaun

0

Например, вам нужно закрыть все ваши соединения: если вы делаете оператор INSERT INTO, вам нужно закрыть оператор и ваше соединение следующим образом:

statement.close();
Connexion.close():

И если вы сделаете оператор SELECT, вам нужно закрыть оператор, соединение и набор результатов следующим образом:

resultset.close();
statement.close();
Connexion.close();

Я сделал это, и это сработало

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.