1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Manual merge of mysql-trunk into mysql-trunk-merge.

Conflicts:

Text conflict in client/mysqlbinlog.cc
Text conflict in mysql-test/Makefile.am
Text conflict in mysql-test/collections/default.daily
Text conflict in mysql-test/r/mysqlbinlog_row_innodb.result
Text conflict in mysql-test/suite/rpl/r/rpl_typeconv_innodb.result
Text conflict in mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test
Text conflict in mysql-test/suite/rpl/t/rpl_row_create_table.test
Text conflict in mysql-test/suite/rpl/t/rpl_slave_skip.test
Text conflict in mysql-test/suite/rpl/t/rpl_typeconv_innodb.test
Text conflict in mysys/charset.c
Text conflict in sql/field.cc
Text conflict in sql/field.h
Text conflict in sql/item.h
Text conflict in sql/item_func.cc
Text conflict in sql/log.cc
Text conflict in sql/log_event.cc
Text conflict in sql/log_event_old.cc
Text conflict in sql/mysqld.cc
Text conflict in sql/rpl_utility.cc
Text conflict in sql/rpl_utility.h
Text conflict in sql/set_var.cc
Text conflict in sql/share/Makefile.am
Text conflict in sql/sql_delete.cc
Text conflict in sql/sql_plugin.cc
Text conflict in sql/sql_select.cc
Text conflict in sql/sql_table.cc
Text conflict in storage/example/ha_example.h
Text conflict in storage/federated/ha_federated.cc
Text conflict in storage/myisammrg/ha_myisammrg.cc
Text conflict in storage/myisammrg/myrg_open.c
This commit is contained in:
Alexey Kopytov
2010-03-24 18:03:44 +03:00
2460 changed files with 596951 additions and 233067 deletions

View File

