Pregunta

¿Cuál es la forma correcta de controlar los tiempos de espera, desde el cliente, cuando se ejecuta contra una base de datos MySQL, usando SQLAlchemy? El parámetro de URL connect_timeout parece ser insuficiente.

Estoy más interesado en lo que sucede cuando la máquina en la que se ejecuta la base de datos, por ejemplo, desaparece inesperadamente de la red. No me preocupan las consultas que tardan demasiado.

El siguiente script hace lo que esperaría (es decir, tiempo de espera después de aproximadamente un segundo) si somehost no está disponible antes el while Se llega al bucle. Pero si somehost se cae durante el bucle while (por ejemplo, intente desconectar el cable de red después de que el bucle haya comenzado), entonces el tiempo de espera parece tomar al menos 18 segundos. ¿Hay alguna configuración o parámetro adicional que me falta?

No es sorprendente que la variable de sesión wait_timeout no funcione, ya que creo que es una variable del lado del servidor. Pero lo tiré allí solo para asegurarme.

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"
¿Fue útil?

Solución

esto no es posible debido a la forma en que funciona TCP. Si la otra computadora abandona la red, simplemente dejará de responder a los paquetes entrantes. los "18 segundos" estás viendo que algo en tu pila TCP está agotando debido a que no hay respuesta.

la única forma en que puede obtener su comportamiento deseado es hacer que la computadora genere un "me estoy muriendo" mensaje inmediatamente antes de que muera. que, si la muerte es inesperada, es completamente imposible.

¿alguna vez has oído hablar de los latidos? Estos son paquetes que los sistemas de alta disponibilidad se envían entre sí cada segundo o menos para que el otro sepa que todavía existen. si desea que su aplicación sepa "inmediatamente" que el servidor se ha ido, primero debe decidir cuánto tiempo "inmediato" es (1 segundo, 200 ms, etc.) y luego diseñó un sistema (como latidos) para detectar cuándo el otro sistema ya no está allí.

Otros consejos

¿Podría ser esto un error en el conector mysql / python? https://bugs.launchpad.net/myconnpy/+bug/328998 que dice que el tiempo de espera está codificado a 10 segundos.

Para ver realmente dónde está el desglose, puede usar un sniffer de paquetes para verificar la conversación entre el servidor y el cliente. wireshark + tcpdump funciona muy bien para este tipo de cosas.

Creo que está llegando a un error totalmente diferente, este es un temido "mysql se ha ido" error, si tengo razón, la solución es actualizar a un controlador mysqldb más nuevo ya que el error ha sido parches en el controlador.

Si por alguna razón no puede / no desea actualizar, debe probar la solución SA para esto

db= create_engine('mysql://root@localhost/test', pool_recycle=True) 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top