Domanda

Qual è il modo giusto per controllare i timeout, dal client, quando si esegue su un database MySQL, usando SQLAlchemy? Il parametro URL connect_timeout sembra essere insufficiente.

Sono più interessato a ciò che accade quando la macchina su cui è in esecuzione il database, ad esempio, scompare inaspettatamente dalla rete. Non sono preoccupato per le domande stesse che impiegano troppo tempo.

Il seguente script fa quello che ti aspetteresti (ovvero, il timeout dopo circa un secondo) se somehost non è disponibile prima il mentre il ciclo è mai raggiunto. Ma se somehost scende durante il ciclo while (ad esempio, prova a strappare il cavo di rete dopo l'avvio del loop), il timeout sembra impiegare almeno 18 secondi. Manca qualche impostazione o parametro aggiuntivo?

Non sorprende che la variabile di sessione wait_timeout non funzioni, poiché penso che sia una variabile lato server. Ma l'ho buttato lì solo per essere sicuro.

from sqlalchemy import *
from sqlalchemy.exc import *
import time
import sys

engine = create_engine("mysql://user:password@somehost/test?connect_timeout=1")
try:
    engine.execute("set session wait_timeout = 1;")
    while True:
        t = time.time()
        print t
        engine.execute("show tables;")
except DBAPIError:
    pass
finally:
    print time.time() - t, "seconds to time out"
È stato utile?

Soluzione

questo non è possibile a causa del modo in cui TCP funziona. se l'altro computer esce dalla rete, smetterà semplicemente di rispondere ai pacchetti in arrivo. i "18 secondi" stai vedendo qualcosa sul timeout dello stack TCP a causa della mancata risposta.

l'unico modo per ottenere il comportamento desiderato è far generare al computer un "sto morendo" messaggio immediatamente prima che muoia. che, se la morte è inaspettata, è completamente impossibile.

hai mai sentito parlare di hearbeat? questi sono pacchetti che i sistemi ad alta disponibilità si inviano l'un l'altro ogni secondo o meno per far sapere all'altro che esistono ancora. se desideri che la tua applicazione sappia "immediatamente" " che il server non c'è più, devi prima decidere per quanto tempo "immediato" è (1 secondo, 200 ms, ecc.) e quindi progettato un sistema (come battiti cardiaci) per rilevare quando l'altro sistema non è più presente.

Altri suggerimenti

Potrebbe essere un bug nel connettore mysql / python? https://bugs.launchpad.net/myconnpy/+bug/328998 che indica che il timeout è programmato su 10 secondi.

Per vedere davvero dove si trova la suddivisione, è possibile utilizzare uno sniffer di pacchetti per verificare la conversazione tra il server e il client. wirehark + tcpdump funziona alla grande per questo genere di cose.

Credo che tu stia raggiungendo un errore totalmente diverso, questo è un temuto "mysql è andato via" errore, se ho ragione, la soluzione è aggiornare a un driver mysqldb più recente poiché il bug è stato patch nel driver.

Se per qualche motivo non riesci / non vuoi aggiornare, dovresti provare la correzione SA per questo

db= create_engine('mysql://root@localhost/test', pool_recycle=True) 
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top