Frage

habe ich einen Pool von MySQL-Verbindungen für einen Web-basierte Daten-Service. Wenn es startet eine Anfrage zu bedienen, dauert es eine Verbindung aus dem Pool zu nutzen. Das Problem ist, dass, wenn es eine erhebliche Pause gewesen ist, da diese bestimmte Verbindung verwendet wurde, der Server einer Zeitüberschreitung hat und geschlossen sein Ende. Ich möchte in der Lage sein, diesen Code im Pool-Management zu erkennen.

Der Trick ist dies: Die Umgebung, in der ich Codierung bin, gibt mir nur eine sehr abstrakte API in die Verbindung ein. Ich kann im Grunde nur SQL-Anweisungen ausführen. Ich habe keinen Zugriff auf die aktuellen Fassung oder den direkten Zugriff auf die MySQL-Client-API.

Also, die Frage ist: Was ist die billigste MySQL-Anweisung ich auf der Verbindung durchführen kann, um zu bestimmen, ob es funktioniert. Für sollte Beispiel SELECT 1; arbeiten, aber ich frage mich, ob es etwas ist sogar günstiger? Vielleicht etwas, das nicht einmal über den Draht geht, werden aber in dem MySQL-Client lib behandelt und effektiv beantwortet die gleiche Frage?

Zur Verdeutlichung: Ich bin besorgt nicht zu überprüfen, ob der MySQL-Server ausgeführt wird, oder wenn es die Datenbank-Konfiguration bis genug, um Beantwortung von Anfragen. Wenn diese Dinge nach unten, dann wird die nachfolgende SQL des Service ausführt erhalten und die entsprechenden Fehler behandeln. Ich bin nur wirklich besorgt mit, wenn die TCP-Verbindung geöffnet ist ... da, wenn der Server geschlossen, dann die SQL-Web-Service wird eine Fehlermeldung erhalten, dass Mittel „nur wieder an und versuchen Sie es erneut“, und das wäre unbequem sein, wenn zu tun unten in der Dreck des Servicecodes.

Verschluss: Der /* ping */ Hack ist genau das, was ich suchte, aber leider nur über JDBC zur Verfügung. Durch das Lesen der Dokumentation für diesen Hack, ist es klar, es wurde dort setzen für genau der gleiche Grund, warum ich es wollte. Für die Neugierigen, ich arbeite in Haskel , mit HDBC und HDBC-mysql . Ich werde den Autor von HDBC-mysql bitten, einen Weg zu Call mysql_ping() hinzuzufügen, entweder direkt oder über einen ähnlichen Hack.

Vlads DO 1 war auch die Art der Sache, die ich nach war, und da der andere Hack nicht verfügbar außerhalb von JDBC ist, werde ich mit ihm sein.

Vielen Dank für die große Diskussion, vor allem @Vlad!

War es hilfreich?

Lösung

Sie nicht den tatsächlichen Zustand der Verbindung kennen, ohne über den Draht zu gehen , und SELECT 1 ist ein gut genug Kandidat (wohl könnte man mit einem kürzeren Befehl kommen, die weniger Zeit in Anspruch Parst nimmt, aber im Vergleich zu Netzwerk oder sogar Loopback-Latenz dieser Einsparungen würden unbedeutend sein.)

Dies wird gesagt, ich würde behaupten, dass eine Verbindung Pingen vor es Prüfung aus dem Pool heraus ist nicht der beste Ansatz .

Sie sollten wahrscheinlich einfach Ihre Verbindung Pool-Manager haben erzwingen seine eigene Keep-Alive (Timeout) Politik , um nicht von dem Server getrennt wird (kurz für ein ernsthaftes Konnektivitätsproblem dazwischen, die Sie beeinflussen konnten genau in der Mitte von den regulären Betrieb sowieso - und für Ihre Verbindung Pool-Manager zu Hilfe bei der ohnehin nicht in der Lage wäre) sowie , um die Datenbank zu Schwein (man denke Dateihandies und Speichernutzung) unnötig .

Es ist daher fraglich, meiner Meinung nach, welcher Wert für Konnektivitätsbedingung zu testen, bevor eine Verbindung aus dem Pool Check-out wirklich hat. Es kann sich lohnen Testverbindungsstatus sein, bevor eine Verbindung in wieder in den Pool überprüft , aber das kann implizit durch einfaches Markieren der Verbindung als schmutzig gemacht werden, wenn ein SQL-Fest Fehler (oder eine entsprechende Ausnahme) entsteht ( es sei denn, die API Sie bereits verwenden legt einen is-bad artigen Anruf für Sie.)

