<div dir="ltr">Hi,<div><br></div><div>I'm trying this code and I can't get it to throw that exception. How are you triggering it?</div><div><br></div><div>See my code here: <a href="https://review.openstack.org/#/c/102715/1/neutron/plugins/ml2/drivers/mech_bigswitch/driver.py">https://review.openstack.org/#/c/102715/1/neutron/plugins/ml2/drivers/mech_bigswitch/driver.py</a></div>

</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Jun 25, 2014 at 8:49 PM, Li Ma <span dir="ltr"><<a href="mailto:skywalker.nick@gmail.com" target="_blank">skywalker.nick@gmail.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Sorry, I was thought that the code was straightforward to understand. I can explain what I wanna do.<br>
I try to use postcommit to dynamically set some specific port attribute into port binding when a certain port is created.<br>
So, I write an example to see whether it is working or not. But,<br>
<br>
def create_port_postcommit(self, context):<br>
    port_id = context._port['id']<br>
    session = db_api.get_session()<br>
<br>
    # insert some attr in profile<br>
    profile = {'type': 1, 'priority': 2}<br>
<div class=""><br>
    try:<br>
        binding = (session.query(models.PortBinding).<br>
                  filter(models.PortBinding.port_id.startswith(port_id)).<br>
                  one())<br>
</div>        binding.profile = str(profile)<br>
        session.merge(binding)<br>
    except exc.NoResultFound:<br>
        binding = models.PortBinding(<br>
                  port_id=port_id,<br>
                  vif_type=portbindings.VIF_TYPE_UNBOUND,<br>
                  profile=str(profile))<br>
        session.add(binding)<br>
    except Exception as e:<br>
        LOG.error(_("Error with port %(port_id)s"), {'port_id': port_id})  <-- line 95<br>
<br>
Message is as follows:<br>
<div class=""><br>
2014-06-25 10:05:17.195 9915 ERROR neutron.plugins.ml2.managers [req-961680da-ce69-43c6-974c-57132def411d None] Mechanism driver 'hello' failed in create_port_postcommit<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers Traceback (most recent call last):<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib/python2.6/site-packages/neutron/plugins/ml2/managers.py", line 158, in _call_on_drivers<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     getattr(driver.obj, method_name)(context)<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib/python2.6/site-packages/neutron/plugins/ml2/drivers/mech_hello.py", line 95, in create_port_postcommit<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     {'port_id': port_id})<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/orm/session.py", line 402, in __exit__<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     self.commit()<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/orm/session.py", line 314, in commit<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     self._prepare_impl()<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/orm/session.py", line 298, in _prepare_impl<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     self.session.flush()<br>
</div>2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib/python2.6/site-packages/neutron/openstack/common/db/sqlalchemy/session.py", line 597, in _wrap<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     return f(*args, **kwargs)<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib/python2.6/site-packages/neutron/openstack/common/db/sqlalchemy/session.py", line 836, in flush<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     return super(Session, self).flush(*args, **kwargs)<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/orm/session.py", line 1583, in flush<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     self._flush(objects)<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/orm/session.py", line 1654, in _flush<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     flush_context.execute()<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/orm/unitofwork.py", line 331, in execute<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     rec.execute(self)<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/orm/unitofwork.py", line 475, in execute<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     uow<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/orm/persistence.py", line 64, in save_obj<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     table, insert)<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/orm/persistence.py", line 530, in _emit_insert_statements<br>


2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     execute(statement, multiparams)<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1449, in execute<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     params)<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1584, in _execute_clauseelement<br>


2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     compiled_sql, distilled_params<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1698, in _execute_context<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     context)<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1691, in _execute_context<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     context)<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/engine/default.py", line 331, in do_execute<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     cursor.execute(statement, parameters)<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib64/python2.6/site-packages/MySQLdb/cursors.py", line 173, in execute<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     self.errorhandler(self, exc, value)<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File "/usr/lib64/python2.6/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     raise errorclass, errorvalue<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers OperationalError: (OperationalError) (1205, 'Lock wait timeout exceeded; try restarting transaction') 'INSERT INTO ml2_port_bindings (port_id, host, vnic_type, profile, vif_type, vif_details, driver, segment) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)' ('2f7996c2-7a60-4334-a71d-11e82285e272', '', 'normal', "{'type': 1, 'priority': 2}", 'unbound', '', None, None)<br>


