summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Lamar <brian.lamar@rackspace.com>2011-08-12 15:24:33 +0000
committerTarmac <>2011-08-12 15:24:33 +0000
commit1f116df9b65fc317db26492115bc36ce465ba296 (patch)
tree259dc78d871418efb7bda60b16b848af39f3a537
parentc3b1538261313132fc7e2fa28d7f66aa4c4a0926 (diff)
parent3017d3a7cd9cd4928a5e5247054b877e63fac095 (diff)
Allows for a tunable number of SQL connections to be maintained between services and the SQL server using new configuration flags. Only applies when using the MySQLdb dialect in SQLAlchemy.
-rw-r--r--nova/db/sqlalchemy/session.py90
-rw-r--r--nova/flags.py6
2 files changed, 72 insertions, 24 deletions
diff --git a/nova/db/sqlalchemy/session.py b/nova/db/sqlalchemy/session.py
index 4a9a28f43..07f281938 100644
--- a/nova/db/sqlalchemy/session.py
+++ b/nova/db/sqlalchemy/session.py
@@ -19,37 +19,79 @@
Session Handling for SQLAlchemy backend
"""
-from sqlalchemy import create_engine
-from sqlalchemy import pool
-from sqlalchemy.orm import sessionmaker
+import eventlet.patcher
+eventlet.patcher.monkey_patch()
-from nova import exception
-from nova import flags
+import eventlet.db_pool
+import sqlalchemy.orm
+import sqlalchemy.pool
+
+import nova.exception
+import nova.flags
+import nova.log
+
+
+FLAGS = nova.flags.FLAGS
+LOG = nova.log.getLogger("nova.db.sqlalchemy")
+
+
+try:
+ import MySQLdb
+except ImportError:
+ MySQLdb = None
-FLAGS = flags.FLAGS
_ENGINE = None
_MAKER = None
def get_session(autocommit=True, expire_on_commit=False):
- """Helper method to grab session"""
- global _ENGINE
- global _MAKER
- if not _MAKER:
- if not _ENGINE:
- kwargs = {'pool_recycle': FLAGS.sql_idle_timeout,
- 'echo': False}
-
- if FLAGS.sql_connection.startswith('sqlite'):
- kwargs['poolclass'] = pool.NullPool
-
- _ENGINE = create_engine(FLAGS.sql_connection,
- **kwargs)
- _MAKER = (sessionmaker(bind=_ENGINE,
- autocommit=autocommit,
- expire_on_commit=expire_on_commit))
+ """Return a SQLAlchemy session."""
+ global _ENGINE, _MAKER
+
+ if _MAKER is None or _ENGINE is None:
+ _ENGINE = get_engine()
+ _MAKER = get_maker(_ENGINE, autocommit, expire_on_commit)
+
session = _MAKER()
- session.query = exception.wrap_db_error(session.query)
- session.flush = exception.wrap_db_error(session.flush)
+ session.query = nova.exception.wrap_db_error(session.query)
+ session.flush = nova.exception.wrap_db_error(session.flush)
return session
+
+
+def get_engine():
+ """Return a SQLAlchemy engine."""
+ connection_dict = sqlalchemy.engine.url.make_url(FLAGS.sql_connection)
+
+ engine_args = {
+ "pool_recycle": FLAGS.sql_idle_timeout,
+ "echo": False,
+ }
+
+ if "sqlite" in connection_dict.drivername:
+ engine_args["poolclass"] = sqlalchemy.pool.NullPool
+
+ elif MySQLdb and "mysql" in connection_dict.drivername:
+ LOG.info(_("Using mysql/eventlet db_pool."))
+ pool_args = {
+ "db": connection_dict.database,
+ "passwd": connection_dict.password,
+ "host": connection_dict.host,
+ "user": connection_dict.username,
+ "min_size": FLAGS.sql_min_pool_size,
+ "max_size": FLAGS.sql_max_pool_size,
+ "max_idle": FLAGS.sql_idle_timeout,
+ }
+ creator = eventlet.db_pool.ConnectionPool(MySQLdb, **pool_args)
+ engine_args["pool_size"] = FLAGS.sql_max_pool_size
+ engine_args["pool_timeout"] = FLAGS.sql_pool_timeout
+ engine_args["creator"] = creator.create
+
+ return sqlalchemy.create_engine(FLAGS.sql_connection, **engine_args)
+
+
+def get_maker(engine, autocommit=True, expire_on_commit=False):
+ """Return a SQLAlchemy sessionmaker using the given engine."""
+ return sqlalchemy.orm.sessionmaker(bind=engine,
+ autocommit=autocommit,
+ expire_on_commit=expire_on_commit)
diff --git a/nova/flags.py b/nova/flags.py
index 7916501a4..e994a1665 100644
--- a/nova/flags.py
+++ b/nova/flags.py
@@ -345,6 +345,12 @@ DEFINE_string('logdir', None, 'output to a per-service log file in named '
'directory')
DEFINE_integer('logfile_mode', 0644, 'Default file mode of the logs.')
DEFINE_string('sqlite_db', 'nova.sqlite', 'file name for sqlite')
+DEFINE_integer('sql_pool_timeout', 30,
+ 'seconds to wait for connection from pool before erroring')
+DEFINE_integer('sql_min_pool_size', 10,
+ 'minimum number of SQL connections to pool')
+DEFINE_integer('sql_max_pool_size', 10,
+ 'maximum number of SQL connections to pool')
DEFINE_string('sql_connection',
'sqlite:///$state_path/$sqlite_db',
'connection string for sql database')