From 094de71742fbed4d49d38017d56f13100050c747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 31 Aug 2021 13:54:20 +0300 Subject: [PATCH] MDEV-25919 preparation: Various cleanup que_eval_sql(): Remove the parameter lock_dict. The only caller with lock_dict=true was dict_stats_exec_sql(), which will now explicitly invoke dict_sys.lock() and dict_sys.unlock() by itself. row_import_cleanup(): Do not unnecessarily lock the dictionary. Concurrent access to the table during ALTER TABLE...IMPORT TABLESPACE is prevented by MDL and the fact that there cannot exist any undo log or change buffer records that would refer to the table or tablespace. row_import_for_mysql(): Do not unnecessarily lock the dictionary while accessing fil_system. Thanks to MDL_EXCLUSIVE that was acquired by the SQL layer, only one IMPORT may be in effect for the table name. row_quiesce_set_state(): Do not unnecessarily lock the dictionary. The dict_table_t::quiesce state is documented to be protected by all index latches, which we are acquiring. dict_table_close(): Introduce a simpler variant with fewer parameters. dict_table_close(): Reduce the amount of calls. We can simply invoke dict_table_t::release() on startup or in DDL operations, or when the table is inaccessible. In none of these cases, there is no need to invalidate the InnoDB persistent statistics. pars_info_t::graph_owns_us: Remove (unused). pars_info_free(): Define inline. fts_delete(), trx_t::evict_table(), row_prebuilt_free(), row_rename_table_for_mysql(): Simplify. row_mysql_lock_data_dictionary(): Remove some references; use dict_sys.lock() and dict_sys.unlock() instead. row_mysql_lock_table(): Remove. Use lock_table_for_trx() instead. ha_innobase::check_if_supported_inplace_alter(), row_create_table_for_mysql(): Simply assert dict_sys.sys_tables_exist(). In commit 49e2c8f0a6fefdeac50925f758090d6bd099768d and commit 1bd681c8b3c5213ce1f7976940a7dc38b48a0d39 srv_start() actually guarantees that the system tables will exist, or the server is in read-only mode, or startup will fail. Reviewed by: Thirunarayanan Balathandayuthapani --- storage/innobase/dict/dict0crea.cc | 8 +- storage/innobase/dict/dict0dict.cc | 38 +++++---- storage/innobase/dict/dict0stats.cc | 10 +-- storage/innobase/dict/dict0stats_bg.cc | 6 +- storage/innobase/dict/drop.cc | 6 +- storage/innobase/fts/fts0fts.cc | 42 ++++------ storage/innobase/handler/ha_innodb.cc | 53 ++++++------- storage/innobase/handler/handler0alter.cc | 61 ++++++--------- storage/innobase/include/dict0dict.h | 20 ++--- storage/innobase/include/fts0fts.h | 6 +- storage/innobase/include/pars0pars.h | 12 +-- storage/innobase/include/que0que.h | 3 - storage/innobase/include/row0mysql.h | 21 +---- storage/innobase/pars/pars0pars.cc | 16 +--- storage/innobase/que/que0que.cc | 21 +---- storage/innobase/row/row0import.cc | 27 ++----- storage/innobase/row/row0ins.cc | 4 +- storage/innobase/row/row0merge.cc | 10 +-- storage/innobase/row/row0mysql.cc | 93 +++-------------------- storage/innobase/row/row0quiesce.cc | 4 - storage/innobase/row/row0upd.cc | 8 +- storage/innobase/trx/trx0trx.cc | 11 ++- 22 files changed, 153 insertions(+), 327 deletions(-) diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index c293ab302a355..eafc9bf78146a 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -1403,7 +1403,7 @@ dberr_t dict_sys_t::create_or_check_sys_tables() " ON SYS_FOREIGN (FOR_NAME);\n" "CREATE INDEX REF_IND" " ON SYS_FOREIGN (REF_NAME);\n" - "END;\n", false, trx); + "END;\n", trx); if (UNIV_UNLIKELY(error != DB_SUCCESS)) { tablename= SYS_TABLE[SYS_FOREIGN].data(); @@ -1425,7 +1425,7 @@ dberr_t dict_sys_t::create_or_check_sys_tables() " FOR_COL_NAME CHAR, REF_COL_NAME CHAR);\n" "CREATE UNIQUE CLUSTERED INDEX ID_IND" " ON SYS_FOREIGN_COLS (ID, POS);\n" - "END;\n", false, trx); + "END;\n", trx); if (UNIV_UNLIKELY(error != DB_SUCCESS)) { tablename= SYS_TABLE[SYS_FOREIGN_COLS].data(); @@ -1440,7 +1440,7 @@ dberr_t dict_sys_t::create_or_check_sys_tables() "SYS_VIRTUAL(TABLE_ID BIGINT,POS INT,BASE_POS INT);\n" "CREATE UNIQUE CLUSTERED INDEX BASE_IDX" " ON SYS_VIRTUAL(TABLE_ID, POS, BASE_POS);\n" - "END;\n", false, trx); + "END;\n", trx); if (UNIV_UNLIKELY(error != DB_SUCCESS)) { tablename= SYS_TABLE[SYS_VIRTUAL].data(); @@ -1504,7 +1504,7 @@ dict_foreign_eval_sql( dberr_t error; FILE* ef = dict_foreign_err_file; - error = que_eval_sql(info, sql, FALSE, trx); + error = que_eval_sql(info, sql, trx); if (error == DB_DUPLICATE_KEY) { mysql_mutex_lock(&dict_foreign_err_mutex); diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 400cda111fe03..13b71c9a8b68b 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -299,6 +299,25 @@ dict_table_try_drop_aborted_and_unlock( } } +/** Decrement the count of open handles */ +void dict_table_close(dict_table_t *table) +{ + if (dict_stats_is_persistent_enabled(table) && + strchr(table->name.m_name, '/')) + { + dict_sys.freeze(SRW_LOCK_CALL); + if (table->release()) + { + table->stats_mutex_lock(); + dict_stats_deinit(table); + table->stats_mutex_unlock(); + } + dict_sys.unfreeze(); + } + else + table->release(); +} + /** Decrements the count of open handles of a table. @param[in,out] table table @param[in] dict_locked data dictionary locked @@ -4223,12 +4242,7 @@ void dict_set_encrypted_by_space(const fil_space_t* space) /**********************************************************************//** Flags an index corrupted both in the data dictionary cache and in the SYS_INDEXES */ -void -dict_set_corrupted( -/*===============*/ - dict_index_t* index, /*!< in/out: index */ - trx_t* trx, /*!< in/out: transaction */ - const char* ctx) /*!< in: context */ +void dict_set_corrupted(dict_index_t *index, const char *ctx, bool dict_locked) { mem_heap_t* heap; mtr_t mtr; @@ -4238,10 +4252,9 @@ dict_set_corrupted( byte* buf; const char* status; btr_cur_t cursor; - bool locked = RW_X_LATCH == trx->dict_operation_lock_mode; - if (!locked) { - row_mysql_lock_data_dictionary(trx); + if (!dict_locked) { + dict_sys.lock(SRW_LOCK_CALL); } ut_ad(dict_sys.locked()); @@ -4311,14 +4324,13 @@ dict_set_corrupted( } mtr_commit(&mtr); - mem_heap_empty(heap); + mem_heap_free(heap); ib::error() << status << " corruption of " << index->name << " in table " << index->table->name << " in " << ctx; - mem_heap_free(heap); func_exit: - if (!locked) { - row_mysql_unlock_data_dictionary(trx); + if (!dict_locked) { + dict_sys.unlock(); } } diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index ee72d7db3cdf1..9c4d87f3feaac 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -533,13 +533,13 @@ dberr_t dict_stats_exec_sql(pars_info_t *pinfo, const char* sql, trx_t *trx) } if (trx) - return que_eval_sql(pinfo, sql, FALSE, trx); + return que_eval_sql(pinfo, sql, trx); trx= trx_create(); trx_start_internal(trx); trx->dict_operation_lock_mode= RW_X_LATCH; - dberr_t err= que_eval_sql(pinfo, sql, FALSE, trx); + dberr_t err= que_eval_sql(pinfo, sql, trx); if (err == DB_SUCCESS) trx->commit(); @@ -3255,7 +3255,7 @@ dict_stats_fetch_from_ps( "fetch_index_stats_step", dict_stats_fetch_index_stats_step, &index_fetch_arg); - + dict_sys.lock(SRW_LOCK_CALL); /* FIXME: remove this */ ret = que_eval_sql(pinfo, "PROCEDURE FETCH_STATS () IS\n" "found INT;\n" @@ -3309,9 +3309,9 @@ dict_stats_fetch_from_ps( "END LOOP;\n" "CLOSE index_stats_cur;\n" - "END;", - TRUE, trx); + "END;", trx); /* pinfo is freed by que_eval_sql() */ + dict_sys.unlock(); trx_commit_for_mysql(trx); diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc index 209a2f33ba9c9..23b00bb8e2385 100644 --- a/storage/innobase/dict/dict0stats_bg.cc +++ b/storage/innobase/dict/dict0stats_bg.cc @@ -348,7 +348,7 @@ static bool dict_stats_process_entry_from_recalc_pool() ut_ad(!table->is_temporary()); if (!table->is_accessible()) { - dict_table_close(table, TRUE, FALSE); + table->release(); no_table: dict_sys.unlock(); goto next_table_id; @@ -382,12 +382,10 @@ static bool dict_stats_process_entry_from_recalc_pool() } dict_sys.lock(SRW_LOCK_CALL); - table->stats_bg_flag = BG_STAT_NONE; - dict_table_close(table, TRUE, FALSE); - dict_sys.unlock(); + return ret; } diff --git a/storage/innobase/dict/drop.cc b/storage/innobase/dict/drop.cc index bb0af50c4c284..f837798ab8f0a 100644 --- a/storage/innobase/dict/drop.cc +++ b/storage/innobase/dict/drop.cc @@ -108,7 +108,7 @@ dberr_t trx_t::drop_table_foreign(const table_name_t &name) " DELETE FROM SYS_FOREIGN WHERE ID=fid;\n" "END LOOP;\n" "CLOSE fk;\n" - "END;\n", FALSE, this); + "END;\n", this); } /** Try to drop the statistics for a persistent table. @@ -182,7 +182,7 @@ dberr_t trx_t::drop_table(const dict_table_t &table) "BEGIN\n" "DELETE FROM SYS_VIRTUAL" " WHERE TABLE_ID=:id;\n" - "END;\n", FALSE, this)) + "END;\n", this)) return err; } @@ -224,7 +224,7 @@ dberr_t trx_t::drop_table(const dict_table_t &table) "END LOOP;\n" "CLOSE idx;\n" - "END;\n", FALSE, this); + "END;\n", this); } /** Commit the transaction, possibly after drop_table(). diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index fd2f689825a4c..1d0d9b7148900 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1593,8 +1593,7 @@ dberr_t fts_lock_tables(trx_t *trx, const dict_table_t &table) } /** Drops the common ancillary tables needed for supporting an FTS index -on the given table. row_mysql_lock_data_dictionary must have been called -before this. +on the given table. @param trx transaction to drop fts common table @param fts_table table with an FTS index @param rename whether to rename before dropping @@ -1653,8 +1652,7 @@ dberr_t fts_drop_index_tables(trx_t *trx, const dict_index_t &index) /****************************************************************//** Drops FTS ancillary tables needed for supporting an FTS index -on the given table. row_mysql_lock_data_dictionary must have been called -before this. +on the given table. @return DB_SUCCESS or error code */ static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t @@ -1795,8 +1793,7 @@ fts_create_one_common_table( } /** Creates the common auxiliary tables needed for supporting an FTS index -on the given table. row_mysql_lock_data_dictionary must have been called -before this. +on the given table. The following tables are created. CREATE TABLE $FTS_PREFIX_DELETED (doc_id BIGINT UNSIGNED, UNIQUE CLUSTERED INDEX on doc_id) @@ -1974,8 +1971,7 @@ fts_create_one_index_table( } /** Creates the column specific ancillary tables needed for supporting an -FTS index on the given table. row_mysql_lock_data_dictionary must have -been called before this. +FTS index on the given table. All FTS AUX Index tables have the following schema. CREAT TABLE $FTS_PREFIX_INDEX_[1-6]( @@ -2754,7 +2750,6 @@ fts_delete( { que_t* graph; fts_table_t fts_table; - dberr_t error = DB_SUCCESS; doc_id_t write_doc_id; dict_table_t* table = ftt->table; doc_id_t doc_id = row->doc_id; @@ -2765,7 +2760,7 @@ fts_delete( /* we do not index Documents whose Doc ID value is 0 */ if (doc_id == FTS_NULL_DOC_ID) { ut_ad(!DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID)); - return(error); + return DB_SUCCESS; } ut_a(row->state == FTS_DELETE || row->state == FTS_MODIFY); @@ -2800,29 +2795,20 @@ fts_delete( } /* Note the deleted document for OPTIMIZE to purge. */ - if (error == DB_SUCCESS) { - char table_name[MAX_FULL_NAME_LEN]; + char table_name[MAX_FULL_NAME_LEN]; - trx->op_info = "adding doc id to FTS DELETED"; + trx->op_info = "adding doc id to FTS DELETED"; - info->graph_owns_us = TRUE; + fts_table.suffix = "DELETED"; - fts_table.suffix = "DELETED"; - - fts_get_table_name(&fts_table, table_name); - pars_info_bind_id(info, "deleted", table_name); - - graph = fts_parse_sql( - &fts_table, - info, - "BEGIN INSERT INTO $deleted VALUES (:doc_id);"); + fts_get_table_name(&fts_table, table_name); + pars_info_bind_id(info, "deleted", table_name); - error = fts_eval_sql(trx, graph); + graph = fts_parse_sql(&fts_table, info, + "BEGIN INSERT INTO $deleted VALUES (:doc_id);"); - que_graph_free(graph); - } else { - pars_info_free(info); - } + dberr_t error = fts_eval_sql(trx, graph); + que_graph_free(graph); /* Increment the total deleted count, this is used to calculate the number of documents indexed. */ diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 0a57b847d14ee..96a9012e1cbf4 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1339,7 +1339,7 @@ static void innodb_drop_database(handlerton*, char *path) trx_t *trx= innobase_trx_allocate(current_thd); retry: - row_mysql_lock_data_dictionary(trx); + dict_sys.lock(SRW_LOCK_CALL); for (auto i= dict_sys.table_id_hash.n_cells; i--; ) { @@ -1350,7 +1350,7 @@ static void innodb_drop_database(handlerton*, char *path) if (!strncmp(table->name.m_name, namebuf, len) && !dict_stats_stop_bg(table)) { - row_mysql_unlock_data_dictionary(trx); + dict_sys.unlock(); std::this_thread::sleep_for(std::chrono::milliseconds(250)); goto retry; } @@ -1385,6 +1385,7 @@ static void innodb_drop_database(handlerton*, char *path) } } + trx->dict_operation_lock_mode= RW_X_LATCH; trx_start_for_ddl(trx); uint errors= 0; char db[NAME_LEN + 1]; @@ -1467,7 +1468,7 @@ static void innodb_drop_database(handlerton*, char *path) ? innodb_drop_database_fk : innodb_drop_database_ignore_fk, &report); pars_info_add_str_literal(pinfo, "db", namebuf); - err= que_eval_sql(pinfo, drop_database, false, trx); + err= que_eval_sql(pinfo, drop_database, trx); if (err == DB_SUCCESS && report.violated) err= DB_CANNOT_DROP_CONSTRAINT; } @@ -1940,7 +1941,7 @@ static int innodb_check_version(handlerton *hton, const char *path, { const trx_id_t trx_id= table->def_trx_id; DBUG_ASSERT(trx_id <= create_id); - dict_table_close(table, false, false); + dict_table_close(table); DBUG_PRINT("info", ("create_id: %llu trx_id: %llu", create_id, trx_id)); DBUG_RETURN(create_id != trx_id); } @@ -3197,7 +3198,7 @@ static bool innobase_query_caching_table_check( bool allow = innobase_query_caching_table_check_low(table, trx); - dict_table_close(table, FALSE, FALSE); + dict_table_close(table); if (allow) { /* If the isolation level is high, assign a read view for the @@ -5858,7 +5859,7 @@ ha_innobase::open(const char* name, int, uint) or force recovery can still use it, but not others. */ ib_table->file_unreadable = true; ib_table->corrupted = true; - dict_table_close(ib_table, FALSE, FALSE); + ib_table->release(); set_my_errno(ENOENT); DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); } @@ -5905,7 +5906,7 @@ ha_innobase::open(const char* name, int, uint) ret_err = HA_ERR_DECRYPTION_FAILED; } - dict_table_close(ib_table, FALSE, FALSE); + ib_table->release(); DBUG_RETURN(ret_err); } } @@ -6219,7 +6220,7 @@ ha_innobase::close() { DBUG_ENTER("ha_innobase::close"); - row_prebuilt_free(m_prebuilt, FALSE); + row_prebuilt_free(m_prebuilt); if (m_upd_buf != NULL) { ut_ad(m_upd_buf_size != 0); @@ -13016,7 +13017,7 @@ create_table_info_t::create_table_update_dict() /* Load server stopword into FTS cache */ if (m_flags2 & DICT_TF2_FTS) { if (!innobase_fts_load_stopword(innobase_table, NULL, m_thd)) { - dict_table_close(innobase_table, FALSE, FALSE); + innobase_table->release(); DBUG_RETURN(-1); } @@ -13067,7 +13068,7 @@ create_table_info_t::create_table_update_dict() innobase_parse_hint_from_comment(m_thd, innobase_table, m_form->s); - dict_table_close(innobase_table, FALSE, FALSE); + dict_table_close(innobase_table); DBUG_RETURN(0); } @@ -13217,10 +13218,8 @@ ha_innobase::discard_or_import_tablespace( trx_start_if_not_started(m_prebuilt->trx, true); /* Obtain an exclusive lock on the table. */ - dberr_t err = row_mysql_lock_table( - m_prebuilt->trx, m_prebuilt->table, LOCK_X, - discard ? "setting table lock for DISCARD TABLESPACE" - : "setting table lock for IMPORT TABLESPACE"); + dberr_t err = lock_table_for_trx(m_prebuilt->table, + m_prebuilt->trx, LOCK_X); if (err != DB_SUCCESS) { /* unable to lock the table: do nothing */ @@ -13282,7 +13281,7 @@ ha_innobase::discard_or_import_tablespace( table_id_t id = m_prebuilt->table->id; ut_ad(id); dict_sys.lock(SRW_LOCK_CALL); - dict_table_close(m_prebuilt->table, TRUE, FALSE); + m_prebuilt->table->release(); dict_sys.remove(m_prebuilt->table); m_prebuilt->table = dict_table_open_on_id(id, TRUE, DICT_TABLE_OP_NORMAL); @@ -13627,7 +13626,7 @@ int ha_innobase::truncate() info.options|= HA_LEX_CREATE_TMP_TABLE; btr_drop_temporary_table(*ib_table); m_prebuilt->table = nullptr; - row_prebuilt_free(m_prebuilt, false); + row_prebuilt_free(m_prebuilt); m_prebuilt = nullptr; my_free(m_upd_buf); m_upd_buf = nullptr; @@ -13742,7 +13741,7 @@ int ha_innobase::truncate() m_prebuilt->stored_select_lock_type = stored_lock; m_prebuilt->table->update_time = update_time; - row_prebuilt_free(prebuilt, false); + row_prebuilt_free(prebuilt); my_free(upd_buf); } else { /* Revert to the old table. */ @@ -14837,8 +14836,7 @@ ha_innobase::check( index = dict_table_get_first_index(m_prebuilt->table); if (!index->is_corrupted()) { - dict_set_corrupted( - index, m_prebuilt->trx, "CHECK TABLE"); + dict_set_corrupted(index, "CHECK TABLE", false); } push_warning_printf(m_user_thd, @@ -14919,9 +14917,9 @@ ha_innobase::check( "dict_set_index_corrupted", if (!index->is_primary()) { m_prebuilt->index_usable = FALSE; - // row_mysql_lock_data_dictionary(m_prebuilt->trx); - dict_set_corrupted(index, m_prebuilt->trx, "dict_set_index_corrupted"); - // row_mysql_unlock_data_dictionary(m_prebuilt->trx); + dict_set_corrupted(index, + "dict_set_index_corrupted", + false); }); if (UNIV_UNLIKELY(!m_prebuilt->index_usable)) { @@ -14983,8 +14981,8 @@ ha_innobase::check( " index %s is corrupted.", index->name()); is_ok = false; - dict_set_corrupted( - index, m_prebuilt->trx, "CHECK TABLE-check index"); + dict_set_corrupted(index, "CHECK TABLE-check index", + false); } @@ -14999,9 +14997,8 @@ ha_innobase::check( " entries, should be " ULINTPF ".", index->name(), n_rows, n_rows_in_table); is_ok = false; - dict_set_corrupted( - index, m_prebuilt->trx, - "CHECK TABLE; Wrong count"); + dict_set_corrupted(index, "CHECK TABLE; Wrong count", + false); } } @@ -17103,7 +17100,7 @@ static int innodb_ft_aux_table_validate(THD *thd, st_mysql_sys_var*, table_name, FALSE, TRUE, DICT_ERR_IGNORE_NONE)) { const table_id_t id = dict_table_has_fts_index(table) ? table->id : 0; - dict_table_close(table, FALSE, FALSE); + dict_table_close(table); if (id) { innodb_ft_aux_table_id = id; if (table_name == buf) { diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index e7b01a4f72be3..a9801cd35ae2e 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -2052,11 +2052,7 @@ ha_innobase::check_if_supported_inplace_alter( DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } - if (!dict_sys.sys_tables_exist()) { - ha_alter_info->unsupported_reason - = "missing InnoDB system tables"; - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - } + ut_ad(dict_sys.sys_tables_exist()); /* Only support online add foreign key constraint when check_foreigns is turned off */ @@ -4824,8 +4820,7 @@ innobase_update_gis_column_type( "BEGIN\n" "UPDATE SYS_COLUMNS SET MTYPE=:mtype\n" "WHERE TABLE_ID=:tableid AND NAME=:name;\n" - "END;\n", - false, trx); + "END;\n", trx); trx->error_state = DB_SUCCESS; trx->op_info = ""; @@ -5144,8 +5139,7 @@ static bool innobase_insert_sys_virtual( "PROCEDURE P () IS\n" "BEGIN\n" "INSERT INTO SYS_VIRTUAL VALUES (:id, :pos, :base_pos);\n" - "END;\n", - FALSE, trx)) { + "END;\n", trx)) { my_error(ER_INTERNAL_ERROR, MYF(0), "InnoDB: ADD COLUMN...VIRTUAL"); return true; @@ -5194,7 +5188,7 @@ static bool innodb_insert_sys_columns( "NAME=:name, MTYPE=:mtype, PRTYPE=:prtype, " "LEN=:len, PREC=:base\n" "WHERE TABLE_ID=:id AND POS=:pos;\n" - "END;\n", FALSE, trx)) { + "END;\n", trx)) { my_error(ER_INTERNAL_ERROR, MYF(0), "InnoDB: Updating SYS_COLUMNS failed"); return true; @@ -5209,7 +5203,7 @@ static bool innodb_insert_sys_columns( "BEGIN\n" "INSERT INTO SYS_COLUMNS VALUES" "(:id,:pos,:name,:mtype,:prtype,:len,:base);\n" - "END;\n", FALSE, trx)) { + "END;\n", trx)) { my_error(ER_INTERNAL_ERROR, MYF(0), "InnoDB: Insert into SYS_COLUMNS failed"); return true; @@ -5267,7 +5261,7 @@ static bool innodb_update_cols(const dict_table_t* table, ulint n, trx_t* trx) "BEGIN\n" "UPDATE SYS_TABLES SET N_COLS = :n" " WHERE ID = :id;\n" - "END;\n", FALSE, trx)) { + "END;\n", trx)) { my_error(ER_INTERNAL_ERROR, MYF(0), "InnoDB: Updating SYS_TABLES.N_COLS failed"); return true; @@ -5322,7 +5316,7 @@ static bool innobase_instant_drop_cols(table_id_t id, ulint pos, trx_t* trx) "DELETE FROM SYS_COLUMNS WHERE\n" "TABLE_ID = :id AND POS >= :pos;\n" "DELETE FROM SYS_VIRTUAL WHERE TABLE_ID = :id;\n" - "END;\n", FALSE, trx); + "END;\n", trx); if (err != DB_SUCCESS) { my_error(ER_INTERNAL_ERROR, MYF(0), "InnoDB: DELETE from SYS_COLUMNS/SYS_VIRTUAL failed"); @@ -5360,8 +5354,7 @@ innobase_update_v_pos_sys_columns( "SET POS = :val\n" "WHERE POS = :pos\n" "AND TABLE_ID = :id;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); return(error); } @@ -5394,8 +5387,7 @@ innobase_update_v_pos_sys_virtual( "SET POS = :val\n" "WHERE POS = :pos\n" "AND TABLE_ID = :id;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); return(error); } @@ -5429,8 +5421,7 @@ innobase_drop_one_virtual_sys_columns( "DELETE FROM SYS_COLUMNS\n" "WHERE TABLE_ID = :id\n" "AND NAME = :name;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); if (error != DB_SUCCESS) { return(error); @@ -5488,8 +5479,7 @@ innobase_drop_one_virtual_sys_virtual( "DELETE FROM SYS_VIRTUAL\n" "WHERE TABLE_ID = :id\n" "AND POS = :pos;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); return(error); } @@ -7367,8 +7357,7 @@ rename_index_try( "WHERE\n" "ID = :index_id AND\n" "TABLE_ID = :table_id;\n" - "END;\n", - FALSE, trx); /* pinfo is freed by que_eval_sql() */ + "END;\n", trx); /* pinfo is freed by que_eval_sql() */ DBUG_EXECUTE_IF( "ib_rename_index_fail1", @@ -8864,7 +8853,7 @@ innobase_drop_foreign_try( pars_info_add_str_literal(info, "id", foreign_id); trx->op_info = "dropping foreign key constraint from dictionary"; - error = que_eval_sql(info, sql, FALSE, trx); + error = que_eval_sql(info, sql, trx); trx->op_info = ""; DBUG_EXECUTE_IF("ib_drop_foreign_error", @@ -8949,8 +8938,7 @@ innobase_rename_column_try( "UPDATE SYS_FIELDS SET COL_NAME=:new\n" "WHERE INDEX_ID=:indexid\n" "AND POS=:nth;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); DBUG_EXECUTE_IF("ib_rename_column_error", error = DB_OUT_OF_FILE_SPACE;); @@ -8980,8 +8968,7 @@ innobase_rename_column_try( "UPDATE SYS_FIELDS SET COL_NAME=:new\n" "WHERE INDEX_ID=:indexid\n" "AND POS=:nth;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); if (error != DB_SUCCESS) { goto err_exit; @@ -9042,8 +9029,7 @@ innobase_rename_column_try( "UPDATE SYS_FOREIGN_COLS\n" "SET FOR_COL_NAME=:new\n" "WHERE ID=:id AND POS=:nth;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); if (error != DB_SUCCESS) { goto err_exit; @@ -9084,8 +9070,7 @@ innobase_rename_column_try( "UPDATE SYS_FOREIGN_COLS\n" "SET REF_COL_NAME=:new\n" "WHERE ID=:id AND POS=:nth;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); if (error != DB_SUCCESS) { goto err_exit; @@ -9761,8 +9746,7 @@ vers_change_field_try( "BEGIN\n" "UPDATE SYS_COLUMNS SET PRTYPE=:prtype\n" "WHERE TABLE_ID=:tableid AND POS=:pos;\n" - "END;\n", - false, trx); + "END;\n", trx); if (error != DB_SUCCESS) { my_error_innodb(error, table_name, 0); @@ -10105,8 +10089,7 @@ innobase_page_compression_try( "BEGIN\n" "UPDATE SYS_TABLES SET TYPE=:type\n" "WHERE ID=:id;\n" - "END;\n", - false, trx); + "END;\n", trx); if (error != DB_SUCCESS) { my_error_innodb(error, table_name, 0); @@ -10262,7 +10245,7 @@ commit_try_norebuild( pars_info_t* info = pars_info_create(); pars_info_add_ull_literal(info, "indexid", index->id); - error = que_eval_sql(info, drop_index, FALSE, trx); + error = que_eval_sql(info, drop_index, trx); if (error == DB_SUCCESS && index->type & DICT_FTS) { DBUG_ASSERT(index->table->fts); @@ -11030,7 +11013,9 @@ ha_innobase::commit_inplace_alter_table( ut_ad(ctx->new_table->get_ref_count() == 1); const bool own = m_prebuilt == ctx->prebuilt; trx_t* const user_trx = m_prebuilt->trx; - row_prebuilt_free(ctx->prebuilt, true); + ctx->prebuilt->table->release(); + ctx->prebuilt->table = nullptr; + row_prebuilt_free(ctx->prebuilt); /* Rebuild the prebuilt object. */ ctx->prebuilt = row_create_prebuilt( ctx->new_table, altered_table->s->reclength); diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 1842650f1f62f..a031d2d0e1e8a 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -152,6 +152,9 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked, MDL_ticket **mdl= nullptr) MY_ATTRIBUTE((warn_unused_result)); +/** Decrement the count of open handles */ +void dict_table_close(dict_table_t *table); + /** Decrements the count of open handles of a table. @param[in,out] table table @param[in] dict_locked data dictionary locked @@ -1695,16 +1698,13 @@ dict_table_is_corrupted( const dict_table_t* table) /*!< in: table */ MY_ATTRIBUTE((nonnull, warn_unused_result)); -/**********************************************************************//** -Flags an index and table corrupted both in the data dictionary cache -and in the system table SYS_INDEXES. */ -void -dict_set_corrupted( -/*===============*/ - dict_index_t* index, /*!< in/out: index */ - trx_t* trx, /*!< in/out: transaction */ - const char* ctx) /*!< in: context */ - ATTRIBUTE_COLD __attribute__((nonnull)); +/** Flag an index and table corrupted both in the data dictionary cache +and in the system table SYS_INDEXES. +@param index index to be flagged as corrupted +@param ctx context (for error log reporting) +@param dict_locked whether dict_sys.latch is held in exclusive mode */ +void dict_set_corrupted(dict_index_t *index, const char *ctx, bool dict_locked) + ATTRIBUTE_COLD __attribute__((nonnull)); /** Flags an index corrupted in the data dictionary cache only. This is used mostly to mark a corrupted index when index's own dictionary diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index 4918b3d5747a4..6f9ceca1c0ca8 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -447,8 +447,7 @@ fts_trx_free( fts_trx_t* fts_trx); /*!< in, own: FTS trx */ /** Creates the common auxiliary tables needed for supporting an FTS index -on the given table. row_mysql_lock_data_dictionary must have been called -before this. +on the given table. The following tables are created. CREATE TABLE $FTS_PREFIX_DELETED (doc_id BIGINT UNSIGNED, UNIQUE CLUSTERED INDEX on doc_id) @@ -471,8 +470,7 @@ fts_create_common_tables( bool skip_doc_id_index) MY_ATTRIBUTE((nonnull, warn_unused_result)); /** Creates the column specific ancillary tables needed for supporting an -FTS index on the given table. row_mysql_lock_data_dictionary must have -been called before this. +FTS index on the given table. All FTS AUX Index tables have the following schema. CREAT TABLE $FTS_PREFIX_INDEX_[1-6]( diff --git a/storage/innobase/include/pars0pars.h b/storage/innobase/include/pars0pars.h index bef446184a177..16823ce1461d0 100644 --- a/storage/innobase/include/pars0pars.h +++ b/storage/innobase/include/pars0pars.h @@ -390,13 +390,6 @@ pars_info_t* pars_info_create(void); /*==================*/ -/****************************************************************//** -Free info struct and everything it contains. */ -void -pars_info_free( -/*===========*/ - pars_info_t* info); /*!< in, own: info struct */ - /****************************************************************//** Add bound literal. */ void @@ -559,11 +552,10 @@ struct pars_info_t { (pars_bound_lit_t*) */ ib_vector_t* bound_ids; /*!< bound ids, or NULL (pars_bound_id_t*) */ - - ibool graph_owns_us; /*!< if TRUE (which is the default), - que_graph_free() will free us */ }; +inline void pars_info_free(pars_info_t *info) { mem_heap_free(info->heap); } + /** User-supplied function and argument. */ struct pars_user_func_t { const char* name; /*!< function name */ diff --git a/storage/innobase/include/que0que.h b/storage/innobase/include/que0que.h index d81c77e3d36bf..f0aed6d22f475 100644 --- a/storage/innobase/include/que0que.h +++ b/storage/innobase/include/que0que.h @@ -207,9 +207,6 @@ que_eval_sql( /*=========*/ pars_info_t* info, /*!< in: info struct, or NULL */ const char* sql, /*!< in: SQL string */ - bool lock_dict, - /*!< in: whether to acquire/release - dict_sys.latch around call to pars_sql(). */ trx_t* trx); /*!< in: trx */ /**********************************************************************//** diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 998de196dd9d6..ba8ac02dfd1cc 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -182,13 +182,8 @@ row_create_prebuilt( dict_table_t* table, /*!< in: Innobase table handle */ ulint mysql_row_len); /*!< in: length in bytes of a row in the MySQL format */ -/********************************************************************//** -Free a prebuilt struct for a MySQL table handle. */ -void -row_prebuilt_free( -/*==============*/ - row_prebuilt_t* prebuilt, /*!< in, own: prebuilt struct */ - ibool dict_locked); /*!< in: TRUE=data dictionary locked */ +/** Free a prebuilt struct for a TABLE handle. */ +void row_prebuilt_free(row_prebuilt_t *prebuilt); /*********************************************************************//** Updates the transaction pointers in query graphs stored in the prebuilt struct. */ @@ -362,18 +357,6 @@ row_create_index_for_mysql( uint32_t key_id) /*!< in: encryption key_id */ MY_ATTRIBUTE((warn_unused_result)); -/*********************************************************************//** -Sets an exclusive lock on a table. -@return error code or DB_SUCCESS */ -dberr_t -row_mysql_lock_table( -/*=================*/ - trx_t* trx, /*!< in/out: transaction */ - dict_table_t* table, /*!< in: table to lock */ - enum lock_mode mode, /*!< in: LOCK_X or LOCK_S */ - const char* op_info) /*!< in: string for trx->op_info */ - MY_ATTRIBUTE((nonnull, warn_unused_result)); - /*********************************************************************//** Discards the tablespace of a table which stored in an .ibd file. Discarding means that this function deletes the .ibd file and assigns a new table id for diff --git a/storage/innobase/pars/pars0pars.cc b/storage/innobase/pars/pars0pars.cc index d49e5668aa13b..1ade99eb1c34a 100644 --- a/storage/innobase/pars/pars0pars.cc +++ b/storage/innobase/pars/pars0pars.cc @@ -2051,27 +2051,13 @@ pars_info_create(void) heap = mem_heap_create(512); - info = static_cast(mem_heap_alloc(heap, sizeof(*info))); + info = static_cast(mem_heap_zalloc(heap, sizeof(*info))); info->heap = heap; - info->funcs = NULL; - info->bound_lits = NULL; - info->bound_ids = NULL; - info->graph_owns_us = TRUE; return(info); } -/****************************************************************//** -Free info struct and everything it contains. */ -void -pars_info_free( -/*===========*/ - pars_info_t* info) /*!< in, own: info struct */ -{ - mem_heap_free(info->heap); -} - /****************************************************************//** Add bound literal. */ void diff --git a/storage/innobase/que/que0que.cc b/storage/innobase/que/que0que.cc index 074f8c54e2413..642a852b47308 100644 --- a/storage/innobase/que/que0que.cc +++ b/storage/innobase/que/que0que.cc @@ -435,7 +435,7 @@ que_graph_free( sym_tab_free_private(graph->sym_tab); } - if (graph->info && graph->info->graph_owns_us) { + if (graph->info) { pars_info_free(graph->info); } @@ -748,9 +748,6 @@ que_eval_sql( /*=========*/ pars_info_t* info, /*!< in: info struct, or NULL */ const char* sql, /*!< in: SQL string */ - bool lock_dict, - /*!< in: whether to acquire/release - dict_sys.latch around call to pars_sql(). */ trx_t* trx) /*!< in: trx */ { que_thr_t* thr; @@ -761,16 +758,8 @@ que_eval_sql( ut_a(trx->error_state == DB_SUCCESS); - if (lock_dict) { - dict_sys.lock(SRW_LOCK_CALL); - } - graph = pars_sql(info, sql); - if (lock_dict) { - dict_sys.unlock(); - } - graph->trx = trx; trx->graph = NULL; @@ -778,15 +767,7 @@ que_eval_sql( que_run_threads(thr); - if (lock_dict) { - dict_sys.lock(SRW_LOCK_CALL); - } - que_graph_free(graph); - if (lock_dict) { - dict_sys.unlock(); - } - DBUG_RETURN(trx->error_state); } diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 0d380405e5d86..ce23587090937 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -2209,10 +2209,6 @@ row_import_cleanup( ib::info() << "Discarding tablespace of table " << table->name << ": " << err; - if (!trx->dict_operation_lock_mode) { - row_mysql_lock_data_dictionary(trx); - } - for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); index; index = UT_LIST_GET_NEXT(indexes, index)) { @@ -2220,13 +2216,13 @@ row_import_cleanup( } } - ut_a(trx->dict_operation_lock_mode == RW_X_LATCH); - DBUG_EXECUTE_IF("ib_import_before_commit_crash", DBUG_SUICIDE();); trx_commit_for_mysql(trx); - row_mysql_unlock_data_dictionary(trx); + if (trx->dict_operation_lock_mode) { + row_mysql_unlock_data_dictionary(trx); + } trx->free(); @@ -3343,7 +3339,7 @@ dberr_t row_import_update_discarded_flag(trx_t* trx, table_id_t table_id, pars_info_bind_function( info, "my_func", row_import_set_discarded, &discard); - dberr_t err = que_eval_sql(info, sql, false, trx); + dberr_t err = que_eval_sql(info, sql, trx); ut_a(discard.n_recs == 1); ut_a(discard.flags2 != ULINT32_UNDEFINED); @@ -4179,8 +4175,6 @@ row_import_for_mysql( return(row_import_cleanup(prebuilt, trx, err)); } - row_mysql_lock_data_dictionary(trx); - /* If the table is stored in a remote tablespace, we need to determine that filepath from the link file and system tables. Find the space ID in SYS_TABLES since this is an ALTER TABLE. */ @@ -4202,7 +4196,6 @@ row_import_for_mysql( ); if (filepath == NULL) { - row_mysql_unlock_data_dictionary(trx); return(row_import_cleanup(prebuilt, trx, DB_OUT_OF_MEMORY)); } @@ -4222,22 +4215,16 @@ row_import_for_mysql( err = DB_TABLESPACE_NOT_FOUND; table->space = NULL;); if (!table->space) { - row_mysql_unlock_data_dictionary(trx); - ib_senderrf(trx->mysql_thd, IB_LOG_LEVEL_ERROR, ER_GET_ERRMSG, err, ut_strerr(err), filepath); - - ut_free(filepath); - - return(row_import_cleanup(prebuilt, trx, err)); } - row_mysql_unlock_data_dictionary(trx); - ut_free(filepath); - err = ibuf_check_bitmap_on_import(trx, table->space); + if (err == DB_SUCCESS) { + err = ibuf_check_bitmap_on_import(trx, table->space); + } DBUG_EXECUTE_IF("ib_import_check_bitmap_failure", err = DB_CORRUPTION;); diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index eb5a3cc91b82f..40b51e2e86682 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -1950,8 +1950,8 @@ row_ins_check_foreign_constraints( err = row_ins_check_foreign_constraint( TRUE, foreign, table, ref_tuple, thr); - if (ref_table != NULL) { - dict_table_close(ref_table, FALSE, FALSE); + if (ref_table) { + dict_table_close(ref_table); } } } diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 459f0db39971b..ab294e6554134 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -3685,7 +3685,7 @@ row_merge_drop_index_dict( info = pars_info_create(); pars_info_add_ull_literal(info, "indexid", index_id); trx->op_info = "dropping index from dictionary"; - error = que_eval_sql(info, sql, FALSE, trx); + error = que_eval_sql(info, sql, trx); if (error != DB_SUCCESS) { /* Even though we ensure that DDL transactions are WAIT @@ -3754,7 +3754,7 @@ row_merge_drop_indexes_dict( info = pars_info_create(); pars_info_add_ull_literal(info, "tableid", table_id); trx->op_info = "dropping indexes"; - error = que_eval_sql(info, sql, FALSE, trx); + error = que_eval_sql(info, sql, trx); switch (error) { case DB_SUCCESS: @@ -4036,7 +4036,7 @@ static ibool row_merge_drop_fts(void *node, void *trx) (mach_read_from_8(static_cast(index_id->data)))); auto pinfo= pars_info_create(); pars_info_add_str_literal(pinfo, "name", buf); - que_eval_sql(pinfo, sql, false, static_cast(trx)); + que_eval_sql(pinfo, sql, static_cast(trx)); } return true; @@ -4106,7 +4106,7 @@ void row_merge_drop_temp_indexes() pars_info_t* pinfo = pars_info_create(); pars_info_bind_function(pinfo, "drop_fts", row_merge_drop_fts, trx); - if (dberr_t error = que_eval_sql(pinfo, sql, FALSE, trx)) { + if (dberr_t error = que_eval_sql(pinfo, sql, trx)) { /* Even though we ensure that DDL transactions are WAIT and DEADLOCK free, we could encounter other errors e.g., DB_TOO_MANY_CONCURRENT_TRXS. */ @@ -4254,7 +4254,7 @@ row_merge_rename_index_to_add( pars_info_add_ull_literal(info, "tableid", table_id); pars_info_add_ull_literal(info, "indexid", index_id); - err = que_eval_sql(info, rename_index, FALSE, trx); + err = que_eval_sql(info, rename_index, trx); if (err != DB_SUCCESS) { /* Even though we ensure that DDL transactions are WAIT diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index b38ce54b6cad9..17ac86f2300ba 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -905,13 +905,8 @@ row_create_prebuilt( DBUG_RETURN(prebuilt); } -/********************************************************************//** -Free a prebuilt struct for a MySQL table handle. */ -void -row_prebuilt_free( -/*==============*/ - row_prebuilt_t* prebuilt, /*!< in, own: prebuilt struct */ - ibool dict_locked) /*!< in: TRUE=data dictionary locked */ +/** Free a prebuilt struct for a TABLE handle. */ +void row_prebuilt_free(row_prebuilt_t *prebuilt) { DBUG_ENTER("row_prebuilt_free"); @@ -971,7 +966,7 @@ row_prebuilt_free( rtr_clean_rtr_info(prebuilt->rtr_info, true); } if (prebuilt->table) { - dict_table_close(prebuilt->table, dict_locked, FALSE); + dict_table_close(prebuilt->table); } mem_heap_free(prebuilt->heap); @@ -1273,7 +1268,7 @@ row_insert_for_mysql( /* Mark the table corrupted for the clustered index */ dict_index_t* index = dict_table_get_first_index(table); ut_ad(dict_index_is_clust(index)); - dict_set_corrupted(index, trx, "INSERT TABLE"); }); + dict_set_corrupted(index, "INSERT TABLE", false); }); if (dict_table_is_corrupted(table)) { @@ -2184,6 +2179,7 @@ row_create_table_for_mysql( que_thr_t* thr; dberr_t err; + ut_ad(dict_sys.sys_tables_exist()); ut_ad(dict_sys.locked()); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); @@ -2194,16 +2190,8 @@ row_create_table_for_mysql( dict_mem_table_free(table); return DB_ERROR; ); - if (!dict_sys.sys_tables_exist()) { - sql_print_error("InnoDB: Some system tables are missing"); - dict_mem_table_free(table); - return DB_ERROR; - } - trx->op_info = "creating table"; - trx_start_if_not_started_xa(trx, true); - heap = mem_heap_create(512); trx->dict_operation = true; @@ -2380,7 +2368,7 @@ row_mysql_table_id_reassign( " WHERE TABLE_ID = :old_id;\n" "UPDATE SYS_VIRTUAL SET TABLE_ID = :new_id\n" " WHERE TABLE_ID = :old_id;\n" - "END;\n", FALSE, trx); + "END;\n", trx); return(err); } @@ -2609,54 +2597,6 @@ dberr_t row_discard_tablespace_for_mysql(dict_table_t *table, trx_t *trx) return err; } -/*********************************************************************//** -Sets an exclusive lock on a table. -@return error code or DB_SUCCESS */ -dberr_t -row_mysql_lock_table( -/*=================*/ - trx_t* trx, /*!< in/out: transaction */ - dict_table_t* table, /*!< in: table to lock */ - enum lock_mode mode, /*!< in: LOCK_X or LOCK_S */ - const char* op_info) /*!< in: string for trx->op_info */ -{ - mem_heap_t* heap; - que_thr_t* thr; - dberr_t err; - sel_node_t* node; - - ut_ad(mode == LOCK_X || mode == LOCK_S); - - heap = mem_heap_create(512); - - trx->op_info = op_info; - - node = sel_node_create(heap); - thr = pars_complete_graph_for_exec(node, trx, heap, NULL); - thr->graph->state = QUE_FORK_ACTIVE; - - /* We use the select query graph as the dummy graph needed - in the lock module call */ - - thr = que_fork_get_first_thr( - static_cast(que_node_get_parent(thr))); - - do { - thr->run_node = thr; - thr->prev_node = thr->common.parent; - - err = lock_table(table, mode, thr); - - trx->error_state = err; - } while (err != DB_SUCCESS - && row_mysql_handle_errors(&err, trx, thr, NULL)); - - que_graph_free(thr->graph); - trx->op_info = ""; - - return(err); -} - /****************************************************************//** Delete a single constraint. @return error code or DB_SUCCESS */ @@ -2676,8 +2616,7 @@ row_delete_constraint_low( "BEGIN\n" "DELETE FROM SYS_FOREIGN_COLS WHERE ID = :id;\n" "DELETE FROM SYS_FOREIGN WHERE ID = :id;\n" - "END;\n" - , FALSE, trx)); + "END;\n", trx)); } /****************************************************************//** @@ -2732,7 +2671,6 @@ row_rename_table_for_mysql( ulint n_constraints_to_drop = 0; ibool old_is_tmp, new_is_tmp; pars_info_t* info = NULL; - char* is_part = NULL; ut_a(old_name != NULL); ut_a(new_name != NULL); @@ -2751,14 +2689,6 @@ row_rename_table_for_mysql( table = dict_table_open_on_name(old_name, true, false, DICT_ERR_IGNORE_FK_NOKEY); - /* We look for pattern #P# to see if the table is partitioned - MySQL table. */ -#ifdef _WIN32 - is_part = strstr((char *)old_name, (char *)"#p#"); -#else - is_part = strstr((char *)old_name, (char *)"#P#"); -#endif /* _WIN32 */ - /* MariaDB partition engine hard codes the file name separator as "#P#" and "#SP#". The text case is fixed even if lower_case_table_names is set to 1 or 2. InnoDB always @@ -2775,7 +2705,8 @@ row_rename_table_for_mysql( sensitive platform in Windows, we might need to check the existence of table name without lowering case them in the system table. */ - if (!table && is_part && lower_case_table_names == 1) { + if (!table && lower_case_table_names == 1 + && strstr(old_name, IF_WIN("#p#", "#P#"))) { char par_case_name[MAX_FULL_NAME_LEN + 1]; #ifndef _WIN32 /* Check for the table using lower @@ -2853,8 +2784,7 @@ row_rename_table_for_mysql( "UPDATE SYS_TABLES" " SET NAME = :new_table_name\n" " WHERE NAME = :old_table_name;\n" - "END;\n" - , FALSE, trx); + "END;\n", trx); if (err != DB_SUCCESS) { // Assume the caller guarantees destination name doesn't exist. @@ -2972,8 +2902,7 @@ row_rename_table_for_mysql( "WHERE REF_NAME = :old_table_name\n" " AND TO_BINARY(REF_NAME)\n" " = TO_BINARY(:old_table_name);\n" - "END;\n" - , FALSE, trx); + "END;\n", trx); } else if (n_constraints_to_drop > 0) { /* Drop some constraints of tmp tables. */ diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc index 04de3465dcfd4..0d941feb0a1c1 100644 --- a/storage/innobase/row/row0quiesce.cc +++ b/storage/innobase/row/row0quiesce.cc @@ -667,8 +667,6 @@ row_quiesce_set_state( dict_index_t* clust_index = dict_table_get_first_index(table); - row_mysql_lock_data_dictionary(trx); - for (dict_index_t* index = dict_table_get_next_index(clust_index); index != NULL; index = dict_table_get_next_index(index)) { @@ -698,8 +696,6 @@ row_quiesce_set_state( index->lock.x_unlock(); } - row_mysql_unlock_data_dictionary(trx); - return(DB_SUCCESS); } diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index 7261636a9eeb8..b343141f84bdc 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -255,8 +255,8 @@ row_upd_check_references_constraints( err = row_ins_check_foreign_constraint( FALSE, foreign, table, entry, thr); - if (ref_table != NULL) { - dict_table_close(ref_table, FALSE, FALSE); + if (ref_table) { + dict_table_close(ref_table); } if (err != DB_SUCCESS) { @@ -345,8 +345,8 @@ wsrep_row_upd_check_foreign_constraints( TRUE, foreign, table, entry, thr); if (foreign->referenced_table) { - if (opened == TRUE) { - dict_table_close(foreign->referenced_table, FALSE, FALSE); + if (opened) { + dict_table_close(foreign->referenced_table); opened = FALSE; } } diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 4f01de111832f..246a036379655 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -605,7 +605,7 @@ trx_resurrect_table_locks( p.first, FALSE, DICT_TABLE_OP_LOAD_TABLESPACE)) { if (!table->is_readable()) { dict_sys.lock(SRW_LOCK_CALL); - dict_table_close(table, TRUE, FALSE); + table->release(); dict_sys.remove(table); dict_sys.unlock(); continue; @@ -622,7 +622,7 @@ trx_resurrect_table_locks( "resurrect " << ib::hex(trx->id) << " lock on " << table->name); - dict_table_close(table, FALSE, FALSE); + table->release(); } } } @@ -1199,18 +1199,17 @@ void trx_t::evict_table(table_id_t table_id, bool reset_only) { ut_ad(in_rollback); - dict_table_t* table = dict_table_open_on_id( - table_id, true, DICT_TABLE_OP_OPEN_ONLY_IF_CACHED); + dict_table_t* table = dict_sys.find_table(table_id); if (!table) { return; } table->def_trx_id = 0; - if (!table->release()) { + if (auto ref_count = table->get_ref_count()) { /* This must be a DDL operation that is being rolled back in an active connection. */ - ut_a(table->get_ref_count() == 1); + ut_a(ref_count == 1); ut_ad(!is_recovered); ut_ad(mysql_thd); return;