[Sqlalchemy-tickets] Issue #4184: `MySQL server has gone away` when raising DisconnectionError in c
Brought to you by:
zzzeek
From: Sylvain D. <iss...@bi...> - 2018-02-08 16:48:27
|
New issue 4184: `MySQL server has gone away` when raising DisconnectionError in checkout https://bitbucket.org/zzzeek/sqlalchemy/issues/4184/mysql-server-has-gone-away-when-raising Sylvain Duchesne: The following code should trigger the error: ``` #!python import logging logging.basicConfig(level=logging.DEBUG) import time from sqlalchemy import create_engine from sqlalchemy.exc import DisconnectionError import sqlalchemy e = create_engine("mysql://test:test@localhost/test", echo=True) def _check_out(dbapi_connection, connection_record, connection_proxy): logging.getLogger().info("checking out") checkout_time = connection_record.info.get('checkout_time') now = time.time() if checkout_time and now - checkout_time > 1: logging.getLogger().info("connection expired") raise DisconnectionError() connection_record.info['checkout_time'] = now sqlalchemy.event.listen(e, 'checkout', _check_out) r = e.execute("select 1") del r time.sleep(2) r = e.execute("select 1") del r ``` Executing the last execute should yield the following output: ``` #!python >>> del r >>> time.sleep(2) >>> r = e.execute("select 1") INFO:root:checking out INFO:root:connection expired INFO:root:checking out 2018-02-08 11:27:52,270 INFO sqlalchemy.engine.base.Engine select 1 INFO:sqlalchemy.engine.base.Engine:select 1 2018-02-08 11:27:52,272 INFO sqlalchemy.engine.base.Engine () INFO:sqlalchemy.engine.base.Engine:() >>> del r ERROR:sqlalchemy.pool.QueuePool:Exception during reset or similar Traceback (most recent call last): File "F:\rdv_git\rendezvous\venv\rendezvous\lib\site-packages\sqlalchemy\pool.py", line 703, in _finalize_fairy fairy._reset(pool) File "F:\rdv_git\rendezvous\venv\rendezvous\lib\site-packages\sqlalchemy\pool.py", line 873, in _reset pool._dialect.do_rollback(self) File "F:\rdv_git\rendezvous\venv\rendezvous\lib\site-packages\sqlalchemy\dialects\mysql\base.py", line 1775, in do_rollback dbapi_connection.rollback() OperationalError: (2006, 'MySQL server has gone away') >>> ``` I traced the error back to the `weakref` https://bitbucket.org/zzzeek/sqlalchemy/src/a54b3bb0a8a3a33c4c68349484ef4f3dc915416e/lib/sqlalchemy/pool.py?at=master&fileviewer=file-view-default#pool.py-540 which has its callback bound with the `dbapi connection` that will be closed. When the gc passes and the callback gets called, https://bitbucket.org/zzzeek/sqlalchemy/src/a54b3bb0a8a3a33c4c68349484ef4f3dc915416e/lib/sqlalchemy/pool.py?at=master&fileviewer=file-view-default#pool.py-703 the `dbapi connection` happens to be closed. Due to a lack of time (and having already spent quite a bit debugging), I am not able to create a PR. Also, better let the experts tackle the issue (I would verify if the connection is already closed prior to calling `reset`). |