mirror of
https://github.com/MariaDB/server.git
synced 2025-12-12 08:01:43 +03:00
branches/zip: Merge revisions 1009:1165 from trunk.
This commit is contained in:
@@ -794,16 +794,20 @@ dict_init(void)
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Returns a table object. NOTE! This is a high-level function to be used
|
||||
mainly from outside the 'dict' directory. Inside this directory
|
||||
dict_table_get_low is usually the appropriate function. */
|
||||
Returns a table object and optionally increment its MySQL open handle count.
|
||||
NOTE! This is a high-level function to be used mainly from outside the
|
||||
'dict' directory. Inside this directory dict_table_get_low is usually the
|
||||
appropriate function. */
|
||||
|
||||
dict_table_t*
|
||||
dict_table_get(
|
||||
/*===========*/
|
||||
/* out: table, NULL if
|
||||
does not exist */
|
||||
const char* table_name) /* in: table name */
|
||||
const char* table_name, /* in: table name */
|
||||
ibool inc_mysql_count)
|
||||
/* in: whether to increment the open
|
||||
handle count on the table */
|
||||
{
|
||||
dict_table_t* table;
|
||||
|
||||
@@ -811,42 +815,17 @@ dict_table_get(
|
||||
|
||||
table = dict_table_get_low(table_name);
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
|
||||
if (table != NULL) {
|
||||
if (!table->stat_initialized) {
|
||||
dict_update_statistics(table);
|
||||
}
|
||||
}
|
||||
|
||||
return(table);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Returns a table object and increments MySQL open handle count on the table. */
|
||||
|
||||
dict_table_t*
|
||||
dict_table_get_and_increment_handle_count(
|
||||
/*======================================*/
|
||||
/* out: table, NULL if
|
||||
does not exist */
|
||||
const char* table_name) /* in: table name */
|
||||
{
|
||||
dict_table_t* table;
|
||||
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
table = dict_table_get_low(table_name);
|
||||
|
||||
if (table != NULL) {
|
||||
|
||||
if (inc_mysql_count && table) {
|
||||
table->n_mysql_handles_opened++;
|
||||
}
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
|
||||
if (table != NULL) {
|
||||
if (!table->stat_initialized && !table->ibd_file_missing) {
|
||||
if (!table->stat_initialized) {
|
||||
/* If table->ibd_file_missing == TRUE, this will
|
||||
print an error message and return without doing
|
||||
anything. */
|
||||
dict_update_statistics(table);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,9 +40,6 @@ have disables the InnoDB inlining in this file. */
|
||||
#include <myisampack.h>
|
||||
#include <mysys_err.h>
|
||||
#include <my_sys.h>
|
||||
|
||||
#define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1))
|
||||
|
||||
#include "ha_innodb.h"
|
||||
|
||||
pthread_mutex_t innobase_share_mutex, /* to protect innobase_open_files */
|
||||
@@ -1257,18 +1254,6 @@ trx_is_interrupted(
|
||||
return(trx && trx->mysql_thd && ((THD*) trx->mysql_thd)->killed);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Obtain a pointer to the MySQL THD object, as in current_thd(). This
|
||||
definition must match the one in sql/ha_innodb.cc! */
|
||||
extern "C"
|
||||
void*
|
||||
innobase_current_thd(void)
|
||||
/*======================*/
|
||||
/* out: MySQL THD object */
|
||||
{
|
||||
return(current_thd);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
Call this when you have opened a new table handle in HANDLER, before you
|
||||
call index_read_idx() etc. Actually, we can let the cursor stay open even
|
||||
@@ -2328,7 +2313,7 @@ ha_innobase::open(
|
||||
|
||||
/* Get pointer to a table object in InnoDB dictionary cache */
|
||||
|
||||
ib_table = dict_table_get_and_increment_handle_count(norm_name);
|
||||
ib_table = dict_table_get(norm_name, TRUE);
|
||||
|
||||
if (NULL == ib_table) {
|
||||
ut_print_timestamp(stderr);
|
||||
@@ -2490,7 +2475,7 @@ get_field_offset(
|
||||
/******************************************************************
|
||||
Checks if a field in a record is SQL NULL. Uses the record format
|
||||
information in table to track the null bit in record. */
|
||||
inline
|
||||
static inline
|
||||
uint
|
||||
field_in_record_is_null(
|
||||
/*====================*/
|
||||
@@ -4915,7 +4900,7 @@ ha_innobase::create(
|
||||
|
||||
log_buffer_flush_to_disk();
|
||||
|
||||
innobase_table = dict_table_get(norm_name);
|
||||
innobase_table = dict_table_get(norm_name, FALSE);
|
||||
|
||||
DBUG_ASSERT(innobase_table != 0);
|
||||
|
||||
@@ -5526,16 +5511,10 @@ ha_innobase::info(
|
||||
prebuilt->trx->op_info = (char*)
|
||||
"returning various info to MySQL";
|
||||
|
||||
if (ib_table->space != 0) {
|
||||
my_snprintf(path, sizeof(path), "%s/%s%s",
|
||||
mysql_data_home, ib_table->name, ".ibd");
|
||||
unpack_filename(path,path);
|
||||
} else {
|
||||
my_snprintf(path, sizeof(path), "%s/%s%s",
|
||||
my_snprintf(path, sizeof(path), "%s/%s%s",
|
||||
mysql_data_home, ib_table->name, reg_ext);
|
||||
|
||||
unpack_filename(path,path);
|
||||
}
|
||||
unpack_filename(path,path);
|
||||
|
||||
/* Note that we do not know the access time of the table,
|
||||
nor the CHECK TABLE time, nor the UPDATE or INSERT time. */
|
||||
@@ -7344,7 +7323,6 @@ innobase_get_at_most_n_mbchars(
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
/**********************************************************************
|
||||
This function returns true if
|
||||
|
||||
@@ -7354,33 +7332,34 @@ is either REPLACE or LOAD DATA INFILE REPLACE.
|
||||
2) SQL-query in the current thread
|
||||
is INSERT ON DUPLICATE KEY UPDATE.
|
||||
|
||||
NOTE that /mysql/innobase/row/row0ins.c must contain the
|
||||
NOTE that storage/innobase/row/row0ins.c must contain the
|
||||
prototype for this function ! */
|
||||
|
||||
extern "C"
|
||||
ibool
|
||||
innobase_query_is_update(void)
|
||||
/*==========================*/
|
||||
{
|
||||
THD* thd;
|
||||
THD* thd = current_thd;
|
||||
|
||||
thd = (THD *)innobase_current_thd();
|
||||
if (!thd) {
|
||||
/* InnoDB's internal threads may run InnoDB stored procedures
|
||||
that call this function. Then current_thd is not defined
|
||||
(it is probably NULL). */
|
||||
|
||||
if (thd->lex->sql_command == SQLCOM_REPLACE ||
|
||||
thd->lex->sql_command == SQLCOM_REPLACE_SELECT ||
|
||||
(thd->lex->sql_command == SQLCOM_LOAD &&
|
||||
thd->lex->duplicates == DUP_REPLACE)) {
|
||||
|
||||
return(1);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if (thd->lex->sql_command == SQLCOM_INSERT &&
|
||||
thd->lex->duplicates == DUP_UPDATE) {
|
||||
|
||||
return(1);
|
||||
switch (thd->lex->sql_command) {
|
||||
case SQLCOM_REPLACE:
|
||||
case SQLCOM_REPLACE_SELECT:
|
||||
return(TRUE);
|
||||
case SQLCOM_LOAD:
|
||||
return(thd->lex->duplicates == DUP_REPLACE);
|
||||
case SQLCOM_INSERT:
|
||||
return(thd->lex->duplicates == DUP_UPDATE);
|
||||
default:
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
@@ -183,7 +183,7 @@ struct btr_search_struct{
|
||||
number of full fields */
|
||||
ulint n_bytes; /* recommended prefix: number of bytes in
|
||||
an incomplete field;
|
||||
cf. BTR_PAGE_MAX_REC_SIZE */
|
||||
see also BTR_PAGE_MAX_REC_SIZE */
|
||||
ibool left_side; /* TRUE or FALSE, depending on whether
|
||||
the leftmost record of several records with
|
||||
the same prefix should be indexed in the
|
||||
|
||||
@@ -65,8 +65,8 @@ dtype_get_mblen(
|
||||
innobase_get_cset_width(dtype_get_charset_coll(prtype),
|
||||
mbminlen, mbmaxlen);
|
||||
ut_ad(*mbminlen <= *mbmaxlen);
|
||||
ut_ad(*mbminlen <= 2); /* cf. the bit-field in dtype_t */
|
||||
ut_ad(*mbmaxlen < 1 << 3); /* cf. the bit-field in dtype_t */
|
||||
ut_ad(*mbminlen <= 2); /* mbminlen in dtype_t is 0..3 */
|
||||
ut_ad(*mbmaxlen < 1 << 3); /* mbmaxlen in dtype_t is 0..7 */
|
||||
#else /* !UNIV_HOTBACKUP */
|
||||
ut_a(mtype <= DATA_BINARY);
|
||||
*mbminlen = *mbmaxlen = 1;
|
||||
|
||||
@@ -333,26 +333,20 @@ dict_foreign_parse_drop_constraints(
|
||||
const char*** constraints_to_drop); /* out: id's of the
|
||||
constraints to drop */
|
||||
/**************************************************************************
|
||||
Returns a table object. NOTE! This is a high-level function to be used
|
||||
mainly from outside the 'dict' directory. Inside this directory
|
||||
dict_table_get_low is usually the appropriate function. */
|
||||
Returns a table object and optionally increment its MySQL open handle count.
|
||||
NOTE! This is a high-level function to be used mainly from outside the
|
||||
'dict' directory. Inside this directory dict_table_get_low is usually the
|
||||
appropriate function. */
|
||||
|
||||
dict_table_t*
|
||||
dict_table_get(
|
||||
/*===========*/
|
||||
/* out: table, NULL if
|
||||
does not exist */
|
||||
const char* table_name); /* in: table name */
|
||||
/**************************************************************************
|
||||
Returns a table object and increments MySQL open handle count on the table.
|
||||
*/
|
||||
|
||||
dict_table_t*
|
||||
dict_table_get_and_increment_handle_count(
|
||||
/*======================================*/
|
||||
/* out: table, NULL if
|
||||
does not exist */
|
||||
const char* table_name); /* in: table name */
|
||||
const char* table_name, /* in: table name */
|
||||
ibool inc_mysql_count);
|
||||
/* in: whether to increment the open
|
||||
handle count on the table */
|
||||
/**************************************************************************
|
||||
Returns a table object based on table id. */
|
||||
|
||||
|
||||
@@ -516,12 +516,6 @@ to 20 microseconds. */
|
||||
|
||||
#define SYNC_SPIN_ROUNDS srv_n_spin_wait_rounds
|
||||
|
||||
#define SYNC_INFINITE_TIME ((ulint)(-1))
|
||||
|
||||
/* Means that a timeout elapsed when waiting */
|
||||
|
||||
#define SYNC_TIME_EXCEEDED (ulint)1
|
||||
|
||||
/* The number of system calls made in this module. Intended for performance
|
||||
monitoring. */
|
||||
|
||||
|
||||
@@ -77,25 +77,37 @@ memory is read outside the allocated blocks. */
|
||||
/* Make a non-inline debug version */
|
||||
|
||||
#if 0
|
||||
#define UNIV_DEBUG_VALGRIND
|
||||
#define UNIV_DEBUG_PRINT
|
||||
#define UNIV_BUF_DEBUG
|
||||
#define UNIV_DEBUG
|
||||
#define UNIV_DEBUG_FILE_ACCESSES
|
||||
#define UNIV_LIST_DEBUG
|
||||
#define UNIV_MEM_DEBUG
|
||||
#define UNIV_IBUF_DEBUG
|
||||
#define UNIV_SYNC_DEBUG
|
||||
#define UNIV_SEARCH_DEBUG
|
||||
#define UNIV_SYNC_PERF_STAT
|
||||
#define UNIV_SEARCH_PERF_STAT
|
||||
#define UNIV_SRV_PRINT_LATCH_WAITS
|
||||
#define UNIV_BTR_PRINT
|
||||
#define UNIV_DEBUG_VALGRIND /* Enable extra
|
||||
Valgrind instrumentation */
|
||||
#define UNIV_DEBUG_PRINT /* Enable the compilation of
|
||||
some debug print functions */
|
||||
#define UNIV_BUF_DEBUG /* Enable buffer pool
|
||||
debugging without UNIV_DEBUG */
|
||||
#define UNIV_DEBUG /* Enable ut_ad() assertions */
|
||||
#define UNIV_DEBUG_FILE_ACCESSES /* Debug .ibd file access
|
||||
(field file_page_was_freed
|
||||
in buf_page_t) */
|
||||
#define UNIV_LIST_DEBUG /* debug UT_LIST_ macros */
|
||||
#define UNIV_MEM_DEBUG /* detect memory leaks etc */
|
||||
#define UNIV_IBUF_DEBUG /* debug the insert buffer;
|
||||
this limits the database to IBUF_COUNT_N_SPACES and IBUF_COUNT_N_PAGES,
|
||||
and the insert buffer must be empty when the database is started */
|
||||
#define UNIV_SYNC_DEBUG /* debug mutex and latch
|
||||
operations (very slow); also UNIV_DEBUG must be defined */
|
||||
#define UNIV_SEARCH_DEBUG /* debug B-tree comparisons */
|
||||
#define UNIV_SYNC_PERF_STAT /* operation counts for
|
||||
rw-locks and mutexes */
|
||||
#define UNIV_SEARCH_PERF_STAT /* statistics for the
|
||||
adaptive hash index */
|
||||
#define UNIV_SRV_PRINT_LATCH_WAITS /* enable diagnostic output
|
||||
in sync0sync.c */
|
||||
#define UNIV_BTR_PRINT /* enable functions for
|
||||
printing B-trees */
|
||||
#define UNIV_ZIP_DEBUG
|
||||
#endif
|
||||
|
||||
#define UNIV_BTR_DEBUG
|
||||
#define UNIV_LIGHT_MEM_DEBUG
|
||||
#define UNIV_BTR_DEBUG /* check B-tree links */
|
||||
#define UNIV_LIGHT_MEM_DEBUG /* light memory debugging */
|
||||
|
||||
#ifdef HAVE_purify
|
||||
/* The following sets all new allocated memory to zero before use:
|
||||
|
||||
@@ -127,7 +127,8 @@ ulint
|
||||
ut_2_power_up(
|
||||
/*==========*/
|
||||
/* out: first power of 2 which is >= n */
|
||||
ulint n); /* in: number != 0 */
|
||||
ulint n) /* in: number != 0 */
|
||||
__attribute__((const));
|
||||
/****************************************************************
|
||||
Sort function for ulint arrays. */
|
||||
|
||||
|
||||
@@ -34,6 +34,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
|
||||
@@ -191,6 +192,7 @@ recv_sys_empty_hash(void)
|
||||
recv_sys->addr_hash = hash_create(buf_pool_get_curr_size() / 256);
|
||||
}
|
||||
|
||||
#ifndef UNIV_LOG_DEBUG
|
||||
/************************************************************
|
||||
Frees the recovery system. */
|
||||
static
|
||||
@@ -210,6 +212,7 @@ recv_sys_free(void)
|
||||
|
||||
mutex_exit(&(recv_sys->mutex));
|
||||
}
|
||||
#endif /* UNIV_LOG_DEBUG */
|
||||
|
||||
/************************************************************
|
||||
Truncates possible corrupted or extra records from a log group. */
|
||||
@@ -2887,6 +2890,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 */
|
||||
|
||||
@@ -335,6 +335,8 @@ que_fork_start_command(
|
||||
que_fork_t* fork) /* in: a query fork */
|
||||
{
|
||||
que_thr_t* thr;
|
||||
que_thr_t* suspended_thr = NULL;
|
||||
que_thr_t* completed_thr = NULL;
|
||||
|
||||
fork->state = QUE_FORK_ACTIVE;
|
||||
|
||||
@@ -344,14 +346,18 @@ que_fork_start_command(
|
||||
but in a parallelized select, which necessarily is non-scrollable,
|
||||
there may be several to choose from */
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
First we try to find a query thread in the QUE_THR_COMMAND_WAIT state
|
||||
*/
|
||||
/* First we try to find a query thread in the QUE_THR_COMMAND_WAIT
|
||||
state. Then we try to find a query thread in the QUE_THR_SUSPENDED
|
||||
state, finally we try to find a query thread in the QUE_THR_COMPLETED
|
||||
state */
|
||||
|
||||
thr = UT_LIST_GET_FIRST(fork->thrs);
|
||||
|
||||
while (thr != NULL) {
|
||||
if (thr->state == QUE_THR_COMMAND_WAIT) {
|
||||
/* We make a single pass over the thr list within which we note which
|
||||
threads are ready to run. */
|
||||
while (thr) {
|
||||
switch (thr->state) {
|
||||
case QUE_THR_COMMAND_WAIT:
|
||||
|
||||
/* We have to send the initial message to query thread
|
||||
to start it */
|
||||
@@ -359,49 +365,44 @@ que_fork_start_command(
|
||||
que_thr_init_command(thr);
|
||||
|
||||
return(thr);
|
||||
}
|
||||
|
||||
ut_ad(thr->state != QUE_THR_LOCK_WAIT);
|
||||
|
||||
thr = UT_LIST_GET_NEXT(thrs, thr);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
Then we try to find a query thread in the QUE_THR_SUSPENDED state */
|
||||
|
||||
thr = UT_LIST_GET_FIRST(fork->thrs);
|
||||
|
||||
while (thr != NULL) {
|
||||
if (thr->state == QUE_THR_SUSPENDED) {
|
||||
case QUE_THR_SUSPENDED:
|
||||
/* In this case the execution of the thread was
|
||||
suspended: no initial message is needed because
|
||||
execution can continue from where it was left */
|
||||
if (!suspended_thr) {
|
||||
suspended_thr = thr;
|
||||
}
|
||||
|
||||
que_thr_move_to_run_state(thr);
|
||||
break;
|
||||
|
||||
case QUE_THR_COMPLETED:
|
||||
if (!completed_thr) {
|
||||
completed_thr = thr;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case QUE_THR_LOCK_WAIT:
|
||||
ut_error;
|
||||
|
||||
return(thr);
|
||||
}
|
||||
|
||||
thr = UT_LIST_GET_NEXT(thrs, thr);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
Then we try to find a query thread in the QUE_THR_COMPLETED state */
|
||||
if (suspended_thr) {
|
||||
|
||||
thr = UT_LIST_GET_FIRST(fork->thrs);
|
||||
thr = suspended_thr;
|
||||
que_thr_move_to_run_state(thr);
|
||||
|
||||
while (thr != NULL) {
|
||||
if (thr->state == QUE_THR_COMPLETED) {
|
||||
que_thr_init_command(thr);
|
||||
} else if (completed_thr) {
|
||||
|
||||
return(thr);
|
||||
}
|
||||
|
||||
thr = UT_LIST_GET_NEXT(thrs, thr);
|
||||
thr = completed_thr;
|
||||
que_thr_init_command(thr);
|
||||
}
|
||||
|
||||
/* Else we return NULL */
|
||||
return(NULL);
|
||||
return(thr);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
||||
@@ -1535,7 +1535,8 @@ row_ins_check_foreign_constraints(
|
||||
if (foreign->foreign_index == index) {
|
||||
|
||||
if (foreign->referenced_table == NULL) {
|
||||
dict_table_get(foreign->referenced_table_name);
|
||||
dict_table_get(foreign->referenced_table_name,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
if (0 == trx->dict_operation_lock_mode) {
|
||||
|
||||
@@ -4506,7 +4506,7 @@ row_search_check_if_query_cache_permitted(
|
||||
dict_table_t* table;
|
||||
ibool ret = FALSE;
|
||||
|
||||
table = dict_table_get(norm_name);
|
||||
table = dict_table_get(norm_name, FALSE);
|
||||
|
||||
if (table == NULL) {
|
||||
|
||||
|
||||
@@ -203,7 +203,8 @@ row_upd_check_references_constraints(
|
||||
foreign->n_fields))) {
|
||||
|
||||
if (foreign->foreign_table == NULL) {
|
||||
dict_table_get(foreign->foreign_table_name);
|
||||
dict_table_get(foreign->foreign_table_name,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
if (foreign->foreign_table) {
|
||||
|
||||
@@ -1558,17 +1558,6 @@ innobase_start_or_create_for_mysql(void)
|
||||
srv_was_started = TRUE;
|
||||
srv_is_being_started = FALSE;
|
||||
|
||||
#ifdef UNIV_SYNC_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);
|
||||
sync_order_checks_on = TRUE;
|
||||
#endif
|
||||
|
||||
if (trx_doublewrite == NULL) {
|
||||
/* Create the doublewrite buffer to a new tablespace */
|
||||
|
||||
|
||||
@@ -131,6 +131,24 @@ 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. */
|
||||
|
||||
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 = "";
|
||||
|
||||
@@ -1595,6 +1595,24 @@ trx_commit_for_mysql(
|
||||
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user