summaryrefslogtreecommitdiff
path: root/innobase
diff options
context:
space:
mode:
authorunknown <tsmith/tim@siva.hindu.god>2006-12-18 18:41:38 -0700
committerunknown <tsmith/tim@siva.hindu.god>2006-12-18 18:41:38 -0700
commit306f42701cdbf0801c710f3c0fe0e74c521455fc (patch)
tree71350d152b8e2b1979b7b4d1fd2566eb731baabe /innobase
parent3d033fb322f4d747c42ce15e50dab951c6811ca2 (diff)
downloadmariadb-git-306f42701cdbf0801c710f3c0fe0e74c521455fc.tar.gz
This ChangeSet must be null-merged to 5.1.
Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Bugs fixed: - Bug #21468: InnoDB crash during recovery with corrupted data pages: XA bug? - Bug #24299: Identifiers in foreign keys cannot contain U+0160, U+0360, ..., U+FF60 - Bug #24386: Performance degradation caused by instrumentation in mutex_struct - Bug #24712: SHOW TABLE STATUS for file-per-table showing incorrect time fields innobase/dict/dict0dict.c: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1030: branches/5.0: Replace isspace() with a wrapper ib_isspace(), because on Win32 isspace(0xa0) appears to hold. (Bug #24299) innobase/include/sync0rw.h: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1040: branches/5.0: Port r1039 from trunk: Port r1034 from branches/zip: Remove some instrumentation and reduce the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386) innobase/include/sync0sync.h: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1040: branches/5.0: Port r1039 from trunk: Port r1034 from branches/zip: Remove some instrumentation and reduce the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386) innobase/include/sync0sync.ic: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1040: branches/5.0: Port r1039 from trunk: Port r1034 from branches/zip: Remove some instrumentation and reduce the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386) innobase/log/log0recv.c: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1076: branches/5.0: Remove the unintentionally committed change to univ.i in r1075. Fix assertion failure sync0sync.c line 1239 (the latter ut_error in sync_thread_reset_level()) in crash recovery when UNIV_SYNC_DEBUG is enabled. Revision r1079: branches/5.0: recv_recovery_from_checkpoint_finish(): Add 1 sec delay before switching on the sync order checks in crash recovery, so that file I/O threads have time to suspend themselves. innobase/srv/srv0start.c: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1075: branches/5.0: Fix assertion failure sync0sync.c line 1239 (the latter ut_error in sync_thread_reset_level()) in crash recovery when UNIV_SYNC_DEBUG is enabled. Revision r1077: branches/5.0: innobase_start_or_create_for_mysql(): Remove unnecessary delay now that we moved the setting sync_order_checks_on=TRUE to log0recv.c, to the start of the rollback phase in crash recovery. innobase/sync/sync0rw.c: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1040: branches/5.0: Port r1039 from trunk: Port r1034 from branches/zip: Remove some instrumentation and reduce the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386) innobase/sync/sync0sync.c: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1040: branches/5.0: Port r1039 from trunk: Port r1034 from branches/zip: Remove some instrumentation and reduce the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386) innobase/trx/trx0roll.c: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1067: branches/5.0: trx_rollback_for_mysql(), trx_commit_for_mysql(): Protect the creation of trx_dummy_sess with kernel_mutex. This error was introduced in r1046 and r1050. Revision r1050: branches/5.0: trx_rollback_for_mysql(): Fix the comment introduced in r1046. trx_commit_for_mysql(): Use the dummy trx->sess also for committing a prepared transaction in XA recovery, just in case our code would need the session object also in that case (does not seem to need it right now). Revision r1048: branches/5.0: trx_rollback_for_mysql(): Do not set trx->sess back to NULL. This bug was introduced in r1046. Revision r1046: branches/5.0: trx_rollback_for_mysql(): Ensure that trx->sess is non-NULL when calling trx_general_rollback_for_mysql(). This removes a segmentation fault when rolling back a prepared transaction in XA recovery. (Bug #21468) innobase/trx/trx0trx.c: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1067: branches/5.0: trx_rollback_for_mysql(), trx_commit_for_mysql(): Protect the creation of trx_dummy_sess with kernel_mutex. This error was introduced in r1046 and r1050. Revision r1050: branches/5.0: trx_rollback_for_mysql(): Fix the comment introduced in r1046. trx_commit_for_mysql(): Use the dummy trx->sess also for committing a prepared transaction in XA recovery, just in case our code would need the session object also in that case (does not seem to need it right now). sql/ha_innodb.cc: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1040: branches/5.0: Port r1039 from trunk: Port r1034 from branches/zip: Remove some instrumentation and reduce the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386) Revision r1099: branches/5.0: Merge revision 1098 from trunk: Fix bug #24712: SHOW TABLE STATUS for file-per-table showing incorrect time fields
Diffstat (limited to 'innobase')
-rw-r--r--innobase/dict/dict0dict.c29
-rw-r--r--innobase/include/sync0rw.h14
-rw-r--r--innobase/include/sync0sync.h32
-rw-r--r--innobase/include/sync0sync.ic4
-rw-r--r--innobase/log/log0recv.c10
-rw-r--r--innobase/srv/srv0start.c11
-rw-r--r--innobase/sync/sync0rw.c14
-rw-r--r--innobase/sync/sync0sync.c32
-rw-r--r--innobase/trx/trx0roll.c20
-rw-r--r--innobase/trx/trx0trx.c18
10 files changed, 122 insertions, 62 deletions
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index fffe851bc52..ba03e1f5e41 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -27,6 +27,9 @@ Created 1/8/1996 Heikki Tuuri
#include "que0que.h"
#include "rem0cmp.h"
+/* Implement isspace() in a locale-independent way. (Bug #24299) */
+#define ib_isspace(c) strchr(" \v\f\t\r\n", c)
+
dict_sys_t* dict_sys = NULL; /* the dictionary system */
rw_lock_t dict_operation_lock; /* table create, drop, etc. reserve
@@ -2406,7 +2409,7 @@ dict_accept(
*success = FALSE;
- while (isspace(*ptr)) {
+ while (ib_isspace(*ptr)) {
ptr++;
}
@@ -2451,7 +2454,7 @@ dict_scan_id(
*id = NULL;
- while (isspace(*ptr)) {
+ while (ib_isspace(*ptr)) {
ptr++;
}
@@ -2482,7 +2485,7 @@ dict_scan_id(
len++;
}
} else {
- while (!isspace(*ptr) && *ptr != '(' && *ptr != ')'
+ while (!ib_isspace(*ptr) && *ptr != '(' && *ptr != ')'
&& (accept_also_dot || *ptr != '.')
&& *ptr != ',' && *ptr != '\0') {
@@ -2512,12 +2515,12 @@ dict_scan_id(
if (heap && !quote) {
/* EMS MySQL Manager sometimes adds characters 0xA0 (in
latin1, a 'non-breakable space') to the end of a table name.
- But isspace(0xA0) is not true, which confuses our foreign key
- parser. After the UTF-8 conversion in ha_innodb.cc, bytes 0xC2
- and 0xA0 are at the end of the string.
+ After the UTF-8 conversion in ha_innodb.cc, bytes 0xC2
+ and 0xA0 are at the end of the string, and ib_isspace()
+ does not work for multi-byte UTF-8 characters.
- TODO: we should lex the string using thd->charset_info, and
- my_isspace(). Only after that, convert id names to UTF-8. */
+ In MySQL 5.1 we lex the string using thd->charset_info, and
+ my_isspace(). This workaround is not needed there. */
b = (byte*)(*id);
id_len = strlen((char*) b);
@@ -3006,11 +3009,11 @@ loop:
ut_a(success);
- if (!isspace(*ptr) && *ptr != '"' && *ptr != '`') {
+ if (!ib_isspace(*ptr) && *ptr != '"' && *ptr != '`') {
goto loop;
}
- while (isspace(*ptr)) {
+ while (ib_isspace(*ptr)) {
ptr++;
}
@@ -3052,7 +3055,7 @@ loop:
goto loop;
}
- if (!isspace(*ptr)) {
+ if (!ib_isspace(*ptr)) {
goto loop;
}
@@ -3140,7 +3143,7 @@ col_loop1:
}
ptr = dict_accept(ptr, "REFERENCES", &success);
- if (!success || !isspace(*ptr)) {
+ if (!success || !ib_isspace(*ptr)) {
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
@@ -3527,7 +3530,7 @@ loop:
ptr = dict_accept(ptr, "DROP", &success);
- if (!isspace(*ptr)) {
+ if (!ib_isspace(*ptr)) {
goto loop;
}
diff --git a/innobase/include/sync0rw.h b/innobase/include/sync0rw.h
index 741f9500612..4cd26ba1921 100644
--- a/innobase/include/sync0rw.h
+++ b/innobase/include/sync0rw.h
@@ -61,8 +61,12 @@ Creates, or rather, initializes an rw-lock object in a specified memory
location (which must be appropriately aligned). The rw-lock is initialized
to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
is necessary only if the memory block containing it is freed. */
-#define rw_lock_create(L) rw_lock_create_func((L), __FILE__, __LINE__, #L)
-
+#ifdef UNIV_DEBUG
+# define rw_lock_create(L) rw_lock_create_func((L), #L, __FILE__, __LINE__)
+#else /* UNIV_DEBUG */
+# define rw_lock_create(L) rw_lock_create_func((L), __FILE__, __LINE__)
+#endif /* UNIV_DEBUG */
+
/*=====================*/
/**********************************************************************
Creates, or rather, initializes an rw-lock object in a specified memory
@@ -74,9 +78,11 @@ void
rw_lock_create_func(
/*================*/
rw_lock_t* lock, /* in: pointer to memory */
+#ifdef UNIV_DEBUG
+ const char* cmutex_name, /* in: mutex name */
+#endif /* UNIV_DEBUG */
const char* cfile_name, /* in: file name where created */
- ulint cline, /* in: file line where created */
- const char* cmutex_name); /* in: mutex name */
+ ulint cline); /* in: file line where created */
/**********************************************************************
Calling this function is obligatory only if the memory buffer containing
the rw-lock is freed. Removes an rw-lock object from the global list. The
diff --git a/innobase/include/sync0sync.h b/innobase/include/sync0sync.h
index 9893921c5d2..769c2a98244 100644
--- a/innobase/include/sync0sync.h
+++ b/innobase/include/sync0sync.h
@@ -39,7 +39,11 @@ location (which must be appropriately aligned). The mutex is initialized
in the reset state. Explicit freeing of the mutex with mutex_free is
necessary only if the memory block containing it is freed. */
-#define mutex_create(M) mutex_create_func((M), __FILE__, __LINE__, #M)
+#ifdef UNIV_DEBUG
+# define mutex_create(M) mutex_create_func((M), #M, __FILE__, __LINE__)
+#else
+# define mutex_create(M) mutex_create_func((M), __FILE__, __LINE__)
+#endif
/*===================*/
/**********************************************************************
Creates, or rather, initializes a mutex object in a specified memory
@@ -51,9 +55,11 @@ void
mutex_create_func(
/*==============*/
mutex_t* mutex, /* in: pointer to memory */
+#ifdef UNIV_DEBUG
+ const char* cmutex_name, /* in: mutex name */
+#endif /* UNIV_DEBUG */
const char* cfile_name, /* in: file name where created */
- ulint cline, /* in: file line where created */
- const char* cmutex_name); /* in: mutex name */
+ ulint cline); /* in: file line where created */
/**********************************************************************
Calling this function is obligatory only if the memory buffer containing
the mutex is freed. Removes a mutex object from the mutex list. The mutex
@@ -479,15 +485,17 @@ struct mutex_struct {
ulint cline; /* Line where created */
ulint magic_n;
#ifndef UNIV_HOTBACKUP
- ulong count_using; /* count of times mutex used */
- ulong count_spin_loop; /* count of spin loops */
- ulong count_spin_rounds; /* count of spin rounds */
- ulong count_os_wait; /* count of os_wait */
- ulong count_os_yield; /* count of os_wait */
- ulonglong lspent_time; /* mutex os_wait timer msec */
- ulonglong lmax_spent_time; /* mutex os_wait timer msec */
- const char* cmutex_name;/* mutex name */
- ulint mutex_type;/* 0 - usual mutex 1 - rw_lock mutex */
+ ulong count_os_wait; /* count of os_wait */
+# ifdef UNIV_DEBUG
+ ulong count_using; /* count of times mutex used */
+ ulong count_spin_loop; /* count of spin loops */
+ ulong count_spin_rounds; /* count of spin rounds */
+ ulong count_os_yield; /* count of os_wait */
+ ulonglong lspent_time; /* mutex os_wait timer msec */
+ ulonglong lmax_spent_time; /* mutex os_wait timer msec */
+ const char* cmutex_name;/* mutex name */
+ ulint mutex_type;/* 0 - usual mutex 1 - rw_lock mutex */
+# endif /* UNIV_DEBUG */
#endif /* !UNIV_HOTBACKUP */
};
diff --git a/innobase/include/sync0sync.ic b/innobase/include/sync0sync.ic
index b3fde61db5e..a32a82d6e8b 100644
--- a/innobase/include/sync0sync.ic
+++ b/innobase/include/sync0sync.ic
@@ -250,9 +250,9 @@ mutex_enter_func(
/* Note that we do not peek at the value of lock_word before trying
the atomic test_and_set; we could peek, and possibly save time. */
-#ifndef UNIV_HOTBACKUP
+#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
mutex->count_using++;
-#endif /* UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
if (!mutex_test_and_set(mutex))
{
diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c
index 113d237b535..c1ceb9791f2 100644
--- a/innobase/log/log0recv.c
+++ b/innobase/log/log0recv.c
@@ -33,6 +33,7 @@ Created 9/20/1997 Heikki Tuuri
#include "btr0cur.h"
#include "dict0boot.h"
#include "fil0fil.h"
+#include "sync0sync.h"
#ifdef UNIV_HOTBACKUP
/* This is set to FALSE if the backup was originally taken with the
@@ -2969,6 +2970,15 @@ recv_recovery_from_checkpoint_finish(void)
#ifndef UNIV_LOG_DEBUG
recv_sys_free();
#endif
+
+#ifdef UNIV_SYNC_DEBUG
+ /* Wait for a while so that created threads have time to suspend
+ themselves before we switch the latching order checks on */
+ os_thread_sleep(1000000);
+
+ /* Switch latching order checks on in sync0sync.c */
+ sync_order_checks_on = TRUE;
+#endif
if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO) {
/* Rollback the uncommitted transactions which have no user
session */
diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c
index b41dcbe44cd..5f8707a661c 100644
--- a/innobase/srv/srv0start.c
+++ b/innobase/srv/srv0start.c
@@ -1554,17 +1554,6 @@ innobase_start_or_create_for_mysql(void)
srv_was_started = TRUE;
srv_is_being_started = FALSE;
-#ifdef UNIV_DEBUG
- /* Wait a while so that the created threads have time to suspend
- themselves before we switch sync debugging on; otherwise a thread may
- execute mutex_enter() before the checks are on, and mutex_exit() after
- the checks are on, which will cause an assertion failure in sync
- debug. */
-
- os_thread_sleep(3000000);
-#endif
- sync_order_checks_on = TRUE;
-
if (trx_doublewrite == NULL) {
/* Create the doublewrite buffer to a new tablespace */
diff --git a/innobase/sync/sync0rw.c b/innobase/sync/sync0rw.c
index 050de73db9e..629331d6049 100644
--- a/innobase/sync/sync0rw.c
+++ b/innobase/sync/sync0rw.c
@@ -89,9 +89,11 @@ void
rw_lock_create_func(
/*================*/
rw_lock_t* lock, /* in: pointer to memory */
+#ifdef UNIV_DEBUG
+ const char* cmutex_name, /* in: mutex name */
+#endif /* UNIV_DEBUG */
const char* cfile_name, /* in: file name where created */
- ulint cline, /* in: file line where created */
- const char* cmutex_name) /* in: mutex name */
+ ulint cline) /* in: file line where created */
{
/* If this is the very first time a synchronization
object is created, then the following call initializes
@@ -102,10 +104,10 @@ rw_lock_create_func(
lock->mutex.cfile_name = cfile_name;
lock->mutex.cline = cline;
-#ifndef UNIV_HOTBACKUP
- lock->mutex.cmutex_name = cmutex_name;
- lock->mutex.mutex_type = 1;
-#endif /* !UNIV_HOTBACKUP */
+#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
+ lock->mutex.cmutex_name = cmutex_name;
+ lock->mutex.mutex_type = 1;
+#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
rw_lock_set_waiters(lock, 0);
rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED);
diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c
index 95bf83dce79..25b7a5588d9 100644
--- a/innobase/sync/sync0sync.c
+++ b/innobase/sync/sync0sync.c
@@ -202,9 +202,11 @@ void
mutex_create_func(
/*==============*/
mutex_t* mutex, /* in: pointer to memory */
+#ifdef UNIV_DEBUG
+ const char* cmutex_name, /* in: mutex name */
+#endif /* UNIV_DEBUG */
const char* cfile_name, /* in: file name where created */
- ulint cline, /* in: file line where created */
- const char* cmutex_name) /* in: mutex name */
+ ulint cline) /* in: file line where created */
{
#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
mutex_reset_lock_word(mutex);
@@ -223,6 +225,8 @@ mutex_create_func(
mutex->cfile_name = cfile_name;
mutex->cline = cline;
#ifndef UNIV_HOTBACKUP
+ mutex->count_os_wait = 0;
+# ifdef UNIV_DEBUG
mutex->cmutex_name= cmutex_name;
mutex->count_using= 0;
mutex->mutex_type= 0;
@@ -230,8 +234,8 @@ mutex_create_func(
mutex->lmax_spent_time= 0;
mutex->count_spin_loop= 0;
mutex->count_spin_rounds= 0;
- mutex->count_os_wait= 0;
mutex->count_os_yield= 0;
+# endif /* UNIV_DEBUG */
#endif /* !UNIV_HOTBACKUP */
/* Check that lock_word is aligned; this is important on Intel */
@@ -378,13 +382,13 @@ mutex_spin_wait(
{
ulint index; /* index of the reserved wait cell */
ulint i; /* spin round count */
-#ifndef UNIV_HOTBACKUP
+#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
ib_longlong lstart_time = 0, lfinish_time; /* for timing os_wait */
ulint ltime_diff;
ulint sec;
ulint ms;
uint timer_started = 0;
-#endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
ut_ad(mutex);
mutex_loop:
@@ -398,10 +402,10 @@ mutex_loop:
memory word. */
spin_loop:
-#ifndef UNIV_HOTBACKUP
+#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
mutex_spin_wait_count++;
mutex->count_spin_loop++;
-#endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
while (mutex_get_lock_word(mutex) != 0 && i < SYNC_SPIN_ROUNDS)
{
@@ -415,7 +419,7 @@ spin_loop:
if (i == SYNC_SPIN_ROUNDS)
{
-#ifndef UNIV_HOTBACKUP
+#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
mutex->count_os_yield++;
if (timed_mutexes == 1 && timer_started==0)
{
@@ -423,7 +427,7 @@ spin_loop:
lstart_time= (ib_longlong)sec * 1000000 + ms;
timer_started = 1;
}
-#endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
os_thread_yield();
}
@@ -436,9 +440,9 @@ spin_loop:
mutex_spin_round_count += i;
-#ifndef UNIV_HOTBACKUP
+#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
mutex->count_spin_rounds += i;
-#endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
if (mutex_test_and_set(mutex) == 0)
{
@@ -522,6 +526,7 @@ Now there is no risk of infinite wait on the event. */
#ifndef UNIV_HOTBACKUP
mutex->count_os_wait++;
+# ifdef UNIV_DEBUG
/*
!!!!! Sometimes os_wait can be called without os_thread_yield
*/
@@ -532,13 +537,14 @@ Now there is no risk of infinite wait on the event. */
lstart_time= (ib_longlong)sec * 1000000 + ms;
timer_started = 1;
}
+# endif /* UNIV_DEBUG */
#endif /* !UNIV_HOTBACKUP */
sync_array_wait_event(sync_primary_wait_array, index);
goto mutex_loop;
finish_timing:
-#ifndef UNIV_HOTBACKUP
+#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
if (timed_mutexes == 1 && timer_started==1)
{
ut_usectime(&sec, &ms);
@@ -551,7 +557,7 @@ finish_timing:
mutex->lmax_spent_time= ltime_diff;
}
}
-#endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
return;
}
diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c
index fdfb7428129..bf8b9fd1939 100644
--- a/innobase/trx/trx0roll.c
+++ b/innobase/trx/trx0roll.c
@@ -129,9 +129,27 @@ trx_rollback_for_mysql(
}
trx->op_info = "rollback";
+
+ /* If we are doing the XA recovery of prepared transactions, then
+ the transaction object does not have an InnoDB session object, and we
+ set a dummy session that we use for all MySQL transactions. */
- err = trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ mutex_enter(&kernel_mutex);
+
+ if (trx->sess == NULL) {
+ /* Open a dummy session */
+
+ if (!trx_dummy_sess) {
+ trx_dummy_sess = sess_open();
+ }
+ trx->sess = trx_dummy_sess;
+ }
+
+ mutex_exit(&kernel_mutex);
+
+ err = trx_general_rollback_for_mysql(trx, FALSE, NULL);
+
trx->op_info = "";
return(err);
diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c
index 2637b28ef90..4dc826e5947 100644
--- a/innobase/trx/trx0trx.c
+++ b/innobase/trx/trx0trx.c
@@ -1601,7 +1601,25 @@ trx_commit_for_mysql(
ut_a(trx);
trx->op_info = "committing";
+
+ /* If we are doing the XA recovery of prepared transactions, then
+ the transaction object does not have an InnoDB session object, and we
+ set the dummy session that we use for all MySQL transactions. */
+
+ mutex_enter(&kernel_mutex);
+
+ if (trx->sess == NULL) {
+ /* Open a dummy session */
+
+ if (!trx_dummy_sess) {
+ trx_dummy_sess = sess_open();
+ }
+
+ trx->sess = trx_dummy_sess;
+ }
+ mutex_exit(&kernel_mutex);
+
trx_start_if_not_started(trx);
mutex_enter(&kernel_mutex);