<br>
<br>
Thanks,<br>
<div class="im HOEnZb">Li Ma<br>
<br>
<br>
----- Original Message -----<br>
From: "Kevin Benton" <<a href="mailto:blak111@gmail.com">blak111@gmail.com</a>><br>
To: "OpenStack Development Mailing List (not for usage questions)" <<a href="mailto:openstack-dev@lists.openstack.org">openstack-dev@lists.openstack.org</a>><br>
</div><div class="HOEnZb"><div class="h5">Sent: 星期四, 2014年 6 月 26日 上午 10:32:47<br>
Subject: Re: [openstack-dev] [Neutron ML2] Potential DB lock when developing new mechanism driver<br>
<br>
<br>
<br>
What is in the variable named 'query' that you are trying to merge into the session? Can you include the full create_port_postcommit method? The line raising the exception ends with " {'port_id': port_id})" and that doesn't matching anything included in your sample.<br>


<br>
<br>
<br>
On Wed, Jun 25, 2014 at 6:53 PM, Li Ma < <a href="mailto:skywalker.nick@gmail.com">skywalker.nick@gmail.com</a> > wrote:<br>
<br>
<br>
Here's a code sample which can raise db lock wait exception:<br>
<br>
def create_port_postcommit(self, context):<br>
<br>
port_id = ...<br>
with session.begin(subtransactions=True):<br>
try:<br>
binding = (session.query(models.PortBinding).<br>
filter(models.PortBinding.port_id.startswith(port_id)).<br>
one())<br>
# Here I modify some attributes if port binding is existed<br>
session.merge(query)<br>
except exc.NoResultFound:<br>
# Here I insert new port binding record to initialize some attributes<br>
except ...<br>
LOG.error("error happened")<br>
<br>
The exception is as follows:<br>
2014-06-25 10:05:17.195 9915 ERROR neutron.plugins.ml2.managers [req-961680da-ce69-43c6-974c-57132def411d None] Mechanism driver 'hello' failed in create_port_postcommit<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers Traceback (most recent call last):<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers File "/usr/lib/python2.6/site-packages/neutron/plugins/ml2/managers.py", line 158, in _call_on_drivers<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers getattr(driver.obj, method_name)(context)<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers File "/usr/lib/python2.6/site-packages/neutron/plugins/ml2/drivers/mech_hello.py", line 95, in create_port_postcommit<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers {'port_id': port_id})<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers File "/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/orm/session.py", line 402, in __exit__<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers self.commit()<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers File "/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/orm/session.py", line 314, in commit<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers self._prepare_impl()<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers File "/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/orm/session.py", line 298, in _prepare_impl<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers self.session.flush()<br>
<br>
...<br>
<br>
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers OperationalError: (OperationalError) (1205, 'Lock wait timeout exceeded; try restarting transaction') 'INSERT INTO ml2_port_bindings (port_id, host, vnic_type, profile, vif_type, vif_details, driver, segment) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)' (...)<br>


<br>
It seems that the transaction in the postcommit cannot be committed.<br>
<br>
Thanks a lot,<br>
<br>
Li Ma<br>
<br>
----- Original Message -----<br>
<br>
From: "Li Ma" < <a href="mailto:skywalker.nick@gmail.com">skywalker.nick@gmail.com</a> ><br>
To: "OpenStack Development Mailing List (not for usage questions)" < <a href="mailto:openstack-dev@lists.openstack.org">openstack-dev@lists.openstack.org</a> ><br>
<br>
<br>
Sent: 星期三, 2014年 6 月 25日 下午 6:21:10<br>
Subject: Re: [openstack-dev] [Neutron ML2] Potential DB lock when developing new mechanism driver<br>
<br>
Hi Kevin,<br>
<br>
Thanks for your reply. Actually, it is not that straightforward.<br>
Even if postcommit is outside the 'with' statement, the transaction is not 'truly' committed immediately. Because when I put my db code (reading and writing ml2-related tables) in postcommit, db lock wait exception is still thrown.<br>


