summaryrefslogtreecommitdiff
path: root/sql/sql_show.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_show.cc')
-rw-r--r--sql/sql_show.cc52
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),