From 55abed4afd22e7e29f6579a67efad52f0b800278 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Sat, 4 Oct 2008 18:32:23 +0200 Subject: [PATCH 1/5] Fix some bad merge that got the string "5.1-bugteam" into this 5.0 tree. --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index e613cefc614..f79c1cd6319 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.1-bugteam" +tree_name = "mysql-5.0" From 36e4c7d281e73897e35fb82e7aa81bddab560f74 Mon Sep 17 00:00:00 2001 From: Kent Boortz Date: Mon, 13 Oct 2008 14:23:39 +0200 Subject: [PATCH 2/5] The header "config.h" needs to be included "early" to control other headers. This time the inclusion of before "config.h" enabled legacy large file support, seek64() and similar, on AIX breaking the compile of "gzio.c" --- zlib/gzio.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/zlib/gzio.c b/zlib/gzio.c index 7e90f4928fc..ed4e77ca7e9 100644 --- a/zlib/gzio.c +++ b/zlib/gzio.c @@ -7,6 +7,11 @@ /* @(#) $Id$ */ +/* Need to be included "early" to control other headers */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include "zutil.h" From b0d673fc4d659ed87f9a2b64a597b533bdc12f92 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 21 Oct 2008 16:07:31 -0200 Subject: [PATCH 3/5] Bug#28323: Server crashed in xid cache operations The problem was that the server did not robustly handle a unilateral roll back issued by the Resource Manager (RM) due to a resource deadlock within the transaction branch. By not acknowledging the roll back, the server (TM) would eventually corrupt the XA transaction state and crash. The solution is to mark the transaction as rollback-only if the RM indicates that it rolled back its branch of the transaction. --- mysql-test/r/xa.result | 19 ++++++++++ mysql-test/t/xa.test | 44 ++++++++++++++++++++++++ sql/handler.cc | 7 +++- sql/share/errmsg.txt | 4 +++ sql/sql_class.h | 4 ++- sql/sql_parse.cc | 78 +++++++++++++++++++++++++++++++++++++----- 6 files changed, 145 insertions(+), 11 deletions(-) diff --git a/mysql-test/r/xa.result b/mysql-test/r/xa.result index 5fb03d2378e..25d09f59247 100644 --- a/mysql-test/r/xa.result +++ b/mysql-test/r/xa.result @@ -55,3 +55,22 @@ select * from t1; a 20 drop table t1; +drop table if exists t1; +create table t1(a int, b int, c varchar(20), primary key(a)) engine = innodb; +insert into t1 values(1, 1, 'a'); +insert into t1 values(2, 2, 'b'); +xa start 'a','b'; +update t1 set c = 'aa' where a = 1; +xa start 'a','c'; +update t1 set c = 'bb' where a = 2; +update t1 set c = 'bb' where a = 2; +update t1 set c = 'aa' where a = 1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +select count(*) from t1; +count(*) +2 +xa end 'a','c'; +ERROR XA102: XA_RBDEADLOCK: Transaction branch was rolled back: deadlock was detected +xa rollback 'a','c'; +xa start 'a','c'; +End of 5.0 tests diff --git a/mysql-test/t/xa.test b/mysql-test/t/xa.test index 0d564727fe3..8f408fb1eda 100644 --- a/mysql-test/t/xa.test +++ b/mysql-test/t/xa.test @@ -74,3 +74,47 @@ xa start 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'; select * from t1; drop table t1; +disconnect con1; + +# +# Bug#28323: Server crashed in xid cache operations +# + +--disable_warnings +drop table if exists t1; +--enable_warnings + +create table t1(a int, b int, c varchar(20), primary key(a)) engine = innodb; +insert into t1 values(1, 1, 'a'); +insert into t1 values(2, 2, 'b'); + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +--connection con1 +xa start 'a','b'; +update t1 set c = 'aa' where a = 1; +--connection con2 +xa start 'a','c'; +update t1 set c = 'bb' where a = 2; +--connection con1 +--send update t1 set c = 'bb' where a = 2 +--connection con2 +--sleep 1 +--error ER_LOCK_DEADLOCK +update t1 set c = 'aa' where a = 1; +select count(*) from t1; +--error ER_XA_RBDEADLOCK +xa end 'a','c'; +xa rollback 'a','c'; +--disconnect con2 + +connect (con3,localhost,root,,); +--connection con3 +xa start 'a','c'; + +--disconnect con1 +--disconnect con3 +--connection default + +--echo End of 5.0 tests diff --git a/sql/handler.cc b/sql/handler.cc index 0de772e366b..67ec5f3e759 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -817,7 +817,12 @@ int ha_rollback_trans(THD *thd, bool all) trans->nht=0; trans->no_2pc=0; if (is_real_trans) - thd->transaction.xid_state.xid.null(); + { + if (thd->transaction_rollback_request) + thd->transaction.xid_state.rm_error= thd->net.last_errno; + else + thd->transaction.xid_state.xid.null(); + } if (all) { thd->variables.tx_isolation=thd->session_tx_isolation; diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 0916ad56cef..c688ba88b7b 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5645,3 +5645,7 @@ ER_LOAD_DATA_INVALID_COLUMN eng "Invalid column reference (%-.64s) in LOAD DATA" ER_LOG_PURGE_NO_FILE eng "Being purged log %s was not found" +ER_XA_RBTIMEOUT XA106 + eng "XA_RBTIMEOUT: Transaction branch was rolled back: took too long" +ER_XA_RBDEADLOCK XA102 + eng "XA_RBDEADLOCK: Transaction branch was rolled back: deadlock was detected" diff --git a/sql/sql_class.h b/sql/sql_class.h index a9700c9e91b..44dff38979e 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -920,7 +920,7 @@ struct st_savepoint { uint length, nht; }; -enum xa_states {XA_NOTR=0, XA_ACTIVE, XA_IDLE, XA_PREPARED}; +enum xa_states {XA_NOTR=0, XA_ACTIVE, XA_IDLE, XA_PREPARED, XA_ROLLBACK_ONLY}; extern const char *xa_state_names[]; typedef struct st_xid_state { @@ -928,6 +928,8 @@ typedef struct st_xid_state { XID xid; // transaction identifier enum xa_states xa_state; // used by external XA only bool in_thd; + /* Error reported by the Resource Manager (RM) to the Transaction Manager. */ + uint rm_error; } XID_STATE; extern pthread_mutex_t LOCK_xid_cache; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 713aca9de47..345f2d0420f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -90,9 +90,57 @@ const char *command_name[]={ }; const char *xa_state_names[]={ - "NON-EXISTING", "ACTIVE", "IDLE", "PREPARED" + "NON-EXISTING", "ACTIVE", "IDLE", "PREPARED", "ROLLBACK ONLY" }; +/** + Mark a XA transaction as rollback-only if the RM unilaterally + rolled back the transaction branch. + + @note If a rollback was requested by the RM, this function sets + the appropriate rollback error code and transits the state + to XA_ROLLBACK_ONLY. + + @return TRUE if transaction was rolled back or if the transaction + state is XA_ROLLBACK_ONLY. FALSE otherwise. +*/ +static bool xa_trans_rolled_back(XID_STATE *xid_state) +{ + if (xid_state->rm_error) + { + switch (xid_state->rm_error) { + case ER_LOCK_WAIT_TIMEOUT: + my_error(ER_XA_RBTIMEOUT, MYF(0)); + break; + case ER_LOCK_DEADLOCK: + my_error(ER_XA_RBDEADLOCK, MYF(0)); + break; + default: + my_error(ER_XA_RBROLLBACK, MYF(0)); + } + xid_state->xa_state= XA_ROLLBACK_ONLY; + } + + return (xid_state->xa_state == XA_ROLLBACK_ONLY); +} + +/** + Rollback work done on behalf of at ransaction branch. +*/ +static bool xa_trans_rollback(THD *thd) +{ + bool status= test(ha_rollback(thd)); + + thd->options&= ~(ulong) OPTION_BEGIN; + thd->transaction.all.modified_non_trans_table= FALSE; + thd->server_status&= ~SERVER_STATUS_IN_TRANS; + xid_cache_delete(&thd->transaction.xid_state); + thd->transaction.xid_state.xa_state= XA_NOTR; + thd->transaction.xid_state.rm_error= 0; + + return status; +} + #ifndef EMBEDDED_LIBRARY static bool do_command(THD *thd); #endif // EMBEDDED_LIBRARY @@ -5049,6 +5097,7 @@ create_sp_error: } DBUG_ASSERT(thd->transaction.xid_state.xid.is_null()); 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); thd->transaction.all.modified_non_trans_table= FALSE; @@ -5074,6 +5123,8 @@ create_sp_error: my_error(ER_XAER_NOTA, MYF(0)); break; } + if (xa_trans_rolled_back(&thd->transaction.xid_state)) + break; thd->transaction.xid_state.xa_state=XA_IDLE; send_ok(thd); break; @@ -5105,6 +5156,12 @@ create_sp_error: XID_STATE *xs=xid_cache_search(thd->lex->xid); if (!xs || xs->in_thd) my_error(ER_XAER_NOTA, MYF(0)); + else if (xa_trans_rolled_back(xs)) + { + ha_commit_or_rollback_by_xid(thd->lex->xid, 0); + xid_cache_delete(xs); + break; + } else { ha_commit_or_rollback_by_xid(thd->lex->xid, 1); @@ -5113,6 +5170,11 @@ create_sp_error: } break; } + if (xa_trans_rolled_back(&thd->transaction.xid_state)) + { + xa_trans_rollback(thd); + break; + } if (thd->transaction.xid_state.xa_state == XA_IDLE && thd->lex->xa_opt == XA_ONE_PHASE) { @@ -5159,28 +5221,26 @@ create_sp_error: my_error(ER_XAER_NOTA, MYF(0)); else { + bool ok= !xa_trans_rolled_back(xs); ha_commit_or_rollback_by_xid(thd->lex->xid, 0); xid_cache_delete(xs); - send_ok(thd); + if (ok) + send_ok(thd); } break; } if (thd->transaction.xid_state.xa_state != XA_IDLE && - thd->transaction.xid_state.xa_state != XA_PREPARED) + thd->transaction.xid_state.xa_state != XA_PREPARED && + thd->transaction.xid_state.xa_state != XA_ROLLBACK_ONLY) { my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[thd->transaction.xid_state.xa_state]); break; } - if (ha_rollback(thd)) + if (xa_trans_rollback(thd)) my_error(ER_XAER_RMERR, MYF(0)); else send_ok(thd); - thd->options&= ~(ulong) OPTION_BEGIN; - thd->transaction.all.modified_non_trans_table= FALSE; - thd->server_status&= ~SERVER_STATUS_IN_TRANS; - xid_cache_delete(&thd->transaction.xid_state); - thd->transaction.xid_state.xa_state=XA_NOTR; break; case SQLCOM_XA_RECOVER: res= mysql_xa_recover(thd); From e139d9c77571a5a9ebb1144f6d86dc06d5fd6099 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 21 Oct 2008 19:02:26 -0200 Subject: [PATCH 4/5] Post-merge fix: drop table at the end of test. --- mysql-test/r/xa.result | 1 + mysql-test/t/xa.test | 1 + 2 files changed, 2 insertions(+) diff --git a/mysql-test/r/xa.result b/mysql-test/r/xa.result index 25d09f59247..592cf07522b 100644 --- a/mysql-test/r/xa.result +++ b/mysql-test/r/xa.result @@ -73,4 +73,5 @@ xa end 'a','c'; ERROR XA102: XA_RBDEADLOCK: Transaction branch was rolled back: deadlock was detected xa rollback 'a','c'; xa start 'a','c'; +drop table t1; End of 5.0 tests diff --git a/mysql-test/t/xa.test b/mysql-test/t/xa.test index 8f408fb1eda..591d7ac2c4d 100644 --- a/mysql-test/t/xa.test +++ b/mysql-test/t/xa.test @@ -116,5 +116,6 @@ xa start 'a','c'; --disconnect con1 --disconnect con3 --connection default +drop table t1; --echo End of 5.0 tests From f14edb91fb4b8587864462641145b4c393f9b72f Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 23 Oct 2008 15:28:53 +0200 Subject: [PATCH 5/5] Bug#40280: Message compiler(mc.exe) needed to compile MySQL on windows. Visual Studio 2008 Express edition does not include message compiler mc.exe It is not possible to build MySQL server if only VC2008 Express is installed, because we use mc.exe to generate event log messages. This patch removes the mc.exe dependency. Generated files message.h, message.rc and MSG00001.bin are checked into source code repository. Instructions on how to add or change messages are added to messages.mc --- sql/CMakeLists.txt | 15 +++---------- sql/MSG00001.bin | Bin 0 -> 184 bytes sql/Makefile.am | 3 ++- sql/message.h | 55 +++++++++++++++++++++++++++++++++++++++++++++ sql/message.mc | 8 +++++++ sql/message.rc | 2 ++ 6 files changed, 70 insertions(+), 13 deletions(-) create mode 100644 sql/MSG00001.bin create mode 100644 sql/message.h create mode 100644 sql/message.rc diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 9ea9874c1b1..860afb42a27 100755 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -28,10 +28,8 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/bdb/build_win32 ${CMAKE_SOURCE_DIR}/bdb/dbinc) -SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/sql/message.rc - ${CMAKE_SOURCE_DIR}/sql/message.h - ${CMAKE_SOURCE_DIR}/sql/sql_yacc.h - ${CMAKE_SOURCE_DIR}/sql/sql_yacc.cc +SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/sql/sql_yacc.h + ${CMAKE_SOURCE_DIR}/sql/sql_yacc.cc ${CMAKE_SOURCE_DIR}/include/mysql_version.h ${CMAKE_SOURCE_DIR}/sql/lex_hash.h ${PROJECT_SOURCE_DIR}/include/mysqld_error.h @@ -120,13 +118,6 @@ ADD_CUSTOM_COMMAND( DEPENDS ${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc ) -# Windows message file -ADD_CUSTOM_COMMAND( - SOURCE ${PROJECT_SOURCE_DIR}/sql/message.mc - OUTPUT message.rc message.h - COMMAND mc ARGS ${PROJECT_SOURCE_DIR}/sql/message.mc - DEPENDS ${PROJECT_SOURCE_DIR}/sql/message.mc) - # Gen_lex_hash # About "mysqlclient_notls", see note in "client/CMakeLists.txt" ADD_EXECUTABLE(gen_lex_hash gen_lex_hash.cc) @@ -141,7 +132,7 @@ ADD_DEPENDENCIES(mysqld${MYSQLD_EXE_SUFFIX} gen_lex_hash) # Remove the auto-generated files as part of 'Clean Solution' SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES - "lex_hash.h;message.rc;message.h;sql_yacc.h;sql_yacc.cc") + "lex_hash.h;sql_yacc.h;sql_yacc.cc") ADD_LIBRARY(udf_example MODULE udf_example.c udf_example.def) ADD_DEPENDENCIES(udf_example strings) diff --git a/sql/MSG00001.bin b/sql/MSG00001.bin new file mode 100644 index 0000000000000000000000000000000000000000..89f547694f5fd13c7773d3b80d0119aa4bccb713 GIT binary patch literal 184 zcmW-bK?=e^5Ckh%LGTH=c$0`%uY!2@1;MN+xJlF%@kc(xr&$@Aou1yA?%fLL;5VIx z{g;X*8}}?n=)&RHmh<2X9tRo+MFou-+K$S|^=+