<br>
Li Ma<br>
<br>
----- Original Message -----<br>
From: "Kevin Benton" < <a href="mailto:blak111@gmail.com">blak111@gmail.com</a> ><br>
To: "OpenStack Development Mailing List (not for usage questions)" < <a href="mailto:openstack-dev@lists.openstack.org">openstack-dev@lists.openstack.org</a> ><br>
Sent: 星期三, 2014年 6 月 25日 下午 4:59:26<br>
Subject: Re: [openstack-dev] [Neutron ML2] Potential DB lock when developing new mechanism driver<br>
<br>
<br>
<br>
The post_commit methods occur outside of the transactions. You should be able to perform the necessary database calls there.<br>
<br>
<br>
If you look at the code snippet in the email you provided, you can see that the 'try' block surrounding the postcommit method is at the same indentation-level as the 'with' statement for the transaction so it will be closed at that point.<br>


<br>
<br>
Cheers,<br>
Kevin Benton<br>
<br>
<br>
--<br>
Kevin Benton<br>
<br>
<br>
<br>
On Tue, Jun 24, 2014 at 8:33 PM, Li Ma < <a href="mailto:skywalker.nick@gmail.com">skywalker.nick@gmail.com</a> > wrote:<br>
<br>
<br>
Hi all,<br>
<br>
I'm developing a new mechanism driver. I'd like to access ml2-related tables in create_port_precommit and create_port_postcommit. However I find it hard to do that because the two functions are both inside an existed database transaction defined in create_port function of ml2/plugin.py.<br>


<br>
The related code is as follows:<br>
<br>
def create_port(self, context, port):<br>
...<br>
session = context.session<br>
with session.begin(subtransactions=True):<br>
...<br>
self.mechanism_manager.create_port_precommit(mech_context)<br>
try:<br>
self.mechanism_manager.create_port_postcommit(mech_context)<br>
...<br>
...<br>
return result<br>
<br>
As a result, I need to carefully deal with the database nested transaction issue to prevent from db lock when I develop my own mechanism driver. Right now, I'm trying to get the idea behind the scene. Is it possible to refactor it in order to make precommit and postcommit out of the db transaction? I think it is perfect for those who develop mechanism driver and do not know well about the functioning context of the whole ML2 plugin.<br>


<br>
Thanks,<br>
Li Ma<br>
<br>
_______________________________________________<br>
OpenStack-dev mailing list<br>
<a href="mailto:OpenStack-dev@lists.openstack.org">OpenStack-dev@lists.openstack.org</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
<br>
<br>
<br>
<br>
--<br>
<br>
Kevin Benton<br>
_______________________________________________<br>
OpenStack-dev mailing list<br>
<a href="mailto:OpenStack-dev@lists.openstack.org">OpenStack-dev@lists.openstack.org</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
<br>
_______________________________________________<br>
OpenStack-dev mailing list<br>
<a href="mailto:OpenStack-dev@lists.openstack.org">OpenStack-dev@lists.openstack.org</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
<br>
<br>
<br>
<br>
--<br>
<br>
Kevin Benton<br>
_______________________________________________<br>
OpenStack-dev mailing list<br>
<a href="mailto:OpenStack-dev@lists.openstack.org">OpenStack-dev@lists.openstack.org</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
<br>
_______________________________________________<br>
OpenStack-dev mailing list<br>
<a href="mailto:OpenStack-dev@lists.openstack.org">OpenStack-dev@lists.openstack.org</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div>Kevin Benton</div>
</div>