The problem is that configure_db is called before the workers are forked. This causes all of the workers to share the same underlying socket connection to the database even though each process has its own copy of ENGINE. I bet a stress test blasting at glance-api would fail quickly. I didn't actually do such a stress test on glance but I did on another application that borrowed this part of the glance code and found the same problem. I believe this could cause arbitrary corruption of the glance database.
Setting workers to 8:
stack@xg08:~/devstack$ ps aux | grep glance-api
root 32691 0.1 0.0 204212 35000 ? Ss 09:33 0:00 /usr/bin/python /usr/local/bin/glance-api
root 32697 0.0 0.0 204492 30744 ? S 09:33 0:00 /usr/bin/python /usr/local/bin/glance-api
root 32698 0.0 0.0 204496 30744 ? S 09:33 0:00 /usr/bin/python /usr/local/bin/glance-api
root 32699 0.0 0.0 204496 30744 ? S 09:33 0:00 /usr/bin/python /usr/local/bin/glance-api
root 32700 0.0 0.0 204496 30744 ? S 09:33 0:00 /usr/bin/python /usr/local/bin/glance-api
root 32701 0.0 0.0 204496 30740 ? S 09:33 0:00 /usr/bin/python /usr/local/bin/glance-api
root 32702 0.0 0.0 204496 30744 ? S 09:33 0:00 /usr/bin/python /usr/local/bin/glance-api
root 32703 0.0 0.0 204496 30744 ? S 09:33 0:00 /usr/bin/python /usr/local/bin/glance-api
root 32704 0.0 0.0 204496 30744 ? S 09:33 0:00 /usr/bin/python /usr/local/bin/glance-api
stack@xg08:~/devstack$ sudo lsof -p 14562 | grep mysqld.sock
mysqld 14562 mysql 12u unix 0xffff880beebcf500 0t0 29258 /var/run/mysqld/mysqld.sock
mysqld 14562 mysql 31u unix 0xffff880bec75c780 0t0 2356782 /var/run/mysqld/mysqld.sock
Putting a printf in configure_db also showed it was getting called only in the initial process. Here is one error I saw in the other app before fixing this:
File "/usr/lib/ python2. 7/dist- packages/ sqlalchemy/ orm/query. py", line 1947, in all python2. 7/dist- packages/ sqlalchemy/ orm/query. py", line 2057, in __iter__ and_instances( context) python2. 7/dist- packages/ sqlalchemy/ orm/query. py", line 2072, in _execute_ and_instances querycontext. statement, self._params) python2. 7/dist- packages/ sqlalchemy/ engine/ base.py" , line 1405, in execute python2. 7/dist- packages/ sqlalchemy/ engine/ base.py" , line 1538, in _execute_ clauseelement python2. 7/dist- packages/ sqlalchemy/ engine/ base.py" , line 1646, in _execute_context python2. 7/dist- packages/ sqlalchemy/ engine/ base.py" , line 1639, in _execute_context python2. 7/dist- packages/ sqlalchemy/ engine/ default. py", line 330, in do_execute execute( statement, parameters) python2. 7/dist- packages/ MySQLdb/ cursors. py", line 174, in execute errorhandler( self, exc, value) python2. 7/dist- packages/ MySQLdb/ connections. py", line 36, in defaulterrorhandler time, files.user AS files_user, files.swif\ container_ name, files.swift_ object_ name AS files_swift_ object_ name \nFROM files \nWHERE fi\ 1d8c-4d26- bb65-1ab019d33b 7c',)
return list(self)
File "/usr/lib/
return self._execute_
File "/usr/lib/
result = conn.execute(
File "/usr/lib/
params)
File "/usr/lib/
compiled_sql, distilled_params
File "/usr/lib/
context)
File "/usr/lib/
context)
File "/usr/lib/
cursor.
File "/usr/lib/
self.
File "/usr/lib/
raise errorclass, errorvalue
OperationalError: (OperationalError) (2006, 'MySQL server has gone away') 'SELECT files.id AS files_id, files.name AS file\
s_name, files.description AS files_description, files.command_line AS files_command_line, files.jobs_id AS files_jobs_id, \
files.content_type AS files_content_type, files.creation_time AS files_creation_
t_container_name AS files_swift_
les.name = %s' ('657e9377-