Backport of:
------------------------------------------------------------ revno: 2630.4.33 committer: Dmitry Lenev <dlenev@mysql.com> branch nick: mysql-6.0-3726-w2 timestamp: Fri 2008-06-20 17:11:20 +0400 message: WL#3726 "DDL locking for all metadata objects". After-review fixes in progress. Minimized dependency of mdl.cc on other modules (particularly made it independant of mysql_priv.h) in order to be able write unit tests for metadata locking subsystem.
This commit is contained in:
parent
0a49fd92d9
commit
edddfa0ef4
@ -141,7 +141,7 @@ static Uint64 *p_latest_trans_gci= 0;
|
|||||||
static TABLE *ndb_binlog_index= 0;
|
static TABLE *ndb_binlog_index= 0;
|
||||||
static TABLE_LIST binlog_tables;
|
static TABLE_LIST binlog_tables;
|
||||||
static MDL_LOCK_DATA binlog_mdl_lock_data;
|
static MDL_LOCK_DATA binlog_mdl_lock_data;
|
||||||
static char binlog_mdlkey[MAX_DBKEY_LENGTH];
|
static char binlog_mdlkey[MAX_MDLKEY_LENGTH];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Helper functions
|
Helper functions
|
||||||
|
@ -8074,7 +8074,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
|
|||||||
&db_mem, (uint) NAME_LEN + 1,
|
&db_mem, (uint) NAME_LEN + 1,
|
||||||
&tname_mem, (uint) NAME_LEN + 1,
|
&tname_mem, (uint) NAME_LEN + 1,
|
||||||
&mdl_lock_data, sizeof(MDL_LOCK_DATA),
|
&mdl_lock_data, sizeof(MDL_LOCK_DATA),
|
||||||
&mdlkey, MAX_DBKEY_LENGTH,
|
&mdlkey, MAX_MDLKEY_LENGTH,
|
||||||
NullS)))
|
NullS)))
|
||||||
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
|
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
|
||||||
|
|
||||||
|
136
sql/mdl.cc
136
sql/mdl.cc
@ -15,13 +15,9 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
TODO: Remove this dependency on mysql_priv.h. It's not
|
|
||||||
trivial step at the moment since currently we access to
|
|
||||||
some of THD members and use some of its methods here.
|
|
||||||
*/
|
|
||||||
#include "mysql_priv.h"
|
|
||||||
#include "mdl.h"
|
#include "mdl.h"
|
||||||
|
#include <hash.h>
|
||||||
|
#include <mysqld_error.h>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -308,7 +304,7 @@ MDL_LOCK_DATA *mdl_alloc_lock(int type, const char *db, const char *name,
|
|||||||
char *key;
|
char *key;
|
||||||
|
|
||||||
if (!multi_alloc_root(root, &lock_data, sizeof(MDL_LOCK_DATA), &key,
|
if (!multi_alloc_root(root, &lock_data, sizeof(MDL_LOCK_DATA), &key,
|
||||||
MAX_DBKEY_LENGTH, NULL))
|
MAX_MDLKEY_LENGTH, NULL))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
mdl_init_lock(lock_data, key, type, db, name);
|
mdl_init_lock(lock_data, key, type, db, name);
|
||||||
@ -441,6 +437,58 @@ static bool is_shared(MDL_LOCK_DATA *lock_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Helper functions and macros to be used for killable waiting in metadata
|
||||||
|
locking subsystem.
|
||||||
|
|
||||||
|
@sa THD::enter_cond()/exit_cond()/killed.
|
||||||
|
|
||||||
|
@note We can't use THD::enter_cond()/exit_cond()/killed directly here
|
||||||
|
since this will make metadata subsystem dependant on THD class
|
||||||
|
and thus prevent us from writing unit tests for it. And usage of
|
||||||
|
wrapper functions to access THD::killed/enter_cond()/exit_cond()
|
||||||
|
will probably introduce too much overhead.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MDL_ENTER_COND(A, B) mdl_enter_cond(A, B, __func__, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
static inline const char* mdl_enter_cond(MDL_CONTEXT *context,
|
||||||
|
st_my_thread_var *mysys_var,
|
||||||
|
const char *calling_func,
|
||||||
|
const char *calling_file,
|
||||||
|
const unsigned int calling_line)
|
||||||
|
{
|
||||||
|
safe_mutex_assert_owner(&LOCK_mdl);
|
||||||
|
|
||||||
|
mysys_var->current_mutex= &LOCK_mdl;
|
||||||
|
mysys_var->current_cond= &COND_mdl;
|
||||||
|
|
||||||
|
return set_thd_proc_info(context->thd, "Waiting for table",
|
||||||
|
calling_func, calling_file, calling_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MDL_EXIT_COND(A, B, C) mdl_exit_cond(A, B, C, __func__, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
static inline void mdl_exit_cond(MDL_CONTEXT *context,
|
||||||
|
st_my_thread_var *mysys_var,
|
||||||
|
const char* old_msg,
|
||||||
|
const char *calling_func,
|
||||||
|
const char *calling_file,
|
||||||
|
const unsigned int calling_line)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(&LOCK_mdl == mysys_var->current_mutex);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&LOCK_mdl);
|
||||||
|
pthread_mutex_lock(&mysys_var->mutex);
|
||||||
|
mysys_var->current_mutex= 0;
|
||||||
|
mysys_var->current_cond= 0;
|
||||||
|
pthread_mutex_unlock(&mysys_var->mutex);
|
||||||
|
|
||||||
|
(void) set_thd_proc_info(context->thd, old_msg, calling_func,
|
||||||
|
calling_file, calling_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Check if request for the lock on particular object can be satisfied given
|
Check if request for the lock on particular object can be satisfied given
|
||||||
current state of the global metadata lock.
|
current state of the global metadata lock.
|
||||||
@ -752,9 +800,7 @@ bool mdl_acquire_exclusive_locks(MDL_CONTEXT *context)
|
|||||||
bool signalled= FALSE;
|
bool signalled= FALSE;
|
||||||
const char *old_msg;
|
const char *old_msg;
|
||||||
I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> it(context->locks);
|
I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> it(context->locks);
|
||||||
THD *thd= context->thd;
|
st_my_thread_var *mysys_var= my_thread_var;
|
||||||
|
|
||||||
DBUG_ASSERT(thd == current_thd);
|
|
||||||
|
|
||||||
safe_mutex_assert_not_owner(&LOCK_open);
|
safe_mutex_assert_not_owner(&LOCK_open);
|
||||||
|
|
||||||
@ -766,7 +812,7 @@ bool mdl_acquire_exclusive_locks(MDL_CONTEXT *context)
|
|||||||
|
|
||||||
pthread_mutex_lock(&LOCK_mdl);
|
pthread_mutex_lock(&LOCK_mdl);
|
||||||
|
|
||||||
old_msg= thd->enter_cond(&COND_mdl, &LOCK_mdl, "Waiting for table");
|
old_msg= MDL_ENTER_COND(context, mysys_var);
|
||||||
|
|
||||||
while ((lock_data= it++))
|
while ((lock_data= it++))
|
||||||
{
|
{
|
||||||
@ -826,8 +872,11 @@ bool mdl_acquire_exclusive_locks(MDL_CONTEXT *context)
|
|||||||
!lock->active_shared_waiting_upgrade.is_empty();
|
!lock->active_shared_waiting_upgrade.is_empty();
|
||||||
|
|
||||||
while ((conf_lock_data= it++))
|
while ((conf_lock_data= it++))
|
||||||
|
{
|
||||||
signalled|=
|
signalled|=
|
||||||
notify_thread_having_shared_lock(thd, conf_lock_data->ctx->thd);
|
mysql_notify_thread_having_shared_lock(context->thd,
|
||||||
|
conf_lock_data->ctx->thd);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -848,7 +897,7 @@ bool mdl_acquire_exclusive_locks(MDL_CONTEXT *context)
|
|||||||
set_timespec(abstime, 10);
|
set_timespec(abstime, 10);
|
||||||
pthread_cond_timedwait(&COND_mdl, &LOCK_mdl, &abstime);
|
pthread_cond_timedwait(&COND_mdl, &LOCK_mdl, &abstime);
|
||||||
}
|
}
|
||||||
if (thd->killed)
|
if (mysys_var->abort)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
it.rewind();
|
it.rewind();
|
||||||
@ -863,8 +912,8 @@ bool mdl_acquire_exclusive_locks(MDL_CONTEXT *context)
|
|||||||
(*lock->cached_object_release_hook)(lock->cached_object);
|
(*lock->cached_object_release_hook)(lock->cached_object);
|
||||||
lock->cached_object= NULL;
|
lock->cached_object= NULL;
|
||||||
}
|
}
|
||||||
/* As a side-effect THD::exit_cond() unlocks LOCK_mdl. */
|
/* As a side-effect MDL_EXIT_COND() unlocks LOCK_mdl. */
|
||||||
thd->exit_cond(old_msg);
|
MDL_EXIT_COND(context, mysys_var, old_msg);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
@ -880,7 +929,7 @@ err:
|
|||||||
}
|
}
|
||||||
/* May be some pending requests for shared locks can be satisfied now. */
|
/* May be some pending requests for shared locks can be satisfied now. */
|
||||||
pthread_cond_broadcast(&COND_mdl);
|
pthread_cond_broadcast(&COND_mdl);
|
||||||
thd->exit_cond(old_msg);
|
MDL_EXIT_COND(context, mysys_var, old_msg);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -907,12 +956,10 @@ bool mdl_upgrade_shared_lock_to_exclusive(MDL_CONTEXT *context,
|
|||||||
{
|
{
|
||||||
MDL_LOCK *lock;
|
MDL_LOCK *lock;
|
||||||
const char *old_msg;
|
const char *old_msg;
|
||||||
THD *thd= context->thd;
|
st_my_thread_var *mysys_var= my_thread_var;
|
||||||
|
|
||||||
DBUG_ENTER("mdl_upgrade_shared_lock_to_exclusive");
|
DBUG_ENTER("mdl_upgrade_shared_lock_to_exclusive");
|
||||||
|
|
||||||
DBUG_ASSERT(thd == current_thd);
|
|
||||||
|
|
||||||
safe_mutex_assert_not_owner(&LOCK_open);
|
safe_mutex_assert_not_owner(&LOCK_open);
|
||||||
|
|
||||||
DBUG_ASSERT(lock_data->state == MDL_ACQUIRED);
|
DBUG_ASSERT(lock_data->state == MDL_ACQUIRED);
|
||||||
@ -927,7 +974,7 @@ bool mdl_upgrade_shared_lock_to_exclusive(MDL_CONTEXT *context,
|
|||||||
|
|
||||||
pthread_mutex_lock(&LOCK_mdl);
|
pthread_mutex_lock(&LOCK_mdl);
|
||||||
|
|
||||||
old_msg= thd->enter_cond(&COND_mdl, &LOCK_mdl, "Waiting for table");
|
old_msg= MDL_ENTER_COND(context, mysys_var);
|
||||||
|
|
||||||
lock_data->state= MDL_PENDING_UPGRADE;
|
lock_data->state= MDL_PENDING_UPGRADE;
|
||||||
/* Set type of lock request to the type at which we are aiming. */
|
/* Set type of lock request to the type at which we are aiming. */
|
||||||
@ -960,8 +1007,11 @@ bool mdl_upgrade_shared_lock_to_exclusive(MDL_CONTEXT *context,
|
|||||||
while ((conf_lock_data= it++))
|
while ((conf_lock_data= it++))
|
||||||
{
|
{
|
||||||
if (conf_lock_data->ctx != context)
|
if (conf_lock_data->ctx != context)
|
||||||
signalled|= notify_thread_having_shared_lock(thd,
|
{
|
||||||
conf_lock_data->ctx->thd);
|
signalled|=
|
||||||
|
mysql_notify_thread_having_shared_lock(context->thd,
|
||||||
|
conf_lock_data->ctx->thd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signalled)
|
if (signalled)
|
||||||
@ -979,7 +1029,7 @@ bool mdl_upgrade_shared_lock_to_exclusive(MDL_CONTEXT *context,
|
|||||||
DBUG_PRINT("info", ("Failed to wake-up from table-level lock ... sleeping"));
|
DBUG_PRINT("info", ("Failed to wake-up from table-level lock ... sleeping"));
|
||||||
pthread_cond_timedwait(&COND_mdl, &LOCK_mdl, &abstime);
|
pthread_cond_timedwait(&COND_mdl, &LOCK_mdl, &abstime);
|
||||||
}
|
}
|
||||||
if (thd->killed)
|
if (mysys_var->abort)
|
||||||
{
|
{
|
||||||
lock_data->state= MDL_ACQUIRED;
|
lock_data->state= MDL_ACQUIRED;
|
||||||
lock_data->type= MDL_SHARED_UPGRADABLE;
|
lock_data->type= MDL_SHARED_UPGRADABLE;
|
||||||
@ -987,7 +1037,7 @@ bool mdl_upgrade_shared_lock_to_exclusive(MDL_CONTEXT *context,
|
|||||||
lock->active_shared.push_front(lock_data);
|
lock->active_shared.push_front(lock_data);
|
||||||
/* Pending requests for shared locks can be satisfied now. */
|
/* Pending requests for shared locks can be satisfied now. */
|
||||||
pthread_cond_broadcast(&COND_mdl);
|
pthread_cond_broadcast(&COND_mdl);
|
||||||
thd->exit_cond(old_msg);
|
MDL_EXIT_COND(context, mysys_var, old_msg);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -999,8 +1049,8 @@ bool mdl_upgrade_shared_lock_to_exclusive(MDL_CONTEXT *context,
|
|||||||
(*lock->cached_object_release_hook)(lock->cached_object);
|
(*lock->cached_object_release_hook)(lock->cached_object);
|
||||||
lock->cached_object= 0;
|
lock->cached_object= 0;
|
||||||
|
|
||||||
/* As a side-effect THD::exit_cond() unlocks LOCK_mdl. */
|
/* As a side-effect MDL_EXIT_COND() unlocks LOCK_mdl. */
|
||||||
thd->exit_cond(old_msg);
|
MDL_EXIT_COND(context, mysys_var, old_msg);
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1086,32 +1136,31 @@ err:
|
|||||||
|
|
||||||
bool mdl_acquire_global_shared_lock(MDL_CONTEXT *context)
|
bool mdl_acquire_global_shared_lock(MDL_CONTEXT *context)
|
||||||
{
|
{
|
||||||
THD *thd= context->thd;
|
st_my_thread_var *mysys_var= my_thread_var;
|
||||||
const char *old_msg;
|
const char *old_msg;
|
||||||
|
|
||||||
safe_mutex_assert_not_owner(&LOCK_open);
|
safe_mutex_assert_not_owner(&LOCK_open);
|
||||||
DBUG_ASSERT(thd == current_thd);
|
|
||||||
DBUG_ASSERT(!context->has_global_shared_lock);
|
DBUG_ASSERT(!context->has_global_shared_lock);
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_mdl);
|
pthread_mutex_lock(&LOCK_mdl);
|
||||||
|
|
||||||
global_lock.waiting_shared++;
|
global_lock.waiting_shared++;
|
||||||
old_msg= thd->enter_cond(&COND_mdl, &LOCK_mdl, "Waiting for table");
|
old_msg= MDL_ENTER_COND(context, mysys_var);
|
||||||
|
|
||||||
while (!thd->killed && global_lock.active_intention_exclusive)
|
while (!mysys_var->abort && global_lock.active_intention_exclusive)
|
||||||
pthread_cond_wait(&COND_mdl, &LOCK_mdl);
|
pthread_cond_wait(&COND_mdl, &LOCK_mdl);
|
||||||
|
|
||||||
global_lock.waiting_shared--;
|
global_lock.waiting_shared--;
|
||||||
if (thd->killed)
|
if (mysys_var->abort)
|
||||||
{
|
{
|
||||||
/* As a side-effect THD::exit_cond() unlocks LOCK_mdl. */
|
/* As a side-effect MDL_EXIT_COND() unlocks LOCK_mdl. */
|
||||||
thd->exit_cond(old_msg);
|
MDL_EXIT_COND(context, mysys_var, old_msg);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
global_lock.active_shared++;
|
global_lock.active_shared++;
|
||||||
context->has_global_shared_lock= TRUE;
|
context->has_global_shared_lock= TRUE;
|
||||||
/* As a side-effect THD::exit_cond() unlocks LOCK_mdl. */
|
/* As a side-effect MDL_EXIT_COND() unlocks LOCK_mdl. */
|
||||||
thd->exit_cond(old_msg);
|
MDL_EXIT_COND(context, mysys_var, old_msg);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1137,12 +1186,11 @@ bool mdl_wait_for_locks(MDL_CONTEXT *context)
|
|||||||
MDL_LOCK *lock;
|
MDL_LOCK *lock;
|
||||||
I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> it(context->locks);
|
I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> it(context->locks);
|
||||||
const char *old_msg;
|
const char *old_msg;
|
||||||
THD *thd= context->thd;
|
st_my_thread_var *mysys_var= my_thread_var;
|
||||||
|
|
||||||
safe_mutex_assert_not_owner(&LOCK_open);
|
safe_mutex_assert_not_owner(&LOCK_open);
|
||||||
DBUG_ASSERT(thd == current_thd);
|
|
||||||
|
|
||||||
while (!thd->killed)
|
while (!mysys_var->abort)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
We have to check if there are some HANDLERs open by this thread
|
We have to check if there are some HANDLERs open by this thread
|
||||||
@ -1156,7 +1204,7 @@ bool mdl_wait_for_locks(MDL_CONTEXT *context)
|
|||||||
*/
|
*/
|
||||||
mysql_ha_flush(context->thd);
|
mysql_ha_flush(context->thd);
|
||||||
pthread_mutex_lock(&LOCK_mdl);
|
pthread_mutex_lock(&LOCK_mdl);
|
||||||
old_msg= thd->enter_cond(&COND_mdl, &LOCK_mdl, "Waiting for table");
|
old_msg= MDL_ENTER_COND(context, mysys_var);
|
||||||
it.rewind();
|
it.rewind();
|
||||||
while ((lock_data= it++))
|
while ((lock_data= it++))
|
||||||
{
|
{
|
||||||
@ -1179,10 +1227,10 @@ bool mdl_wait_for_locks(MDL_CONTEXT *context)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pthread_cond_wait(&COND_mdl, &LOCK_mdl);
|
pthread_cond_wait(&COND_mdl, &LOCK_mdl);
|
||||||
/* As a side-effect THD::exit_cond() unlocks LOCK_mdl. */
|
/* As a side-effect MDL_EXIT_COND() unlocks LOCK_mdl. */
|
||||||
thd->exit_cond(old_msg);
|
MDL_EXIT_COND(context, mysys_var, old_msg);
|
||||||
}
|
}
|
||||||
return thd->killed;
|
return mysys_var->abort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1422,7 +1470,7 @@ void mdl_release_global_shared_lock(MDL_CONTEXT *context)
|
|||||||
bool mdl_is_exclusive_lock_owner(MDL_CONTEXT *context, int type,
|
bool mdl_is_exclusive_lock_owner(MDL_CONTEXT *context, int type,
|
||||||
const char *db, const char *name)
|
const char *db, const char *name)
|
||||||
{
|
{
|
||||||
char key[MAX_DBKEY_LENGTH];
|
char key[MAX_MDLKEY_LENGTH];
|
||||||
uint key_length;
|
uint key_length;
|
||||||
MDL_LOCK_DATA *lock_data;
|
MDL_LOCK_DATA *lock_data;
|
||||||
I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> it(context->locks);
|
I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> it(context->locks);
|
||||||
@ -1456,7 +1504,7 @@ bool mdl_is_exclusive_lock_owner(MDL_CONTEXT *context, int type,
|
|||||||
bool mdl_is_lock_owner(MDL_CONTEXT *context, int type, const char *db,
|
bool mdl_is_lock_owner(MDL_CONTEXT *context, int type, const char *db,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
char key[MAX_DBKEY_LENGTH];
|
char key[MAX_MDLKEY_LENGTH];
|
||||||
uint key_length;
|
uint key_length;
|
||||||
MDL_LOCK_DATA *lock_data;
|
MDL_LOCK_DATA *lock_data;
|
||||||
I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> it(context->locks);
|
I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> it(context->locks);
|
||||||
|
19
sql/mdl.h
19
sql/mdl.h
@ -19,6 +19,7 @@
|
|||||||
#include "sql_plist.h"
|
#include "sql_plist.h"
|
||||||
#include <my_sys.h>
|
#include <my_sys.h>
|
||||||
#include <m_string.h>
|
#include <m_string.h>
|
||||||
|
#include <mysql_com.h>
|
||||||
|
|
||||||
class THD;
|
class THD;
|
||||||
|
|
||||||
@ -148,6 +149,9 @@ void mdl_context_backup_and_reset(MDL_CONTEXT *ctx, MDL_CONTEXT *backup);
|
|||||||
void mdl_context_restore(MDL_CONTEXT *ctx, MDL_CONTEXT *backup);
|
void mdl_context_restore(MDL_CONTEXT *ctx, MDL_CONTEXT *backup);
|
||||||
void mdl_context_merge(MDL_CONTEXT *target, MDL_CONTEXT *source);
|
void mdl_context_merge(MDL_CONTEXT *target, MDL_CONTEXT *source);
|
||||||
|
|
||||||
|
/** Maximal length of key for metadata locking subsystem. */
|
||||||
|
#define MAX_MDLKEY_LENGTH (4 + NAME_LEN + 1 + NAME_LEN + 1)
|
||||||
|
|
||||||
void mdl_init_lock(MDL_LOCK_DATA *lock_data, char *key, int type,
|
void mdl_init_lock(MDL_LOCK_DATA *lock_data, char *key, int type,
|
||||||
const char *db, const char *name);
|
const char *db, const char *name);
|
||||||
MDL_LOCK_DATA *mdl_alloc_lock(int type, const char *db, const char *name,
|
MDL_LOCK_DATA *mdl_alloc_lock(int type, const char *db, const char *name,
|
||||||
@ -237,4 +241,19 @@ void* mdl_get_cached_object(MDL_LOCK_DATA *lock_data);
|
|||||||
void mdl_set_cached_object(MDL_LOCK_DATA *lock_data, void *cached_object,
|
void mdl_set_cached_object(MDL_LOCK_DATA *lock_data, void *cached_object,
|
||||||
mdl_cached_object_release_hook release_hook);
|
mdl_cached_object_release_hook release_hook);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Functions in the server's kernel used by metadata locking subsystem.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern bool mysql_notify_thread_having_shared_lock(THD *thd, THD *in_use);
|
||||||
|
extern void mysql_ha_flush(THD *thd);
|
||||||
|
extern "C" const char *set_thd_proc_info(THD *thd, const char *info,
|
||||||
|
const char *calling_function,
|
||||||
|
const char *calling_file,
|
||||||
|
const unsigned int calling_line);
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
extern pthread_mutex_t LOCK_open;
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1534,8 +1534,6 @@ char *generate_partition_syntax(partition_info *part_info,
|
|||||||
Alter_info *alter_info);
|
Alter_info *alter_info);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool notify_thread_having_shared_lock(THD *thd, THD *in_use);
|
|
||||||
|
|
||||||
enum enum_tdc_remove_table_type {TDC_RT_REMOVE_ALL, TDC_RT_REMOVE_NOT_OWN,
|
enum enum_tdc_remove_table_type {TDC_RT_REMOVE_ALL, TDC_RT_REMOVE_NOT_OWN,
|
||||||
TDC_RT_REMOVE_UNUSED};
|
TDC_RT_REMOVE_UNUSED};
|
||||||
void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
|
void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
|
||||||
|
@ -1275,7 +1275,7 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
|
|||||||
/*
|
/*
|
||||||
We need to hold LOCK_open while changing the open_tables
|
We need to hold LOCK_open while changing the open_tables
|
||||||
list, since another thread may work on it.
|
list, since another thread may work on it.
|
||||||
@sa notify_thread_having_shared_lock()
|
@sa mysql_notify_thread_having_shared_lock()
|
||||||
*/
|
*/
|
||||||
pthread_mutex_lock(&LOCK_open);
|
pthread_mutex_lock(&LOCK_open);
|
||||||
|
|
||||||
@ -1455,7 +1455,7 @@ void close_thread_tables(THD *thd,
|
|||||||
/*
|
/*
|
||||||
Note that we need to hold LOCK_open while changing the
|
Note that we need to hold LOCK_open while changing the
|
||||||
open_tables list. Another thread may work on it.
|
open_tables list. Another thread may work on it.
|
||||||
(See: notify_thread_having_shared_lock())
|
(See: mysql_notify_thread_having_shared_lock())
|
||||||
Closing a MERGE child before the parent would be fatal if the
|
Closing a MERGE child before the parent would be fatal if the
|
||||||
other thread tries to abort the MERGE lock in between.
|
other thread tries to abort the MERGE lock in between.
|
||||||
*/
|
*/
|
||||||
@ -7956,7 +7956,7 @@ void flush_tables()
|
|||||||
rest of the server is broken.
|
rest of the server is broken.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool notify_thread_having_shared_lock(THD *thd, THD *in_use)
|
bool mysql_notify_thread_having_shared_lock(THD *thd, THD *in_use)
|
||||||
{
|
{
|
||||||
bool signalled= FALSE;
|
bool signalled= FALSE;
|
||||||
if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) &&
|
if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) &&
|
||||||
@ -8501,7 +8501,7 @@ void close_performance_schema_table(THD *thd, Open_tables_state *backup)
|
|||||||
/*
|
/*
|
||||||
Note that we need to hold LOCK_open while changing the
|
Note that we need to hold LOCK_open while changing the
|
||||||
open_tables list. Another thread may work on it.
|
open_tables list. Another thread may work on it.
|
||||||
(See: notify_thread_having_shared_lock())
|
(See: mysql_notify_thread_having_shared_lock())
|
||||||
Closing a MERGE child before the parent would be fatal if the
|
Closing a MERGE child before the parent would be fatal if the
|
||||||
other thread tries to abort the MERGE lock in between.
|
other thread tries to abort the MERGE lock in between.
|
||||||
*/
|
*/
|
||||||
|
@ -247,7 +247,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
|
|||||||
&name, (uint) namelen,
|
&name, (uint) namelen,
|
||||||
&alias, (uint) aliaslen,
|
&alias, (uint) aliaslen,
|
||||||
&mdl_lock_data, sizeof(MDL_LOCK_DATA),
|
&mdl_lock_data, sizeof(MDL_LOCK_DATA),
|
||||||
&mdlkey, MAX_DBKEY_LENGTH,
|
&mdlkey, MAX_MDLKEY_LENGTH,
|
||||||
NullS)))
|
NullS)))
|
||||||
{
|
{
|
||||||
DBUG_PRINT("exit",("ERROR"));
|
DBUG_PRINT("exit",("ERROR"));
|
||||||
|
@ -3084,7 +3084,7 @@ uint get_table_open_method(TABLE_LIST *tables,
|
|||||||
@param mdlkey Pointer to the buffer for key for the lock request
|
@param mdlkey Pointer to the buffer for key for the lock request
|
||||||
(should be at least strlen(db) + strlen(name) + 2
|
(should be at least strlen(db) + strlen(name) + 2
|
||||||
bytes, or, if the lengths are not known,
|
bytes, or, if the lengths are not known,
|
||||||
MAX_DBNAME_LENGTH)
|
MAX_MDLKEY_LENGTH)
|
||||||
@param table Table list element for the table
|
@param table Table list element for the table
|
||||||
|
|
||||||
@note This is an auxiliary function to be used in cases when we want to
|
@note This is an auxiliary function to be used in cases when we want to
|
||||||
@ -3157,7 +3157,7 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table,
|
|||||||
uint key_length;
|
uint key_length;
|
||||||
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_MDLKEY_LENGTH];
|
||||||
|
|
||||||
bzero((char*) &table_list, sizeof(TABLE_LIST));
|
bzero((char*) &table_list, sizeof(TABLE_LIST));
|
||||||
bzero((char*) &tbl, sizeof(TABLE));
|
bzero((char*) &tbl, sizeof(TABLE));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user