У нас есть сервер Python, который использует SQLAlchemy для чтения/записи данных из экземпляра AWS MySQL MultiAZ RDS.
Мы сталкиваемся с поведением, которого мы хотели бы избежать, когда всякий раз, когда мы запускаем аварийную перезагрузку, соединение, которое уже было открыто, а затем выдает оператор, зависает на неопределенный срок. Хотя согласно документации AWS этого следует ожидать, мы ожидаем, что коннектор Python MySQL сможет справиться с этой ситуацией.
Ближайший случай, который мы нашли в Интернете, — это тема групп Google. в котором говорится о проблеме и предлагается решение, касающееся Postgres RDS.
Например, приведенный ниже сценарий будет зависать на неопределенный срок при запуске аварийной перезагрузки (взято из упомянутого выше потока групп Google).
from datetime import datetime
from time import time, sleep
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm.scoping import scoped_session
from sqlalchemy.ext.declarative import declarative_base
import logging
current_milli_time = lambda: int(round(time() * 1000))
Base = declarative_base()
logging.basicConfig(format='%(asctime)s %(filename)s %(lineno)s %(process)d %(levelname)s: %(message)s', level="INFO")
class Message(Base):
__tablename__ = 'message'
id = Column(Integer, primary_key=True)
body = Column(String(450), nullable=False)
engine = create_engine('mysql://<username>:<password>@<db_host>/<db_name>',echo=False, pool_recycle=1800,)
session_maker = scoped_session(sessionmaker(bind=engine, autocommit=False, autoflush=False))
session = session_maker()
while True:
try:
ids = ''
start = current_milli_time()
for msg in session.query(Message).order_by(Message.id.desc()).limit(5):
ids += str(msg.id) + ', '
logging.info('({!s}) (took {!s} ms) fetched ids: {!s}'.format(datetime.now().time().isoformat(), current_milli_time() - start, ids))
start = current_milli_time()
m = Message()
m.body = 'some text'
session.add(m)
session.commit()
logging.info('({!s}) (took {!s} ms) inserted new message'.format(datetime.now().time().isoformat(), current_milli_time() - start))
except Exception, e:
logging.exception(e)
session.rollback()
finally:
session_maker.remove()
sleep(0.25)
Мы пробовали играть с тайм-аутами соединения, но, похоже, проблема связана с уже открытым соединением, которое просто зависает, как только AWS переключается на резервный экземпляр.
Наш вопрос: кто-нибудь сталкивался с этой проблемой или есть возможные направления, которые стоит проверить?
engine = create_engine('mysql://<username>:<password>@<db_host>/<db_name>', echo=False, pool_recycle=1800, connect_args = {'connect_timeout': <x_seconds>})
илиengine = create_engine('mysql://<username>:<password>@<db_host>/<db_name>?connect_timeout=<x_seconds>', echo=False, pool_recycle=1800)
- person wilfo   schedule 05.04.2016