Commit 5fa4c235 authored by unknown's avatar unknown

MDEV-26: Global transaction ID.

Fix remaining two sporadic test failures in the full test suite:

 - Remove crash in DBUG_ASSERT() in _db_flush() (bug also exists in main
   tree).

 - Fix locking order violation for LOCK_status by temporarily unlocking it
   while locking LOCK_active_mi (like a similar fix for
   LOCK_global_variables).
parent d9f975d0
......@@ -89,7 +89,7 @@ extern const char* _db_get_func_(void);
#define DBUG_END() _db_end_ ()
#define DBUG_LOCK_FILE _db_lock_file_()
#define DBUG_UNLOCK_FILE _db_unlock_file_()
#define DBUG_ASSERT(A) do { _db_flush_(); assert(A); } while(0)
#define DBUG_ASSERT(A) assert(A)
#define DBUG_EXPLAIN(buf,len) _db_explain_(0, (buf),(len))
#define DBUG_EXPLAIN_INITIAL(buf,len) _db_explain_init_((buf),(len))
#define DEBUGGER_OFF do { _dbug_on_= 0; } while(0)
......
......@@ -6681,19 +6681,24 @@ static int show_rpl_status(THD *thd, SHOW_VAR *var, char *buff)
static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff)
{
Master_info *mi;
bool tmp;
var->type= SHOW_MY_BOOL;
var->value= buff;
mysql_mutex_unlock(&LOCK_status);
mysql_mutex_lock(&LOCK_active_mi);
mi= master_info_index->
get_master_info(&thd->variables.default_master_connection,
MYSQL_ERROR::WARN_LEVEL_NOTE);
if (mi)
*((my_bool *)buff)= (my_bool) (mi->slave_running ==
MYSQL_SLAVE_RUN_CONNECT &&
mi->rli.slave_running);
tmp= (my_bool) (mi->slave_running == MYSQL_SLAVE_RUN_CONNECT &&
mi->rli.slave_running);
mysql_mutex_unlock(&LOCK_active_mi);
mysql_mutex_lock(&LOCK_status);
if (mi)
*((my_bool *)buff)= tmp;
else
var->type= SHOW_UNDEF;
mysql_mutex_unlock(&LOCK_active_mi);
return 0;
}
......@@ -6701,17 +6706,23 @@ static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff)
static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff)
{
Master_info *mi;
longlong tmp;
var->type= SHOW_LONGLONG;
var->value= buff;
mysql_mutex_unlock(&LOCK_status);
mysql_mutex_lock(&LOCK_active_mi);
mi= master_info_index->
get_master_info(&thd->variables.default_master_connection,
MYSQL_ERROR::WARN_LEVEL_NOTE);
if (mi)
*((longlong *)buff)= mi->received_heartbeats;
tmp= mi->received_heartbeats;
mysql_mutex_unlock(&LOCK_active_mi);
mysql_mutex_lock(&LOCK_status);
if (mi)
*((longlong *)buff)= tmp;
else
var->type= SHOW_UNDEF;
mysql_mutex_unlock(&LOCK_active_mi);
return 0;
}
......@@ -6719,17 +6730,23 @@ static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff)
static int show_heartbeat_period(THD *thd, SHOW_VAR *var, char *buff)
{
Master_info *mi;
float heartbeat_period;
var->type= SHOW_CHAR;
var->value= buff;
mysql_mutex_unlock(&LOCK_status);
mysql_mutex_lock(&LOCK_active_mi);
mi= master_info_index->
get_master_info(&thd->variables.default_master_connection,
MYSQL_ERROR::WARN_LEVEL_NOTE);
if (mi)
sprintf(buff, "%.3f", mi->heartbeat_period);
heartbeat_period= mi->heartbeat_period;
mysql_mutex_unlock(&LOCK_active_mi);
mysql_mutex_lock(&LOCK_status);
if (mi)
sprintf(buff, "%.3f", heartbeat_period);
else
var->type= SHOW_UNDEF;
mysql_mutex_unlock(&LOCK_active_mi);
return 0;
}
......
......@@ -380,6 +380,13 @@ bool table_def_init(void)
#endif
mysql_mutex_init(key_LOCK_open, &LOCK_open, MY_MUTEX_INIT_FAST);
mysql_mutex_record_order(&LOCK_active_mi, &LOCK_open);
/*
When we delete from the table_def_cache(), the free function
table_def_free_entry() is invoked from my_hash_delete(), which calls
free_table_share(), which may unload plugins, which can remove status
variables and hence takes LOCK_status. Record this locking order here.
*/
mysql_mutex_record_order(&LOCK_open, &LOCK_status);
oldest_unused_share= &end_of_unused_share;
end_of_unused_share.prev= &oldest_unused_share;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment