diff options
Diffstat (limited to 'sql/sql_show.cc')
-rw-r--r-- | sql/sql_show.cc | 52 |
1 files changed, 44 insertions, 8 deletions
diff --git a/sql/sql_show.cc b/sql/sql_show.cc index babadc34842..c83a6981166 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2963,7 +2963,7 @@ fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables, table, res, db_name, table_name)); thd->temporary_tables= 0; - close_tables_for_reopen(thd, &show_table_list); + close_tables_for_reopen(thd, &show_table_list, FALSE); DBUG_RETURN(error); } @@ -3106,6 +3106,9 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table, char key[MAX_DBKEY_LENGTH]; uint key_length; char db_name_buff[NAME_LEN + 1], table_name_buff[NAME_LEN + 1]; + MDL_LOCK mdl_lock; + char mdlkey[MAX_DBKEY_LENGTH]; + bool retry; bzero((char*) &table_list, sizeof(TABLE_LIST)); bzero((char*) &tbl, sizeof(TABLE)); @@ -3130,6 +3133,34 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table, table_list.db= db_name->str; } + mdl_init_lock(&mdl_lock, mdlkey, 0, db_name->str, table_name->str); + table_list.mdl_lock= &mdl_lock; + mdl_add_lock(&thd->mdl_context, &mdl_lock); + mdl_set_lock_priority(&mdl_lock, MDL_HIGH_PRIO); + + /* + TODO: investigate if in this particular situation we can get by + simply obtaining internal lock of data-dictionary (ATM it + is LOCK_open) instead of obtaning full-blown metadata lock. + */ + while (1) + { + if (mdl_acquire_shared_lock(&mdl_lock, &retry)) + { + if (!retry || mdl_wait_for_locks(&thd->mdl_context)) + { + /* + Some error occured or we have been killed while waiting + for conflicting locks to go away, let the caller to handle + the situation. + */ + return 1; + } + continue; + } + break; + } + key_length= create_table_def_key(thd, key, &table_list, 0); pthread_mutex_lock(&LOCK_open); share= get_table_share(thd, &table_list, key, @@ -3137,7 +3168,7 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table, if (!share) { res= 0; - goto err; + goto err_unlock; } if (share->is_view) @@ -3146,7 +3177,7 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table, { /* skip view processing */ res= 0; - goto err1; + goto err_share; } else if (schema_table->i_s_requested_object & OPEN_VIEW_FULL) { @@ -3155,7 +3186,7 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table, open_normal_and_derived_tables() */ res= 1; - goto err1; + goto err_share; } } @@ -3171,14 +3202,17 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table, res= schema_table->process_table(thd, &table_list, table, res, db_name, table_name); closefrm(&tbl, true); - goto err; + goto err_unlock; } -err1: +err_share: release_table_share(share, RELEASE_NORMAL); -err: +err_unlock: pthread_mutex_unlock(&LOCK_open); + +err: + mdl_release_lock(&thd->mdl_context, &mdl_lock); thd->clear_error(); return res; } @@ -3425,7 +3459,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) res= schema_table->process_table(thd, show_table_list, table, res, &orig_db_name, &tmp_lex_string); - close_tables_for_reopen(thd, &show_table_list); + close_tables_for_reopen(thd, &show_table_list, FALSE); } DBUG_ASSERT(!lex->query_tables_own_last); if (res) @@ -7273,6 +7307,8 @@ bool show_create_trigger(THD *thd, const sp_name *trg_name) uint num_tables; /* NOTE: unused, only to pass to open_tables(). */ + alloc_mdl_locks(lst, thd->mem_root); + if (open_tables(thd, &lst, &num_tables, 0)) { my_error(ER_TRG_CANT_OPEN_TABLE, MYF(0), |