On Thu, Oct 25, 2018 at 12:50 PM Sebastian Meinhardt <seb.meinha...@gmail.com> wrote: > > Our database environment drops idle connections after an hour. My application > uses the SQLAlchemy connection pool to deal with this. The problem is: When a > connection is closed, it takes the pool a real long time (15-20 minutes) to > recover. This happens with both strategies, pool_pre_ping and pool_recylce. > Apparently, the pool hangs when trying to operate on the already dead > connections. > > Here is an excerpt from the logs. Look at the timestamps! > > With pool_pre_ping: > > 2018-10-25 12:30:38,866:DEBUG:Connection <cx_Oracle.Connection to > USER@DATABASE> checked out from pool > 2018-10-25 12:30:38,868:DEBUG:Pool pre-ping on connection > <cx_Oracle.Connection to USER@DATABASE> > 2018-10-25 12:46:26,624:DEBUG:Pool pre-ping on connection > <cx_Oracle.Connection to USER@DATABASE> failed, will invalidate pool > 2018-10-25 12:46:26,626:INFO:Disconnection detected on checkout, invalidating > all pooled connections prior to current timestamp (reason: > InvalidatePoolError()) > > > With pool_recycle: > > 2018-10-25 12:40:51,869:INFO:Connection <cx_Oracle.Connection to > USER@DATABASE> exceeded timeout; recycling > 2018-10-25 12:40:51,871:DEBUG:Closing connection <cx_Oracle.Connection to > USER@DATABASE> > 2018-10-25 12:56:39,493:ERROR:Exception closing connection > <cx_Oracle.Connection to USER@DATABASE> > Traceback (most recent call last): > File "/usr/local/lib/python3.6/site-packages/sqlalchemy/pool.py", line 314, > in _close_connection > self._dialect.do_close(connection) > File "/usr/local/lib/python3.6/site-packages/sqlalchemy/engine/default.py", > line 465, in do_close > dbapi_connection.close() > cx_Oracle.OperationalError: ORA-03113: end-of-file on communication channel > Process ID: 0 > Session ID: 540 Serial number: 46277 > 2018-10-25 12:56:39,674:DEBUG:Created new connection <cx_Oracle.Connection to > USER@DATABASE> > > > As this is an interactive application, I cannot let the user wait for 16 > minutes. While I could implement an application side timeout that creates a > new pool every 59 minutes, it feels like that would be missing the point. Is > there an SQLAlchemy solution to my problem? Decrease the timeout on > ping/close? Recycle connections in a background threads? Am I doing something > fundamentally wrong here? >
Here's how SQLAlchemy pings the database: https://bitbucket.org/zzzeek/sqlalchemy/src/580d114405f3d200682f3a219dcb9004c81300c7/lib/sqlalchemy/pool/base.py?at=master&fileviewer=file-view-default#base.py-767 if pool._pre_ping: if fairy._echo: pool.logger.debug( "Pool pre-ping on connection %s", fairy.connection) result = pool._dialect.do_ping(fairy.connection) # <-- this is apparently taking 16 minutes if not result: if fairy._echo: pool.logger.debug( "Pool pre-ping on connection %s failed, " "will invalidate pool", fairy.connection) raise exc.InvalidatePoolError() https://bitbucket.org/zzzeek/sqlalchemy/src/580d114405f3d200682f3a219dcb9004c81300c7/lib/sqlalchemy/engine/default.py?at=master&fileviewer=file-view-default#default.py-471 def do_ping(self, dbapi_connection): cursor = None try: cursor = dbapi_connection.cursor() try: cursor.execute(self._dialect_specific_select_one) finally: cursor.close() except self.dbapi.Error as err: if self.is_disconnect(err, dbapi_connection, cursor): return False else: raise else: return True So the first question is: do you see this 15-20 minute timeout with a plain DBAPI connection? From a python prompt, create a cx_Oracle connection, then kill the connection from the DB side (or wait an hour). Then try to create a cursor and execute a trivial query. If it takes a very long time to return, you need a DBAPI-level fix. The cx_Oracle docs suggest there is a configurable timeout parameter (https://cx-oracle.readthedocs.io/en/latest/connection.html#Connection.callTimeout). If it fails immediately, repeat the experiment using an SQLAlchemy engine. Let us know how you get on, Simon -- SQLAlchemy - The Python SQL Toolkit and Object Relational Mapper http://www.sqlalchemy.org/ To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description. --- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.