Ich teste die Fehlertoleranz eines ActiveMQ-Systems, das als JDBC Master/Slave konfiguriert ist. In diesem Setup gibt es eine Postgres-Datenbank und zwei Broker - einer ist der Master-Broker, der andere ist ein Slave-Broker. Wie dieser Mechanismus funktioniert, nimmt der Master eine exklusive Sperre für eine Tabelle in der Datenbank heraus. Der Slave 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 wird übernehmen. Wenn jedoch der Master die Netzwerkverbindung mit der Datenbank verliert, wird die Sperre nie aufgehoben, was zu einem Deadlock-Szenario führt. Was hier erforderlich erscheint, ist eine Möglichkeit, Postgres mitzuteilen, dass die Sperre automatisch aufgehoben wird, wenn sie nicht innerhalb eines bestimmten Zeitraums erneuert wird. Das POSA 3-Buch mit Designmustern nennt dies das Leasing-Muster. Ist es möglich, Postgres dazu zu bringen? Wenn nicht, werden sie von anderen Datenbankanbietern unterstützt?Ist es möglich, eine Sperre in PostgreSQL automatisch zu lösen?
Antwort
Dies ist kein Deadlock, das ist Verbindungsproblem verloren.
Ein Deadlock tritt auf, wenn zwei Transaktionen versuchen, die zuvor voneinander gesperrten Ressourcen zu sperren. PostgreSQL
erkennt diese Situationen.
In Ihrem Fall sperrt master
eine Ressource, slave
wartet auf master
und master
wartet auf die Benutzereingabe, die er empfängt nie, weil die Verbindung verloren geht.
Immer wenn PostgreSQL
eine verlorene Verbindung erkennt, wird die Transaktion automatisch zurückgesetzt.
Um die Verbindungsverlusterkennung zu steuern, können Sie die folgende PostgreSQL
connection options:
tcp_keepalives_idle (integer)
Auf Systemen, die die
TCP_KEEPIDLE
Socket-Option unterstützen, gibt die Anzahl der Sekunden zwischen dem Senden von Keep Alive auf einem ansonsten im Leerlauf Verbindung. Ein Wert von Null verwendet den Systemstandard. WennTCP_KEEPIDLE
nicht unterstützt wird, muss dieser Parameter Null sein. Dieser Parameter wird für Verbindungen über einen Unix-Domain-Socket ignoriert.
tcp_keepalives_interval (integer)
Auf Systemen, die die
TCP_KEEPINTVL
Socket-Option unterstützen angibt, wie lange in Sekunden vor einem erneuten Übertragung zu einer Keep-Alive auf eine Antwort zu warten. Ein Wert von Null verwendet den Systemstandard. WennTCP_KEEPINTVL
nicht unterstützt wird, muss dieser Parameter Null sein. Dieser Parameter wird für Verbindungen über einen Unix-Domain-Socket ignoriert.
tcp_keepalives_count (integer)
Auf Systemen, die die
TCP_KEEPCNT
Socket-Option unterstützen angibt, wie viele Keep Alive verloren gehen kann, bevor die Verbindung tot betrachtet wird. Ein Wert von Null verwendet den Systemstandard. WennTCP_KEEPCNT
nicht unterstützt wird, muss dieser Parameter Null sein. Dieser Parameter wird für Verbindungen über einen Unix-Domain-Socket ignoriert.
Deshalb liebe ich Stackoverflow – Andy