10

使用 SQLAlchemy 对 MySQL 数据库运行时,从客户端控制超时的正确方法是什么?connect_timeoutURL 参数似乎不足。

我更感兴趣的是当运行数据库的机器(例如,意外从网络中消失)时会发生什么。我不担心查询本身花费太长时间。

如果在到达循环之前somehost不可用,则以下脚本会执行您所期望的操作(即,大约一秒后超时) 。但是如果某个主机在循环过程中出现故障(例如,尝试在循环开始后拔掉它的网络电缆),那么超时似乎至少需要 18 秒。我缺少一些其他设置或参数吗?whilewhile

wait_timeout会话变量不起作用并不奇怪,因为我认为这是一个服务器端变量。但我把它扔在那里只是为了确定。

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"
4

3 回答 3

5

由于 TCP 的工作方式,这是不可能的。如果另一台计算机掉线,它将停止响应传入的数据包。您看到的“18 秒”是由于没有响应而导致 TCP 堆栈超时。

获得所需行为的唯一方法是让计算机在死机前立即生成“我快死了”的消息。如果死亡是意料之外的,那是完全不可能的。

have you ever heard of hearbeats? these are packets that high-availability systems send to each other every second or less to let the other one know they still exist. if you want your application to know "immediately" that the server is gone, you first have to decide how long "immediate" is (1 second, 200 ms, etc.) and then designed a system (such as heartbeats) to detect when the other system is no longer there.

于 2009-08-28T19:42:05.510 回答
1

这可能是 mysql/python 连接器中的错误吗? https://bugs.launchpad.net/myconnpy/+bug/328998 表示超时被硬编码为 10 秒。

要真正查看故障在哪里,您可以使用数据包嗅探器来检查服务器和客户端之间的对话。wireshark + tcpdump 非常适合这种事情。

于 2009-08-21T02:26:47.197 回答
1

我相信您遇到了一个完全不同的错误,这是一个可怕的“mysql 已消失”错误,如果我是对的,解决方案是更新到更新的 mysqldb 驱动程序,因为该错误已在驱动程序中修补。

如果由于某种原因您不能/不会更新,您应该为此尝试 SA 修复

db= create_engine('mysql://root@localhost/test', pool_recycle=True) 
于 2009-08-23T14:30:09.213 回答