diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index a29e819f90b..94875210d0b 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1488,7 +1488,7 @@ inline int open_and_lock_tables(THD *thd, TABLE_LIST *tables) } /* simple open_and_lock_tables without derived handling for single table */ TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l, - thr_lock_type lock_type); + thr_lock_type lock_type, uint flags); bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags); int lock_tables(THD *thd, TABLE_LIST *tables, uint counter, uint flags, bool *need_reopen); @@ -2040,6 +2040,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count, #define MYSQL_OPEN_TEMPORARY_ONLY 0x0004 #define MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY 0x0008 #define MYSQL_LOCK_PERF_SCHEMA 0x0010 +#define MYSQL_OPEN_TAKE_UPGRADABLE_MDL 0x0020 void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock); void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 237c4c8e771..a08a96465ca 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2598,6 +2598,9 @@ void table_share_release_hook(void *share) No version number checking is done. MYSQL_OPEN_TEMPORARY_ONLY - Open only temporary table not the base table or view. + MYSQL_OPEN_TAKE_UPGRADABLE_MDL - Obtain upgradable + metadata lock for tables on which we are going to + take some kind of write table-level lock. IMPLEMENTATION Uses a cache of open tables to find a table not in use. @@ -2825,7 +2828,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, { bool retry; - if (table_list->mdl_upgradable) + if (flags & MYSQL_OPEN_TAKE_UPGRADABLE_MDL && + table_list->lock_type >= TL_WRITE_ALLOW_WRITE) mdl_set_upgradable(mdl_lock_data); mdl_set_lock_priority(mdl_lock_data, (flags & MYSQL_LOCK_IGNORE_FLUSH) ? MDL_HIGH_PRIO : MDL_NORMAL_PRIO); @@ -4146,7 +4150,6 @@ static int add_merge_table_list(TABLE_LIST *tlist) /* Set lock type. */ child_l->lock_type= tlist->lock_type; - child_l->mdl_upgradable= tlist->mdl_upgradable; /* Set parent reference. */ child_l->parent_l= tlist; @@ -4905,6 +4908,8 @@ static bool check_lock_and_start_stmt(THD *thd, TABLE *table, @param[in] thd thread handle @param[in] table_l table to open is first table in this list @param[in] lock_type lock to use for table + @param[in] flags options to be used while opening and locking + table (see open_table(), mysql_lock_tables()) @return table @retval != NULL OK, opened table returned @@ -4930,7 +4935,7 @@ static bool check_lock_and_start_stmt(THD *thd, TABLE *table, */ TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l, - thr_lock_type lock_type) + thr_lock_type lock_type, uint flags) { TABLE_LIST *save_next_global; DBUG_ENTER("open_n_lock_single_table"); @@ -4946,7 +4951,7 @@ TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l, table_l->required_type= FRMTYPE_TABLE; /* Open the table. */ - if (simple_open_n_lock_tables(thd, table_l)) + if (open_and_lock_tables_derived(thd, table_l, FALSE, flags)) table_l->table= NULL; /* Just to be sure. */ /* Restore list. */ diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index a0c198f3196..75ad46f1440 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2304,7 +2304,7 @@ void kill_delayed_threads(void) bool Delayed_insert::open_and_lock_table() { if (!(table= open_n_lock_single_table(&thd, &table_list, - TL_WRITE_DELAYED))) + TL_WRITE_DELAYED, 0))) { thd.fatal_error(); // Abort waiting inserts return TRUE; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 52a4a4e0144..31bd34531e3 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -47,7 +47,6 @@ "FUNCTION" : "PROCEDURE") static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables); -static void adjust_mdl_locks_upgradability(TABLE_LIST *tables); const char *any_db="*any*"; // Special symbol for check_access @@ -3608,9 +3607,9 @@ end_with_restore_list: thd->options|= OPTION_TABLE_LOCK; alloc_mdl_locks(all_tables, &thd->locked_tables_root); thd->mdl_el_root= &thd->locked_tables_root; - adjust_mdl_locks_upgradability(all_tables); - if (!(res= simple_open_n_lock_tables(thd, all_tables))) + if (!(res= open_and_lock_tables_derived(thd, all_tables, FALSE, + MYSQL_OPEN_TAKE_UPGRADABLE_MDL))) { #ifdef HAVE_QUERY_CACHE if (thd->variables.query_cache_wlock_invalidate) @@ -8106,21 +8105,6 @@ bool parse_sql(THD *thd, return ret_value; } - -/** - Auxiliary function which marks metadata locks for all tables - on which we plan to take write lock as upgradable. -*/ - -static void adjust_mdl_locks_upgradability(TABLE_LIST *tables) -{ - for (TABLE_LIST *tab= tables; tab; tab= tab->next_global) - { - if (tab->lock_type >= TL_WRITE_ALLOW_WRITE) - tab->mdl_upgradable= TRUE; - } -} - /** @} (end of group Runtime_Environment) */ diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f5c22d32e94..306fa5dcdf4 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4617,7 +4617,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, if (view_operator_func == NULL) table->required_type=FRMTYPE_TABLE; - open_and_lock_tables(thd, table); + open_and_lock_tables_derived(thd, table, TRUE, + MYSQL_OPEN_TAKE_UPGRADABLE_MDL); thd->no_warnings_for_error= 0; table->next_global= save_next_global; table->next_local= save_next_local; @@ -5074,7 +5075,6 @@ bool mysql_restore_table(THD* thd, TABLE_LIST* table_list) bool mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) { DBUG_ENTER("mysql_repair_table"); - set_all_mdl_upgradable(tables); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, "repair", TL_WRITE, 1, test(check_opt->sql_flags & TT_USEFRM), @@ -5087,7 +5087,6 @@ bool mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) bool mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) { DBUG_ENTER("mysql_optimize_table"); - set_all_mdl_upgradable(tables); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, "optimize", TL_WRITE, 1,0,0,0, &handler::ha_optimize, 0)); @@ -6604,9 +6603,8 @@ view_err: DBUG_RETURN(error); } - table_list->mdl_upgradable= TRUE; - - if (!(table= open_n_lock_single_table(thd, table_list, TL_WRITE_ALLOW_READ))) + if (!(table= open_n_lock_single_table(thd, table_list, TL_WRITE_ALLOW_READ, + MYSQL_OPEN_TAKE_UPGRADABLE_MDL))) DBUG_RETURN(TRUE); table->use_all_columns(); mdl_lock_data= table->mdl_lock_data; @@ -7898,7 +7896,7 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, strxmov(table_name, table->db ,".", table->table_name, NullS); - t= table->table= open_n_lock_single_table(thd, table, TL_READ); + t= table->table= open_n_lock_single_table(thd, table, TL_READ, 0); thd->clear_error(); // these errors shouldn't get client protocol->prepare_for_resend(); diff --git a/sql/sql_view.cc b/sql/sql_view.cc index c40f6643042..9382880ba1b 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1329,10 +1329,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, anyway. */ for (tbl= view_main_select_tables; tbl; tbl= tbl->next_local) - { tbl->lock_type= table->lock_type; - tbl->mdl_upgradable= table->mdl_upgradable; - } /* If the view is mergeable, we might want to INSERT/UPDATE/DELETE into tables of this view. Preserve the diff --git a/sql/table.h b/sql/table.h index de1354e17e5..e7d7e2b08bf 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1371,11 +1371,6 @@ struct TABLE_LIST */ TAKE_EXCLUSIVE_MDL } open_type; - /** - Indicates that for this table/view we need to take shared metadata - lock which should be upgradable to exclusive metadata lock. - */ - bool mdl_upgradable; bool internal_tmp_table; /** TRUE if an alias for this table was specified in the SQL. */ bool is_alias; @@ -1796,14 +1791,4 @@ size_t max_row_length(TABLE *table, const uchar *data); void alloc_mdl_locks(TABLE_LIST *table_list, MEM_ROOT *root); -/** - Helper function which allows to mark all elements in table list - as requiring upgradable metadata locks. -*/ - -inline void set_all_mdl_upgradable(TABLE_LIST *tables) -{ - for (; tables; tables= tables->next_global) - tables->mdl_upgradable= TRUE; -} #endif /* TABLE_INCLUDED */