summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/buf/buf0dump.cc4
-rw-r--r--storage/innobase/dict/dict0dict.cc2
-rw-r--r--storage/innobase/handler/ha_innodb.cc436
-rw-r--r--storage/innobase/handler/ha_innodb.h43
-rw-r--r--storage/innobase/handler/handler0alter.cc6
-rw-r--r--storage/innobase/include/log0recv.h9
-rw-r--r--storage/innobase/lock/lock0lock.cc4
-rw-r--r--storage/innobase/log/log0log.cc13
-rw-r--r--storage/innobase/log/log0recv.cc26
-rw-r--r--storage/innobase/page/page0cur.cc3
-rw-r--r--storage/innobase/row/row0import.cc3
-rw-r--r--storage/innobase/row/row0merge.cc11
-rw-r--r--storage/innobase/row/row0mysql.cc2
-rw-r--r--storage/innobase/row/row0vers.cc1
-rw-r--r--storage/innobase/srv/srv0srv.cc25
-rw-r--r--storage/innobase/trx/trx0purge.cc17
16 files changed, 146 insertions, 459 deletions
diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc
index 7ede67fd0e4..088741e8ce8 100644
--- a/storage/innobase/buf/buf0dump.cc
+++ b/storage/innobase/buf/buf0dump.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, MariaDB Corporation.
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
@@ -391,7 +391,7 @@ buf_dump(
/* leave tmp_filename to exist */
return;
}
- if ( (j % 1024) == 0) {
+ if (SHUTTING_DOWN() && !(j % 1024)) {
service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
"Dumping buffer pool "
ULINTPF "/" ULINTPF ", "
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 51190ff2ef6..3fba1679cdf 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -6110,7 +6110,7 @@ dict_table_get_index_on_name(
while (index != NULL) {
if (index->is_committed() == committed
- && innobase_strcasecmp(index->name, name) == 0) {
+ && strcmp(index->name, name) == 0) {
return(index);
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 52d4c815dc3..bfb7abd7ab3 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -169,8 +169,6 @@ static int innobase_wsrep_set_checkpoint(handlerton* hton, const XID* xid);
static int innobase_wsrep_get_checkpoint(handlerton* hton, XID* xid);
#endif /* WITH_WSREP */
-/** to protect innobase_open_files */
-static mysql_mutex_t innobase_share_mutex;
/** to force correct commit order in binlog */
static ulong commit_threads = 0;
static mysql_cond_t commit_cond;
@@ -461,8 +459,6 @@ operation, we only do it every INNOBASE_WAKE_INTERVAL'th step. */
#define INNOBASE_WAKE_INTERVAL 32
static ulong innobase_active_counter = 0;
-static hash_table_t* innobase_open_tables;
-
/** Allowed values of innodb_change_buffering */
static const char* innodb_change_buffering_names[] = {
"none", /* IBUF_USE_NONE */
@@ -571,7 +567,6 @@ const struct _ft_vft_ext ft_vft_ext_result = {innobase_fts_get_version,
/* Keys to register pthread mutexes/cond in the current file with
performance schema */
-static mysql_pfs_key_t innobase_share_mutex_key;
static mysql_pfs_key_t commit_cond_mutex_key;
static mysql_pfs_key_t commit_cond_key;
static mysql_pfs_key_t pending_checkpoint_mutex_key;
@@ -580,7 +575,6 @@ static mysql_pfs_key_t thd_destructor_thread_key;
static PSI_mutex_info all_pthread_mutexes[] = {
PSI_KEY(commit_cond_mutex),
PSI_KEY(pending_checkpoint_mutex),
- PSI_KEY(innobase_share_mutex)
};
static PSI_cond_info all_innodb_conds[] = {
@@ -1197,23 +1191,6 @@ static SHOW_VAR innodb_status_variables[]= {
{NullS, NullS, SHOW_LONG}
};
-/************************************************************************//**
-Handling the shared INNOBASE_SHARE structure that is needed to provide table
-locking. Register the table name if it doesn't exist in the hash table. */
-static
-INNOBASE_SHARE*
-get_share(
-/*======*/
- const char* table_name); /*!< in: table to lookup */
-
-/************************************************************************//**
-Free the shared object that was registered with get_share(). */
-static
-void
-free_share(
-/*=======*/
- INNOBASE_SHARE* share); /*!< in/own: share to free */
-
/*****************************************************************//**
Frees a possible InnoDB trx object associated with the current THD.
@return 0 or error number */
@@ -4291,10 +4268,6 @@ static int innodb_init(void* p)
ibuf_max_size_update(srv_change_buffer_max_size);
- innobase_open_tables = hash_create(200);
- mysql_mutex_init(innobase_share_mutex_key,
- &innobase_share_mutex,
- MY_MUTEX_INIT_FAST);
mysql_mutex_init(commit_cond_mutex_key,
&commit_cond_m, MY_MUTEX_INIT_FAST);
mysql_cond_init(commit_cond_key, &commit_cond, 0);
@@ -4363,9 +4336,6 @@ innobase_end(handlerton*, ha_panic_function)
}
}
- hash_table_free(innobase_open_tables);
- innobase_open_tables = NULL;
-
st_my_thread_var* running = reinterpret_cast<st_my_thread_var*>(
my_atomic_loadptr_explicit(
reinterpret_cast<void**>(&srv_running),
@@ -4383,7 +4353,6 @@ innobase_end(handlerton*, ha_panic_function)
innodb_shutdown();
innobase_space_shutdown();
- mysql_mutex_destroy(&innobase_share_mutex);
mysql_mutex_destroy(&commit_cond_m);
mysql_cond_destroy(&commit_cond);
mysql_mutex_destroy(&pending_checkpoint_mutex);
@@ -5619,6 +5588,7 @@ is consistent between KEY info from mysql and that from innodb index.
@param[in] key_info Index info from mysql
@param[in] index_info Index info from InnoDB
@return true if all column types match. */
+static
bool
innobase_match_index_columns(
const KEY* key_info,
@@ -5908,90 +5878,33 @@ innobase_build_v_templ(
s_templ->tb_name = table->s->table_name.str;
}
-/*******************************************************************//**
-This function builds a translation table in INNOBASE_SHARE
-structure for fast index location with mysql array number from its
-table->key_info structure. This also provides the necessary translation
-between the key order in mysql key_info and InnoDB ib_table->indexes if
-they are not fully matched with each other.
-Note we do not have any mutex protecting the translation table
-building based on the assumption that there is no concurrent
-index creation/drop and DMLs that requires index lookup. All table
-handle will be closed before the index creation/drop.
-@return true if index translation table built successfully */
-static
-bool
-innobase_build_index_translation(
-/*=============================*/
- const TABLE* table, /*!< in: table in MySQL data
- dictionary */
- dict_table_t* ib_table,/*!< in: table in InnoDB data
- dictionary */
- INNOBASE_SHARE* share) /*!< in/out: share structure
- where index translation table
- will be constructed in. */
+/** Check consistency between .frm indexes and InnoDB indexes.
+@param[in] table table object formed from .frm
+@param[in] ib_table InnoDB table definition
+@retval true if not errors were found */
+static bool
+check_index_consistency(const TABLE* table, const dict_table_t* ib_table)
{
- DBUG_ENTER("innobase_build_index_translation");
-
- bool ret = true;
-
- mutex_enter(&dict_sys->mutex);
-
- ulint mysql_num_index = table->s->keys;
- ulint ib_num_index = UT_LIST_GET_LEN(ib_table->indexes);
- dict_index_t** index_mapping = share->idx_trans_tbl.index_mapping;
+ ulint mysql_num_index = table->s->keys;
+ ulint ib_num_index = UT_LIST_GET_LEN(ib_table->indexes);
+ bool ret = true;
/* If there exists inconsistency between MySQL and InnoDB dictionary
(metadata) information, the number of index defined in MySQL
- could exceed that in InnoDB, do not build index translation
- table in such case */
+ could exceed that in InnoDB, return error */
if (ib_num_index < mysql_num_index) {
ret = false;
goto func_exit;
}
- /* If index entry count is non-zero, nothing has
- changed since last update, directly return TRUE */
- if (share->idx_trans_tbl.index_count) {
- /* Index entry count should still match mysql_num_index */
- ut_a(share->idx_trans_tbl.index_count == mysql_num_index);
- goto func_exit;
- }
-
- /* The number of index increased, rebuild the mapping table */
- if (mysql_num_index > share->idx_trans_tbl.array_size) {
-
- index_mapping = reinterpret_cast<dict_index_t**>(
- ut_realloc(index_mapping,
- mysql_num_index * sizeof(*index_mapping)));
-
- if (index_mapping == NULL) {
- /* Report an error if index_mapping continues to be
- NULL and mysql_num_index is a non-zero value */
- sql_print_error("InnoDB: fail to allocate memory for "
- "index translation table. Number of "
- "Index: " ULINTPF
- ", array size:" ULINTPF,
- mysql_num_index,
- share->idx_trans_tbl.array_size);
- ret = false;
- goto func_exit;
- }
-
- share->idx_trans_tbl.array_size = mysql_num_index;
- }
-
/* For each index in the mysql key_info array, fetch its
corresponding InnoDB index pointer into index_mapping
array. */
for (ulint count = 0; count < mysql_num_index; count++) {
-
- /* Fetch index pointers into index_mapping according to mysql
- index sequence */
- index_mapping[count] = dict_table_get_index_on_name(
+ const dict_index_t* index = dict_table_get_index_on_name(
ib_table, table->key_info[count].name.str);
- if (index_mapping[count] == 0) {
+ if (index == NULL) {
sql_print_error("Cannot find index %s in InnoDB"
" index dictionary.",
table->key_info[count].name.str);
@@ -6002,7 +5915,7 @@ innobase_build_index_translation(
/* Double check fetched index has the same
column info as those in mysql key_info. */
if (!innobase_match_index_columns(&table->key_info[count],
- index_mapping[count])) {
+ index)) {
sql_print_error("Found index %s whose column info"
" does not match that of MariaDB.",
table->key_info[count].name.str);
@@ -6011,51 +5924,10 @@ innobase_build_index_translation(
}
}
- /* Successfully built the translation table */
- share->idx_trans_tbl.index_count = mysql_num_index;
-
func_exit:
- if (!ret) {
- /* Build translation table failed. */
- ut_free(index_mapping);
-
- share->idx_trans_tbl.array_size = 0;
- share->idx_trans_tbl.index_count = 0;
- index_mapping = NULL;
- }
-
- share->idx_trans_tbl.index_mapping = index_mapping;
-
- mutex_exit(&dict_sys->mutex);
-
- DBUG_RETURN(ret);
+ return ret;
}
-/*******************************************************************//**
-This function uses index translation table to quickly locate the
-requested index structure.
-Note we do not have mutex protection for the index translatoin table
-access, it is based on the assumption that there is no concurrent
-translation table rebuild (fter create/drop index) and DMLs that
-require index lookup.
-@return dict_index_t structure for requested index. NULL if
-fail to locate the index structure. */
-static
-dict_index_t*
-innobase_index_lookup(
-/*==================*/
- INNOBASE_SHARE* share, /*!< in: share structure for index
- translation table. */
- uint keynr) /*!< in: index number for the requested
- index */
-{
- if (share->idx_trans_tbl.index_mapping == NULL
- || keynr >= share->idx_trans_tbl.index_count) {
- return(NULL);
- }
-
- return(share->idx_trans_tbl.index_mapping[keynr]);
-}
/********************************************************************//**
Get the upper limit of the MySQL integral and floating-point type.
@return maximum allowed value for the field */
@@ -6185,11 +6057,6 @@ ha_innobase::open(const char* name, int, uint)
m_user_thd = NULL;
- if (!(m_share = get_share(name))) {
-
- DBUG_RETURN(1);
- }
-
/* Will be allocated if it is needed in ::update_row() */
m_upd_buf = NULL;
m_upd_buf_size = 0;
@@ -6213,7 +6080,6 @@ ha_innobase::open(const char* name, int, uint)
norm_name);
}
no_such_table:
- free_share(m_share);
set_my_errno(ENOENT);
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
@@ -6271,7 +6137,6 @@ no_such_table:
}
if (!thd_tablespace_op(thd)) {
- free_share(m_share);
set_my_errno(ENOENT);
int ret_err = HA_ERR_NO_SUCH_TABLE;
@@ -6328,9 +6193,10 @@ no_such_table:
mutex_exit(&dict_sys->mutex);
}
- if (!innobase_build_index_translation(table, ib_table, m_share)) {
- sql_print_error("Build InnoDB index translation table for"
- " Table %s failed", name);
+ if (!check_index_consistency(table, ib_table)) {
+ sql_print_error("InnoDB indexes are inconsistent with what "
+ "defined in .frm for table %s",
+ name);
}
/* Allocate a buffer for a 'row reference'. A row reference is
@@ -6426,9 +6292,6 @@ no_such_table:
/* Index block size in InnoDB: used by MySQL in query optimization */
stats.block_size = srv_page_size;
- /* Init table lock structure */
- thr_lock_data_init(&m_share->lock, &lock, NULL);
-
if (m_prebuilt->table == NULL
|| m_prebuilt->table->is_temporary()
|| m_prebuilt->table->persistent_autoinc
@@ -6621,8 +6484,6 @@ ha_innobase::close()
m_upd_buf_size = 0;
}
- free_share(m_share);
-
MONITOR_INC(MONITOR_TABLE_CLOSE);
/* Tell InnoDB server that there might be work for
@@ -8186,7 +8047,7 @@ ha_innobase::write_row(
/* We need the upper limit of the col type to check for
whether we update the table autoinc counter or not. */
- col_max_value = innobase_get_int_col_max_value(table->next_number_field);
+ col_max_value = table->next_number_field->get_max_int_value();
/* Get the value that MySQL attempted to store in the table.*/
auto_inc = table->next_number_field->val_uint();
@@ -8261,14 +8122,30 @@ set_max_autoinc:
/* This should filter out the negative
values set explicitly by the user. */
if (auto_inc <= col_max_value) {
- ut_a(m_prebuilt->autoinc_increment > 0);
-
ulonglong offset;
ulonglong increment;
dberr_t err;
- offset = m_prebuilt->autoinc_offset;
- increment = m_prebuilt->autoinc_increment;
+#ifdef WITH_WSREP
+ /* Applier threads which are
+ processing ROW events and don't go
+ through server level autoinc
+ processing, therefore m_prebuilt
+ autoinc values don't get
+ properly assigned. Fetch values from
+ server side. */
+ if (wsrep_on(m_user_thd) &&
+ wsrep_thd_exec_mode(m_user_thd) == REPL_RECV) {
+ wsrep_thd_auto_increment_variables(m_user_thd, &offset, &increment);
+ } else {
+#endif /* WITH_WSREP */
+ ut_a(m_prebuilt->autoinc_increment > 0);
+
+ offset = m_prebuilt->autoinc_offset;
+ increment = m_prebuilt->autoinc_increment;
+#ifdef WITH_WSREP
+ }
+#endif /* WITH_WSREP */
auto_inc = innobase_next_autoinc(
auto_inc,
@@ -8966,12 +8843,27 @@ ha_innobase::update_row(
/* A value for an AUTO_INCREMENT column
was specified in the UPDATE statement. */
+ ulonglong offset, increment;
+#ifdef WITH_WSREP
+ /* Applier threads which are processing ROW events and
+ don't go through server level autoinc processing,
+ therefore m_prebuilt autoinc values don't get properly
+ assigned. Fetch values from server side. */
+ if (wsrep_on(m_user_thd)
+ && wsrep_thd_exec_mode(m_user_thd) == REPL_RECV) {
+ wsrep_thd_auto_increment_variables(
+ m_user_thd, &offset, &increment);
+ } else {
+#endif /* WITH_WSREP */
+ offset = m_prebuilt->autoinc_offset;
+ increment = m_prebuilt->autoinc_increment;
+#ifdef WITH_WSREP
+ }
+#endif /* WITH_WSREP */
+
autoinc = innobase_next_autoinc(
- autoinc, 1,
- m_prebuilt->autoinc_increment,
- m_prebuilt->autoinc_offset,
- innobase_get_int_col_max_value(
- table->found_next_number_field));
+ autoinc, 1, increment, offset,
+ table->found_next_number_field->get_max_int_value());
error = innobase_set_max_autoinc(autoinc);
@@ -9489,60 +9381,18 @@ ha_innobase::innobase_get_index(
clustered index, even if it was internally
generated by InnoDB */
{
- KEY* key;
+ KEY* key = NULL;
+ dict_table_t* ib_table = m_prebuilt->table;
dict_index_t* index;
DBUG_ENTER("innobase_get_index");
if (keynr != MAX_KEY && table->s->keys > 0) {
-
- key = table->key_info + keynr;
-
- index = innobase_index_lookup(m_share, keynr);
-
- if (index != NULL) {
- if (!key || ut_strcmp(index->name, key->name.str) != 0) {
- ib::error() << " Index for key no " << keynr
- << " mysql name " << (key ? key->name.str : "NULL")
- << " InnoDB name " << index->name()
- << " for table " << m_prebuilt->table->name.m_name;
-
- for(uint i=0; i < table->s->keys; i++) {
- index = innobase_index_lookup(m_share, i);
- key = table->key_info + keynr;
-
- if (index) {
- ib::info() << " Index for key no " << keynr
- << " mysql name " << (key ? key->name.str : "NULL")
- << " InnoDB name " << index->name()
- << " for table " << m_prebuilt->table->name.m_name;
- }
- }
-
- }
-
- ut_a(ut_strcmp(index->name, key->name.str) == 0);
- } else {
- /* Can't find index with keynr in the translation
- table. Only print message if the index translation
- table exists */
- if (m_share->idx_trans_tbl.index_mapping != NULL) {
- sql_print_warning("InnoDB could not find"
- " index %s key no %u for"
- " table %s through its"
- " index translation table",
- key ? key->name.str : "NULL",
- keynr,
- m_prebuilt->table->name
- .m_name);
- }
-
- index = dict_table_get_index_on_name(
- m_prebuilt->table, key->name.str);
- }
+ key = &table->key_info[keynr];
+ index = dict_table_get_index_on_name(ib_table, key->name.str);
+ ut_ad(index);
} else {
- key = 0;
- index = dict_table_get_first_index(m_prebuilt->table);
+ index = dict_table_get_first_index(ib_table);
}
if (index == NULL) {
@@ -9550,7 +9400,7 @@ ha_innobase::innobase_get_index(
"InnoDB could not find key no %u with name %s"
" from dict cache for table %s",
keynr, key ? key->name.str : "NULL",
- m_prebuilt->table->name.m_name);
+ ib_table->name.m_name);
}
DBUG_RETURN(index);
@@ -13703,20 +13553,12 @@ innodb_set_buf_pool_size(ulonglong buf_pool_size)
}
/*********************************************************************//**
-Calculates the key number used inside MySQL for an Innobase index. We will
-first check the "index translation table" for a match of the index to get
-the index number. If there does not exist an "index translation table",
-or not able to find the index in the translation table, then we will fall back
-to the traditional way of looping through dict_index_t list to find a
-match. In this case, we have to take into account if we generated a
-default clustered index for the table
+Calculates the key number used inside MySQL for an Innobase index.
@return the key number used inside MySQL */
static
unsigned
innobase_get_mysql_key_number_for_index(
/*====================================*/
- INNOBASE_SHARE* share, /*!< in: share structure for index
- translation table. */
const TABLE* table, /*!< in: table in MySQL data
dictionary */
dict_table_t* ib_table,/*!< in: table in InnoDB data
@@ -13746,27 +13588,8 @@ innobase_get_mysql_key_number_for_index(
return(i);
}
- /* If index translation table exists, we will first check
- the index through index translation table for a match. */
- if (share->idx_trans_tbl.index_mapping != NULL) {
- for (i = 0; i < share->idx_trans_tbl.index_count; i++) {
- if (share->idx_trans_tbl.index_mapping[i] == index) {
- return(i);
- }
- }
-
- /* Print an error message if we cannot find the index
- in the "index translation table". */
- if (index->is_committed()) {
- sql_print_error("Cannot find index %s in InnoDB index"
- " translation table.", index->name());
- }
- }
-
- /* If we do not have an "index translation table", or not able
- to find the index in the translation table, we'll directly find
- matching index with information from mysql TABLE structure and
- InnoDB dict_index_t list */
+ /* Directly find matching index with information from mysql TABLE
+ structure and InnoDB dict_index_t list */
for (i = 0; i < table->s->keys; i++) {
ind = dict_table_get_index_on_name(
ib_table, table->key_info[i].name.str);
@@ -14123,11 +13946,6 @@ ha_innobase::info_low(
for (i = 0; i < table->s->keys; i++) {
ulong j;
- /* We could get index quickly through internal
- index mapping with the index translation table.
- The identity of index (match up index name with
- that of table->key_info[i]) is already verified in
- innobase_get_index(). */
dict_index_t* index = innobase_get_index(i);
if (index == NULL) {
@@ -14235,7 +14053,7 @@ ha_innobase::info_low(
if (err_index) {
errkey = innobase_get_mysql_key_number_for_index(
- m_share, table, ib_table, err_index);
+ table, ib_table, err_index);
} else {
errkey = (unsigned int) (
(m_prebuilt->trx->error_key_num
@@ -16240,104 +16058,6 @@ innobase_show_status(
/* Success */
return(false);
}
-
-/************************************************************************//**
-Handling the shared INNOBASE_SHARE structure that is needed to provide table
-locking. Register the table name if it doesn't exist in the hash table. */
-static
-INNOBASE_SHARE*
-get_share(
-/*======*/
- const char* table_name)
-{
- INNOBASE_SHARE* share;
-
- mysql_mutex_lock(&innobase_share_mutex);
-
- ulint fold = ut_fold_string(table_name);
-
- HASH_SEARCH(table_name_hash, innobase_open_tables, fold,
- INNOBASE_SHARE*, share,
- ut_ad(share->use_count > 0),
- !strcmp(share->table_name, table_name));
-
- if (share == NULL) {
-
- uint length = (uint) strlen(table_name);
-
- /* TODO: invoke HASH_MIGRATE if innobase_open_tables
- grows too big */
-
- share = reinterpret_cast<INNOBASE_SHARE*>(
- my_malloc(//PSI_INSTRUMENT_ME,
- sizeof(*share) + length + 1,
- MYF(MY_FAE | MY_ZEROFILL)));
-
- share->table_name = reinterpret_cast<char*>(
- memcpy(share + 1, table_name, length + 1));
-
- HASH_INSERT(INNOBASE_SHARE, table_name_hash,
- innobase_open_tables, fold, share);
-
- thr_lock_init(&share->lock);
-
- /* Index translation table initialization */
- share->idx_trans_tbl.index_mapping = NULL;
- share->idx_trans_tbl.index_count = 0;
- share->idx_trans_tbl.array_size = 0;
- }
-
- ++share->use_count;
-
- mysql_mutex_unlock(&innobase_share_mutex);
-
- return(share);
-}
-
-/************************************************************************//**
-Free the shared object that was registered with get_share(). */
-static
-void
-free_share(
-/*=======*/
- INNOBASE_SHARE* share) /*!< in/own: table share to free */
-{
- mysql_mutex_lock(&innobase_share_mutex);
-
-#ifdef UNIV_DEBUG
- INNOBASE_SHARE* share2;
- ulint fold = ut_fold_string(share->table_name);
-
- HASH_SEARCH(table_name_hash, innobase_open_tables, fold,
- INNOBASE_SHARE*, share2,
- ut_ad(share->use_count > 0),
- !strcmp(share->table_name, share2->table_name));
-
- ut_a(share2 == share);
-#endif /* UNIV_DEBUG */
-
- --share->use_count;
-
- if (share->use_count == 0) {
- ulint fold = ut_fold_string(share->table_name);
-
- HASH_DELETE(INNOBASE_SHARE, table_name_hash,
- innobase_open_tables, fold, share);
-
- thr_lock_delete(&share->lock);
-
- /* Free any memory from index translation table */
- ut_free(share->idx_trans_tbl.index_mapping);
-
- my_free(share);
-
- /* TODO: invoke HASH_MIGRATE if innobase_open_tables
- shrinks too much */
- }
-
- mysql_mutex_unlock(&innobase_share_mutex);
-}
-
/*********************************************************************//**
Returns number of THR_LOCK locks used for one instance of InnoDB table.
InnoDB no longer relies on THR_LOCK locks so 0 value is returned.
@@ -16789,16 +16509,16 @@ ha_innobase::get_auto_increment(
"THD: %ld, current: %llu, autoinc: %llu",
m_prebuilt->autoinc_increment,
increment,
- thd_get_thread_id(ha_thd()),
+ thd_get_thread_id(m_user_thd),
current, autoinc);
- if (!wsrep_on(ha_thd())) {
- current = autoinc - m_prebuilt->autoinc_increment;
+ if (!wsrep_on(m_user_thd)) {
+ current = innobase_next_autoinc(
+ autoinc
+ - m_prebuilt->autoinc_increment,
+ 1, increment, offset, col_max_value);
}
- current = innobase_next_autoinc(
- current, 1, increment, offset, col_max_value);
-
dict_table_autoinc_initialize(
m_prebuilt->table, current);
@@ -20722,6 +20442,7 @@ static TABLE* innodb_acquire_mdl(THD* thd, dict_table_t* table)
if (!table_name_parse(table->name, db_buf, tbl_buf,
db_buf_len, tbl_buf_len)) {
+ table->release();
return NULL;
}
@@ -20804,6 +20525,7 @@ static TABLE* innodb_find_table_for_vc(THD* thd, dict_table_t* table)
if (!table_name_parse(table->name, db_buf, tbl_buf,
db_buf_len, tbl_buf_len)) {
+ ut_ad(!"invalid table name");
return NULL;
}
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index f2bb8aa5ef2..c98779f6823 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -23,35 +23,6 @@ this program; if not, write to the Free Software Foundation, Inc.,
system clustered index when there is no primary key. */
extern const char innobase_index_reserve_name[];
-/* Structure defines translation table between mysql index and InnoDB
-index structures */
-struct innodb_idx_translate_t {
-
- ulint index_count; /*!< number of valid index entries
- in the index_mapping array */
-
- ulint array_size; /*!< array size of index_mapping */
-
- dict_index_t** index_mapping; /*!< index pointer array directly
- maps to index in InnoDB from MySQL
- array index */
-};
-
-/** InnoDB table share */
-typedef struct st_innobase_share {
- THR_LOCK lock;
- const char* table_name; /*!< InnoDB table name */
- uint use_count; /*!< reference count,
- incremented in get_share()
- and decremented in
- free_share() */
- void* table_name_hash;
- /*!< hash table chain node */
- innodb_idx_translate_t
- idx_trans_tbl; /*!< index translation table between
- MySQL and InnoDB */
-} INNOBASE_SHARE;
-
/** Prebuilt structures in an InnoDB table handle used within MySQL */
struct row_prebuilt_t;
@@ -496,9 +467,6 @@ protected:
THR_LOCK_DATA lock;
- /** information for MySQL table locking */
- INNOBASE_SHARE* m_share;
-
/** buffer used in updates */
uchar* m_upd_buf;
@@ -635,17 +603,6 @@ trx_t*
innobase_trx_allocate(
MYSQL_THD thd); /*!< in: user thread handle */
-/** Match index columns between MySQL and InnoDB.
-This function checks whether the index column information
-is consistent between KEY info from mysql and that from innodb index.
-@param[in] key_info Index info from mysql
-@param[in] index_info Index info from InnoDB
-@return true if all column types match. */
-bool
-innobase_match_index_columns(
- const KEY* key_info,
- const dict_index_t* index_info);
-
/*********************************************************************//**
This function checks each index name for a table against reserved
system default primary index name 'GEN_CLUST_INDEX'. If a name
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 3f31f253b3f..f9fca700179 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -9775,12 +9775,6 @@ foreign_fail:
log_append_on_checkpoint(NULL);
- /* Invalidate the index translation table. In partitioned
- tables, there is no share. */
- if (m_share) {
- m_share->idx_trans_tbl.index_count = 0;
- }
-
/* Tell the InnoDB server that there might be work for
utility threads: */
diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h
index eda991661c1..8065ff2c96c 100644
--- a/storage/innobase/include/log0recv.h
+++ b/storage/innobase/include/log0recv.h
@@ -139,10 +139,15 @@ bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t store, bool apply);
/** Moves the parsing buffer data left to the buffer start. */
void recv_sys_justify_left_parsing_buf();
-/** Report optimized DDL operation (without redo log), corresponding to MLOG_INDEX_LOAD.
+/** Report optimized DDL operation (without redo log),
+corresponding to MLOG_INDEX_LOAD.
@param[in] space_id tablespace identifier
*/
-extern void(*log_optimized_ddl_op)(ulint space_id);
+extern void (*log_optimized_ddl_op)(ulint space_id);
+
+/** Report backup-unfriendly TRUNCATE operation (with separate log file),
+corresponding to MLOG_TRUNCATE. */
+extern void (*log_truncate)();
/** Report an operation to create, delete, or rename a file during backup.
@param[in] space_id tablespace identifier
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 07ae85ced5a..b7c4f8d37cd 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -3528,7 +3528,7 @@ lock_table_create(
UT_LIST_ADD_LAST(trx->lock.trx_locks, lock);
#ifdef WITH_WSREP
- if (c_lock) {
+ if (c_lock && wsrep_on_trx(trx)) {
if (wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
ut_list_insert(table->locks, c_lock, lock,
TableLockGetNode());
@@ -3758,7 +3758,7 @@ lock_table_enqueue_waiting(
}
#ifdef WITH_WSREP
- if (trx->lock.was_chosen_as_deadlock_victim) {
+ if (trx->lock.was_chosen_as_deadlock_victim && wsrep_on_trx(trx)) {
return(DB_DEADLOCK);
}
#endif /* WITH_WSREP */
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index 09ed2f16d7d..c871acb5389 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -959,12 +959,6 @@ log_write_up_to(
return;
}
- if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
- service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
- "log write up to: " LSN_PF,
- lsn);
- }
-
loop:
ut_ad(++loop_count < 128);
@@ -1092,6 +1086,13 @@ loop:
}
}
+ if (UNIV_UNLIKELY(srv_shutdown_state != SRV_SHUTDOWN_NONE)) {
+ service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
+ "InnoDB log write: "
+ LSN_PF "," LSN_PF,
+ log_sys.write_lsn, lsn);
+ }
+
if (log_sys.is_encrypted()) {
log_crypt(write_buf + area_start, log_sys.write_lsn,
area_end - area_start);
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 3d240dc58fe..f5c3f1ecb23 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -169,11 +169,16 @@ typedef std::map<
static recv_spaces_t recv_spaces;
-/** Report optimized DDL operation (without redo log), corresponding to MLOG_INDEX_LOAD.
+/** Report optimized DDL operation (without redo log),
+corresponding to MLOG_INDEX_LOAD.
@param[in] space_id tablespace identifier
*/
void (*log_optimized_ddl_op)(ulint space_id);
+/** Report backup-unfriendly TRUNCATE operation (with separate log file),
+corresponding to MLOG_TRUNCATE. */
+void (*log_truncate)();
+
/** Report an operation to create, delete, or rename a file during backup.
@param[in] space_id tablespace identifier
@param[in] flags tablespace flags (NULL if not create)
@@ -189,11 +194,9 @@ void (*log_file_op)(ulint space_id, const byte* flags,
@param[in,out] name file name
@param[in] len length of the file name
@param[in] space_id the tablespace ID
-@param[in] deleted whether this is a MLOG_FILE_DELETE record
-@retval true if able to process file successfully.
-@retval false if unable to process the file */
+@param[in] deleted whether this is a MLOG_FILE_DELETE record */
static
-bool
+void
fil_name_process(
char* name,
ulint len,
@@ -201,15 +204,13 @@ fil_name_process(
bool deleted)
{
if (srv_operation == SRV_OPERATION_BACKUP) {
- return true;
+ return;
}
ut_ad(srv_operation == SRV_OPERATION_NORMAL
|| srv_operation == SRV_OPERATION_RESTORE
|| srv_operation == SRV_OPERATION_RESTORE_EXPORT);
- bool processed = true;
-
/* We will also insert space=NULL into the map, so that
further checks can ensure that a MLOG_FILE_NAME record was
scanned before applying any page records for the space_id. */
@@ -256,7 +257,6 @@ fil_name_process(
<< f.name << "' and '" << name << "'."
" You must delete one of them.";
recv_sys->found_corrupt_fs = true;
- processed = false;
}
break;
@@ -309,7 +309,6 @@ fil_name_process(
" remove the .ibd file, you can set"
" --innodb_force_recovery.";
recv_sys->found_corrupt_fs = true;
- processed = false;
break;
}
@@ -320,7 +319,6 @@ fil_name_process(
break;
}
}
- return(processed);
}
/** Parse or process a MLOG_FILE_* record.
@@ -1093,6 +1091,12 @@ recv_parse_or_apply_log_rec_body(
}
return(ptr + 8);
case MLOG_TRUNCATE:
+ if (log_truncate) {
+ ut_ad(srv_operation != SRV_OPERATION_NORMAL);
+ log_truncate();
+ recv_sys->found_corrupt_fs = true;
+ return NULL;
+ }
return(truncate_t::parse_redo_entry(ptr, end_ptr, space_id));
default:
diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc
index 36b9a135b10..fb8f62f5fe3 100644
--- a/storage/innobase/page/page0cur.cc
+++ b/storage/innobase/page/page0cur.cc
@@ -846,7 +846,8 @@ page_cur_insert_rec_write_log(
ulint i;
if (index->table->is_temporary()) {
- ut_ad(!mlog_open(mtr, 0));
+ mtr->set_modified();
+ ut_ad(mtr->get_log_mode() == MTR_LOG_NO_REDO);
return;
}
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index aab445cb197..8758db3c346 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -3915,7 +3915,7 @@ row_import_for_mysql(
DBUG_EXECUTE_IF("ib_import_reset_space_and_lsn_failure",
err = DB_TOO_MANY_CONCURRENT_TRXS;);
-
+#ifdef BTR_CUR_HASH_ADAPT
/* On DISCARD TABLESPACE, we did not drop any adaptive hash
index entries. If we replaced the discarded tablespace with a
smaller one here, there could still be some adaptive hash
@@ -3932,6 +3932,7 @@ row_import_for_mysql(
break;
}
}
+#endif /* BTR_CUR_HASH_ADAPT */
if (err != DB_SUCCESS) {
char table_name[MAX_FULL_NAME_LEN + 1];
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index ba8a7044baa..000da4b0562 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -3934,17 +3934,6 @@ row_merge_drop_indexes(
ut_ad(prev);
ut_a(table->fts);
fts_drop_index(table, index, trx);
- /* Since
- INNOBASE_SHARE::idx_trans_tbl
- is shared between all open
- ha_innobase handles to this
- table, no thread should be
- accessing this dict_index_t
- object. Also, we should be
- holding LOCK=SHARED MDL on the
- table even after the MDL
- upgrade timeout. */
-
/* We can remove a DICT_FTS
index from the cache, because
we do not allow ADD FULLTEXT INDEX
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index a3c3d0eaaa6..7c68bf6f7c2 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -3536,6 +3536,7 @@ row_drop_table_for_mysql(
if (!table->no_rollback()) {
if (table->space != fil_system.sys_space) {
+#ifdef BTR_CUR_HASH_ADAPT
/* On DISCARD TABLESPACE, we would not drop the
adaptive hash index entries. If the tablespace is
missing here, delete-marking the record in SYS_INDEXES
@@ -3557,6 +3558,7 @@ row_drop_table_for_mysql(
goto funct_exit;
}
}
+#endif /* BTR_CUR_HASH_ADAPT */
/* Delete the link file if used. */
if (DICT_TF_HAS_DATA_DIR(table->flags)) {
diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc
index 187fa2a0929..fac01fe26cc 100644
--- a/storage/innobase/row/row0vers.cc
+++ b/storage/innobase/row/row0vers.cc
@@ -452,6 +452,7 @@ row_vers_build_clust_v_col(
byte* record= 0;
ut_ad(dict_index_has_virtual(index));
+ ut_ad(index->table == clust_index->table);
if (vcol_info != NULL) {
vcol_info->set_used();
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 44cb3276561..ae4922af235 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -2417,7 +2417,22 @@ static bool srv_purge_should_exit()
return(true);
}
/* Slow shutdown was requested. */
- return !trx_sys.any_active_transactions() && !trx_sys.history_size();
+ if (ulint history_size = trx_sys.history_size()) {
+#if defined HAVE_SYSTEMD && !defined EMBEDDED_LIBRARY
+ static ib_time_t progress_time;
+ ib_time_t time = ut_time();
+ if (time - progress_time >= 15) {
+ progress_time = time;
+ service_manager_extend_timeout(
+ INNODB_EXTEND_TIMEOUT_INTERVAL,
+ "InnoDB: to purge " ULINTPF " transactions",
+ history_size);
+ }
+#endif
+ return false;
+ }
+
+ return !trx_sys.any_active_transactions();
}
/*********************************************************************//**
@@ -2583,14 +2598,6 @@ srv_do_purge(ulint* n_total_purged)
(++count % rseg_truncate_frequency) == 0);
*n_total_purged += n_pages_purged;
-
- if (n_pages_purged) {
- service_manager_extend_timeout(
- INNODB_EXTEND_TIMEOUT_INTERVAL,
- "InnoDB " ULINTPF " pages purged", n_pages_purged);
- /* The previous round still did some work. */
- continue;
- }
} while (n_pages_purged > 0 && !purge_sys.paused()
&& !srv_purge_should_exit());
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index 32e050e9b91..8f6e585f66b 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -258,7 +258,12 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
trx_sys.get_max_trx_id(), mtr);
}
- /* Before any transaction-generating background threads or the
+ /* After the purge thread has been given permission to exit,
+ we may roll back transactions (trx->undo_no==0)
+ in THD::cleanup() invoked from unlink_thd() in fast shutdown,
+ or in trx_rollback_resurrected() in slow shutdown.
+
+ Before any transaction-generating background threads or the
purge have been started, recv_recovery_rollback_active() can
start transactions in row_merge_drop_temp_indexes() and
fts_drop_orphaned_tables(), and roll back recovered transactions.
@@ -268,17 +273,15 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
innodb_force_recovery=2 or innodb_force_recovery=3.
DROP TABLE may be executed at any innodb_force_recovery level.
- After the purge thread has been given permission to exit,
- in fast shutdown, we may roll back transactions (trx->undo_no==0)
- in THD::cleanup() invoked from unlink_thd(), and we may also
- continue to execute user transactions. */
+ During fast shutdown, we may also continue to execute
+ user transactions. */
ut_ad(srv_undo_sources
+ || trx->undo_no == 0
|| (!purge_sys.enabled()
&& (srv_startup_is_before_trx_rollback_phase
|| trx_rollback_is_active
|| srv_force_recovery >= SRV_FORCE_NO_BACKGROUND))
- || ((trx->undo_no == 0 || trx->mysql_thd
- || trx->internal)
+ || ((trx->mysql_thd || trx->internal)
&& srv_fast_shutdown));
#ifdef WITH_WSREP