Mysql
 sql >> Database >  >> RDS >> Mysql

Il modo più economico per determinare se una connessione MySQL è ancora attiva

Non conoscerai lo stato reale della connessione senza passare dal cavo e SELECT 1 è un candidato abbastanza buono (probabilmente potresti trovare un comando più breve che richiede meno tempo per l'analisi, ma rispetto alla latenza di rete o addirittura di loopback quei risparmi sarebbero insignificanti.)

Detto questo, direi che eseguire il ping di una connessione prima controllarlo dalla piscina non è l'approccio migliore .

Probabilmente dovresti semplicemente chiedere al gestore del pool di connessioni di applicare la propria politica di mantenimento in vita (timeout) per evitare di essere disconnessi dal server (a meno di un problema di connettività intervenuto più serio, che potrebbe comunque interessarti nel bel mezzo delle normali operazioni e con il quale il tuo gestore del pool di connessioni non sarebbe comunque in grado di aiutarti), così come per non monopolizzare il database (pensa ai filehandle e all'utilizzo della memoria) inutilmente.

È quindi discutibile, a mio parere, quale valore abbia realmente il test per la condizione di connettività prima di verificare una connessione dal pool. Potrebbe valere la pena testare lo stato della connessione prima che una connessione venga nuovamente archiviata nel pool , ma ciò può essere fatto implicitamente semplicemente contrassegnando la connessione come sporca quando si verifica un errore hardware SQL (o un'eccezione equivalente) (a meno che l'API che stai utilizzando non esponga già un is-bad -come chiama per te.)

Consiglierei quindi:

  • implementare una politica keep-alive lato client
  • non eseguire alcun controllo durante il check out delle connessioni dal pool
  • esecuzione di controlli sporchi prima che una connessione venga restituita al pool
  • consenti al codice dell'applicazione di gestire altre condizioni di connessione eccezionali (non timeout)

AGGIORNAMENTO

Dai tuoi commenti sembrerebbe che tu davvero davvero vuoi eseguire il ping della connessione (presumo che ciò sia dovuto al fatto che non hai il pieno controllo o la conoscenza delle caratteristiche di timeout sul server MySQL o sulle apparecchiature di rete intermedie come i proxy ecc.)

In questo caso puoi usare DO 1 in alternativa a SELECT 1; è marginalmente più veloce -- più breve da analizzare e non restituisce i dati effettivi (sebbene lo farai ottenere il TCP ack s, quindi continuerai a eseguire il viaggio di andata e ritorno verificando che la connessione sia ancora stabilita.)

AGGIORNAMENTO 2

Riguardo al post di Joshua , ecco le tracce di acquisizione dei pacchetti per vari scenari:

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>

Come puoi vedere, a parte il fatto che mysql_ping il pacchetto è di 5 byte invece di DO 1; 's 9 byte, il numero di roundtrip (e di conseguenza, la latenza indotta dalla rete) è esattamente lo stesso. L'unico costo aggiuntivo che stai pagando con DO 1 al contrario di mysql_ping è l'analisi di DO 1 , che è banale.