Ist es möglich, in PostgreSQL eine Sperre automatisch freigeben?
-
19-09-2019 - |
Frage
Ich teste die Fehlertoleranz eines ActiveMQ-System konfiguriert als JDBC-Master / Slave. In dieser Konfiguration ist es eine Postgres-Datenbank und zwei Broker - ist der Master-Broker, der andere ist ein Slave-Broker. Die Art und Weise dieser Mechanismus funktioniert, ist der Master eine exklusive Sperre aus auf einem Tisch in der db nimmt. Der Sklave versucht, dies auch zu tun, und wartet, bis die Sperre verfügbar wird. Wenn der Master stirbt, sollte die Sperre aufgehoben werden und der Slave übernehmen wird. Wenn jedoch die Master-Netzwerkverbindung mit der Datenbank verliert, wird die Sperre freigegeben nie in einem Deadlock-Szenario führt. Was scheint hier erforderlich ist, ist ein Weg, Postgres zu sagen, automatisch die Verriegelung zu lösen, wenn nicht innerhalb einer bestimmten Frist erneuert. Das POSA 3 Buch von Entwurfsmustern nennt dies das Leasing-Muster. Ist es möglich, Postgres zu bekommen, dies zu tun? Wenn nicht, unterstützen andere Datenbankanbieter das?
Lösung
Dies ist kein Deadlock, das verloren Verbindungsproblem.
Ein Deadlock tritt auf, wenn zwei Transaktionen versuchen, die Ressourcen, die von einander verriegelt vorher zu sperren. PostgreSQL
erkennt diese Situationen.
In Ihrem Fall master
sperrt eine Ressource, slave
wartet auf master
und master
wartet auf die Benutzereingabe, die er empfängt nie, weil die Verbindung verloren geht.
Wenn PostgreSQL
eine verlorene Verbindung erkennt, Rollbacks seine Transaktion automatisch.
Um die Verbindungsverlusterkennung zu steuern, können Sie die folgende PostgreSQL
verwenden Verbindungsoptionen :
tcp_keepalives_idle (integer)
Auf Systemen, die die
TCP_KEEPIDLE
Socket-Option unterstützen, gibt die Anzahl der Sekunden zwischen Keep Alive auf eine ansonsten inaktive Verbindung zu senden. Ein Wert von Null verwendet das System-Standard. WennTCP_KEEPIDLE
nicht unterstützt wird, muss dieser Parameter gleich Null sein. Dieser Parameter wird für Verbindungen ignoriert über ein Unix-Domain-Socket hergestellt.
tcp_keepalives_interval (integer)
Auf Systemen, die die
TCP_KEEPINTVL
Socket-Option unterstützen, gibt an, wie lange in Sekunden zu einer Keep-Alive auf eine Antwort zu warten, vor einem erneuten Übertragung. Ein Wert von Null verwendet das System-Standard. WennTCP_KEEPINTVL
nicht unterstützt wird, muss dieser Parameter gleich Null sein. Dieser Parameter wird für Verbindungen ignoriert über ein Unix-Domain-Socket hergestellt.
tcp_keepalives_count (integer)
Auf Systemen, die die
TCP_KEEPCNT
Socket-Option unterstützen, gibt an, wie viele Keep Alive verloren gehen kann, bevor die Verbindung tot betrachtet. Ein Wert von Null verwendet das System-Standard. WennTCP_KEEPCNT
nicht unterstützt wird, muss dieser Parameter gleich Null sein. Dieser Parameter wird für Verbindungen ignoriert über ein Unix-Domain-Socket hergestellt.