von Vasiliy Ovchinnikov
Einführung
In Systemen mit InterBase- oder Firebird-Datenbanken, die im Echtzeit- oder Fast-Echtzeitbetrieb arbeiten, besteht das Problem, den Status der Clientverbindungen serverseitig zu verfolgen und die Verbindung zwangsweise zu trennen, wenn der Client wegen Verbindungsabbruchs nicht mehr erreichbar ist.
Es ist wichtig, die durch solche Phantomverbindungen belegten Ressourcen zeitnah freizugeben – insbesondere bei Servern mit Classic-Architektur. Wenn Benutzer über eine instabile Modemverbindung auf den Server zugreifen, ist das Risiko eines Verbindungsabbruchs recht hoch.
Beispielsweise speichert ein Client einen geänderten Datensatzsatz, und nach Ausführung von UPDATE (während COMMIT noch nicht erfolgt ist) wird die Verbindung getrennt.
In solchen Situationen stellen Clientanwendungen in der Regel die Verbindung zum Server wieder her. Der Client kann die Änderungen jedoch nicht speichern (obwohl er weiter mit den Daten arbeitet, bei deren Speicherung wegen des Verbindungsfehlers eine Fehlermeldung kam), weil er eine Sperrkonfliktmeldung erhält („lock conflict on update“). Die vorherige Verbindung, die die Transaktion geöffnet hat (in deren Kontext UPDATE ausgeführt, COMMIT aber nicht), hält diese Datensätze weiterhin.
Verbindungsfehler können auch im lokalen Netzwerk auftreten, wenn die Hardware (Netzwerkkarten, Hubs, Switches) defekt oder schlecht abgestimmt ist und/oder durch Störungen im Netzwerk. In den InterBase- und Firebird-Protokollen werden TCP-Verbindungsfehler unter Windows als Fehler 10054 und unter Unix als 104 angezeigt; NetBEUI-Fehler erscheinen als Fehler 108/109.
Methoden zur Kontrolle hängender Verbindungen
In InterBase und Firebird werden die Mechanismen DUMMY-Pakete oder KEEPALIVE-Sockets verwendet, um solche „toten“ Verbindungen zu erkennen und zu trennen.
Ab InterBase 5.0 ist der DUMMY-Paket-Mechanismus auf Anwendungsebene zwischen InterBase-/Firebird-Server und der Clientbibliothek gds32/fbclient implementiert. Er wird in ibconfig/firebird.conf konfiguriert und in diesem Artikel nicht näher behandelt.
Hinweis
Aus bisheriger Erfahrung hängt die Stabilität des Dummy-Paket-Mechanismus (implementiert in InterBase 5.0 und mehrfach in Firebird 1.5.x korrigiert) stark von den Betriebssystemen von Server und Client, den TCP-Stack-Versionen und vielen anderen Bedingungen ab. Die Wirksamkeit eines solchen Systems in einem realen Netzwerk geht daher gegen null.
KEEPALIVE-Sockets sind ein interessanterer Mechanismus. Ab InterBase 6.0 implementiert, dient er der Erkennung von Verbindungsfehlern. KEEPALIVE wird aktiviert, indem beim Öffnen die Socket-Option SO_KEEPALIVE gesetzt wird. Bei Firebird 1.5 oder höher müssen Sie dies nicht manuell setzen, da es im Programmcode des Firebird-Servers sowohl für Classic als auch für Superserver implementiert ist.
Für InterBase- und Firebird-Versionen unter 1.5 in der Classic-Architektur ist eine zusätzliche Einstellung erforderlich. Diese wird weiter unten beschrieben.
In diesem Fall ist der TCP-Stack des Betriebssystems (nicht der Firebird-Server) für den Verbindungsstatus verantwortlich. Damit der Mechanismus greift, müssen die KEEPALIVE-Parameter angepasst werden.
Beschreibung von KEEPALIVE
Das Verhalten von KEEPALIVE-Sockets wird durch die Parameter in der folgenden Tabelle gesteuert.
| Parameter | Beschreibung |
|---|---|
| KEEPALIVE_TIME | Zeitintervall, nach dessen Ablauf die KEEPALIVE-Probes beginnen |
| KEEPALIVE_INTERVAL | Zeitintervall zwischen den KEEPALIVE-Probes |
| KEEPALIVE_PROBES | Anzahl der KEEPALIVE-Probes |
Der TCP-Stack erkennt den Moment, in dem keine Pakete mehr zwischen Client und Server übertragen werden, und startet den KEEPALIVE-Timer. Sobald der Timer den Wert KEEPALIVE_TIME erreicht, führt der Server-TCP-Stack die erste KEEPALIVE-Probe aus. Eine Probe ist ein leeres Paket mit ACK-Flag an den Benutzer. Wenn auf der Clientseite alles in Ordnung ist, sendet der Client-TCP-Stack ein Antwortpaket mit ACK-Flag, und der Server-TCP-Stack setzt den KEEPALIVE-Timer zurück, sobald er die Antwort erhält.
Antwortet der Client nicht auf die Probe, werden weiterhin Probes vom Server gesendet. Ihre Anzahl entspricht dem Wert KEEPALIVE_PROBES; sie werden im Intervall KEEPALIVE_INTERVAL ausgeführt. Antwortet der Client nicht auf die letzte Probe, schließt der TCP-Stack des Betriebssystems nach Ablauf eines weiteren KEEPALIVE_INTERVAL die Verbindung, und der Server (in diesem Fall die Instanz des InterBase- oder Firebird-Servers) gibt alle für diese Verbindung belegten Ressourcen frei.
Eine fehlgeschlagene Clientverbindung wird also nach folgendem Zeitintervall geschlossen:
KEEPALIVE_TIME+ ( KEEPALIVE_PROBES+1)* KEEPALIVE_INTERVAL.
Standardmäßig sind die Parameterwerte recht groß, was ihre Nutzung ineffektiv macht. Der Standardwert von KEEPALIVE_TIME beträgt beispielsweise sowohl unter Linux als auch unter Windows „2 Stunden“. Tatsächlich reichen 1–2 Minuten aus, um über die zwangsweise Trennung eines unerreichbaren Clients zu entscheiden. Andererseits führen die KEEPALIVE-Standardeinstellungen in Windows-Netzwerken manchmal dazu, dass Verbindungen, die während dieser 2 Stunden inaktiv bleiben, zwangsweise getrennt werden (natürlich kann man die Notwendigkeit solcher Verbindungen in Anwendungen hinterfragen, aber das ist ein anderes Thema).
Im Folgenden wird die Anpassung dieser Parameter für die Betriebssysteme Windows und Linux beschrieben.
KEEPALIVE unter Linux einstellen
KEEPALIVE-Parameter unter Linux können entweder durch direktes Bearbeiten des Dateisystems unter /proc oder durch Aufruf von sysctl geändert werden.
Im ersten Fall sollten die folgenden Zeilen bearbeitet werden:
/proc/sys/net/ipv4/tcp_keepalive_time /proc/sys/net/ipv4/tcp_keepalive_intvl /proc/sys/net/ipv4/tcp_keepalive_probes
Im zweiten Fall sollten die folgenden Befehle ausgeführt werden:
sysctl -w net.ipv4.tcp_keepalive_time=value sysctl -w net.ipv4.tcp_keepalive_intvl=value sysctl -w net.ipv4.tcp_keepalive_probes=value
Zeitwerte werden in Sekunden angegeben.
Für die automatische Einstellung dieser Parameter bei einem Neustart des Servers fügen Sie Folgendes hinzu:
net.ipv4.tcp_keepalive_intvl = value net.ipv4.tcp_keepalive_time = value net.ipv4.tcp_keepalive_probes = value
Ersetzen Sie das Wort <value> durch die erforderlichen Werte.
Wenn Sie Firebird Classic in einer Version unter 1.5 verwenden, fügen Sie in /etc/xinet.d/firebird Folgendes hinzu:
FLAGS=REUSE KEEPALIVE
KEEPALIVE unter Windows 95/98/ME anpassen
Registrierungszweig:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP
Alles zur TCP-Anpassung finden Sie hier:
http://support.microsoft.com/default.aspx?scid=kb;en-us;158474
Parameter:
-
KeepAliveTime = MillisekundenTyp: DWORDUnter Windows 98 Typ: STRING.Definiert die Verbindungsinaktivität in Millisekunden.Nach Ablauf beginnen die KEEPALIVE-Probes.Standardwert: 2 Stunden (7200000).
-
KeepAliveInterval = 32-Bit-WertTyp: DWORDUnter Windows 98 Typ: STRING.Definiert die Zeit zwischen KEEPALIVE-Probes (in Millisekunden).Sobald das angegebene KeepAliveTime-Intervall abgelaufen ist,werden nach jedem KeepAliveInterval (in Millisekunden)KEEPALIVE-Probes bis zur MaximalanzahlMaxDataRetries gesendet. Bleibt die Antwort aus, wird die Verbindunggeschlossen. Standardwert: 1 Sekunde (1000).
-
MaxDataRetries = 32-Bit-WertTyp: STRINGDefiniert die maximale Anzahl der KEEPALIVE-Probes.Standardwert: 5.
KEEPALIVE unter Windows 2000/NT/XP einstellen
Registrierungszweig:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\.
Alles zur TCP-Anpassung:
XP: http://support.microsoft.com/kb/314053
Der Parameter MaxDataRetries wird durch TCPMaxDataRetransmissions ersetzt.
Alle übrigen Parameter haben dieselben Namen wie unter Windows 9x.
KEEPALIVE unter Windows einstellen (für Clients)
Diese Einstellung ist optional, kann aber die Anzahl der Meldungen über Verbindungsfehler bei unzuverlässigen Kommunikationskanälen verringern. Fügen Sie im Registrierungszweig:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
den Parameter DisableDHCPMediaSense=1 ein. Eine Beschreibung dieses Parameters finden Sie hier:
Beispiel
Betrachten wir die Einstellung von Firebird SQL Server 1.5.2 CS unter Linux.
-
Stellen Sie sicher, dass der DUMMY-Paket-Mechanismus in firebird.conf deaktiviert ist(der Parameter ist auskommentiert).......#DummyPacketsInterval=0......
-
Stellen Sie sicher, dass die Konfigurationsdatei /etc/xinet.d/firebird vorhanden ist
Wir haben alles unverändert belassen, wie bei der Installation registriert. Es muss nichts hinzugefügt werden.
-
Ändern Sie die TCP-Stack-Parameter:
sysctl -w net.ipv4.tcp_keepalive_time = 15 sysctl -w net.ipv4.tcp_keepalive_intvl = 10 sysctl -w net.ipv4.tcp_keepalive_probes = 5
-
Verbinden Sie sich von einem beliebigen Netzwerkclient mit einer beliebigen Datenbank auf dem Server
-
Prüfen Sie den Traffic auf dem Server mit einem beliebigen Paketfilter.
Bei den Parametern wie unter /proc/sys/net/tcp_keepalive_* erzeugt der Server innerhalb von 15 Sekunden, nachdem im Kanal alles zum Stillstand gekommen ist, eine Probe. Ist der Client „lebendig“, erhält der Server ein Antwortpaket. 15 Sekunden danach wiederholt sich die Prüfung usw.
-
Wird ein Client physisch ausgeschaltet (oder der Multiplexer bzw. das Modem unerwartet getrennt – alles ist möglich), erhält der Server keine Antwort und beginnt, Probes im Abstand von 10 Sekunden zu senden. Antwortet der Client nicht auf die fünfte Probe, wird 10 Sekunden danach der Serverprozess beendet und gibt Ressourcen und Sperren frei. Sendet der Client irgendwelche Signale und antwortet zumindest auf die fünfte Probe (im ungünstigsten Fall), beginnt der Server nach einem weiteren Timeout von 15 Sekunden erneut, Probes zu senden. Und so weiter.
Empfehlungen
Abschließend möchten wir einige Hinweise zur Auswahl der KEEPALIVE-Werte geben.
Bestimmen Sie zuerst den erforderlichen Wert von KEEPALIVE_TIME. Je größer der Wert, desto später starten die KEEPALIVE-Probes. Wenn Sie ständig Fehler 10054/104 im Serverprotokoll sehen und diese manuell löschen müssen, empfiehlt es sich, den Wert KEEPALIVE_TIME zu erhöhen.
Zweitens sollten die Werte von KEEPALIVE_INTERVAL und KEEPALIVE_PROBES Ihren Anforderungen an die rechtzeitige Freigabe bereits hängender Verbindungen entsprechen. Wenn Ihre Benutzer über unzuverlässige Kanäle auf den Server zugreifen, möchten Sie die Anzahl der Probes und das Intervall dazwischen vermutlich erhöhen, damit der Benutzer den Fehler erkennen und die Verbindung wiederherstellen kann. Bei DSL-Zugang zum Internet oder Zugriff auf einen SQL-Server über das lokale Netzwerk kann das Intervall zwischen den KEEPALIVE-Probes verringert werden.
Allgemeine Empfehlungen: Wenn Sie ohne besonderen Grund viele Fehlermeldungen von Clients zum Speichern von Ergebnissen wegen Sperrkonflikten erhalten (d. h. es gibt keine konkurrierenden Verbindungen, die mit denselben Daten arbeiten), müssen Sie die Reaktion des Systems auf die Freigabe hängender Verbindungen erhöhen. Praktisch kann der Wert KEEPALIVE_TIME bei 1 Minute oder darüber liegen. Schätzen Sie selbst die Dauer der längsten Transaktion, damit der Traffic nicht durch KEEPALIVE-Prüfungen normal arbeitender Verbindungen mit langen Transaktionen überlastet wird. Der Wert KEEPALIVE_INTERVAL liegt bei 10 Sekunden oder darüber, der Wert KEEPALIVE_PROBES bei 5 Prüfungen oder darüber. Bei vielen gleichzeitigen Benutzern denken Sie daran: Zu häufige Prüfungen können den Netzwerktraffic erheblich erhöhen.
Denken Sie auch daran, dass bei aktiver Änderung gemeinsamer Daten durch Ihre Benutzer Sperrfehler als Folge einer normalen Situation auftreten. In diesem Fall benötigen Sie eine korrekte Behandlung von Sperrfehlern in den Clientanwendungen. Gleichzeitig sollte die Anwendung das Auftreten solcher Fehler möglichst minimieren.
Beispiele für Standardkonfigurationen
Abschließend noch einige Beispiele für Standardkonfigurationen. Die Ausfallzeit (Downtime) ist die Zeit, in der Benutzer Daten nicht aktualisieren können, die zu diesem Zeitpunkt von der Transaktion der hängenden Verbindung aktualisiert wurden. Die Gesamtzeit ist die Zeit, nach deren Ablauf die hängende Verbindung geschlossen wird.
-
Clients nutzen Modemverbindungen; die meisten Transaktionen im System sind kurz; Downtime auf 3 Minuten begrenzt:
KEEPALIVE_TIME 1 minutes KEEPALIVE_PROBES 3 KEEPALIVE_INTERVAL 30 seconds TOTAL 3 minutes
-
Clients nutzen LAN-Verbindung; die meisten Transaktionen im System sind kurz; Downtime auf 2 Minuten begrenzt:
KEEPALIVE_TIME 30 sec KEEPALIVE_PROBES 5 KEEPALIVE_INTERVAL 10 sec TOTAL 90 seconds
-
Clients nutzen beliebige Verbindungen; Downtime ist nicht geregelt:
KEEPALIVE_TIME12 minutes KEEPALIVE_PROBES 7 KEEPALIVE_INTERVAL 15 sec TOTAL 14 minutes
Wir hoffen, dass die gezeigten Beispiele für die korrekte Einstellung des KEEPALIVE-Mechanismus im TCP-Stack ausreichen.
Quelle: https://www.ibphoenix.com/resources/documents/how_to/doc_104