Как вы контролируете тайм-ауты MySQL из SQLAlchemy? - PullRequest
9 голосов
/ 31 июля 2009

Как правильно контролировать время ожидания с клиента при работе с базой данных MySQL с использованием SQLAlchemy? Параметр URL connect_timeout кажется недостаточным.

Меня больше интересует, что происходит, когда машина, на которой работает база данных, например, неожиданно исчезает из сети. Я не беспокоюсь о том, что сами запросы занимают слишком много времени.

Следующий скрипт делает то, что вы ожидаете (то есть, время ожидания приблизительно через одну секунду), если somehost недоступен до того, как когда-либо будет достигнут цикл while. Но если somehost выйдет из строя во время цикла while (например, попробуйте выдернуть сетевой кабель после запуска цикла), то время ожидания, по-видимому, займет не менее 18 секунд. Я пропускаю какие-то дополнительные настройки или параметры?

Не удивительно, что переменная сеанса 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"

Ответы [ 3 ]

5 голосов
/ 28 августа 2009

это невозможно из-за того, как работает TCP. если другой компьютер отключится от сети, он просто перестанет отвечать на входящие пакеты. «18 секунд», которые вы видите, означают, что время в стеке TCP истекло из-за отсутствия ответа.

единственный способ получить желаемое поведение - заставить компьютер генерировать сообщение «Я умираю» непосредственно перед тем, как оно умрет. что, если смерть неожиданна, совершенно невозможна.

Вы когда-нибудь слышали о звуках ударов? это пакеты, которые системы высокой доступности отправляют друг другу каждую секунду или реже, чтобы другой знал, что они все еще существуют. если вы хотите, чтобы ваше приложение «немедленно» знало, что сервер ушел, сначала вы должны решить, как долго «немедленно» (1 секунда, 200 мс и т. д.), а затем спроектировать систему (например, биения), чтобы определить другой системы больше нет.

1 голос
/ 23 августа 2009

Я полагаю, что вы сталкиваетесь с совершенно другой ошибкой, это страшная ошибка «mysql ушла». Если я прав, решение состоит в том, чтобы обновить драйвер до нового mysqldb, поскольку в драйвере исправлена ​​ошибка.

Если по какой-то причине вы не можете / не хотите обновляться, попробуйте исправить SA для этого

db= create_engine('mysql://root@localhost/test', pool_recycle=True) 
1 голос
/ 21 августа 2009

Может ли это быть ошибкой в ​​коннекторе mysql / python? https://bugs.launchpad.net/myconnpy/+bug/328998 который говорит, что время ожидания жестко закодировано до 10 секунд.

Чтобы действительно увидеть, где происходит разбивка, вы можете использовать анализатор пакетов для проверки диалога между сервером и клиентом. wireshark + tcpdump отлично работает для такого рода вещей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...