É possível liberar automaticamente um bloqueio no PostgreSQL?
-
19-09-2019 - |
Pergunta
Eu estou testando a tolerância a falhas de um sistema de ActiveMQ configurado como JDBC Master / Slave. Nesta configuração, há um banco de dados Postgres e dois corretores - um é o corretor mestre, o outro é um corretor escravo. A forma como este mecanismo funciona é o mestre tira um bloqueio exclusivo em uma tabela no db. As tentativas de escravos para fazer isso também e espera até que o bloqueio se torna disponível. Se o mestre morre, o bloqueio deve ser liberado e o escravo assumirá. No entanto, se o mestre perde conectividade de rede com o banco de dados, o bloqueio nunca é liberado, resultando em um cenário de impasse. O que parece ser necessário aqui é uma maneira de dizer Postgres para liberar automaticamente o bloqueio se não renovados durante um determinado período de tempo. O POSA 3 livro de padrões de projeto chama este o padrão de Leasing. É possível obter Postgres para fazer isso? Se não, outros fornecedores de banco de dados apoiá-lo?
Solução
Este não é um impasse, este é problema de conexão perdida.
Um impasse ocorre quando duas transações tentar bloquear os recursos anteriormente bloqueados por outro. PostgreSQL
detecta estas situações.
No seu caso, master
bloqueia um recurso, espera slave
para master
e master
aguarda a entrada do usuário que nunca recebe porque a conexão for perdida.
Sempre que PostgreSQL
detecta uma conexão perdida, ele reversões sua transação automaticamente.
Para detecção de perda de conexão de controle, você pode usar o seguinte PostgreSQL
opções de conexão :
tcp_keepalives_idle (integer)
Em sistemas que suportam a opção de socket
TCP_KEEPIDLE
, especifica o número de segundos entre o envio keepalives em uma conexão de outro modo ocioso. Um valor de zero usa o padrão do sistema. SeTCP_KEEPIDLE
não é suportado, este parâmetro deve ser zero. Este parâmetro é ignorado para conexões feitas através de um soquete do domínio Unix.
tcp_keepalives_interval (integer)
Em sistemas que suportam a opção de socket
TCP_KEEPINTVL
, especifica por quanto tempo, em segundos, para aguardar uma resposta a um keepalive antes de retransmitir. Um valor de zero usa o padrão do sistema. SeTCP_KEEPINTVL
não é suportado, este parâmetro deve ser zero. Este parâmetro é ignorado para conexões feitas através de um soquete do domínio Unix.
tcp_keepalives_count (integer)
Em sistemas que suportam a opção de socket
TCP_KEEPCNT
, especifica quantos keepalives podem ser perdidos antes que a conexão é considerada morta. Um valor de zero usa o padrão do sistema. SeTCP_KEEPCNT
não é suportado, este parâmetro deve ser zero. Este parâmetro é ignorado para conexões feitas através de um soquete do domínio Unix.