MySQL server has gone away - Disconnect-Behandlung über Kasse-event-handler funktioniert nicht

Update 3/4:

Habe ich ein paar Tests gemacht und bewiesen, dass die Verwendung von checkout-event-handler, um zu überprüfen, trennt arbeitet mit Elixier. langsam glaube mein problem hat etwas zu tun mit Berufung session.commit() von einem Teilprozess? Update: ich habe gerade widerlegt sich selbst durch den Aufruf session.commit() in einem Teilprozess, aktualisiert Beispiel unten. Ich bin mit dem multiprocessing-Modul zum erstellen Teilprozess.

Hier ist der code, der zeigt, wie es funktionieren sollte (auch ohne Verwendung pool_recycle!):

from sqlalchemy import exc
from sqlalchemy import event
from sqlalchemy.pool import Pool
from elixir import *
import multiprocessing as mp

class SubProcess(mp.Process):
    def run(self):
        a3 = TestModel(name="monkey")
        session.commit()

class TestModel(Entity):
    name = Field(String(255))

@event.listens_for(Pool, "checkout")
def ping_connection(dbapi_connection, connection_record, connection_proxy):
    cursor = dbapi_connection.cursor()
    try:
        cursor.execute("SELECT 1")
    except:
        # optional - dispose the whole pool
        # instead of invalidating one at a time
        # connection_proxy._pool.dispose()

        # raise DisconnectionError - pool will try
        # connecting again up to three times before raising.
        raise exc.DisconnectionError()
    cursor.close()

from sqlalchemy import create_engine
metadata.bind = create_engine("mysql://foo:bar@localhost/some_db", echo_pool=True)
setup_all(True)

subP = SubProcess()

a1 = TestModel(name='foo')
session.commit()

# pool size is now three.

print "Restart the server"
raw_input()

subP.start()

#a2 = TestModel(name='bar')
#session.commit()

Update 2:

Bin ich gezwungen, eine andere Lösung finden als post 1.2.2 Versionen von MySQL-python-Tropfen Unterstützung für die reconnect-param. Hat jemand eine Lösung? :\

Update 1 (alte Lösung funktioniert nicht bei MySQL-python-Versionen > 1.2.2):

Eine Lösung gefunden werden: die übergabe connect_args={'reconnect':True} zu den create_engine aufrufen behebt das problem, automatisch die Verbindung wiederherstellt. Gar nicht zu benötigen scheint, wird der checkout-event-handler.

So, in dem Beispiel aus der Frage:

metadata.bind = create_engine("mysql://foo:bar@localhost/db_name", pool_size=100, pool_recycle=3600, connect_args={'reconnect':True})

Ursprünglichen Frage:

Ganz ein bisschen Googeln für dieses problem und noch nicht scheinen, um eine Lösung spezifisch für Elixier - ich bin versucht, die "Trennen Sie Die Handhabung - Pessimistisch" ein Beispiel aus der SQLAlchemy-docs behandeln MySQL trennt. Allerdings, wenn ich dies testen (durch einen Neustart des MySQL-Servers), den "MySQL server has gone away" - error ausgelöst, bevor meine checkout-event-handler.

Hier ist der code, den ich verwenden, um zu initialisieren Elixier:

##### Initialize elixir/SQLAlchemy
# Disconnect handling
from sqlalchemy import exc
from sqlalchemy import event
from sqlalchemy.pool import Pool

@event.listens_for(Pool, "checkout")
def ping_connection(dbapi_connection, connection_record, connection_proxy):
    logging.debug("***********ping_connection**************")
    cursor = dbapi_connection.cursor()
    try:
        cursor.execute("SELECT 1")
    except:
        logging.debug("######## DISCONNECTION ERROR #########")            
        # optional - dispose the whole pool
        # instead of invalidating one at a time
        # connection_proxy._pool.dispose()

        # raise DisconnectionError - pool will try
        # connecting again up to three times before raising.
        raise exc.DisconnectionError()
    cursor.close()

metadata.bind= create_engine("mysql://foo:bar@localhost/db_name", pool_size=100, pool_recycle=3600)

setup_all()

Ich erstellen Elixier entity-Objekte und speichern Sie Sie mit session.commit(), bei denen ich sehe die "ping_connection" - Nachricht erzeugt von der Veranstaltung, die oben definiert werden. Allerdings, wenn ich starten Sie den mysql-server und testen Sie es erneut, schlägt es mit dem mysql server has gone away-Nachricht, kurz bevor die ping-Verbindung Ereignis.

Hier ist der stack-trace, ausgehend von den relevanten Zeilen:

  File "/usr/local/lib/python2.6/dist-packages/elixir/entity.py", line 1135, in get_by
    return cls.query.filter_by(*args, **kwargs).first()
  File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/query.py", line 1963, in first
    ret = list(self[0:1])
  File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/query.py", line 1857, in __getitem__
    return list(res)
  File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/query.py", line 2032, in __iter__
    return self._execute_and_instances(context)
  File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/query.py", line 2047, in _execute_and_instances
    result = conn.execute(querycontext.statement, self._params)
  File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/engine/base.py", line 1399, in execute
    params)
  File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/engine/base.py", line 1532, in _execute_clauseelement
    compiled_sql, distilled_params
  File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/engine/base.py", line 1640, in _execute_context
    context)
  File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/engine/base.py", line 1633, in _execute_context
    context)
  File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/engine/default.py", line 330, in do_execute
    cursor.execute(statement, parameters)
  File "/usr/lib/pymodules/python2.6/MySQLdb/cursors.py", line 166, in execute
    self.errorhandler(self, exc, value)
  File "/usr/lib/pymodules/python2.6/MySQLdb/connections.py", line 35, in defaulterrorhandler
    raise errorclass, errorvalue
OperationalError: (OperationalError) (2006, 'MySQL server has gone away') 
  • Seien Sie vorsichtig mit reconnect parameter, da seine Unterstützung ist nicht standard, und es auch nicht richtig funktioniert. Finden Sie hier weitere Informationen: stackoverflow.com/questions/207981/...
  • Danke für den Tipp, dies ist besorgniserregend, dass test-reconnect-Szenarios gründlich.
InformationsquelleAutor ronalddddd | 2011-10-27
Schreibe einen Kommentar