Como você controla o tempo limite de MySQL de SQLAlchemy?
-
06-07-2019 - |
Pergunta
O que é o caminho certo para controlar o tempo limite, a partir do cliente, ao executar contra um banco de dados MySQL, usando SQLAlchemy? O parâmetro connect_timeout
URL parece ser insuficiente.
Estou mais interessado no que acontece quando a máquina que o banco de dados está sendo executado em, por exemplo, desaparece a partir da rede de forma inesperada. Eu não estou preocupado com as consultas si demorando muito.
O script a seguir faz o que você esperaria (ou seja, o tempo fora após aproximadamente um segundo) se somehost não está disponível antes o loop while
nunca é alcançado. Mas se somehost vai para baixo durante o loop while
(por exemplo, tente tirar fora seu cabo de rede após o loop começou), então o tempo limite parece ter pelo menos 18 segundos. Existe alguma configuração adicional ou parâmetro que estou perdendo?
Não é surpreendente que a variável de sessão wait_timeout
não funciona, como eu acho que é uma variável do lado do servidor. Mas eu joguei lá só para ter certeza.
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"
Solução
isso não é possível devido às obras TCP maneira. se o outro computador cai fora da rede, ele vai simplesmente parar de responder a pacotes de entrada. os "18 segundos" você está vendo é algo sobre o seu timing pilha TCP devido a nenhuma resposta.
a única maneira que você pode obter o seu comportamento desejado é ter o computador gerar uma mensagem "Eu estou morrendo" imediatamente antes de morrer. que, se a morte é inesperada, é completamente impossível.
Você já ouviu falar de hearbeats? estes são os pacotes que sistemas de alta disponibilidade enviam um ao outro a cada segundo ou menos para permitir que o outro sabe que eles ainda existem. se você quiser que seu aplicativo para saber "imediatamente" que o servidor está desaparecido, você primeiro tem que decidir por quanto tempo "imediata" é (1 segundo, a 200 ms, etc.) e, em seguida, projetou um sistema (tais como batimentos cardíacos) para detectar quando o outro sistema não está mais lá.
Outras dicas
Poderia ser este um erro no mysql / python conector? https://bugs.launchpad.net/myconnpy/+bug/328998 que diz que o out é codificado para 10 segundos.
Para realmente ver onde a repartição é, você poderia usar um sniffer de pacotes para a verificação da conversa entre o servidor eo cliente. wireshark + tcpdump funciona muito bem para esse tipo de coisa.
Eu acredito que você está atingindo um erro totalmente diferente, este é um temido "mysql desapareceu" de erro, Se eu estiver certo a solução é atualizar para um driver mysqldb mais recente como o bug foi manchas no driver.
Se por algum motivo você não pode / não vai atualizar você deve tentar a correção SA para este
db= create_engine('mysql://root@localhost/test', pool_recycle=True)