Ich würde daher empfehlen:

  • eine clientseitige Keep-Alive-policty Umsetzung
  • keine Überprüfungen durchgeführt, wenn Verbindungen Auschecken aus dem Pool
  • Ausführen schmutzig Kontrollen, bevor eine Verbindung an den Pool zurückgegeben
  • lassen Sie den Anwendungscode handeln von anderen (nicht-Timeout) Ausnahmeanschlussbedingungen

UPDATE

Es wäre von Ihren Kommentaren, dass Sie wirklich wirklich will die Verbindung ping (Ich gehe davon aus, dass, weil Sie nicht die volle Kontrolle über sie haben, oder Kenntnis von Timeout Merkmalen auf dem MySQL-Server oder dazwischenliegende Netzwerk-Geräte wie Proxys usw.).

In diesem Fall können Sie verwenden DO 1 als Alternativ zu SELECT 1; es ist marginal schneller - kürzer zu analysieren, und es kehrt nicht aktuelle Daten (obwohl Sie wird die TCP acks erhalten, so dass Sie immer noch der Umlauf, dass die Validierung tun Verbindung wird noch festgelegt.)

UPDATE 2

In Bezug auf Joshuas Post , hier die Paketerfassung Spuren für verschiedene Szenarien:

SELECT 1;
13:51:01.463112 IP client.45893 > server.mysql: P 2270604498:2270604511(13) ack 2531191393 win 1460 <nop,nop,timestamp 2983462950 59680547>
13:51:01.463682 IP server.mysql > client.45893: P 1:57(56) ack 13 win 65306 <nop,nop,timestamp 59680938 2983462950>
13:51:01.463698 IP client.45893 > server.mysql: . ack 57 win 1460 <nop,nop,timestamp 2983462951 59680938>

DO 1;
13:51:27.415520 IP client.45893 > server.mysql: P 13:22(9) ack 57 win 1460 <nop,nop,timestamp 2983488906 59680938>
13:51:27.415931 IP server.mysql > client.45893: P 57:68(11) ack 22 win 65297 <nop,nop,timestamp 59681197 2983488906>
13:51:27.415948 IP client.45893 > server.mysql: . ack 68 win 1460 <nop,nop,timestamp 2983488907 59681197>

mysql_ping
14:54:05.545860 IP client.46156 > server.mysql: P 69:74(5) ack 78 win 1460 <nop,nop,timestamp 2987247459 59718745>
14:54:05.546076 IP server.mysql > client.46156: P 78:89(11) ack 74 win 65462 <nop,nop,timestamp 59718776 2987247459>
14:54:05.546092 IP client.46156 > server.mysql: . ack 89 win 1460 <nop,nop,timestamp 2987247459 59718776>

Wie Sie sehen können, mit Ausnahme der Tatsache, dass das mysql_ping Paket 5 Bytes statt DO 1; des 9 Byte, die Anzahl der Roundtrips (und damit auch Netzwerk-induzierte Latenz) ist genau das gleiche. Die einzige zusätzliche Kosten Sie mit DO 1 zahlen als zu mysql_ping Gegensatz ist das Parsen von DO 1, die trivial ist.

Andere Tipps

Ich bin mir nicht sicher, welche API Sie gerade verwenden (oder was Sprache), aber für Java, gibt es einen speziellen Trick der JDBC-Treiber tun.

Die Standard-Testabfrage ist:

select 1

, wie Sie angegeben haben. Wenn Sie ändern Sie es an:

/* ping */ select 1

der JDBC-Treiber wird dies bemerken, und nur ein einziges Paket mit dem MySQL-Server eine Antwort zu erhalten, senden.

Ich habe gelernt, das zu einer Sun 'Deep Dive' Episode mit dem Titel MySQL Tipps für Java-Entwickler mit Mark Matthews .

Auch wenn Sie nicht Java verwenden, vielleicht dies gleichen Trick hat in anderen MySQL-Treiber implementiert? Ich nehme an, der Server benötigen würde bewusst dieses speziellen Paket sein, so dass es eine Antwort senden kann ...

"Connection" in diesem Fall hat mehrere Bedeutungen. MySQL hört auf einem Sockel-, dass die Netzwerkebene ist „Verbindung“. MySQL hält „Datenbankverbindungen“, die einen Kontext für die Abfrageausführung und andere Overhead umfassen.

Wenn Sie nur wissen wollen, ob der Dienst hören ist, sollte es möglich sein, einen Netzwerk-Level-Aufruf ausführen, um zu sehen, ob die Port (nicht wissen, was der Standard ist) auf dem Ziel-IP hören. Wenn Sie die MySQL-Engine reagieren zu wollen, glaube ich Ihre SELECT 1 Idee gut- es holt nicht wirklich alle Daten aus der Datenbank aber nicht bestätigt, dass der Motor gesponnen und antwortet.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top