Я тестирую отказоустойчивость системы ActiveMQ, сконфигурированной как JDBC Master/Slave. В этой настройке есть одна база данных postgres и два брокера — один является главным брокером, а другой — подчиненным. Этот механизм работает следующим образом: мастер снимает эксклюзивную блокировку таблицы в БД. Ведомый также пытается сделать это и ждет, пока блокировка не станет доступной. Если мастер умирает, блокировка должна быть снята, и раб вступит во владение. Однако, если мастер теряет сетевое соединение с базой данных, блокировка никогда не снимается, что приводит к взаимоблокировке. Кажется, что здесь требуется способ указать Postgres автоматически снимать блокировку, если она не будет продлена в течение определенного периода времени. Книга шаблонов проектирования POSA 3 называет это шаблоном аренды. Можно ли заставить Postgres сделать это? Если нет, поддерживают ли его другие поставщики баз данных?
Можно ли автоматически снять блокировку в PostgreSQL?
Ответы (1)
Это не тупик, это проблема с потерей соединения.
Тупик возникает, когда две транзакции пытаются заблокировать ресурсы, ранее заблокированные друг другом. PostgreSQL
обнаруживает такие ситуации.
В вашем случае master
блокирует ресурс, slave
ждет master
, а master
ждет ввода пользователя, который он никогда не получает, потому что соединение потеряно.
Всякий раз, когда PostgreSQL
обнаруживает потерю соединения, он автоматически откатывает свою транзакцию.
Для управления обнаружением потери соединения вы можете использовать следующий PostgreSQL
варианты подключения:
tcp_keepalives_idle (integer)
В системах, поддерживающих параметр сокета
TCP_KEEPIDLE
, задает количество секунд между отправкой сообщений проверки активности при бездействующем соединении. Нулевое значение использует системное значение по умолчанию. ЕслиTCP_KEEPIDLE
не поддерживается, этот параметр должен быть равен нулю. Этот параметр игнорируется для соединений, выполненных через сокет домена Unix.
tcp_keepalives_interval (integer)
В системах, поддерживающих параметр сокета
TCP_KEEPINTVL
, указывает, как долго в секундах ждать ответа на сообщение проверки активности перед повторной передачей. Нулевое значение использует системное значение по умолчанию. ЕслиTCP_KEEPINTVL
не поддерживается, этот параметр должен быть равен нулю. Этот параметр игнорируется для соединений, выполненных через сокет домена Unix.
tcp_keepalives_count (integer)
В системах, поддерживающих параметр сокета
TCP_KEEPCNT
, указывает, сколько сообщений поддержки активности может быть потеряно, прежде чем соединение будет считаться мертвым. Нулевое значение использует системное значение по умолчанию. ЕслиTCP_KEEPCNT
не поддерживается, этот параметр должен быть равен нулю. Этот параметр игнорируется для соединений, выполненных через сокет домена Unix.