@ -221,14 +221,14 @@
There are quite a few places in MySQL, where we use a synchronization
pattern like this:
pthread_mutex_lock(&mutex);
mysql_mutex_lock(&mutex);
thd->enter_cond(&condition_variable, &mutex, new_message);
#if defined(ENABLE_DEBUG_SYNC)
if (!thd->killed && !end_of_wait_condition)
DEBUG_SYNC(thd, "sync_point_name");
#endif
while (!thd->killed && !end_of_wait_condition)
pthread_cond_wait(&condition_variable, &mutex);
mysql_cond_wait(&condition_variable, &mutex);
thd->exit_cond(old_message);
Here some explanations:
@ -264,12 +264,12 @@
while (!thd->killed && !end_of_wait_condition)
{
pthread_mutex_lock(&mutex);
mysql_mutex_lock(&mutex);
thd->enter_cond(&condition_variable, &mutex, new_message);
if (!thd->killed [&& !end_of_wait_condition])
{
[DEBUG_SYNC(thd, "sync_point_name");]
pthread_cond_wait(&condition_variable, &mutex);
mysql_cond_wait(&condition_variable, &mutex);
}
thd->exit_cond(old_message);
}
@ -285,7 +285,7 @@
before sleeping, we hold the mutex, which is registered in mysys_var.
The killing thread would try to acquire the mutex before signaling
the condition variable. Since the mutex is only released implicitly in
pthread_cond_wait(), the signaling happens at the right place. We
mysql_cond_wait(), the signaling happens at the right place. We
have a safe synchronization.
=== Co-work with the DBUG facility ===
@ -373,8 +373,8 @@ struct st_debug_sync_control
struct st_debug_sync_globals
{
String ds_signal; /* signal variable */
pthread_cond_t ds_cond; /* condition variable */
pthread_mutex_t ds_mutex; /* mutex variable */
mysql_cond_t ds_cond; /* condition variable */
mysql_mutex_t ds_mutex; /* mutex variable */
ulonglong dsp_hits; /* statistics */
ulonglong dsp_executed; /* statistics */
ulonglong dsp_max_active; /* statistics */
@ -425,6 +425,37 @@ static void debug_sync_C_callback(const char *sync_point_name,
debug_sync(current_thd, sync_point_name, name_len);
}
#ifdef HAVE_PSI_INTERFACE
static PSI_mutex_key key_debug_sync_globals_ds_mutex;
static PSI_mutex_info all_debug_sync_mutexes[]=
{
{ &key_debug_sync_globals_ds_mutex, "DEBUG_SYNC::mutex", PSI_FLAG_GLOBAL}
};
static PSI_cond_key key_debug_sync_globals_ds_cond;
static PSI_cond_info all_debug_sync_conds[]=
{
{ &key_debug_sync_globals_ds_cond, "DEBUG_SYNC::cond", PSI_FLAG_GLOBAL}
};
static void init_debug_sync_psi_keys(void)
{
const char* category= "sql";
int count;
if (PSI_server == NULL)
return;
count= array_elements(all_debug_sync_mutexes);
PSI_server->register_mutex(category, all_debug_sync_mutexes, count);
count= array_elements(all_debug_sync_conds);
PSI_server->register_cond(category, all_debug_sync_conds, count);
}
#endif /* HAVE_PSI_INTERFACE */
/**
Initialize the debug sync facility at server start.
@ -438,15 +469,21 @@ int debug_sync_init(void)
{
DBUG_ENTER("debug_sync_init");
#ifdef HAVE_PSI_INTERFACE
init_debug_sync_psi_keys();
#endif
if (opt_debug_sync_timeout)
{
int rc;
/* Initialize the global variables. */
debug_sync_global.ds_signal.length(0);
if ((rc= pthread_cond_init(&debug_sync_global.ds_cond, NULL)) ||
(rc= pthread_mutex_init(&debug_sync_global.ds_mutex,
MY_MUTEX_INIT_FAST)))
if ((rc= mysql_cond_init(key_debug_sync_globals_ds_cond,
&debug_sync_global.ds_cond, NULL)) ||
(rc= mysql_mutex_init(key_debug_sync_globals_ds_mutex,
&debug_sync_global.ds_mutex,
MY_MUTEX_INIT_FAST)))
DBUG_RETURN(rc); /* purecov: inspected */
/* Set the call back pointer in C files. */
@ -476,8 +513,8 @@ void debug_sync_end(void)
/* Destroy the global variables. */
debug_sync_global.ds_signal.free();
(void) pthread_cond_destroy(&debug_sync_global.ds_cond);
(void) pthread_mutex_destroy(&debug_sync_global.ds_mutex);
mysql_cond_destroy(&debug_sync_global.ds_cond);
mysql_mutex_destroy(&debug_sync_global.ds_mutex);
/* Print statistics. */
{
@ -585,12 +622,12 @@ void debug_sync_end_thread(THD *thd)
}
/* Statistics. */
pthread_mutex_lock(&debug_sync_global.ds_mutex);
mysql_mutex_lock(&debug_sync_global.ds_mutex);
debug_sync_global.dsp_hits+= ds_control->dsp_hits;
debug_sync_global.dsp_executed+= ds_control->dsp_executed;
if (debug_sync_global.dsp_max_active < ds_control->dsp_max_active)
debug_sync_global.dsp_max_active= ds_control->dsp_max_active;
pthread_mutex_unlock(&debug_sync_global.ds_mutex);
mysql_mutex_unlock(&debug_sync_global.ds_mutex);
my_free(ds_control, MYF(0));
thd->debug_sync_control= NULL;
@ -824,9 +861,9 @@ static void debug_sync_reset(THD *thd)
ds_control->ds_active= 0;
/* Clear the global signal. */
pthread_mutex_lock(&debug_sync_global.ds_mutex);
mysql_mutex_lock(&debug_sync_global.ds_mutex);
debug_sync_global.ds_signal.length(0);
pthread_mutex_unlock(&debug_sync_global.ds_mutex);
mysql_mutex_unlock(&debug_sync_global.ds_mutex);
DBUG_VOID_RETURN;
}
@ -1524,56 +1561,6 @@ static bool debug_sync_eval_action(THD *thd, char *action_str)
DBUG_RETURN(FALSE);
}
/**
Check if the system variable 'debug_sync' can be set.
@param[in] thd thread handle
@param[in] var set variable request
@return status
@retval FALSE ok, variable can be set
@retval TRUE error, variable cannot be set
*/
bool sys_var_debug_sync::check(THD *thd, set_var *var)
{
DBUG_ENTER("sys_var_debug_sync::check");
DBUG_ASSERT(thd);
DBUG_ASSERT(var);
/*
Variable can be set for the session only.
This could be changed later. Then we need to have a global array of
actions in addition to the thread local ones. SET GLOBAL would
manage the global array, SET [SESSION] the local array. A sync point
would need to look for a local and a global action. Setting and
executing of global actions need to be protected by a mutex.
The purpose of global actions could be to allow synchronizing with
connectionless threads that cannot execute SET statements.
*/
if (var->type == OPT_GLOBAL)
{
my_error(ER_LOCAL_VARIABLE, MYF(0), name);
DBUG_RETURN(TRUE);
}
/*
Do not check for disabled facility. Test result should not
unnecessarily differ from enabled facility.
*/
/*
Facility requires SUPER privilege. Sync points could be inside
global mutexes (e.g. LOCK_open). Waiting there forever would
stall the whole server.
*/
DBUG_RETURN(check_global_access(thd, SUPER_ACL));
}
/**
Set the system variable 'debug_sync'.
@ -1594,28 +1581,9 @@ bool sys_var_debug_sync::check(THD *thd, set_var *var)
terminators in the string. So we need to take a copy here.
*/
bool sys_var_debug_sync::update(THD *thd, set_var *var)
bool debug_sync_update(THD *thd, char *val_str)
{
char *val_str;
String *val_ptr;
String val_buf;
DBUG_ENTER("sys_var_debug_sync::update");
DBUG_ASSERT(thd);
/*
Depending on the value type (string literal, user variable, ...)
val_buf receives a copy of the value or not. But we always need
a copy. So we take a copy, if it is not done by val_str().
If val_str() puts a copy into val_buf, then it returns &val_buf,
otherwise it returns a pointer to the string object that we need
to copy.
*/
val_ptr= var ? var->value->val_str(&val_buf) : &val_buf;
if (val_ptr != &val_buf)
{
val_buf.copy(*val_ptr);
}
val_str= val_buf.c_ptr();
DBUG_ENTER("debug_sync_update");
DBUG_PRINT("debug_sync", ("set action: '%s'", val_str));
/*
@ -1632,8 +1600,6 @@ bool sys_var_debug_sync::update(THD *thd, set_var *var)
Retrieve the value of the system variable 'debug_sync'.
@param[in] thd thread handle
@param[in] type variable type, unused
@param[in] base variable base, unused
@return string
@retval != NULL ok, string pointer
@ -1646,20 +1612,17 @@ bool sys_var_debug_sync::update(THD *thd, set_var *var)
When "ON", the current signal is added.
*/
uchar *sys_var_debug_sync::value_ptr(THD *thd,
enum_var_type type __attribute__((unused)),
LEX_STRING *base __attribute__((unused)))
uchar *debug_sync_value_ptr(THD *thd)
{
char *value;
DBUG_ENTER("sys_var_debug_sync::value_ptr");
DBUG_ASSERT(thd);
DBUG_ENTER("debug_sync_value_ptr");
if (opt_debug_sync_timeout)
{
static char on[]= "ON - current signal: '";
// Ensure exclusive access to debug_sync_global.ds_signal
pthread_mutex_lock(&debug_sync_global.ds_mutex);
mysql_mutex_lock(&debug_sync_global.ds_mutex);
size_t lgt= (sizeof(on) /* includes '\0' */ +
debug_sync_global.ds_signal.length() + 1 /* for '\'' */);
@ -1676,12 +1639,12 @@ uchar *sys_var_debug_sync::value_ptr(THD *thd,
*(vptr++)= '\'';
*vptr= '\0'; /* We have one byte reserved for the worst case. */
}
pthread_mutex_unlock(&debug_sync_global.ds_mutex);
mysql_mutex_unlock(&debug_sync_global.ds_mutex);
}
else
{
/* purecov: begin tested */
value= strmake_root(thd->mem_root, STRING_WITH_LEN("OFF"));
value= const_cast<char*>("OFF");
/* purecov: end */
}
@ -1744,7 +1707,7 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action)
read access too, to create a memory barrier in order to avoid that
threads just reads an old cached version of the signal.
*/
pthread_mutex_lock(&debug_sync_global.ds_mutex);
mysql_mutex_lock(&debug_sync_global.ds_mutex);
if (action->signal.length())
{
@ -1758,15 +1721,15 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action)
debug_sync_emergency_disable(); /* purecov: tested */
}
/* Wake threads waiting in a sync point. */
pthread_cond_broadcast(&debug_sync_global.ds_cond);
mysql_cond_broadcast(&debug_sync_global.ds_cond);
DBUG_PRINT("debug_sync_exec", ("signal '%s' at: '%s'",
sig_emit, dsp_name));
} /* end if (action->signal.length()) */
if (action->wait_for.length())
{
pthread_mutex_t *old_mutex;
pthread_cond_t *old_cond;
mysql_mutex_t *old_mutex;
mysql_cond_t *old_cond;
int error= 0;
struct timespec abstime;
@ -1797,9 +1760,9 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action)
while (stringcmp(&debug_sync_global.ds_signal, &action->wait_for) &&
!thd->killed && opt_debug_sync_timeout)
{
error= pthread_cond_timedwait(&debug_sync_global.ds_cond,
&debug_sync_global.ds_mutex,
&abstime);
error= mysql_cond_timedwait(&debug_sync_global.ds_cond,
&debug_sync_global.ds_mutex,
&abstime);
DBUG_EXECUTE("debug_sync", {
/* Functions as DBUG_PRINT args can change keyword and line nr. */
const char *sig_glob= debug_sync_global.ds_signal.c_ptr();
@ -1832,18 +1795,17 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action)
protected mutex must always unlocked _before_ mysys_var->mutex
is locked. (See comment in THD::exit_cond().)
*/
pthread_mutex_unlock(&debug_sync_global.ds_mutex);
pthread_mutex_lock(&thd->mysys_var->mutex);
mysql_mutex_unlock(&debug_sync_global.ds_mutex);
mysql_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex= old_mutex;
thd->mysys_var->current_cond= old_cond;
thd_proc_info(thd, old_proc_info);
pthread_mutex_unlock(&thd->mysys_var->mutex);
mysql_mutex_unlock(&thd->mysys_var->mutex);
}
else
{
/* In case we don't wait, we just release the mutex. */
pthread_mutex_unlock(&debug_sync_global.ds_mutex);
mysql_mutex_unlock(&debug_sync_global.ds_mutex);
} /* end if (action->wait_for.length()) */
} /* end if (action->execute) */