This commit is contained in:
Sergei Golubchik 2015-05-04 22:13:46 +02:00
parent 6d06fbbd1d
commit 085297a121
19 changed files with 438 additions and 491 deletions

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 2008, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2015, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -318,35 +318,6 @@ ib_wake_master_thread(void)
}
}
/*********************************************************************//**
Calculate the max row size of the columns in a cluster index.
@return max row length */
UNIV_INLINE
ulint
ib_get_max_row_len(
/*===============*/
dict_index_t* cluster) /*!< in: cluster index */
{
ulint i;
ulint max_len = 0;
ulint n_fields = cluster->n_fields;
/* Add the size of the ordering columns in the
clustered index. */
for (i = 0; i < n_fields; ++i) {
const dict_col_t* col;
col = dict_index_get_nth_col(cluster, i);
/* Use the maximum output size of
mach_write_compressed(), although the encoded
length should always fit in 2 bytes. */
max_len += dict_col_get_max_size(col);
}
return(max_len);
}
/*****************************************************************//**
Read the columns from a rec into a tuple. */
static
@ -710,120 +681,6 @@ ib_trx_rollback(
return(err);
}
/*****************************************************************//**
Find an index definition from the index vector using index name.
@return index def. if found else NULL */
UNIV_INLINE
const ib_index_def_t*
ib_table_find_index(
/*================*/
ib_vector_t* indexes, /*!< in: vector of indexes */
const char* name) /*!< in: index name */
{
ulint i;
for (i = 0; i < ib_vector_size(indexes); ++i) {
const ib_index_def_t* index_def;
index_def = (ib_index_def_t*) ib_vector_get(indexes, i);
if (innobase_strcasecmp(name, index_def->name) == 0) {
return(index_def);
}
}
return(NULL);
}
/*****************************************************************//**
Get the InnoDB internal precise type from the schema column definition.
@return precise type in api format */
UNIV_INLINE
ulint
ib_col_get_prtype(
/*==============*/
const ib_col_t* ib_col) /*!< in: column definition */
{
ulint prtype = 0;
if (ib_col->ib_col_attr & IB_COL_UNSIGNED) {
prtype |= DATA_UNSIGNED;
ut_a(ib_col->ib_col_type == IB_INT);
}
if (ib_col->ib_col_attr & IB_COL_NOT_NULL) {
prtype |= DATA_NOT_NULL;
}
return(prtype);
}
/*****************************************************************//**
Get the InnoDB internal main type from the schema column definition.
@return column main type */
UNIV_INLINE
ulint
ib_col_get_mtype(
/*==============*/
const ib_col_t* ib_col) /*!< in: column definition */
{
/* Note: The api0api.h types should map directly to
the internal numeric codes. */
return(ib_col->ib_col_type);
}
/*****************************************************************//**
Find a column in the the column vector with the same name.
@return col. def. if found else NULL */
UNIV_INLINE
const ib_col_t*
ib_table_find_col(
/*==============*/
const ib_vector_t* cols, /*!< in: column list head */
const char* name) /*!< in: column name to find */
{
ulint i;
for (i = 0; i < ib_vector_size(cols); ++i) {
const ib_col_t* ib_col;
ib_col = static_cast<const ib_col_t*>(
ib_vector_get((ib_vector_t*) cols, i));
if (innobase_strcasecmp(ib_col->name, name) == 0) {
return(ib_col);
}
}
return(NULL);
}
/*****************************************************************//**
Find a column in the the column list with the same name.
@return col. def. if found else NULL */
UNIV_INLINE
const ib_key_col_t*
ib_index_find_col(
/*==============*/
ib_vector_t* cols, /*!< in: column list head */
const char* name) /*!< in: column name to find */
{
ulint i;
for (i = 0; i < ib_vector_size(cols); ++i) {
const ib_key_col_t* ib_col;
ib_col = static_cast<ib_key_col_t*>(ib_vector_get(cols, i));
if (innobase_strcasecmp(ib_col->name, name) == 0) {
return(ib_col);
}
}
return(NULL);
}
#ifdef __WIN__
/*****************************************************************//**
Convert a string to lower case. */
@ -946,34 +803,6 @@ ib_table_name_check(
/*****************************************************************//**
Get an index definition that is tagged as a clustered index.
@return cluster index schema */
UNIV_INLINE
ib_index_def_t*
ib_find_clustered_index(
/*====================*/
ib_vector_t* indexes) /*!< in: index defs. to search */
{
ulint i;
ulint n_indexes;
n_indexes = ib_vector_size(indexes);
for (i = 0; i < n_indexes; ++i) {
ib_index_def_t* ib_index_def;
ib_index_def = static_cast<ib_index_def_t*>(
ib_vector_get(indexes, i));
if (ib_index_def->clustered) {
return(ib_index_def);
}
}
return(NULL);
}
/*****************************************************************//**
Get a table id. The caller must have acquired the dictionary mutex.
@return DB_SUCCESS if found */
@ -3552,41 +3381,6 @@ ib_cursor_set_cluster_access(
prebuilt->need_to_access_clustered = TRUE;
}
/*************************************************************//**
Convert and write an INT column value to an InnoDB tuple.
@return DB_SUCCESS or error */
UNIV_INLINE
ib_err_t
ib_tuple_write_int(
/*===============*/
ib_tpl_t ib_tpl, /*!< in/out: tuple to write to */
ulint col_no, /*!< in: column number */
const void* value, /*!< in: integer value */
ulint value_len) /*!< in: sizeof value type */
{
const dfield_t* dfield;
ulint data_len;
ulint type_len;
ib_tuple_t* tuple = (ib_tuple_t*) ib_tpl;
ut_a(col_no < ib_tuple_get_n_cols(ib_tpl));
dfield = ib_col_get_dfield(tuple, col_no);
data_len = dfield_get_len(dfield);
type_len = dtype_get_len(dfield_get_type(dfield));
if (dtype_get_mtype(dfield_get_type(dfield)) != DATA_INT
|| value_len != data_len) {
return(DB_DATA_MISMATCH);
}
return(ib_col_set_value(
ib_tpl, static_cast<ib_ulint_t>(col_no),
value, static_cast<ib_ulint_t>(type_len), true));
}
/*****************************************************************//**
Write an integer value to a column. Integers are stored in big-endian
format and will need to be converted from the host format.

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
This program is free software; you can redistribute it and/or modify it under
@ -644,6 +644,33 @@ dict_table_get_col_name(
}
#ifndef UNIV_HOTBACKUP
/** Allocate and init the autoinc latch of a given table.
This function must not be called concurrently on the same table object.
@param[in,out] table_void table whose autoinc latch to create */
void
dict_table_autoinc_alloc(
void* table_void)
{
dict_table_t* table = static_cast<dict_table_t*>(table_void);
table->autoinc_mutex = new (std::nothrow) ib_mutex_t();
ut_a(table->autoinc_mutex != NULL);
mutex_create(autoinc_mutex_key,
table->autoinc_mutex, SYNC_DICT_AUTOINC_MUTEX);
}
/** Allocate and init the zip_pad_mutex of a given index.
This function must not be called concurrently on the same index object.
@param[in,out] index_void index whose zip_pad_mutex to create */
void
dict_index_zip_pad_alloc(
void* index_void)
{
dict_index_t* index = static_cast<dict_index_t*>(index_void);
index->zip_pad.mutex = new (std::nothrow) os_fast_mutex_t;
ut_a(index->zip_pad.mutex != NULL);
os_fast_mutex_init(zip_pad_mutex_key, index->zip_pad.mutex);
}
/********************************************************************//**
Acquire the autoinc lock. */
UNIV_INTERN
@ -652,7 +679,32 @@ dict_table_autoinc_lock(
/*====================*/
dict_table_t* table) /*!< in/out: table */
{
mutex_enter(&table->autoinc_mutex);
#ifdef HAVE_ATOMIC_BUILTINS
os_once::do_or_wait_for_done(
&table->autoinc_mutex_created,
dict_table_autoinc_alloc, table);
#else /* HAVE_ATOMIC_BUILTINS */
ut_ad(table->autoinc_mutex_created == os_once::DONE);
#endif /* HAVE_ATOMIC_BUILTINS */
mutex_enter(table->autoinc_mutex);
}
/** Acquire the zip_pad_mutex latch.
@param[in,out] index the index whose zip_pad_mutex to acquire.*/
void
dict_index_zip_pad_lock(
dict_index_t* index)
{
#ifdef HAVE_ATOMIC_BUILTINS
os_once::do_or_wait_for_done(
&index->zip_pad.mutex_created,
dict_index_zip_pad_alloc, index);
#else /* HAVE_ATOMIC_BUILTINS */
ut_ad(index->zip_pad.mutex_created == os_once::DONE);
#endif /* HAVE_ATOMIC_BUILTINS */
os_fast_mutex_lock(index->zip_pad.mutex);
}
/********************************************************************//**
@ -664,7 +716,7 @@ dict_table_autoinc_initialize(
dict_table_t* table, /*!< in/out: table */
ib_uint64_t value) /*!< in: next value to assign to a row */
{
ut_ad(mutex_own(&table->autoinc_mutex));
ut_ad(dict_table_autoinc_own(table));
table->autoinc = value;
}
@ -706,7 +758,7 @@ dict_table_autoinc_read(
/*====================*/
const dict_table_t* table) /*!< in: table */
{
ut_ad(mutex_own(&table->autoinc_mutex));
ut_ad(dict_table_autoinc_own(table));
return(table->autoinc);
}
@ -722,7 +774,7 @@ dict_table_autoinc_update_if_greater(
dict_table_t* table, /*!< in/out: table */
ib_uint64_t value) /*!< in: value which was assigned to a row */
{
ut_ad(mutex_own(&table->autoinc_mutex));
ut_ad(dict_table_autoinc_own(table));
if (value > table->autoinc) {
@ -738,7 +790,7 @@ dict_table_autoinc_unlock(
/*======================*/
dict_table_t* table) /*!< in/out: table */
{
mutex_exit(&table->autoinc_mutex);
mutex_exit(table->autoinc_mutex);
}
#endif /* !UNIV_HOTBACKUP */
@ -1578,15 +1630,18 @@ dict_table_rename_in_cache(
} else if (table->space != TRX_SYS_SPACE) {
char* new_path = NULL;
if (table->dir_path_of_temp_table != NULL) {
if (DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY)) {
ut_print_timestamp(stderr);
fputs(" InnoDB: Error: trying to rename a"
" TEMPORARY TABLE ", stderr);
ut_print_name(stderr, NULL, TRUE, old_name);
fputs(" (", stderr);
ut_print_filename(stderr,
table->dir_path_of_temp_table);
fputs(" )\n", stderr);
if (table->dir_path_of_temp_table != NULL) {
fputs(" (", stderr);
ut_print_filename(
stderr, table->dir_path_of_temp_table);
fputs(" )\n", stderr);
}
return(DB_ERROR);
} else if (DICT_TF_HAS_DATA_DIR(table->flags)) {
@ -6608,10 +6663,10 @@ dict_index_zip_success(
return;
}
os_fast_mutex_lock(&index->zip_pad.mutex);
dict_index_zip_pad_lock(index);
++index->zip_pad.success;
dict_index_zip_pad_update(&index->zip_pad, zip_threshold);
os_fast_mutex_unlock(&index->zip_pad.mutex);
dict_index_zip_pad_unlock(index);
}
/*********************************************************************//**
@ -6631,10 +6686,10 @@ dict_index_zip_failure(
return;
}
os_fast_mutex_lock(&index->zip_pad.mutex);
dict_index_zip_pad_lock(index);
++index->zip_pad.failure;
dict_index_zip_pad_update(&index->zip_pad, zip_threshold);
os_fast_mutex_unlock(&index->zip_pad.mutex);
dict_index_zip_pad_unlock(index);
}
@ -6666,9 +6721,9 @@ dict_index_zip_pad_optimal_page_size(
#ifdef HAVE_ATOMIC_BUILTINS
pad = os_atomic_increment_ulint(&index->zip_pad.pad, 0);
#else /* HAVE_ATOMIC_BUILTINS */
os_fast_mutex_lock(&index->zip_pad.mutex);
dict_index_zip_pad_lock(index);
pad = index->zip_pad.pad;
os_fast_mutex_unlock(&index->zip_pad.mutex);
dict_index_zip_pad_unlock(index);
#endif /* HAVE_ATOMIC_BUILTINS */
ut_ad(pad < UNIV_PAGE_SIZE);

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
This program is free software; you can redistribute it and/or modify it under
@ -109,8 +109,7 @@ dict_mem_table_create(
table->autoinc_lock = static_cast<ib_lock_t*>(
mem_heap_alloc(heap, lock_get_size()));
mutex_create(autoinc_mutex_key,
&table->autoinc_mutex, SYNC_DICT_AUTOINC_MUTEX);
dict_table_autoinc_create_lazy(table);
table->autoinc = 0;
@ -160,7 +159,7 @@ dict_mem_table_free(
}
}
#ifndef UNIV_HOTBACKUP
mutex_free(&(table->autoinc_mutex));
dict_table_autoinc_destroy(table);
#endif /* UNIV_HOTBACKUP */
dict_table_stats_latch_destroy(table);
@ -525,8 +524,7 @@ dict_mem_index_create(
dict_mem_fill_index_struct(index, heap, table_name, index_name,
space, type, n_fields);
os_fast_mutex_init(zip_pad_mutex_key, &index->zip_pad.mutex);
dict_index_zip_pad_mutex_create_lazy(index);
return(index);
}
@ -659,7 +657,7 @@ dict_mem_index_free(
}
#endif /* UNIV_BLOB_DEBUG */
os_fast_mutex_free(&index->zip_pad.mutex);
dict_index_zip_pad_mutex_destroy(index);
mem_heap_free(index->heap);
}

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -300,44 +300,6 @@ xdes_find_bit(
return(ULINT_UNDEFINED);
}
/**********************************************************************//**
Looks for a descriptor bit having the desired value. Scans the extent in
a direction opposite to xdes_find_bit.
@return bit index of the bit, ULINT_UNDEFINED if not found */
UNIV_INLINE
ulint
xdes_find_bit_downward(
/*===================*/
xdes_t* descr, /*!< in: descriptor */
ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */
ibool val, /*!< in: desired bit value */
ulint hint, /*!< in: hint of which bit position would
be desirable */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
ulint i;
ut_ad(descr && mtr);
ut_ad(val <= TRUE);
ut_ad(hint < FSP_EXTENT_SIZE);
ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX));
for (i = hint + 1; i > 0; i--) {
if (val == xdes_mtr_get_bit(descr, bit, i - 1, mtr)) {
return(i - 1);
}
}
for (i = FSP_EXTENT_SIZE - 1; i > hint; i--) {
if (val == xdes_mtr_get_bit(descr, bit, i, mtr)) {
return(i);
}
}
return(ULINT_UNDEFINED);
}
/**********************************************************************//**
Returns the number of used pages in a descriptor.
@return number of pages used */

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 2011, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2011, 2015, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -81,11 +81,13 @@ ulint n_nodes = 0;
/** Error condition reported by fts_utf8_decode() */
const ulint UTF8_ERROR = 0xFFFFFFFF;
#ifdef FTS_CACHE_SIZE_DEBUG
/** The cache size permissible lower limit (1K) */
static const ulint FTS_CACHE_SIZE_LOWER_LIMIT_IN_MB = 1;
/** The cache size permissible upper limit (1G) */
static const ulint FTS_CACHE_SIZE_UPPER_LIMIT_IN_MB = 1024;
#endif /* FTS_CACHE_SIZE_DEBUG */
/** Time to sleep after DEADLOCK error before retrying operation. */
static const ulint FTS_DEADLOCK_RETRY_WAIT = 100000;
@ -191,7 +193,7 @@ static const char* fts_create_common_tables_sql = {
""
"CREATE TABLE \"%s_CONFIG\" (\n"
" key CHAR(50),\n"
" value CHAR(50) NOT NULL\n"
" value CHAR(200) NOT NULL\n"
") COMPACT;\n"
"CREATE UNIQUE CLUSTERED INDEX IND ON \"%s_CONFIG\"(key);\n"
};
@ -329,27 +331,6 @@ fts_update_sync_doc_id(
doc_id_t doc_id, /*!< in: last document id */
trx_t* trx) /*!< in: update trx, or NULL */
__attribute__((nonnull(1)));
/********************************************************************
Check if we should stop. */
UNIV_INLINE
ibool
fts_is_stop_signalled(
/*==================*/
fts_t* fts) /*!< in: fts instance */
{
ibool stop_signalled = FALSE;
mutex_enter(&fts->bg_threads_mutex);
if (fts->fts_status & BG_THREAD_STOP) {
stop_signalled = TRUE;
}
mutex_exit(&fts->bg_threads_mutex);
return(stop_signalled);
}
/****************************************************************//**
This function loads the default InnoDB stopword list */
@ -3408,7 +3389,7 @@ fts_fetch_doc_from_rec(
doc->charset = get_doc->index_cache->charset;
/* Null Field */
if (doc->text.f_len == UNIV_SQL_NULL) {
if (doc->text.f_len == UNIV_SQL_NULL || doc->text.f_len == 0) {
continue;
}
@ -5544,7 +5525,7 @@ fts_savepoint_lookup(
/*********************************************************************//**
Release the savepoint data identified by name. All savepoints created
after the named savepoint are also released.
after the named savepoint are kept.
@return DB_SUCCESS or error code */
UNIV_INTERN
void
@ -5553,81 +5534,37 @@ fts_savepoint_release(
trx_t* trx, /*!< in: transaction */
const char* name) /*!< in: savepoint name */
{
ulint i;
ib_vector_t* savepoints;
ulint top_of_stack = 0;
ut_a(name != NULL);
savepoints = trx->fts_trx->savepoints;
ib_vector_t* savepoints = trx->fts_trx->savepoints;
ut_a(ib_vector_size(savepoints) > 0);
/* Skip the implied savepoint (first element). */
for (i = 1; i < ib_vector_size(savepoints); ++i) {
fts_savepoint_t* savepoint;
ulint i = fts_savepoint_lookup(savepoints, name);
if (i != ULINT_UNDEFINED) {
ut_a(i >= 1);
fts_savepoint_t* savepoint;
savepoint = static_cast<fts_savepoint_t*>(
ib_vector_get(savepoints, i));
/* Even though we release the resources that are part
of the savepoint, we don't (always) actually delete the
entry. We simply set the savepoint name to NULL. Therefore
we have to skip deleted/released entries. */
if (savepoint->name != NULL
&& strcmp(name, savepoint->name) == 0) {
break;
if (i == ib_vector_size(savepoints) - 1) {
/* If the savepoint is the last, we save its
tables to the previous savepoint. */
fts_savepoint_t* prev_savepoint;
prev_savepoint = static_cast<fts_savepoint_t*>(
ib_vector_get(savepoints, i - 1));
/* Track the previous savepoint instance that will
be at the top of the stack after the release. */
} else if (savepoint->name != NULL) {
/* We need to delete all entries
greater than this element. */
top_of_stack = i;
ib_rbt_t* tables = savepoint->tables;
savepoint->tables = prev_savepoint->tables;
prev_savepoint->tables = tables;
}
}
/* Only if we found and element to release. */
if (i < ib_vector_size(savepoints)) {
fts_savepoint_t* last_savepoint;
fts_savepoint_t* top_savepoint;
ib_rbt_t* tables;
ut_a(top_of_stack < ib_vector_size(savepoints));
/* Exchange tables between last savepoint and top savepoint */
last_savepoint = static_cast<fts_savepoint_t*>(
ib_vector_last(trx->fts_trx->savepoints));
top_savepoint = static_cast<fts_savepoint_t*>(
ib_vector_get(savepoints, top_of_stack));
tables = top_savepoint->tables;
top_savepoint->tables = last_savepoint->tables;
last_savepoint->tables = tables;
/* Skip the implied savepoint. */
for (i = ib_vector_size(savepoints) - 1;
i > top_of_stack;
--i) {
fts_savepoint_t* savepoint;
savepoint = static_cast<fts_savepoint_t*>(
ib_vector_get(savepoints, i));
/* Skip savepoints that were released earlier. */
if (savepoint->name != NULL) {
savepoint->name = NULL;
fts_savepoint_free(savepoint);
}
ib_vector_pop(savepoints);
}
fts_savepoint_free(savepoint);
ib_vector_remove(savepoints, *(void**)savepoint);
/* Make sure we don't delete the implied savepoint. */
ut_a(ib_vector_size(savepoints) > 0);
/* This must hold. */
ut_a(ib_vector_size(savepoints) == (top_of_stack + 1));
}
}
@ -6329,7 +6266,7 @@ fts_fake_hex_to_dec(
{
ib_id_t dec_id = 0;
char tmp_id[FTS_AUX_MIN_TABLE_ID_LENGTH];
int ret;
int ret __attribute__((unused));
ret = sprintf(tmp_id, UINT64PFx, id);
ut_ad(ret == 16);

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2007, 2015, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -42,9 +42,6 @@ Completed 2011/7/10 Sunny and Jimmy Yang
/** The FTS optimize thread's work queue. */
static ib_wqueue_t* fts_optimize_wq;
/** The number of document ids to delete in one statement. */
static const ulint FTS_MAX_DELETE_DOC_IDS = 1000;
/** Time to wait for a message. */
static const ulint FTS_QUEUE_WAIT_IN_USECS = 5000000;
@ -1154,6 +1151,7 @@ fts_optimize_encode_node(
}
/* Calculate the space required to store the ilist. */
ut_ad(doc_id > node->last_doc_id);
doc_id_delta = doc_id - node->last_doc_id;
enc_len = fts_get_encoded_len(static_cast<ulint>(doc_id_delta));
@ -1396,7 +1394,8 @@ fts_optimize_word(
src_node = (fts_node_t*) ib_vector_get(word->nodes, i);
if (!dst_node) {
if (dst_node == NULL
|| dst_node->last_doc_id > src_node->first_doc_id) {
dst_node = static_cast<fts_node_t*>(
ib_vector_push(nodes, NULL));

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2007, 2015, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -57,9 +57,6 @@ Completed 2011/7/10 Sunny and Jimmy Yang
/*Initial byte length for 'words' in fts_ranking_t */
#define RANKING_WORDS_INIT_LEN 4
/* Coeffecient to use for normalize relevance ranking. */
static const double FTS_NORMALIZE_COEFF = 0.0115F;
// FIXME: Need to have a generic iterator that traverses the ilist.
typedef std::vector<fts_string_t> word_vector_t;

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 2000, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc.
@ -2696,19 +2696,6 @@ trx_is_strict(
return(trx && trx->mysql_thd && THDVAR(trx->mysql_thd, strict_mode));
}
/**********************************************************************//**
Determines if the current MySQL thread is running in strict mode.
If thd==NULL, THDVAR returns the global value of innodb-strict-mode.
@return TRUE if strict */
UNIV_INLINE
ibool
thd_is_strict(
/*==========*/
THD* thd) /*!< in: MySQL thread descriptor */
{
return(THDVAR(thd, strict_mode));
}
/**************************************************************//**
Resets some fields of a prebuilt struct. The template is used in fast
retrieval of just those column values MySQL needs in its processing. */

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2007, 2015, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -3312,8 +3312,6 @@ i_s_fts_index_cache_fill_one_index(
for (rbt_node = rbt_first(index_cache->words);
rbt_node;
rbt_node = rbt_next(index_cache->words, rbt_node)) {
doc_id_t doc_id = 0;
fts_tokenizer_word_t* word;
word = rbt_value(fts_tokenizer_word_t, rbt_node);
@ -3339,6 +3337,7 @@ i_s_fts_index_cache_fill_one_index(
fts_node_t* node;
byte* ptr;
ulint decoded = 0;
doc_id_t doc_id = 0;
node = static_cast<fts_node_t*> (ib_vector_get(
word->nodes, i));
@ -4019,11 +4018,15 @@ i_s_fts_config_fill(
fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
if (!user_table) {
DBUG_RETURN(0);
} else if (!dict_table_has_fts_index(user_table)) {
dict_table_close(user_table, FALSE, FALSE);
DBUG_RETURN(0);
}
trx = trx_allocate_for_background();
trx->op_info = "Select for FTS DELETE TABLE";
trx->op_info = "Select for FTS CONFIG TABLE";
FTS_INIT_FTS_TABLE(&fts_table, "CONFIG", FTS_COMMON_TABLE, user_table);

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
This program is free software; you can redistribute it and/or modify it under
@ -540,11 +540,12 @@ extern ulong zip_failure_threshold_pct;
compression failures */
extern ulong zip_pad_max;
/** Data structure to hold information about about how much space in
/** Data structure to hold information about how much space in
an uncompressed page should be left as padding to avoid compression
failures. This estimate is based on a self-adapting heuristic. */
struct zip_pad_info_t {
os_fast_mutex_t mutex; /*!< mutex protecting the info */
os_fast_mutex_t*
mutex; /*!< mutex protecting the info */
ulint pad; /*!< number of bytes used as pad */
ulint success;/*!< successful compression ops during
current round */
@ -552,6 +553,9 @@ struct zip_pad_info_t {
current round */
ulint n_rounds;/*!< number of currently successful
rounds */
volatile os_once::state_t
mutex_created;
/*!< Creation state of mutex member */
};
/** Data structure for an index. Most fields will be
@ -1142,9 +1146,14 @@ struct dict_table_t{
space from the lock heap of the trx:
otherwise the lock heap would grow rapidly
if we do a large insert from a select */
ib_mutex_t autoinc_mutex;
ib_mutex_t* autoinc_mutex;
/*!< mutex protecting the autoincrement
counter */
/** Creation state of autoinc_mutex member */
volatile os_once::state_t
autoinc_mutex_created;
ib_uint64_t autoinc;/*!< autoinc counter value to give to the
next inserted row */
ulong n_waiting_or_granted_auto_inc_locks;
@ -1207,6 +1216,111 @@ struct dict_foreign_add_to_referenced_table {
}
};
/** Destroy the autoinc latch of the given table.
This function is only called from either single threaded environment
or from a thread that has not shared the table object with other threads.
@param[in,out] table table whose stats latch to destroy */
inline
void
dict_table_autoinc_destroy(
dict_table_t* table)
{
if (table->autoinc_mutex_created == os_once::DONE
&& table->autoinc_mutex != NULL) {
mutex_free(table->autoinc_mutex);
delete table->autoinc_mutex;
}
}
/** Allocate and init the autoinc latch of a given table.
This function must not be called concurrently on the same table object.
@param[in,out] table_void table whose autoinc latch to create */
void
dict_table_autoinc_alloc(
void* table_void);
/** Allocate and init the zip_pad_mutex of a given index.
This function must not be called concurrently on the same index object.
@param[in,out] index_void index whose zip_pad_mutex to create */
void
dict_index_zip_pad_alloc(
void* index_void);
/** Request for lazy creation of the autoinc latch of a given table.
This function is only called from either single threaded environment
or from a thread that has not shared the table object with other threads.
@param[in,out] table table whose autoinc latch is to be created. */
inline
void
dict_table_autoinc_create_lazy(
dict_table_t* table)
{
#ifdef HAVE_ATOMIC_BUILTINS
table->autoinc_mutex = NULL;
table->autoinc_mutex_created = os_once::NEVER_DONE;
#else /* HAVE_ATOMIC_BUILTINS */
dict_table_autoinc_alloc(table);
table->autoinc_mutex_created = os_once::DONE;
#endif /* HAVE_ATOMIC_BUILTINS */
}
/** Request a lazy creation of dict_index_t::zip_pad::mutex.
This function is only called from either single threaded environment
or from a thread that has not shared the table object with other threads.
@param[in,out] index index whose zip_pad mutex is to be created */
inline
void
dict_index_zip_pad_mutex_create_lazy(
dict_index_t* index)
{
#ifdef HAVE_ATOMIC_BUILTINS
index->zip_pad.mutex = NULL;
index->zip_pad.mutex_created = os_once::NEVER_DONE;
#else /* HAVE_ATOMIC_BUILTINS */
dict_index_zip_pad_alloc(index);
index->zip_pad.mutex_created = os_once::DONE;
#endif /* HAVE_ATOMIC_BUILTINS */
}
/** Destroy the zip_pad_mutex of the given index.
This function is only called from either single threaded environment
or from a thread that has not shared the table object with other threads.
@param[in,out] table table whose stats latch to destroy */
inline
void
dict_index_zip_pad_mutex_destroy(
dict_index_t* index)
{
if (index->zip_pad.mutex_created == os_once::DONE
&& index->zip_pad.mutex != NULL) {
os_fast_mutex_free(index->zip_pad.mutex);
delete index->zip_pad.mutex;
}
}
/** Release the zip_pad_mutex of a given index.
@param[in,out] index index whose zip_pad_mutex is to be released */
inline
void
dict_index_zip_pad_unlock(
dict_index_t* index)
{
os_fast_mutex_unlock(index->zip_pad.mutex);
}
#ifdef UNIV_DEBUG
/** Check if the current thread owns the autoinc_mutex of a given table.
@param[in] table the autoinc_mutex belongs to this table
@return true, if the current thread owns the autoinc_mutex, false otherwise.*/
inline
bool
dict_table_autoinc_own(
const dict_table_t* table)
{
return(mutex_own(table->autoinc_mutex));
}
#endif /* UNIV_DEBUG */
#ifndef UNIV_NONINL
#include "dict0mem.ic"
#endif

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -378,8 +378,10 @@ because there is no parallel deadlock check. This stack is protected by
the lock_sys_t::mutex. */
static lock_stack_t* lock_stack;
#ifdef UNIV_DEBUG
/** The count of the types of locks. */
static const ulint lock_types = UT_ARR_SIZE(lock_compatibility_matrix);
#endif /* UNIV_DEBUG */
#ifdef UNIV_PFS_MUTEX
/* Key to register mutex with performance schema */

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1997, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1997, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
This program is free software; you can redistribute it and/or modify it under
@ -1862,7 +1862,7 @@ loop:
goto loop;
}
ut_ad(!allow_ibuf == mutex_own(&log_sys->mutex));
ut_ad((!allow_ibuf) == mutex_own(&log_sys->mutex));
if (!allow_ibuf) {
recv_no_ibuf_operations = TRUE;

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -233,24 +233,6 @@ os_cond_broadcast(
#endif
}
/*********************************************************//**
Wakes one thread waiting for condition variable */
UNIV_INLINE
void
os_cond_signal(
/*==========*/
os_cond_t* cond) /*!< in: condition variable. */
{
ut_a(cond);
#ifdef __WIN__
ut_a(wake_condition_variable != NULL);
wake_condition_variable(cond);
#else
ut_a(pthread_cond_signal(cond) == 0);
#endif
}
/*********************************************************//**
Destroys condition variable */
UNIV_INLINE

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 2005, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2005, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
This program is free software; you can redistribute it and/or modify it under
@ -1572,7 +1572,7 @@ page_zip_fields_free(
{
if (index) {
dict_table_t* table = index->table;
os_fast_mutex_free(&index->zip_pad.mutex);
dict_index_zip_pad_mutex_destroy(index);
mem_heap_free(index->heap);
dict_mem_table_free(table);

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -380,32 +380,6 @@ que_fork_start_command(
return(thr);
}
/****************************************************************//**
Tests if all the query threads in the same fork have a given state.
@return TRUE if all the query threads in the same fork were in the
given state */
UNIV_INLINE
ibool
que_fork_all_thrs_in_state(
/*=======================*/
que_fork_t* fork, /*!< in: query fork */
ulint state) /*!< in: state */
{
que_thr_t* thr_node;
for (thr_node = UT_LIST_GET_FIRST(fork->thrs);
thr_node != NULL;
thr_node = UT_LIST_GET_NEXT(thrs, thr_node)) {
if (thr_node->state != state) {
return(FALSE);
}
}
return(TRUE);
}
/**********************************************************************//**
Calls que_graph_free_recursive for statements in a statement list. */
static

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 2011, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2011, 2015, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -1381,6 +1381,27 @@ blob_done:
dfield_set_data(dfield, data, len);
}
if (len != UNIV_SQL_NULL && col->mtype == DATA_MYSQL
&& col->len != len && !dict_table_is_comp(log->table)) {
ut_ad(col->len >= len);
if (dict_table_is_comp(index->table)) {
byte* buf = (byte*) mem_heap_alloc(heap,
col->len);
memcpy(buf, dfield->data, len);
memset(buf + len, 0x20, col->len - len);
dfield_set_data(dfield, buf, col->len);
} else {
/* field length mismatch should not happen
when rebuilding the redundant row format
table. */
ut_ad(0);
*error = DB_CORRUPTION;
return(NULL);
}
}
/* See if any columns were changed to NULL or NOT NULL. */
const dict_col_t* new_col
= dict_table_get_nth_col(log->table, col_no);

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 2005, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2005, 2015, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -235,22 +235,86 @@ row_merge_buf_free(
mem_heap_free(buf->heap);
}
/******************************************************//**
Insert a data tuple into a sort buffer.
@return number of rows added, 0 if out of space */
/** Convert the field data from compact to redundant format.
@param[in] row_field field to copy from
@param[out] field field to copy to
@param[in] len length of the field data
@param[in] zip_size compressed BLOB page size,
zero for uncompressed BLOBs
@param[in,out] heap memory heap where to allocate data when
converting to ROW_FORMAT=REDUNDANT, or NULL
when not to invoke
row_merge_buf_redundant_convert(). */
static
void
row_merge_buf_redundant_convert(
const dfield_t* row_field,
dfield_t* field,
ulint len,
ulint zip_size,
mem_heap_t* heap)
{
ut_ad(DATA_MBMINLEN(field->type.mbminmaxlen) == 1);
ut_ad(DATA_MBMAXLEN(field->type.mbminmaxlen) > 1);
byte* buf = (byte*) mem_heap_alloc(heap, len);
ulint field_len = row_field->len;
ut_ad(field_len <= len);
if (row_field->ext) {
const byte* field_data = static_cast<byte*>(
dfield_get_data(row_field));
ulint ext_len;
ut_a(field_len >= BTR_EXTERN_FIELD_REF_SIZE);
ut_a(memcmp(field_data + field_len - BTR_EXTERN_FIELD_REF_SIZE,
field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE));
byte* data = btr_copy_externally_stored_field(
&ext_len, field_data, zip_size, field_len, heap);
ut_ad(ext_len < len);
memcpy(buf, data, ext_len);
field_len = ext_len;
} else {
memcpy(buf, row_field->data, field_len);
}
memset(buf + field_len, 0x20, len - field_len);
dfield_set_data(field, buf, len);
}
/** Insert a data tuple into a sort buffer.
@param[in,out] buf sort buffer
@param[in] fts_index fts index to be created
@param[in] old_table original table
@param[in,out] psort_info parallel sort info
@param[in] row table row
@param[in] ext cache of externally stored
column prefixes, or NULL
@param[in,out] doc_id Doc ID if we are creating
FTS index
@param[in,out] conv_heap memory heap where to allocate data when
converting to ROW_FORMAT=REDUNDANT, or NULL
when not to invoke
row_merge_buf_redundant_convert()
@param[in,out] exceed_page set if the record size exceeds the page size
when converting to ROW_FORMAT=REDUNDANT
@return number of rows added, 0 if out of space */
static
ulint
row_merge_buf_add(
/*==============*/
row_merge_buf_t* buf, /*!< in/out: sort buffer */
dict_index_t* fts_index,/*!< in: fts index to be created */
const dict_table_t* old_table,/*!< in: original table */
fts_psort_t* psort_info, /*!< in: parallel sort info */
const dtuple_t* row, /*!< in: table row */
const row_ext_t* ext, /*!< in: cache of externally stored
column prefixes, or NULL */
doc_id_t* doc_id) /*!< in/out: Doc ID if we are
creating FTS index */
row_merge_buf_t* buf,
dict_index_t* fts_index,
const dict_table_t* old_table,
fts_psort_t* psort_info,
const dtuple_t* row,
const row_ext_t* ext,
doc_id_t* doc_id,
mem_heap_t* conv_heap,
bool* exceed_page)
{
ulint i;
const dict_index_t* index;
@ -400,6 +464,23 @@ row_merge_buf_add(
n_row_added = 1;
continue;
}
if (field->len != UNIV_SQL_NULL
&& col->mtype == DATA_MYSQL
&& col->len != field->len) {
if (conv_heap != NULL) {
row_merge_buf_redundant_convert(
row_field, field, col->len,
dict_table_zip_size(old_table),
conv_heap);
} else {
/* Field length mismatch should not
happen when rebuilding redundant row
format table. */
ut_ad(dict_table_is_comp(index->table));
}
}
}
len = dfield_get_len(field);
@ -508,6 +589,14 @@ row_merge_buf_add(
of extra_size. */
data_size += (extra_size + 1) + ((extra_size + 1) >= 0x80);
/* Record size can exceed page size while converting to
redundant row format. But there is assert
ut_ad(size < UNIV_PAGE_SIZE) in rec_offs_data_size().
It may hit the assert before attempting to insert the row. */
if (conv_heap != NULL && data_size > UNIV_PAGE_SIZE) {
*exceed_page = true;
}
ut_ad(data_size < srv_sort_buf_size);
/* Reserve one byte for the end marker of row_merge_block_t. */
@ -527,6 +616,10 @@ row_merge_buf_add(
dfield_dup(field++, buf->heap);
} while (--n_fields);
if (conv_heap != NULL) {
mem_heap_empty(conv_heap);
}
DBUG_RETURN(n_row_added);
}
@ -1208,6 +1301,7 @@ row_merge_read_clustered_index(
os_event_t fts_parallel_sort_event = NULL;
ibool fts_pll_sort = FALSE;
ib_int64_t sig_count = 0;
mem_heap_t* conv_heap = NULL;
DBUG_ENTER("row_merge_read_clustered_index");
ut_ad((old_table == new_table) == !col_map);
@ -1303,6 +1397,11 @@ row_merge_read_clustered_index(
row_heap = mem_heap_create(sizeof(mrec_buf_t));
if (dict_table_is_comp(old_table)
&& !dict_table_is_comp(new_table)) {
conv_heap = mem_heap_create(sizeof(mrec_buf_t));
}
/* Scan the clustered index. */
for (;;) {
const rec_t* rec;
@ -1581,16 +1680,24 @@ write_buffers:
row_merge_buf_t* buf = merge_buf[i];
merge_file_t* file = &files[i];
ulint rows_added = 0;
bool exceed_page = false;
if (UNIV_LIKELY
(row && (rows_added = row_merge_buf_add(
buf, fts_index, old_table,
psort_info, row, ext, &doc_id)))) {
psort_info, row, ext, &doc_id,
conv_heap, &exceed_page)))) {
/* If we are creating FTS index,
a single row can generate more
records for tokenized word */
file->n_rec += rows_added;
if (exceed_page) {
err = DB_TOO_BIG_RECORD;
break;
}
if (doc_id > max_doc_id) {
max_doc_id = doc_id;
}
@ -1691,12 +1798,18 @@ write_buffers:
(!(rows_added = row_merge_buf_add(
buf, fts_index, old_table,
psort_info, row, ext,
&doc_id)))) {
&doc_id, conv_heap,
&exceed_page)))) {
/* An empty buffer should have enough
room for at least one record. */
ut_error;
}
if (exceed_page) {
err = DB_TOO_BIG_RECORD;
break;
}
file->n_rec += rows_added;
}
}
@ -1721,6 +1834,10 @@ func_exit:
}
all_done:
if (conv_heap != NULL) {
mem_heap_free(conv_heap);
}
#ifdef FTS_INTERNAL_DIAG_PRINT
DEBUG_FTS_SORT_PRINT("FTS_SORT: Complete Scan Table\n");
#endif

View file

@ -3411,13 +3411,11 @@ row_truncate_table_for_mysql(
goto funct_exit;
}
if (table->space && !table->dir_path_of_temp_table) {
if (table->space && !DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY)) {
/* Discard and create the single-table tablespace. */
ulint space = table->space;
ulint flags = fil_space_get_flags(space);
ut_a(!DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY));
dict_get_and_save_data_dir_path(table, true);
if (flags != ULINT_UNDEFINED
@ -4217,8 +4215,9 @@ row_drop_table_for_mysql(
is_temp = DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY);
/* If there is a temp path then the temp flag is set.
However, during recovery, we might have a temp flag but
not know the temp path */
However, during recovery or reloading the table object
after eviction from data dictionary cache, we might
have a temp flag but not know the temp path */
ut_a(table->dir_path_of_temp_table == NULL || is_temp);
if (dict_table_is_discarded(table)
|| table->ibd_file_missing) {
@ -4786,6 +4785,7 @@ row_rename_table_for_mysql(
ibool old_is_tmp, new_is_tmp;
pars_info_t* info = NULL;
int retry;
bool aux_fts_rename = false;
ut_a(old_name != NULL);
ut_a(new_name != NULL);
@ -5072,34 +5072,8 @@ row_rename_table_for_mysql(
if (dict_table_has_fts_index(table)
&& !dict_tables_have_same_db(old_name, new_name)) {
err = fts_rename_aux_tables(table, new_name, trx);
if (err != DB_SUCCESS && (table->space != 0)) {
char* orig_name = table->name;
trx_t* trx_bg = trx_allocate_for_background();
/* If the first fts_rename fails, the trx would
be rolled back and committed, we can't use it any more,
so we have to start a new background trx here. */
ut_a(trx_state_eq(trx, TRX_STATE_NOT_STARTED));
trx_bg->op_info = "Revert the failing rename "
"for fts aux tables";
trx_bg->dict_operation_lock_mode = RW_X_LATCH;
trx_start_for_ddl(trx_bg, TRX_DICT_OP_TABLE);
/* If rename fails and table has its own tablespace,
we need to call fts_rename_aux_tables again to
revert the ibd file rename, which is not under the
control of trx. Also notice the parent table name
in cache is not changed yet. If the reverting fails,
the ibd data may be left in the new database, which
can be fixed only manually. */
table->name = const_cast<char*>(new_name);
fts_rename_aux_tables(table, old_name, trx_bg);
table->name = orig_name;
trx_bg->dict_operation_lock_mode = 0;
trx_commit_for_mysql(trx_bg);
trx_free_for_background(trx_bg);
if (err != DB_TABLE_NOT_FOUND) {
aux_fts_rename = true;
}
}
@ -5200,6 +5174,37 @@ end:
}
funct_exit:
if (aux_fts_rename && err != DB_SUCCESS
&& table != NULL && (table->space != 0)) {
char* orig_name = table->name;
trx_t* trx_bg = trx_allocate_for_background();
/* If the first fts_rename fails, the trx would
be rolled back and committed, we can't use it any more,
so we have to start a new background trx here. */
ut_a(trx_state_eq(trx_bg, TRX_STATE_NOT_STARTED));
trx_bg->op_info = "Revert the failing rename "
"for fts aux tables";
trx_bg->dict_operation_lock_mode = RW_X_LATCH;
trx_start_for_ddl(trx_bg, TRX_DICT_OP_TABLE);
/* If rename fails and table has its own tablespace,
we need to call fts_rename_aux_tables again to
revert the ibd file rename, which is not under the
control of trx. Also notice the parent table name
in cache is not changed yet. If the reverting fails,
the ibd data may be left in the new database, which
can be fixed only manually. */
table->name = const_cast<char*>(new_name);
fts_rename_aux_tables(table, old_name, trx_bg);
table->name = orig_name;
trx_bg->dict_operation_lock_mode = 0;
trx_commit_for_mysql(trx_bg);
trx_free_for_background(trx_bg);
}
if (table != NULL) {
dict_table_close(table, dict_locked, FALSE);
}

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@ -298,9 +298,9 @@ mutex_create_func(
/* NOTE! The very first mutexes are not put to the mutex list */
if ((mutex == &mutex_list_mutex)
if (mutex == &mutex_list_mutex
#ifdef UNIV_SYNC_DEBUG
|| (mutex == &sync_thread_mutex)
|| mutex == &sync_thread_mutex
#endif /* UNIV_SYNC_DEBUG */
) {