List:Commits« Previous MessageNext Message »
From:Dmitry Shulga Date:June 30 2010 9:39am
Subject:bzr push into mysql-5.1-bugteam branch (Dmitry.Shulga:3452 to 3453)
Bug#51855
View as plain text  
 3453 Dmitry Shulga	2010-06-29
      Fixed bug #51855. Race condition in XA START. If several threads
      concurrently execute the statement XA START 'x', then mysqld
      server could crash.
     @ sql/sql_class.cc
        xid_cache_insert: added checking for element in cache before
        insert it, return TRUE if such element already exists.
     @ sql/sql_parse.cc
        mysql_execute_command modified:
        * sequence of calls to xid_cache_search(..)/xid_cache_insert(...)
        replaced by call to xid_cache_insert(...) in alternative
        'case SQLCOM_XA_START:'
        * added comment to alternative 'case SQLCOM_XA_COMMIT:'.

    modified:
      sql/sql_class.cc
      sql/sql_parse.cc
 3452 Martin Hansson	2010-06-29
      Fix of bad merge of test case for Bug#41660 (test case moved).

    modified:
      mysql-test/t/error_simulation.test
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2010-06-28 20:59:41 +0000
+++ b/sql/sql_class.cc	2010-06-29 09:32:03 +0000
@@ -3365,9 +3365,13 @@ bool xid_cache_insert(XID *xid, enum xa_
 bool xid_cache_insert(XID_STATE *xid_state)
 {
   pthread_mutex_lock(&LOCK_xid_cache);
-  DBUG_ASSERT(hash_search(&xid_cache, xid_state->xid.key(),
-                          xid_state->xid.key_length())==0);
-  my_bool res=my_hash_insert(&xid_cache, (uchar*)xid_state);
+  if (hash_search(&xid_cache, xid_state->xid.key(), xid_state->xid.key_length()))
+  {
+    pthread_mutex_unlock(&LOCK_xid_cache);
+    my_error(ER_XAER_DUPID, MYF(0));
+    return TRUE;
+  }
+  my_bool res= my_hash_insert(&xid_cache, (uchar*)xid_state);
   pthread_mutex_unlock(&LOCK_xid_cache);
   return res;
 }

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2010-06-28 20:59:41 +0000
+++ b/sql/sql_parse.cc	2010-06-29 09:32:03 +0000
@@ -4730,7 +4730,7 @@ create_sp_error:
         my_error(ER_XAER_NOTA, MYF(0));
         break;
       }
-      thd->transaction.xid_state.xa_state=XA_ACTIVE;
+      thd->transaction.xid_state.xa_state= XA_ACTIVE;
       my_ok(thd);
       break;
     }
@@ -4750,16 +4750,16 @@ create_sp_error:
       my_error(ER_XAER_OUTSIDE, MYF(0));
       break;
     }
-    if (xid_cache_search(thd->lex->xid))
-    {
-      my_error(ER_XAER_DUPID, MYF(0));
-      break;
-    }
     DBUG_ASSERT(thd->transaction.xid_state.xid.is_null());
-    thd->transaction.xid_state.xa_state=XA_ACTIVE;
+    thd->transaction.xid_state.xa_state= XA_ACTIVE;
     thd->transaction.xid_state.rm_error= 0;
     thd->transaction.xid_state.xid.set(thd->lex->xid);
-    xid_cache_insert(&thd->transaction.xid_state);
+    if (xid_cache_insert(&thd->transaction.xid_state))
+    {
+      thd->transaction.xid_state.xa_state= XA_NOTR;
+      thd->transaction.xid_state.xid.null();
+      break;
+    }
     thd->transaction.all.modified_non_trans_table= FALSE;
     thd->options= ((thd->options & ~(OPTION_KEEP_LOG)) | OPTION_BEGIN);
     thd->server_status|= SERVER_STATUS_IN_TRANS;
@@ -4813,6 +4813,16 @@ create_sp_error:
   case SQLCOM_XA_COMMIT:
     if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
     {
+      /*
+        xid_state.in_thd is always true beside of xa recovery
+        procedure. Note, that there is no race condition here
+        between xid_cache_search and xid_cache_delete, since we're always
+        deleting our own XID (thd->lex->xid == thd->transaction.xid_state.xid).
+        The only case when thd->lex->xid != thd->transaction.xid_state.xid
+        and xid_state->in_thd == 0 is in ha_recover() functionality,
+        which is called before starting client connections, and thus is
+        always single-threaded.
+      */
       XID_STATE *xs=xid_cache_search(thd->lex->xid);
       if (!xs || xs->in_thd)
         my_error(ER_XAER_NOTA, MYF(0));


Attachment: [text/bzr-bundle] bzr/dmitry.shulga@sun.com-20100629093203-c80nyfroboy2crlo.bundle
Thread
bzr push into mysql-5.1-bugteam branch (Dmitry.Shulga:3452 to 3453)Bug#51855Dmitry Shulga30 Jun