Bug #51855 Race condition in XA START
Submitted: 9 Mar 2010 8:14 Modified: 14 Oct 2010 14:16
Reporter: Sergey Vojtovich Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Locking Severity:S3 (Non-critical)
Version:5.0+, 5.1, 5.5.99 OS:Any
Assigned to: Dmitry Shulga CPU Architecture:Any

[9 Mar 2010 8:14] Sergey Vojtovich
Description:
Debug server crashes due to assertion failure when running the following test case.

mysqld: sql_class.cc:3314: bool xid_cache_insert(XID_STATE*): Assertion `my_hash_search(&xid_cache, xid_state->xid.key(), xid_state->xid.key_length())==0' failed.

Non-debug will likely crash too, but with different symptoms.

How to repeat:
Test case will be attached shortly. Basically run concurrently:
XA START 'x';
XA END 'x';
XA PREPARE 'x';
XA COMMIT 'x';

Suggested fix:
When we start new distributed transaction, first we check if distributed transaction with the same name exist, then insert new element into distributed transactions name hash. The algorithm is like this:
- lock LOCK_xid_cache
- check if name exists
- unlock LOCK_xid_cache
! here comes race condition
- lock LOCK_xid_cache
- insert new name
- unlock LOCK_xid_cache
[9 Mar 2010 8:16] Sergey Vojtovich
A test case. Done basing on Shane's script.

Attachment: bug51855.c (text/x-csrc), 5.66 KiB.

[9 Mar 2010 10:20] Sveta Smirnova
Thank you for the report.

Verified as described.
[16 Jun 2010 12:24] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/111260

3411 Dmitry Shulga	2010-06-16
      Fixed bug #51855. Race condition in XA START. If several threads concurrently executing statements block like this
      XA START 'x';
      XA END 'x';
      XA PREPARE 'x';
      XA COMMIT 'x';
      then mysqld server (built with debug) could crash
     @ sql/sql_class.cc
        added xid_cache_find_or_insert standalone procedure definition
     @ sql/sql_class.h
        added declaration for xid_cache_find_or_insert
     @ sql/sql_parse.cc
        sequence of calls to xid_cache_search(..) xid_cache_insert(...) replaced by call to xid_cache_find_or_insert(...).
[18 Jun 2010 9:27] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/111523

3411 Dmitry Shulga	2010-06-18
      Fixed bug #51855. Race condition in XA START. If several threads concurrently executing statements block like this
      XA START 'x';
      XA END 'x';
      XA PREPARE 'x';
      XA COMMIT 'x';
      then mysqld server (built with debug) could crash.
      Fixed race condition in XA COMMIT/XA ROLLBACK.
     @ sql/handler.cc
        XID_STATE's attributes xa_state/in_thd/rm_error moved to separate class XA_INFO and reference to ones made as value.xa_state/value.in_thd/value.rm_error.
     @ sql/set_var.cc
        XID_STATE's attributes xa_state/in_thd/rm_error moved to separate class XA_INFO and reference to ones made as value.xa_state/value.in_thd/value.rm_error.
     @ sql/sql_class.cc
        added xid_cache_find_or_insert standalone procedure definition; xid_cache_search now returns XA_INFO value in second argument and returns bool value as search result (false if cache entry not found, else return true); changed argument typr for xid_cache_delete - now it have type XID_STATE*.
     @ sql/sql_class.h
        added declaration for xid_cache_find_or_insert; modified signature for xid_cache_delete and xid_cache_serach; modified definition for XID_STATE - attributes xa_state, in_thd, rm_error moved to separate struct XA_INFO and value of this struct included as field to XID_STATE.
     @ sql/sql_parse.cc
        sequence of calls to xid_cache_search(..) xid_cache_insert(...) replaced by call to xid_cache_find_or_insert(...); XID_STATE's attributes xa_state/in_thd/rm_error moved to separate class XA_INFO and reference to ones made as value.xa_state/value.in_thd/value.rm_error; at case SQLCOM_XA_COMMIT/SQLCOM_XA_ROLLBACK: get information about XA state by value when calling to xid_cache_search.
[23 Jun 2010 7:53] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/111862

3411 Dmitry Shulga	2010-06-23
      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_init: hash inited with flag HASH_UNIQUE; xid_cache_insert: reset my_errno value before call to my_hash_insert, removed call to superfluous DBUG_ASSERT macros.
     @ sql/sql_parse.cc
        sequence of calls to xid_cache_search(..)/xid_cache_insert(...) replaced by call to xid_cache_insert(...) - xid_cache was previously initited with HASH_UNIQUE flag.
[25 Jun 2010 5:06] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/112156

3411 Dmitry Shulga	2010-06-25
      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:'.
[25 Jun 2010 8:34] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/112188

3411 Dmitry Shulga	2010-06-25
      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:'.
[29 Jun 2010 9:32] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/112427

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:'.
[30 Jun 2010 4:42] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/112510

3088 Dmitry Shulga	2010-06-30 [merge]
      Merge fix for bug #51855
     @ sql/sql_class.cc
        xid_cache_insert modified: added checking for element in cache
        before insert it,
     @ sql/transaction.cc
        trans_xa_start modified: sequence of calls to 
        xid_cache_search/xid_cache_insert replaced to xid_cache_insert
        that does cache search/insert operations atomically
[24 Jul 2010 1:11] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/114277

3140 Davi Arnaut	2010-07-23 [merge]
      Null merge Bug#51855 into mysql-trunk-merge.
[24 Jul 2010 1:22] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/114279

3143 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:'.
[4 Aug 2010 7:52] Bugs System
Pushed into mysql-trunk 5.5.6-m3 (revid:alik@sun.com-20100731131027-1n61gseejyxsqk5d) (version source revid:alik@sun.com-20100731074942-o840woifuqioxxe4) (merge vers: 5.5.6-m3) (pib:18)
[4 Aug 2010 8:07] Bugs System
Pushed into mysql-trunk 5.6.1-m4 (revid:alik@ibmvm-20100804080001-bny5271e65xo34ig) (version source revid:alik@sun.com-20100731075120-qz9z8c25zum2wgmm) (merge vers: 5.6.99-m4) (pib:18)
[4 Aug 2010 8:23] Bugs System
Pushed into mysql-trunk 5.6.1-m4 (revid:alik@ibmvm-20100804081533-c1d3rbipo9e8rt1s) (version source revid:alik@sun.com-20100731075120-qz9z8c25zum2wgmm) (merge vers: 5.6.99-m4) (pib:18)
[4 Aug 2010 9:03] Bugs System
Pushed into mysql-next-mr (revid:alik@ibmvm-20100804081630-ntapn8bf9pko9vj3) (version source revid:alik@sun.com-20100731075120-qz9z8c25zum2wgmm) (pib:20)
[12 Aug 2010 19:21] Paul DuBois
Noted in 5.5.6 changelog.

XA START had a race condition that could cause a server crash.
[19 Aug 2010 15:42] Bugs System
Pushed into mysql-5.1 5.1.51 (revid:build@mysql.com-20100819151858-muaaor6jojb5ouzj) (version source revid:build@mysql.com-20100819151858-muaaor6jojb5ouzj) (merge vers: 5.1.51) (pib:20)
[14 Oct 2010 8:31] Bugs System
Pushed into mysql-5.1-telco-7.0 5.1.51-ndb-7.0.20 (revid:martin.skold@mysql.com-20101014082627-jrmy9xbfbtrebw3c) (version source revid:martin.skold@mysql.com-20101014082627-jrmy9xbfbtrebw3c) (merge vers: 5.1.51-ndb-7.0.20) (pib:21)
[14 Oct 2010 8:47] Bugs System
Pushed into mysql-5.1-telco-6.3 5.1.51-ndb-6.3.39 (revid:martin.skold@mysql.com-20101014083757-5qo48b86d69zjvzj) (version source revid:martin.skold@mysql.com-20101014083757-5qo48b86d69zjvzj) (merge vers: 5.1.51-ndb-6.3.39) (pib:21)
[14 Oct 2010 9:01] Bugs System
Pushed into mysql-5.1-telco-6.2 5.1.51-ndb-6.2.19 (revid:martin.skold@mysql.com-20101014084420-y54ecj85j5we27oa) (version source revid:martin.skold@mysql.com-20101014084420-y54ecj85j5we27oa) (merge vers: 5.1.51-ndb-6.2.19) (pib:21)
[14 Oct 2010 14:16] Jon Stephens
Also noted in the 5.1.51 changelog. 

No additional changelog entries required. 

Closed.