summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2015-06-16 12:46:14 +0200
committerSergei Golubchik <serg@mariadb.org>2015-06-16 12:46:14 +0200
commit9859d366b5dede25308b562c24316c44a6474275 (patch)
tree0b39ae57f5bf3f4f69c070d65d0db6e7b14c407c
parenta65162a396b1c298687992dd62ece924978b4c29 (diff)
parent90849456d794aa6df32554a588da5db8cb15f5aa (diff)
downloadmariadb-git-9859d366b5dede25308b562c24316c44a6474275.tar.gz
Merge branch 'merge-xtradb-5.6' into 10.0
-rw-r--r--storage/xtradb/api/api0api.cc208
-rw-r--r--storage/xtradb/dict/dict0boot.cc12
-rw-r--r--storage/xtradb/dict/dict0dict.cc94
-rw-r--r--storage/xtradb/dict/dict0load.cc3
-rw-r--r--storage/xtradb/dict/dict0mem.cc31
-rw-r--r--storage/xtradb/fsp/fsp0fsp.cc40
-rw-r--r--storage/xtradb/fts/fts0fts.cc111
-rw-r--r--storage/xtradb/fts/fts0opt.cc9
-rw-r--r--storage/xtradb/fts/fts0que.cc5
-rw-r--r--storage/xtradb/handler/ha_innodb.cc27
-rw-r--r--storage/xtradb/handler/handler0alter.cc2
-rw-r--r--storage/xtradb/handler/i_s.cc11
-rw-r--r--storage/xtradb/ibuf/ibuf0ibuf.cc5
-rw-r--r--storage/xtradb/include/dict0mem.h136
-rw-r--r--storage/xtradb/include/univ.i4
-rw-r--r--storage/xtradb/lock/lock0lock.cc4
-rw-r--r--storage/xtradb/log/log0recv.cc4
-rw-r--r--storage/xtradb/mtr/mtr0log.cc2
-rw-r--r--storage/xtradb/os/os0sync.cc20
-rw-r--r--storage/xtradb/page/page0zip.cc6
-rw-r--r--storage/xtradb/pars/pars0pars.cc2
-rw-r--r--storage/xtradb/que/que0que.cc28
-rw-r--r--storage/xtradb/row/row0log.cc23
-rw-r--r--storage/xtradb/row/row0merge.cc149
-rw-r--r--storage/xtradb/row/row0mysql.cc71
-rw-r--r--storage/xtradb/sync/sync0sync.cc2
26 files changed, 465 insertions, 544 deletions
diff --git a/storage/xtradb/api/api0api.cc b/storage/xtradb/api/api0api.cc
index 3859fb84b81..8769fc47166 100644
--- a/storage/xtradb/api/api0api.cc
+++ b/storage/xtradb/api/api0api.cc
@@ -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. */
@@ -947,34 +804,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 */
static
@@ -3564,41 +3393,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.
diff --git a/storage/xtradb/dict/dict0boot.cc b/storage/xtradb/dict/dict0boot.cc
index b57a8873bd5..94a3af2852b 100644
--- a/storage/xtradb/dict/dict0boot.cc
+++ b/storage/xtradb/dict/dict0boot.cc
@@ -302,8 +302,7 @@ dict_boot(void)
/* Insert into the dictionary cache the descriptions of the basic
system tables */
/*-------------------------*/
- table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, 0, 0,
- false);
+ table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, 0, 0);
dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
@@ -357,8 +356,7 @@ dict_boot(void)
ut_a(error == DB_SUCCESS);
/*-------------------------*/
- table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, 0, 0,
- false);
+ table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, 0, 0);
dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
@@ -391,8 +389,7 @@ dict_boot(void)
ut_a(error == DB_SUCCESS);
/*-------------------------*/
- table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, 0, 0,
- false);
+ table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, 0, 0);
dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
@@ -425,8 +422,7 @@ dict_boot(void)
ut_a(error == DB_SUCCESS);
/*-------------------------*/
- table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, 0, 0,
- false);
+ table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, 0, 0);
dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc
index f3a5918a09d..8d8347ca726 100644
--- a/storage/xtradb/dict/dict0dict.cc
+++ b/storage/xtradb/dict/dict0dict.cc
@@ -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
@@ -683,6 +683,33 @@ dict_table_get_col_name_for_mysql(
return(s);
}
#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
@@ -691,7 +718,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);
}
/********************************************************************//**
@@ -703,7 +755,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;
}
@@ -745,7 +797,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);
}
@@ -761,7 +813,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) {
@@ -777,7 +829,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 */
@@ -1616,15 +1668,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)) {
@@ -5906,8 +5961,7 @@ dict_ind_init(void)
dict_table_t* table;
/* create dummy table and index for REDUNDANT infimum and supremum */
- table = dict_mem_table_create("SYS_DUMMY1", DICT_HDR_SPACE, 1, 0, 0,
- true);
+ table = dict_mem_table_create("SYS_DUMMY1", DICT_HDR_SPACE, 1, 0, 0);
dict_mem_table_add_col(table, NULL, NULL, DATA_CHAR,
DATA_ENGLISH | DATA_NOT_NULL, 8);
@@ -5920,7 +5974,7 @@ dict_ind_init(void)
/* create dummy table and index for COMPACT infimum and supremum */
table = dict_mem_table_create("SYS_DUMMY2",
DICT_HDR_SPACE, 1,
- DICT_TF_COMPACT, 0, true);
+ DICT_TF_COMPACT, 0);
dict_mem_table_add_col(table, NULL, NULL, DATA_CHAR,
DATA_ENGLISH | DATA_NOT_NULL, 8);
dict_ind_compact = dict_mem_index_create("SYS_DUMMY2", "SYS_DUMMY2",
@@ -6756,10 +6810,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);
}
/*********************************************************************//**
@@ -6779,10 +6833,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);
}
@@ -6814,9 +6868,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);
diff --git a/storage/xtradb/dict/dict0load.cc b/storage/xtradb/dict/dict0load.cc
index 874614bfb5c..ef8a2896b28 100644
--- a/storage/xtradb/dict/dict0load.cc
+++ b/storage/xtradb/dict/dict0load.cc
@@ -2176,8 +2176,7 @@ err_len:
/* See if the tablespace is available. */
*table = dict_mem_table_create(
- name, space, n_cols & ~DICT_N_COLS_COMPACT, flags, flags2,
- false);
+ name, space, n_cols & ~DICT_N_COLS_COMPACT, flags, flags2);
field = rec_get_nth_field_old(rec, DICT_FLD__SYS_TABLES__ID, &len);
ut_ad(len == 8); /* this was checked earlier */
diff --git a/storage/xtradb/dict/dict0mem.cc b/storage/xtradb/dict/dict0mem.cc
index 5788818a6c3..c23a3637632 100644
--- a/storage/xtradb/dict/dict0mem.cc
+++ b/storage/xtradb/dict/dict0mem.cc
@@ -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
@@ -79,10 +79,7 @@ dict_mem_table_create(
the table is placed */
ulint n_cols, /*!< in: number of columns */
ulint flags, /*!< in: table flags */
- ulint flags2, /*!< in: table flags2 */
- bool nonshared)/*!< in: whether the table object is a dummy
- one that does not need the initialization of
- locking-related fields. */
+ ulint flags2) /*!< in: table flags2 */
{
dict_table_t* table;
mem_heap_t* heap;
@@ -118,18 +115,10 @@ dict_mem_table_create(
dict_table_stats_latch_create(table, true);
#ifndef UNIV_HOTBACKUP
+ table->autoinc_lock = static_cast<ib_lock_t*>(
+ mem_heap_alloc(heap, lock_get_size()));
- if (!nonshared) {
-
- 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);
- } else {
-
- table->autoinc_lock = NULL;
- }
+ dict_table_autoinc_create_lazy(table);
table->autoinc = 0;
@@ -212,10 +201,7 @@ dict_mem_table_free(
}
}
#ifndef UNIV_HOTBACKUP
- if (table->autoinc_lock) {
-
- mutex_free(&(table->autoinc_mutex));
- }
+ dict_table_autoinc_destroy(table);
#endif /* UNIV_HOTBACKUP */
dict_table_stats_latch_destroy(table);
@@ -580,8 +566,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);
}
@@ -714,7 +699,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);
}
diff --git a/storage/xtradb/fsp/fsp0fsp.cc b/storage/xtradb/fsp/fsp0fsp.cc
index c06d4213d73..1f894d43031 100644
--- a/storage/xtradb/fsp/fsp0fsp.cc
+++ b/storage/xtradb/fsp/fsp0fsp.cc
@@ -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
@@ -304,44 +304,6 @@ xdes_find_bit(
}
/**********************************************************************//**
-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 */
UNIV_INLINE
diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc
index 37e742bf938..5adda1fad6c 100644
--- a/storage/xtradb/fts/fts0fts.cc
+++ b/storage/xtradb/fts/fts0fts.cc
@@ -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 */
@@ -1971,7 +1952,7 @@ fts_create_one_index_table(
flags2 = DICT_TF2_USE_TABLESPACE;
}
- new_table = dict_mem_table_create(table_name, 0, 5, 1, flags2, false);
+ new_table = dict_mem_table_create(table_name, 0, 5, 1, flags2);
field = dict_index_get_nth_field(index, 0);
charset = innobase_get_fts_charset(
@@ -3409,7 +3390,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;
}
@@ -5545,7 +5526,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
@@ -5554,81 +5535,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));
}
}
@@ -6330,7 +6267,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);
diff --git a/storage/xtradb/fts/fts0opt.cc b/storage/xtradb/fts/fts0opt.cc
index 5891b53a6e2..e096b8bf6d6 100644
--- a/storage/xtradb/fts/fts0opt.cc
+++ b/storage/xtradb/fts/fts0opt.cc
@@ -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));
diff --git a/storage/xtradb/fts/fts0que.cc b/storage/xtradb/fts/fts0que.cc
index 9d8e7aec9ab..66060439215 100644
--- a/storage/xtradb/fts/fts0que.cc
+++ b/storage/xtradb/fts/fts0que.cc
@@ -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;
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 72cc8c87e09..235d0cd95b9 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -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.
@@ -3129,19 +3129,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. */
@@ -9613,19 +9600,19 @@ create_table_def(
if (flags2 & DICT_TF2_FTS) {
/* Adjust for the FTS hidden field */
if (!has_doc_id_col) {
- table = dict_mem_table_create(table_name, 0, s_cols + 1,
- flags, flags2, false);
+ table = dict_mem_table_create(table_name, 0, n_cols + 1,
+ flags, flags2);
/* Set the hidden doc_id column. */
table->fts->doc_col = s_cols;
} else {
- table = dict_mem_table_create(table_name, 0, s_cols,
- flags, flags2, false);
+ table = dict_mem_table_create(table_name, 0, n_cols,
+ flags, flags2);
table->fts->doc_col = doc_id_col;
}
} else {
- table = dict_mem_table_create(table_name, 0, s_cols,
- flags, flags2, false);
+ table = dict_mem_table_create(table_name, 0, n_cols,
+ flags, flags2);
}
if (flags2 & DICT_TF2_TEMPORARY) {
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index e1a038fb4bd..cc18f709043 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -2811,7 +2811,7 @@ prepare_inplace_alter_table_dict(
/* The initial space id 0 may be overridden later. */
ctx->new_table = dict_mem_table_create(
- new_table_name, 0, n_cols, flags, flags2, false);
+ new_table_name, 0, n_cols, flags, flags2);
/* The rebuilt indexed_table will use the renamed
column names. */
ctx->col_names = NULL;
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index ac4c92e8c37..02d2a2100a4 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -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
@@ -3256,8 +3256,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);
@@ -3283,6 +3281,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));
@@ -3954,10 +3953,14 @@ i_s_fts_config_fill(
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);
diff --git a/storage/xtradb/ibuf/ibuf0ibuf.cc b/storage/xtradb/ibuf/ibuf0ibuf.cc
index 068a9fc9334..972208c51bd 100644
--- a/storage/xtradb/ibuf/ibuf0ibuf.cc
+++ b/storage/xtradb/ibuf/ibuf0ibuf.cc
@@ -611,8 +611,7 @@ ibuf_init_at_db_start(void)
heap = mem_heap_create(450);
/* Use old-style record format for the insert buffer. */
- table = dict_mem_table_create(IBUF_TABLE_NAME, IBUF_SPACE_ID, 1, 0, 0,
- false);
+ table = dict_mem_table_create(IBUF_TABLE_NAME, IBUF_SPACE_ID, 1, 0, 0);
dict_mem_table_add_col(table, heap, "DUMMY_COLUMN", DATA_BINARY, 0, 0);
@@ -1573,7 +1572,7 @@ ibuf_dummy_index_create(
table = dict_mem_table_create("IBUF_DUMMY",
DICT_HDR_SPACE, n,
- comp ? DICT_TF_COMPACT : 0, 0, true);
+ comp ? DICT_TF_COMPACT : 0, 0);
index = dict_mem_index_create("IBUF_DUMMY", "IBUF_DUMMY",
DICT_HDR_SPACE, 0, n);
diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h
index a054e122e44..b8df96acc30 100644
--- a/storage/xtradb/include/dict0mem.h
+++ b/storage/xtradb/include/dict0mem.h
@@ -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
@@ -264,10 +264,7 @@ dict_mem_table_create(
of the table is placed */
ulint n_cols, /*!< in: number of columns */
ulint flags, /*!< in: table flags */
- ulint flags2, /*!< in: table flags2 */
- bool nonshared);/*!< in: whether the table object is a dummy
- one that does not need the initialization of
- locking-related fields. */
+ ulint flags2); /*!< in: table flags2 */
/**********************************************************************//**
Determines if a table belongs to a system database
@return true if table belong to a system database */
@@ -559,11 +556,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 */
@@ -571,6 +569,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
@@ -1049,8 +1050,7 @@ struct dict_table_t{
dict_table_t::indexes*::stat_index_size
dict_table_t::indexes*::stat_n_leaf_pages
(*) those are not always protected for
- performance reasons. NULL for dumy table
- objects. */
+ performance reasons. */
unsigned stat_initialized:1; /*!< TRUE if statistics have
been calculated the first time
after database startup or table creation */
@@ -1175,12 +1175,15 @@ struct dict_table_t{
and release it without a need to allocate
space from the lock heap of the trx:
otherwise the lock heap would grow rapidly
- if we do a large insert from a select. NULL
- for dummy table objects. */
- ib_mutex_t autoinc_mutex;
+ if we do a large insert from a select */
+ ib_mutex_t* autoinc_mutex;
/*!< mutex protecting the autoincrement
- counter. Not initialized for dummy table
- objects */
+ 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;
@@ -1244,6 +1247,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
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index ee58128802e..7d97deb71ef 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -44,10 +44,10 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 5
#define INNODB_VERSION_MINOR 6
-#define INNODB_VERSION_BUGFIX 23
+#define INNODB_VERSION_BUGFIX 24
#ifndef PERCONA_INNODB_VERSION
-#define PERCONA_INNODB_VERSION 72.1
+#define PERCONA_INNODB_VERSION 72.2
#endif
/* Enable UNIV_LOG_ARCHIVE in XtraDB */
diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc
index 5c9a8979d9f..e76bb0e2c62 100644
--- a/storage/xtradb/lock/lock0lock.cc
+++ b/storage/xtradb/lock/lock0lock.cc
@@ -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) 2014, 2015, MariaDB Corporation
This program is free software; you can redistribute it and/or modify it under
@@ -385,8 +385,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 */
diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc
index 47c09b6aa7a..c7482e93c25 100644
--- a/storage/xtradb/log/log0recv.cc
+++ b/storage/xtradb/log/log0recv.cc
@@ -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
@@ -1933,7 +1933,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;
diff --git a/storage/xtradb/mtr/mtr0log.cc b/storage/xtradb/mtr/mtr0log.cc
index 0660c819240..5335cb4c9ef 100644
--- a/storage/xtradb/mtr/mtr0log.cc
+++ b/storage/xtradb/mtr/mtr0log.cc
@@ -560,7 +560,7 @@ mlog_parse_index(
n = n_uniq = 1;
}
table = dict_mem_table_create("LOG_DUMMY", DICT_HDR_SPACE, n,
- comp ? DICT_TF_COMPACT : 0, 0, true);
+ comp ? DICT_TF_COMPACT : 0, 0);
ind = dict_mem_index_create("LOG_DUMMY", "LOG_DUMMY",
DICT_HDR_SPACE, 0, n);
ind->table = table;
diff --git a/storage/xtradb/os/os0sync.cc b/storage/xtradb/os/os0sync.cc
index 451ba5285e3..03c53848832 100644
--- a/storage/xtradb/os/os0sync.cc
+++ b/storage/xtradb/os/os0sync.cc
@@ -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
@@ -234,24 +234,6 @@ os_cond_broadcast(
}
/*********************************************************//**
-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
void
diff --git a/storage/xtradb/page/page0zip.cc b/storage/xtradb/page/page0zip.cc
index 535497480b7..d3ac5b261a4 100644
--- a/storage/xtradb/page/page0zip.cc
+++ b/storage/xtradb/page/page0zip.cc
@@ -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.
Copyright (c) 2014, SkySQL Ab. All Rights Reserved.
@@ -1601,7 +1601,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);
@@ -1652,7 +1652,7 @@ page_zip_fields_decode(
}
table = dict_mem_table_create("ZIP_DUMMY", DICT_HDR_SPACE, n,
- DICT_TF_COMPACT, 0, true);
+ DICT_TF_COMPACT, 0);
index = dict_mem_index_create("ZIP_DUMMY", "ZIP_DUMMY",
DICT_HDR_SPACE, 0, n);
index->table = table;
diff --git a/storage/xtradb/pars/pars0pars.cc b/storage/xtradb/pars/pars0pars.cc
index f051481184b..655e5ba1324 100644
--- a/storage/xtradb/pars/pars0pars.cc
+++ b/storage/xtradb/pars/pars0pars.cc
@@ -1997,7 +1997,7 @@ pars_create_table(
n_cols = que_node_list_get_len(column_defs);
table = dict_mem_table_create(
- table_sym->name, 0, n_cols, flags, flags2, false);
+ table_sym->name, 0, n_cols, flags, flags2);
#ifdef UNIV_DEBUG
if (not_fit_in_memory != NULL) {
diff --git a/storage/xtradb/que/que0que.cc b/storage/xtradb/que/que0que.cc
index 8d9b8fac776..e2dc0239e13 100644
--- a/storage/xtradb/que/que0que.cc
+++ b/storage/xtradb/que/que0que.cc
@@ -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
@@ -390,32 +390,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
diff --git a/storage/xtradb/row/row0log.cc b/storage/xtradb/row/row0log.cc
index cfedf1210ea..4a50be3d098 100644
--- a/storage/xtradb/row/row0log.cc
+++ b/storage/xtradb/row/row0log.cc
@@ -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
@@ -1382,6 +1382,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);
diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc
index 2d378eba119..8d2e3645eec 100644
--- a/storage/xtradb/row/row0merge.cc
+++ b/storage/xtradb/row/row0merge.cc
@@ -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;
@@ -1587,16 +1686,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;
}
@@ -1697,12 +1804,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;
}
}
@@ -1727,6 +1840,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
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index 7f9a8df7cb2..8dd84f15bea 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -3457,13 +3457,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
@@ -4263,8 +4261,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) {
@@ -4833,6 +4832,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);
@@ -5119,34 +5119,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;
}
}
@@ -5247,6 +5221,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);
}
diff --git a/storage/xtradb/sync/sync0sync.cc b/storage/xtradb/sync/sync0sync.cc
index 942a3e356e5..cfd8f27c389 100644
--- a/storage/xtradb/sync/sync0sync.cc
+++ b/storage/xtradb/sync/sync0sync.cc
@@ -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