Backport of:
------------------------------------------------------------ revno: 2630.9.3 committer: Dmitry Lenev <dlenev@mysql.com> branch nick: mysql-6.0-3726-w3 timestamp: Wed 2008-06-11 08:33:36 +0400 message: WL#3726 "DDL locking for all metadata objects". After review fixes in progress. Changed close_cached_tables() not to flush all unused TABLE instances when flushing individual table. Renamed expel_table_from_cache() to tdc_remove_table() and added enum parameter to be able more explicitly specify type of removal, rewrote its code to be more efficient. ****** Backport of: ------------------------------------------------------------ revno: 2630.9.4 committer: Dmitry Lenev <dlenev@mysql.com> branch nick: mysql-6.0-3726-w3 timestamp: Wed 2008-06-11 15:53:53 +0400 message: WL#3726 "DDL locking for all metadata objects". After-review fixes in progress. Minor changes in order to improve code readability and simplify debugging.
This commit is contained in:
parent
b474ad262b
commit
cf4a4ba6fd
@ -850,7 +850,7 @@ flush table t1;
|
|||||||
execute stmt;
|
execute stmt;
|
||||||
f1()
|
f1()
|
||||||
6
|
6
|
||||||
call p_verify_reprepare_count(1);
|
call p_verify_reprepare_count(0);
|
||||||
SUCCESS
|
SUCCESS
|
||||||
|
|
||||||
execute stmt;
|
execute stmt;
|
||||||
|
@ -745,7 +745,7 @@ execute stmt;
|
|||||||
call p_verify_reprepare_count(1);
|
call p_verify_reprepare_count(1);
|
||||||
flush table t1;
|
flush table t1;
|
||||||
execute stmt;
|
execute stmt;
|
||||||
call p_verify_reprepare_count(1);
|
call p_verify_reprepare_count(0);
|
||||||
execute stmt;
|
execute stmt;
|
||||||
|
|
||||||
--echo # Test 18-c: dependent VIEW has changed
|
--echo # Test 18-c: dependent VIEW has changed
|
||||||
|
@ -1543,8 +1543,11 @@ char *generate_partition_syntax(partition_info *part_info,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool notify_thread_having_shared_lock(THD *thd, THD *in_use);
|
bool notify_thread_having_shared_lock(THD *thd, THD *in_use);
|
||||||
void expel_table_from_cache(THD *leave_thd, const char *db,
|
|
||||||
const char *table_name);
|
enum enum_tdc_remove_table_type {TDC_RT_REMOVE_ALL, TDC_RT_REMOVE_NOT_OWN,
|
||||||
|
TDC_RT_REMOVE_UNUSED};
|
||||||
|
void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
|
||||||
|
const char *db, const char *table_name);
|
||||||
|
|
||||||
#define NORMAL_PART_NAME 0
|
#define NORMAL_PART_NAME 0
|
||||||
#define TEMP_PART_NAME 1
|
#define TEMP_PART_NAME 1
|
||||||
|
148
sql/sql_base.cc
148
sql/sql_base.cc
@ -921,12 +921,17 @@ void free_io_cache(TABLE *table)
|
|||||||
particular table identified by its share.
|
particular table identified by its share.
|
||||||
|
|
||||||
@param share Table share.
|
@param share Table share.
|
||||||
|
|
||||||
|
@pre Caller should have LOCK_open mutex acquired.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void kill_delayed_threads_for_table(TABLE_SHARE *share)
|
static void kill_delayed_threads_for_table(TABLE_SHARE *share)
|
||||||
{
|
{
|
||||||
I_P_List_iterator<TABLE, TABLE_share> it(share->used_tables);
|
I_P_List_iterator<TABLE, TABLE_share> it(share->used_tables);
|
||||||
TABLE *tab;
|
TABLE *tab;
|
||||||
|
|
||||||
|
safe_mutex_assert_owner(&LOCK_open);
|
||||||
|
|
||||||
while ((tab= it++))
|
while ((tab= it++))
|
||||||
{
|
{
|
||||||
THD *in_use= tab->in_use;
|
THD *in_use= tab->in_use;
|
||||||
@ -983,6 +988,15 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
|
|||||||
DBUG_PRINT("tcache", ("incremented global refresh_version to: %lu",
|
DBUG_PRINT("tcache", ("incremented global refresh_version to: %lu",
|
||||||
refresh_version));
|
refresh_version));
|
||||||
kill_delayed_threads();
|
kill_delayed_threads();
|
||||||
|
/*
|
||||||
|
Get rid of all unused TABLE and TABLE_SHARE instances. By doing
|
||||||
|
this we automatically close all tables which were marked as "old".
|
||||||
|
*/
|
||||||
|
while (unused_tables)
|
||||||
|
free_cache_entry(unused_tables);
|
||||||
|
/* Free table shares which were not freed implicitly by loop above. */
|
||||||
|
while (oldest_unused_share->next)
|
||||||
|
(void) my_hash_delete(&table_def_cache, (uchar*) oldest_unused_share);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -993,8 +1007,10 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
|
|||||||
|
|
||||||
if (share)
|
if (share)
|
||||||
{
|
{
|
||||||
share->version= 0;
|
|
||||||
kill_delayed_threads_for_table(share);
|
kill_delayed_threads_for_table(share);
|
||||||
|
/* tdc_remove_table() also sets TABLE_SHARE::version to 0. */
|
||||||
|
tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED, table->db,
|
||||||
|
table->table_name);
|
||||||
found=1;
|
found=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1002,28 +1018,14 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
|
|||||||
wait_for_refresh=0; // Nothing to wait for
|
wait_for_refresh=0; // Nothing to wait for
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Get rid of all unused TABLE and TABLE_SHARE instances. By doing
|
|
||||||
this we automatically close all tables which were marked as "old".
|
|
||||||
|
|
||||||
FIXME: Do not close all unused TABLE instances when flushing
|
|
||||||
particular table.
|
|
||||||
*/
|
|
||||||
while (unused_tables)
|
|
||||||
free_cache_entry(unused_tables);
|
|
||||||
/* Free table shares */
|
|
||||||
while (oldest_unused_share->next)
|
|
||||||
(void) my_hash_delete(&table_def_cache, (uchar*) oldest_unused_share);
|
|
||||||
|
|
||||||
if (!wait_for_refresh)
|
|
||||||
{
|
|
||||||
if (!have_lock)
|
if (!have_lock)
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
DBUG_RETURN(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!wait_for_refresh)
|
||||||
|
DBUG_RETURN(result);
|
||||||
|
|
||||||
|
/* Code below assume that LOCK_open is released. */
|
||||||
DBUG_ASSERT(!have_lock);
|
DBUG_ASSERT(!have_lock);
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
|
||||||
|
|
||||||
if (thd->locked_tables_mode)
|
if (thd->locked_tables_mode)
|
||||||
{
|
{
|
||||||
@ -2109,27 +2111,6 @@ bool rename_temporary_table(THD* thd, TABLE *table, const char *db,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* move table first in unused links */
|
|
||||||
|
|
||||||
static void relink_unused(TABLE *table)
|
|
||||||
{
|
|
||||||
/* Assert that MERGE children are not attached in unused_tables. */
|
|
||||||
DBUG_ASSERT(!table->is_children_attached());
|
|
||||||
|
|
||||||
if (table != unused_tables)
|
|
||||||
{
|
|
||||||
table->prev->next=table->next; /* Remove from unused list */
|
|
||||||
table->next->prev=table->prev;
|
|
||||||
table->next=unused_tables; /* Link in unused tables */
|
|
||||||
table->prev=unused_tables->prev;
|
|
||||||
unused_tables->prev->next=table;
|
|
||||||
unused_tables->prev=table;
|
|
||||||
unused_tables=table;
|
|
||||||
check_unused();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Prepare an open merge table for close.
|
Prepare an open merge table for close.
|
||||||
|
|
||||||
@ -2241,7 +2222,8 @@ bool wait_while_table_is_used(THD *thd, TABLE *table,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_open);
|
pthread_mutex_lock(&LOCK_open);
|
||||||
expel_table_from_cache(thd, table->s->db.str, table->s->table_name.str);
|
tdc_remove_table(thd, TDC_RT_REMOVE_NOT_OWN,
|
||||||
|
table->s->db.str, table->s->table_name.str);
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
}
|
}
|
||||||
@ -4075,7 +4057,7 @@ recover_from_failed_open_table_attempt(THD *thd, TABLE_LIST *table,
|
|||||||
if (mdl_acquire_exclusive_locks(&thd->mdl_context))
|
if (mdl_acquire_exclusive_locks(&thd->mdl_context))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
pthread_mutex_lock(&LOCK_open);
|
pthread_mutex_lock(&LOCK_open);
|
||||||
expel_table_from_cache(0, table->db, table->table_name);
|
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name);
|
||||||
ha_create_table_from_engine(thd, table->db, table->table_name);
|
ha_create_table_from_engine(thd, table->db, table->table_name);
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
|
|
||||||
@ -4089,7 +4071,7 @@ recover_from_failed_open_table_attempt(THD *thd, TABLE_LIST *table,
|
|||||||
if (mdl_acquire_exclusive_locks(&thd->mdl_context))
|
if (mdl_acquire_exclusive_locks(&thd->mdl_context))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
pthread_mutex_lock(&LOCK_open);
|
pthread_mutex_lock(&LOCK_open);
|
||||||
expel_table_from_cache(0, table->db, table->table_name);
|
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name);
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
|
|
||||||
result= auto_repair_table(thd, table);
|
result= auto_repair_table(thd, table);
|
||||||
@ -8549,13 +8531,27 @@ bool notify_thread_having_shared_lock(THD *thd, THD *in_use)
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Remove all instances of the table from cache assuming that current thread
|
Remove all or some (depending on parameter) instances of TABLE and
|
||||||
has exclusive meta-data lock on it (optionally leave instances belonging
|
TABLE_SHARE from the table definition cache.
|
||||||
to the current thread in cache).
|
|
||||||
|
|
||||||
@param leave_thd 0 If we should remove all instances
|
@param thd Thread context
|
||||||
non-0 Pointer to current thread context if we should
|
@param remove_type Type of removal:
|
||||||
leave instances belonging to this thread.
|
TDC_RT_REMOVE_ALL - remove all TABLE instances and
|
||||||
|
TABLE_SHARE instance. There
|
||||||
|
should be no used TABLE objects
|
||||||
|
and caller should have exclusive
|
||||||
|
metadata lock on the table.
|
||||||
|
TDC_RT_REMOVE_NOT_OWN - remove all TABLE instances
|
||||||
|
except those that belong to
|
||||||
|
this thread. There should be
|
||||||
|
no TABLE objects used by other
|
||||||
|
threads and caller should have
|
||||||
|
exclusive metadata lock on the
|
||||||
|
table.
|
||||||
|
TDC_RT_REMOVE_UNUSED - remove all unused TABLE
|
||||||
|
instances (if there are no
|
||||||
|
used instances will also
|
||||||
|
remove TABLE_SHARE).
|
||||||
@param db Name of database
|
@param db Name of database
|
||||||
@param table_name Name of table
|
@param table_name Name of table
|
||||||
|
|
||||||
@ -8564,35 +8560,53 @@ bool notify_thread_having_shared_lock(THD *thd, THD *in_use)
|
|||||||
by using meta-data locks).
|
by using meta-data locks).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void expel_table_from_cache(THD *leave_thd, const char *db, const char *table_name)
|
void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
|
||||||
|
const char *db, const char *table_name)
|
||||||
{
|
{
|
||||||
char key[MAX_DBKEY_LENGTH];
|
char key[MAX_DBKEY_LENGTH];
|
||||||
uint key_length;
|
uint key_length;
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
TABLE_SHARE *share;
|
TABLE_SHARE *share;
|
||||||
|
|
||||||
|
safe_mutex_assert_owner(&LOCK_open);
|
||||||
|
|
||||||
|
DBUG_ASSERT(remove_type == TDC_RT_REMOVE_UNUSED ||
|
||||||
|
mdl_is_exclusive_lock_owner(&thd->mdl_context, 0,
|
||||||
|
db, table_name));
|
||||||
|
|
||||||
key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
|
key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
|
||||||
|
|
||||||
if ((share= (TABLE_SHARE*) my_hash_search(&table_def_cache,(uchar*) key,
|
if ((share= (TABLE_SHARE*) my_hash_search(&table_def_cache,(uchar*) key,
|
||||||
key_length)))
|
key_length)))
|
||||||
{
|
{
|
||||||
I_P_List_iterator<TABLE, TABLE_share> it(share->free_tables);
|
if (share->ref_count)
|
||||||
share->version= 0;
|
|
||||||
|
|
||||||
while ((table= it++))
|
|
||||||
relink_unused(table);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This may destroy share so we have to do new look-up later. */
|
|
||||||
while (unused_tables && !unused_tables->s->version)
|
|
||||||
free_cache_entry(unused_tables);
|
|
||||||
|
|
||||||
if ((share= (TABLE_SHARE*) my_hash_search(&table_def_cache,(uchar*) key,
|
|
||||||
key_length)))
|
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(leave_thd || share->ref_count == 0);
|
I_P_List_iterator<TABLE, TABLE_share> it(share->free_tables);
|
||||||
if (share->ref_count == 0)
|
#ifndef DBUG_OFF
|
||||||
my_hash_delete(&table_def_cache, (uchar*) share);
|
if (remove_type == TDC_RT_REMOVE_ALL)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(share->used_tables.is_empty());
|
||||||
|
}
|
||||||
|
else if (remove_type == TDC_RT_REMOVE_NOT_OWN)
|
||||||
|
{
|
||||||
|
I_P_List_iterator<TABLE, TABLE_share> it2(share->used_tables);
|
||||||
|
while ((table= it2++))
|
||||||
|
if (table->in_use != thd)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
Set share's version to zero in order to ensure that it gets
|
||||||
|
automatically deleted once it is no longer referenced.
|
||||||
|
*/
|
||||||
|
share->version= 0;
|
||||||
|
while ((table= it++))
|
||||||
|
free_cache_entry(table);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
(void) my_hash_delete(&table_def_cache, (uchar*) share);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8793,7 +8807,7 @@ int abort_and_upgrade_lock(ALTER_PARTITION_PARAM_TYPE *lpt)
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
pthread_mutex_lock(&LOCK_open);
|
pthread_mutex_lock(&LOCK_open);
|
||||||
expel_table_from_cache(lpt->thd, lpt->db, lpt->table_name);
|
tdc_remove_table(lpt->thd, TDC_RT_REMOVE_NOT_OWN, lpt->db, lpt->table_name);
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
@ -1172,7 +1172,8 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
|
|||||||
if (mdl_acquire_exclusive_locks(&thd->mdl_context))
|
if (mdl_acquire_exclusive_locks(&thd->mdl_context))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
pthread_mutex_lock(&LOCK_open);
|
pthread_mutex_lock(&LOCK_open);
|
||||||
expel_table_from_cache(0, table_list->db, table_list->table_name);
|
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_list->db,
|
||||||
|
table_list->table_name);
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +139,8 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
|
|||||||
pthread_mutex_lock(&LOCK_open);
|
pthread_mutex_lock(&LOCK_open);
|
||||||
|
|
||||||
for (ren_table= table_list; ren_table; ren_table= ren_table->next_local)
|
for (ren_table= table_list; ren_table; ren_table= ren_table->next_local)
|
||||||
expel_table_from_cache(0, ren_table->db, ren_table->table_name);
|
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, ren_table->db,
|
||||||
|
ren_table->table_name);
|
||||||
|
|
||||||
error=0;
|
error=0;
|
||||||
if ((ren_table=rename_tables(thd,table_list,0)))
|
if ((ren_table=rename_tables(thd,table_list,0)))
|
||||||
|
@ -3075,6 +3075,56 @@ uint get_table_open_method(TABLE_LIST *tables,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Acquire high priority share metadata lock on a table.
|
||||||
|
|
||||||
|
@param thd Thread context.
|
||||||
|
@param mdl_lock_data Pointer to memory to be used for MDL_LOCK_DATA
|
||||||
|
object for a lock request.
|
||||||
|
@param mdlkey Pointer to the buffer for key for the lock request
|
||||||
|
(should be at least strlen(db) + strlen(name) + 2
|
||||||
|
bytes, or, if the lengths are not known,
|
||||||
|
MAX_DBNAME_LENGTH)
|
||||||
|
@param table Table list element for the table
|
||||||
|
|
||||||
|
@note This is an auxiliary function to be used in cases when we want to
|
||||||
|
access table's description by looking up info in TABLE_SHARE without
|
||||||
|
going through full-blown table open.
|
||||||
|
@note This function assumes that there are no other metadata lock requests
|
||||||
|
in the current metadata locking context.
|
||||||
|
|
||||||
|
@retval FALSE Success
|
||||||
|
@retval TRUE Some error occured (probably thread was killed).
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool
|
||||||
|
acquire_high_prio_shared_mdl_lock(THD *thd, MDL_LOCK_DATA *mdl_lock_data,
|
||||||
|
char *mdlkey, TABLE_LIST *table)
|
||||||
|
{
|
||||||
|
bool retry;
|
||||||
|
|
||||||
|
mdl_init_lock(mdl_lock_data, mdlkey, 0, table->db, table->table_name);
|
||||||
|
table->mdl_lock_data= mdl_lock_data;
|
||||||
|
mdl_add_lock(&thd->mdl_context, mdl_lock_data);
|
||||||
|
mdl_set_lock_type(mdl_lock_data, MDL_SHARED_HIGH_PRIO);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (mdl_acquire_shared_lock(&thd->mdl_context, mdl_lock_data, &retry))
|
||||||
|
{
|
||||||
|
if (!retry || mdl_wait_for_locks(&thd->mdl_context))
|
||||||
|
{
|
||||||
|
mdl_remove_all_locks(&thd->mdl_context);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Fill I_S table with data from FRM file only
|
@brief Fill I_S table with data from FRM file only
|
||||||
|
|
||||||
@ -3108,7 +3158,6 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table,
|
|||||||
char db_name_buff[NAME_LEN + 1], table_name_buff[NAME_LEN + 1];
|
char db_name_buff[NAME_LEN + 1], table_name_buff[NAME_LEN + 1];
|
||||||
MDL_LOCK_DATA mdl_lock_data;
|
MDL_LOCK_DATA mdl_lock_data;
|
||||||
char mdlkey[MAX_DBKEY_LENGTH];
|
char mdlkey[MAX_DBKEY_LENGTH];
|
||||||
bool retry;
|
|
||||||
|
|
||||||
bzero((char*) &table_list, sizeof(TABLE_LIST));
|
bzero((char*) &table_list, sizeof(TABLE_LIST));
|
||||||
bzero((char*) &tbl, sizeof(TABLE));
|
bzero((char*) &tbl, sizeof(TABLE));
|
||||||
@ -3133,33 +3182,21 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table,
|
|||||||
table_list.db= db_name->str;
|
table_list.db= db_name->str;
|
||||||
}
|
}
|
||||||
|
|
||||||
mdl_init_lock(&mdl_lock_data, mdlkey, 0, db_name->str, table_name->str);
|
|
||||||
table_list.mdl_lock_data= &mdl_lock_data;
|
|
||||||
mdl_add_lock(&thd->mdl_context, &mdl_lock_data);
|
|
||||||
mdl_set_lock_type(&mdl_lock_data, MDL_SHARED_HIGH_PRIO);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: investigate if in this particular situation we can get by
|
TODO: investigate if in this particular situation we can get by
|
||||||
simply obtaining internal lock of data-dictionary (ATM it
|
simply obtaining internal lock of data-dictionary (ATM it
|
||||||
is LOCK_open) instead of obtaning full-blown metadata lock.
|
is LOCK_open) instead of obtaning full-blown metadata lock.
|
||||||
*/
|
*/
|
||||||
while (1)
|
if (acquire_high_prio_shared_mdl_lock(thd, &mdl_lock_data, mdlkey,
|
||||||
{
|
&table_list))
|
||||||
if (mdl_acquire_shared_lock(&thd->mdl_context, &mdl_lock_data, &retry))
|
|
||||||
{
|
|
||||||
if (!retry || mdl_wait_for_locks(&thd->mdl_context))
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Some error occured or we have been killed while waiting
|
Some error occured (most probably we have been killed while
|
||||||
for conflicting locks to go away, let the caller to handle
|
waiting for conflicting locks to go away), let the caller to
|
||||||
the situation.
|
handle the situation.
|
||||||
*/
|
*/
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
key_length= create_table_def_key(thd, key, &table_list, 0);
|
key_length= create_table_def_key(thd, key, &table_list, 0);
|
||||||
pthread_mutex_lock(&LOCK_open);
|
pthread_mutex_lock(&LOCK_open);
|
||||||
|
@ -1897,7 +1897,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
pthread_mutex_lock(&LOCK_open);
|
pthread_mutex_lock(&LOCK_open);
|
||||||
for (table= tables; table; table= table->next_local)
|
for (table= tables; table; table= table->next_local)
|
||||||
expel_table_from_cache(0, table->db, table->table_name);
|
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name);
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -4345,7 +4345,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
|
|||||||
if (mdl_acquire_exclusive_locks(&thd->mdl_context))
|
if (mdl_acquire_exclusive_locks(&thd->mdl_context))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
pthread_mutex_lock(&LOCK_open);
|
pthread_mutex_lock(&LOCK_open);
|
||||||
expel_table_from_cache(0, table->db, table->table_name);
|
tdc_remove_table(0, TDC_RT_REMOVE_UNUSED, table->db, table->table_name);
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
|
|
||||||
if (my_copy(src_path, dst_path, MYF(MY_WME)))
|
if (my_copy(src_path, dst_path, MYF(MY_WME)))
|
||||||
|
@ -469,7 +469,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
|
|||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_open);
|
pthread_mutex_lock(&LOCK_open);
|
||||||
expel_table_from_cache(0, tables->db, tables->table_name);
|
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, tables->db, tables->table_name);
|
||||||
|
|
||||||
if (reopen_name_locked_table(thd, tables))
|
if (reopen_name_locked_table(thd, tables))
|
||||||
goto end_unlock;
|
goto end_unlock;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user