mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
5.6.24
This commit is contained in:
parent
6d06fbbd1d
commit
085297a121
19 changed files with 438 additions and 491 deletions
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
) {
|
||||
|
||||
|
|
Loading…
Reference in a new issue