postgresql9.0 заблокирован и не отвечает, если операция обновления выполняется в строке, где операция обновления прерывается - PullRequest
0 голосов
/ 13 февраля 2019

Сценарий:

  1. В таблице есть строка с id=1
  2. командой обновления, инициированной с помощью JDBC в строке id=1, но до ее фиксации,Java-программа, которая установила соединение JDBC, была прервана
  3. Теперь другое соединение JDBC пытается обновить ту же строку id=1

Наблюдение:

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

Итак, мой вопрос:

Есть ли способ (конфигурация, инструменты, ...) принудительно устанавливать, закрывать и сбрасывать блокировки на сервере Postgres для любых мертвых соединений БД от клиента

Код:

package postgrestest;

import java.sql.*;

public class IncompleteTransvanilla implements Runnable {
    private int seq = 0;
    private Connection connection = null;
    private boolean insertoperation = true;

    public static void main(String[] args) throws Exception{
        boolean flag = true;
        if(args.length>0) {flag = false;}
        for(int i=0;i<10;i++) {
            new Thread(new IncompleteTransvanilla(i,flag)).start();
            //Thread.sleep(1000*(int)(Math.random()*10));
        }
        Thread.sleep(10000);
    }

    public IncompleteTransvanilla(int i, boolean flag) {
        try {
            connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/testdb", "postgres", "postgres");
            connection.setAutoCommit(false);
        } catch (Exception e) {
            System.out.println("error");
        }
        seq=i;
        insertoperation = flag;
    }

    public void run() {
        try {
            PreparedStatement statement;
            if(insertoperation == true) {
                System.out.println("Inserting");
                statement = connection.prepareStatement("Insert into uacc(user_id,username,password,email) values(DEFAULT,?,'samplepass','samplemail')");
            }
            else {
                System.out.println("Updating");
                statement = connection.prepareStatement("update uacc set username=? where user_id=1");
            }
            int maxval = 100;
            for(int i=0;i<maxval;i++) {
                statement.setString(1, "sampleuser"+((seq*maxval)+i));
                statement.execute();
            }
            Thread.sleep(10000);
            connection.commit();
        } catch (Exception e) {
            System.out.println("Connection failure.");
        }
    }

}

мониторинг базы данныхСкриншот тире для справки:

Database Monitoring - pashviewer postgres9.0 locks

Редактировать: любые предложения / конфигурации на сервере, которые можно использовать для автоматического удаления таких блокировок или конфигурации для уменьшениявремя ожидания соединения и снятия блокировок?

или ... будет ли обновление postgres9.0 до версии 9.5 исправлять подобные проблемы?

1 Ответ

0 голосов
/ 13 февраля 2019

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

  • tcp_keepalives_idle: установите его нанизкое значение, например 60, так что сервер проверяет клиента через минуту бездействия и может прервать сеанс, если клиент мертв.

  • idle_in_transaction_session_timeout:Установите это значение и даже уменьшите его, поскольку ни одна транзакция не должна оставаться в режиме ожидания в течение длительного времени.Это убьет сеансы, которые простаивают, удерживая блокировки.Будьте осторожны, чтобы не нарушить нормальную активность в вашей базе данных!

Первым приоритетом должно быть обновление с 9.0, поскольку 9.0 опасно устарел и не поддерживается.Обновление до версии 11, а не до 9,5.

...