mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
Fix for BUG#791:
a safer way of initing the mutexes in MYSQL_LOG. is_open() is now always thread-safe. See each file for details.
This commit is contained in:
parent
2ca501f7ea
commit
fbebac9a48
18 changed files with 234 additions and 200 deletions
|
@ -346,7 +346,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
|
|||
bool transaction_commited= 0;
|
||||
|
||||
/* Update the binary log if we have cached some queries */
|
||||
if (trans == &thd->transaction.all && mysql_bin_log.is_open() &&
|
||||
if (trans == &thd->transaction.all && mysql_bin_log.is_open(1) &&
|
||||
my_b_tell(&thd->transaction.trans_log))
|
||||
{
|
||||
mysql_bin_log.write(thd, &thd->transaction.trans_log);
|
||||
|
@ -385,7 +385,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
|
|||
if (transaction_commited && thd->transaction.changed_tables)
|
||||
query_cache.invalidate(thd->transaction.changed_tables);
|
||||
#endif /*HAVE_QUERY_CACHE*/
|
||||
if (error && trans == &thd->transaction.all && mysql_bin_log.is_open())
|
||||
if (error && trans == &thd->transaction.all && mysql_bin_log.is_open(1))
|
||||
sql_print_error("Error: Got error during commit; Binlog is not up to date!");
|
||||
thd->variables.tx_isolation=thd->session_tx_isolation;
|
||||
if (operation_done)
|
||||
|
|
|
@ -1504,7 +1504,7 @@ void item_user_lock_free(void)
|
|||
void item_user_lock_release(ULL *ull)
|
||||
{
|
||||
ull->locked=0;
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
char buf[256];
|
||||
String tmp(buf,sizeof(buf));
|
||||
|
|
316
sql/log.cc
316
sql/log.cc
|
@ -82,12 +82,14 @@ static int find_uniq_filename(char *name)
|
|||
|
||||
MYSQL_LOG::MYSQL_LOG()
|
||||
:bytes_written(0), last_time(0), query_start(0), name(0),
|
||||
file_id(1), open_count(1), log_type(LOG_CLOSED), write_error(0), inited(0),
|
||||
file_id(1), open_count(1), log_type(LOG_CLOSED), write_error(0),
|
||||
no_rotate(0), need_start_event(1)
|
||||
{
|
||||
/*
|
||||
We don't want to intialize LOCK_Log here as the thread system may
|
||||
not have been initailized yet. We do it instead at 'open'.
|
||||
We don't want to initialize LOCK_Log here as such initialization depends on
|
||||
safe_mutex (when using safe_mutex) which depends on MY_INIT(), which is
|
||||
called only in main(). Doing initialization here would make it happen before
|
||||
main().
|
||||
*/
|
||||
index_file_name[0] = 0;
|
||||
bzero((char*) &log_file,sizeof(log_file));
|
||||
|
@ -100,18 +102,35 @@ MYSQL_LOG::~MYSQL_LOG()
|
|||
cleanup();
|
||||
}
|
||||
|
||||
void MYSQL_LOG::cleanup()
|
||||
void MYSQL_LOG::cleanup() /* this is called only once */
|
||||
{
|
||||
if (inited)
|
||||
{
|
||||
close(1);
|
||||
inited= 0;
|
||||
(void) pthread_mutex_destroy(&LOCK_log);
|
||||
(void) pthread_mutex_destroy(&LOCK_index);
|
||||
(void) pthread_cond_destroy(&update_cond);
|
||||
}
|
||||
close(1);
|
||||
(void) pthread_mutex_destroy(&LOCK_log);
|
||||
(void) pthread_mutex_destroy(&LOCK_index);
|
||||
(void) pthread_cond_destroy(&update_cond);
|
||||
}
|
||||
|
||||
bool MYSQL_LOG::is_open(bool need_mutex)
|
||||
{
|
||||
/*
|
||||
Since MySQL 4.0.14, LOCK_log is always inited:
|
||||
* for log/update_log/slow_log/bin_log which are global objects, this is done in
|
||||
main(), even if the server does not use these logs.
|
||||
* for relay_log which belongs to rli which belongs to active_mi, this is
|
||||
done in the constructor of rli.
|
||||
In older versions, we were never 100% sure that LOCK_log was inited, which
|
||||
was a problem.
|
||||
*/
|
||||
if (need_mutex)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_log);
|
||||
bool res= (log_type != LOG_CLOSED);
|
||||
pthread_mutex_unlock(&LOCK_log);
|
||||
return res;
|
||||
}
|
||||
else
|
||||
return (log_type != LOG_CLOSED);
|
||||
}
|
||||
|
||||
int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
|
||||
{
|
||||
|
@ -142,16 +161,15 @@ void MYSQL_LOG::init(enum_log_type log_type_arg,
|
|||
no_auto_events = no_auto_events_arg;
|
||||
max_size=max_size_arg;
|
||||
DBUG_PRINT("info",("log_type: %d max_size: %lu", log_type, max_size));
|
||||
if (!inited)
|
||||
{
|
||||
inited= 1;
|
||||
(void) pthread_mutex_init(&LOCK_log,MY_MUTEX_INIT_SLOW);
|
||||
(void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW);
|
||||
(void) pthread_cond_init(&update_cond, 0);
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void MYSQL_LOG::init_pthread_objects()
|
||||
{
|
||||
(void) pthread_mutex_init(&LOCK_log,MY_MUTEX_INIT_SLOW);
|
||||
(void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW);
|
||||
(void) pthread_cond_init(&update_cond, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
Open a (new) log file.
|
||||
|
@ -182,8 +200,6 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
|
|||
last_time=query_start=0;
|
||||
write_error=0;
|
||||
|
||||
if (!inited && log_type_arg == LOG_BIN && *fn_ext(log_name))
|
||||
no_rotate = 1;
|
||||
init(log_type_arg,io_cache_type_arg,no_auto_events_arg,max_size);
|
||||
|
||||
if (!(name=my_strdup(log_name,MYF(MY_WME))))
|
||||
|
@ -631,7 +647,7 @@ int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli)
|
|||
Assume that we have previously read the first log and
|
||||
stored it in rli->relay_log_name
|
||||
*/
|
||||
DBUG_ASSERT(is_open());
|
||||
DBUG_ASSERT(is_open(1));
|
||||
DBUG_ASSERT(rli->slave_running == 1);
|
||||
DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->relay_log_name));
|
||||
DBUG_ASSERT(rli->linfo.index_file_offset ==
|
||||
|
@ -770,14 +786,11 @@ err:
|
|||
|
||||
void MYSQL_LOG::make_log_name(char* buf, const char* log_ident)
|
||||
{
|
||||
if (inited) // QQ When is this not true ?
|
||||
{
|
||||
uint dir_len = dirname_length(log_file_name);
|
||||
if (dir_len > FN_REFLEN)
|
||||
dir_len=FN_REFLEN-1;
|
||||
strnmov(buf, log_file_name, dir_len);
|
||||
strmake(buf+dir_len, log_ident, FN_REFLEN - dir_len);
|
||||
}
|
||||
uint dir_len = dirname_length(log_file_name);
|
||||
if (dir_len > FN_REFLEN)
|
||||
dir_len=FN_REFLEN-1;
|
||||
strnmov(buf, log_file_name, dir_len);
|
||||
strmake(buf+dir_len, log_ident, FN_REFLEN - dir_len);
|
||||
}
|
||||
|
||||
|
||||
|
@ -787,7 +800,7 @@ void MYSQL_LOG::make_log_name(char* buf, const char* log_ident)
|
|||
|
||||
bool MYSQL_LOG::is_active(const char *log_file_name_arg)
|
||||
{
|
||||
return inited && !strcmp(log_file_name, log_file_name_arg);
|
||||
return !strcmp(log_file_name, log_file_name_arg);
|
||||
}
|
||||
|
||||
|
||||
|
@ -809,7 +822,7 @@ void MYSQL_LOG::new_file(bool need_lock)
|
|||
enum_log_type save_log_type;
|
||||
|
||||
DBUG_ENTER("MYSQL_LOG::new_file");
|
||||
if (!is_open())
|
||||
if (!is_open(need_lock))
|
||||
{
|
||||
DBUG_PRINT("info",("log is closed"));
|
||||
DBUG_VOID_RETURN;
|
||||
|
@ -876,7 +889,9 @@ void MYSQL_LOG::new_file(bool need_lock)
|
|||
name=0; // Don't free name
|
||||
close();
|
||||
|
||||
// TODO: at this place is_open() will see the log closed, which is BUG#791.
|
||||
/*
|
||||
Note that at this point, log_type == LOG_CLOSED (important for is_open()).
|
||||
*/
|
||||
|
||||
open(old_name, save_log_type, new_name_ptr, index_file_name, io_cache_type,
|
||||
no_auto_events, max_size);
|
||||
|
@ -967,12 +982,11 @@ err:
|
|||
bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
|
||||
const char *format,...)
|
||||
{
|
||||
if (is_open() && (what_to_log & (1L << (uint) command)))
|
||||
if (what_to_log & (1L << (uint) command))
|
||||
{
|
||||
int error=0;
|
||||
VOID(pthread_mutex_lock(&LOCK_log));
|
||||
|
||||
/* Test if someone closed between the is_open test and lock */
|
||||
if (is_open())
|
||||
{
|
||||
time_t skr;
|
||||
|
@ -1055,14 +1069,13 @@ bool MYSQL_LOG::write(Log_event* event_info)
|
|||
bool error=0;
|
||||
DBUG_ENTER("MYSQL_LOG::write(event)");
|
||||
|
||||
if (!inited) // Can't use mutex if not init
|
||||
{
|
||||
DBUG_PRINT("error",("not initied"));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
pthread_mutex_lock(&LOCK_log);
|
||||
|
||||
/* In most cases this is only called if 'is_open()' is true */
|
||||
/*
|
||||
In most cases this is only called if 'is_open()' is true; in fact this is
|
||||
mostly called if is_open() *was* true a few instructions before, but it
|
||||
could have changed since.
|
||||
*/
|
||||
if (is_open())
|
||||
{
|
||||
bool should_rotate = 0;
|
||||
|
@ -1380,120 +1393,117 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
|
|||
time_t query_start_arg)
|
||||
{
|
||||
bool error=0;
|
||||
time_t current_time;
|
||||
VOID(pthread_mutex_lock(&LOCK_log));
|
||||
if (is_open())
|
||||
{
|
||||
time_t current_time;
|
||||
VOID(pthread_mutex_lock(&LOCK_log));
|
||||
if (is_open())
|
||||
{ // Safety agains reopen
|
||||
int tmp_errno=0;
|
||||
char buff[80],*end;
|
||||
end=buff;
|
||||
if (!(thd->options & OPTION_UPDATE_LOG) &&
|
||||
(thd->master_access & SUPER_ACL))
|
||||
{ // Safety agains reopen
|
||||
int tmp_errno=0;
|
||||
char buff[80],*end;
|
||||
end=buff;
|
||||
if (!(thd->options & OPTION_UPDATE_LOG) &&
|
||||
(thd->master_access & SUPER_ACL))
|
||||
{
|
||||
VOID(pthread_mutex_unlock(&LOCK_log));
|
||||
return 0;
|
||||
}
|
||||
if ((specialflag & SPECIAL_LONG_LOG_FORMAT) || query_start_arg)
|
||||
{
|
||||
current_time=time(NULL);
|
||||
if (current_time != last_time)
|
||||
{
|
||||
VOID(pthread_mutex_unlock(&LOCK_log));
|
||||
return 0;
|
||||
last_time=current_time;
|
||||
struct tm tm_tmp;
|
||||
struct tm *start;
|
||||
localtime_r(¤t_time,&tm_tmp);
|
||||
start=&tm_tmp;
|
||||
/* Note that my_b_write() assumes it knows the length for this */
|
||||
sprintf(buff,"# Time: %02d%02d%02d %2d:%02d:%02d\n",
|
||||
start->tm_year % 100,
|
||||
start->tm_mon+1,
|
||||
start->tm_mday,
|
||||
start->tm_hour,
|
||||
start->tm_min,
|
||||
start->tm_sec);
|
||||
if (my_b_write(&log_file, (byte*) buff,24))
|
||||
tmp_errno=errno;
|
||||
}
|
||||
if ((specialflag & SPECIAL_LONG_LOG_FORMAT) || query_start_arg)
|
||||
if (my_b_printf(&log_file, "# User@Host: %s[%s] @ %s [%s]\n",
|
||||
thd->priv_user,
|
||||
thd->user,
|
||||
thd->host ? thd->host : "",
|
||||
thd->ip ? thd->ip : "") == (uint) -1)
|
||||
tmp_errno=errno;
|
||||
}
|
||||
if (query_start_arg)
|
||||
{
|
||||
/* For slow query log */
|
||||
if (my_b_printf(&log_file,
|
||||
"# Query_time: %lu Lock_time: %lu Rows_sent: %lu Rows_examined: %lu\n",
|
||||
(ulong) (current_time - query_start_arg),
|
||||
(ulong) (thd->time_after_lock - query_start_arg),
|
||||
(ulong) thd->sent_row_count,
|
||||
(ulong) thd->examined_row_count) == (uint) -1)
|
||||
tmp_errno=errno;
|
||||
}
|
||||
if (thd->db && strcmp(thd->db,db))
|
||||
{ // Database changed
|
||||
if (my_b_printf(&log_file,"use %s;\n",thd->db) == (uint) -1)
|
||||
tmp_errno=errno;
|
||||
strmov(db,thd->db);
|
||||
}
|
||||
if (thd->last_insert_id_used)
|
||||
{
|
||||
end=strmov(end,",last_insert_id=");
|
||||
end=longlong10_to_str((longlong) thd->current_insert_id,end,-10);
|
||||
}
|
||||
// Save value if we do an insert.
|
||||
if (thd->insert_id_used)
|
||||
{
|
||||
if (specialflag & SPECIAL_LONG_LOG_FORMAT)
|
||||
{
|
||||
current_time=time(NULL);
|
||||
if (current_time != last_time)
|
||||
{
|
||||
last_time=current_time;
|
||||
struct tm tm_tmp;
|
||||
struct tm *start;
|
||||
localtime_r(¤t_time,&tm_tmp);
|
||||
start=&tm_tmp;
|
||||
/* Note that my_b_write() assumes it knows the length for this */
|
||||
sprintf(buff,"# Time: %02d%02d%02d %2d:%02d:%02d\n",
|
||||
start->tm_year % 100,
|
||||
start->tm_mon+1,
|
||||
start->tm_mday,
|
||||
start->tm_hour,
|
||||
start->tm_min,
|
||||
start->tm_sec);
|
||||
if (my_b_write(&log_file, (byte*) buff,24))
|
||||
tmp_errno=errno;
|
||||
}
|
||||
if (my_b_printf(&log_file, "# User@Host: %s[%s] @ %s [%s]\n",
|
||||
thd->priv_user,
|
||||
thd->user,
|
||||
thd->host ? thd->host : "",
|
||||
thd->ip ? thd->ip : "") == (uint) -1)
|
||||
tmp_errno=errno;
|
||||
}
|
||||
if (query_start_arg)
|
||||
{
|
||||
/* For slow query log */
|
||||
if (my_b_printf(&log_file,
|
||||
"# Query_time: %lu Lock_time: %lu Rows_sent: %lu Rows_examined: %lu\n",
|
||||
(ulong) (current_time - query_start_arg),
|
||||
(ulong) (thd->time_after_lock - query_start_arg),
|
||||
(ulong) thd->sent_row_count,
|
||||
(ulong) thd->examined_row_count) == (uint) -1)
|
||||
tmp_errno=errno;
|
||||
}
|
||||
if (thd->db && strcmp(thd->db,db))
|
||||
{ // Database changed
|
||||
if (my_b_printf(&log_file,"use %s;\n",thd->db) == (uint) -1)
|
||||
tmp_errno=errno;
|
||||
strmov(db,thd->db);
|
||||
}
|
||||
if (thd->last_insert_id_used)
|
||||
{
|
||||
end=strmov(end,",last_insert_id=");
|
||||
end=longlong10_to_str((longlong) thd->current_insert_id,end,-10);
|
||||
}
|
||||
// Save value if we do an insert.
|
||||
if (thd->insert_id_used)
|
||||
{
|
||||
if (specialflag & SPECIAL_LONG_LOG_FORMAT)
|
||||
{
|
||||
end=strmov(end,",insert_id=");
|
||||
end=longlong10_to_str((longlong) thd->last_insert_id,end,-10);
|
||||
}
|
||||
}
|
||||
if (thd->query_start_used)
|
||||
{
|
||||
if (query_start_arg != thd->query_start())
|
||||
{
|
||||
query_start_arg=thd->query_start();
|
||||
end=strmov(end,",timestamp=");
|
||||
end=int10_to_str((long) query_start_arg,end,10);
|
||||
}
|
||||
}
|
||||
if (end != buff)
|
||||
{
|
||||
*end++=';';
|
||||
*end='\n';
|
||||
if (my_b_write(&log_file, (byte*) "SET ",4) ||
|
||||
my_b_write(&log_file, (byte*) buff+1,(uint) (end-buff)))
|
||||
tmp_errno=errno;
|
||||
}
|
||||
if (!query)
|
||||
{
|
||||
end=strxmov(buff, "# administrator command: ",
|
||||
command_name[thd->command], NullS);
|
||||
query_length=(ulong) (end-buff);
|
||||
query=buff;
|
||||
}
|
||||
if (my_b_write(&log_file, (byte*) query,query_length) ||
|
||||
my_b_write(&log_file, (byte*) ";\n",2) ||
|
||||
flush_io_cache(&log_file))
|
||||
tmp_errno=errno;
|
||||
if (tmp_errno)
|
||||
{
|
||||
error=1;
|
||||
if (! write_error)
|
||||
{
|
||||
write_error=1;
|
||||
sql_print_error(ER(ER_ERROR_ON_WRITE),name,error);
|
||||
}
|
||||
end=strmov(end,",insert_id=");
|
||||
end=longlong10_to_str((longlong) thd->last_insert_id,end,-10);
|
||||
}
|
||||
}
|
||||
if (thd->query_start_used)
|
||||
{
|
||||
if (query_start_arg != thd->query_start())
|
||||
{
|
||||
query_start_arg=thd->query_start();
|
||||
end=strmov(end,",timestamp=");
|
||||
end=int10_to_str((long) query_start_arg,end,10);
|
||||
}
|
||||
}
|
||||
if (end != buff)
|
||||
{
|
||||
*end++=';';
|
||||
*end='\n';
|
||||
if (my_b_write(&log_file, (byte*) "SET ",4) ||
|
||||
my_b_write(&log_file, (byte*) buff+1,(uint) (end-buff)))
|
||||
tmp_errno=errno;
|
||||
}
|
||||
if (!query)
|
||||
{
|
||||
end=strxmov(buff, "# administrator command: ",
|
||||
command_name[thd->command], NullS);
|
||||
query_length=(ulong) (end-buff);
|
||||
query=buff;
|
||||
}
|
||||
if (my_b_write(&log_file, (byte*) query,query_length) ||
|
||||
my_b_write(&log_file, (byte*) ";\n",2) ||
|
||||
flush_io_cache(&log_file))
|
||||
tmp_errno=errno;
|
||||
if (tmp_errno)
|
||||
{
|
||||
error=1;
|
||||
if (! write_error)
|
||||
{
|
||||
write_error=1;
|
||||
sql_print_error(ER(ER_ERROR_ON_WRITE),name,error);
|
||||
}
|
||||
}
|
||||
VOID(pthread_mutex_unlock(&LOCK_log));
|
||||
}
|
||||
VOID(pthread_mutex_unlock(&LOCK_log));
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -1591,14 +1601,12 @@ void MYSQL_LOG::set_max_size(ulong max_size_arg)
|
|||
uses the old_max_size argument, so max_size_arg has been overwritten and
|
||||
it's like if the SET command was never run.
|
||||
*/
|
||||
DBUG_ENTER("MYSQL_LOG::set_max_size");
|
||||
pthread_mutex_lock(&LOCK_log);
|
||||
if (is_open())
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_log);
|
||||
pthread_mutex_lock(&LOCK_index);
|
||||
max_size= max_size_arg;
|
||||
pthread_mutex_unlock(&LOCK_index);
|
||||
pthread_mutex_unlock(&LOCK_log);
|
||||
}
|
||||
pthread_mutex_unlock(&LOCK_log);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -2167,7 +2167,7 @@ int Rand_log_event::exec_event(struct st_relay_log_info* rli)
|
|||
|
||||
int Slave_log_event::exec_event(struct st_relay_log_info* rli)
|
||||
{
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
mysql_bin_log.write(this);
|
||||
return Log_event::exec_event(rli);
|
||||
}
|
||||
|
@ -2217,7 +2217,7 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli)
|
|||
slave_print_error(rli,my_errno, "Write to '%s' failed", fname_buf);
|
||||
goto err;
|
||||
}
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
mysql_bin_log.write(this);
|
||||
error=0; // Everything is ok
|
||||
|
||||
|
@ -2237,7 +2237,7 @@ int Delete_file_log_event::exec_event(struct st_relay_log_info* rli)
|
|||
(void) my_delete(fname, MYF(MY_WME));
|
||||
memcpy(p, ".info", 6);
|
||||
(void) my_delete(fname, MYF(MY_WME));
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
mysql_bin_log.write(this);
|
||||
return Log_event::exec_event(rli);
|
||||
}
|
||||
|
@ -2260,7 +2260,7 @@ int Append_block_log_event::exec_event(struct st_relay_log_info* rli)
|
|||
slave_print_error(rli,my_errno, "Write to '%s' failed", fname);
|
||||
goto err;
|
||||
}
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
mysql_bin_log.write(this);
|
||||
error=0;
|
||||
|
||||
|
@ -2319,7 +2319,7 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
|
|||
(void) my_delete(fname, MYF(MY_WME));
|
||||
memcpy(p, ".data", 6);
|
||||
(void) my_delete(fname, MYF(MY_WME));
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
mysql_bin_log.write(this);
|
||||
error = 0;
|
||||
|
||||
|
|
|
@ -1972,6 +1972,8 @@ bool open_log(MYSQL_LOG *log, const char *hostname,
|
|||
strmake(tmp,opt_name,min(length,FN_REFLEN));
|
||||
opt_name=tmp;
|
||||
}
|
||||
if (*fn_ext(opt_name))
|
||||
log->set_no_rotate(1);
|
||||
}
|
||||
return log->open(opt_name, type, 0, index_file_name,
|
||||
(read_append) ? SEQ_READ_APPEND : WRITE_CACHE,
|
||||
|
@ -2019,6 +2021,17 @@ int main(int argc, char **argv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
Init mutexes for the global MYSQL_LOG objects.
|
||||
As safe_mutex depends on what MY_INIT() does, we can't init the mutexes of
|
||||
global MYSQL_LOGs in their constructors, because then they would be inited
|
||||
before MY_INIT(). So we do it here.
|
||||
*/
|
||||
mysql_log.init_pthread_objects();
|
||||
mysql_update_log.init_pthread_objects();
|
||||
mysql_slow_log.init_pthread_objects();
|
||||
mysql_bin_log.init_pthread_objects();
|
||||
|
||||
if (gethostname(glob_hostname,sizeof(glob_hostname)-4) < 0)
|
||||
strmov(glob_hostname,"mysql");
|
||||
strmake(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
|
||||
|
|
|
@ -265,7 +265,7 @@ int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg)
|
|||
LINT_INIT(cmp_res);
|
||||
DBUG_ENTER("translate_master");
|
||||
|
||||
if (!mysql_bin_log.is_open())
|
||||
if (!mysql_bin_log.is_open(1))
|
||||
{
|
||||
strmov(errmsg,"Binary log is not open");
|
||||
DBUG_RETURN(1);
|
||||
|
|
14
sql/slave.cc
14
sql/slave.cc
|
@ -1736,6 +1736,7 @@ st_relay_log_info::st_relay_log_info()
|
|||
pthread_cond_init(&start_cond, NULL);
|
||||
pthread_cond_init(&stop_cond, NULL);
|
||||
pthread_cond_init(&log_space_cond, NULL);
|
||||
relay_log.init_pthread_objects();
|
||||
}
|
||||
|
||||
|
||||
|
@ -3443,14 +3444,18 @@ void rotate_relay_log(MASTER_INFO* mi)
|
|||
{
|
||||
DBUG_ENTER("rotate_relay_log");
|
||||
RELAY_LOG_INFO* rli= &mi->rli;
|
||||
/* If this server is not a slave (or RESET SLAVE has just been run) */
|
||||
|
||||
lock_slave_threads(mi);
|
||||
pthread_mutex_lock(&rli->data_lock);
|
||||
/*
|
||||
We need to test inited because otherwise, new_file() will attempt to lock
|
||||
LOCK_log, which may not be inited (if we're not a slave).
|
||||
*/
|
||||
if (!rli->inited)
|
||||
{
|
||||
DBUG_PRINT("info", ("rli->inited == 0"));
|
||||
DBUG_VOID_RETURN;
|
||||
goto end;
|
||||
}
|
||||
lock_slave_threads(mi);
|
||||
pthread_mutex_lock(&rli->data_lock);
|
||||
|
||||
/* If the relay log is closed, new_file() will do nothing. */
|
||||
rli->relay_log.new_file(1);
|
||||
|
@ -3469,6 +3474,7 @@ void rotate_relay_log(MASTER_INFO* mi)
|
|||
0 as they probably have been harvested.
|
||||
*/
|
||||
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
|
||||
end:
|
||||
pthread_mutex_unlock(&rli->data_lock);
|
||||
unlock_slave_threads(mi);
|
||||
DBUG_VOID_RETURN;
|
||||
|
|
|
@ -574,7 +574,7 @@ void close_temporary_tables(THD *thd)
|
|||
next=table->next;
|
||||
close_temporary(table);
|
||||
}
|
||||
if (query && found_user_tables && mysql_bin_log.is_open())
|
||||
if (query && found_user_tables && mysql_bin_log.is_open(1))
|
||||
{
|
||||
/* The -1 is to remove last ',' */
|
||||
Query_log_event qinfo(thd, query, (ulong)(end-query)-1, 0);
|
||||
|
|
|
@ -61,6 +61,11 @@ class Log_event;
|
|||
|
||||
class MYSQL_LOG {
|
||||
private:
|
||||
/*
|
||||
LOCK_log is inited by MYSQL_LOG::init(), so one should try to lock it only
|
||||
if he is sure MYSQL_LOG::init() has been called (i.e. if 'inited' is true).
|
||||
Same for LOCK_index.
|
||||
*/
|
||||
pthread_mutex_t LOCK_log, LOCK_index;
|
||||
pthread_cond_t update_cond;
|
||||
ulonglong bytes_written;
|
||||
|
@ -80,7 +85,7 @@ class MYSQL_LOG {
|
|||
*/
|
||||
volatile enum_log_type log_type;
|
||||
enum cache_type io_cache_type;
|
||||
bool write_error,inited;
|
||||
bool write_error;
|
||||
bool no_rotate;
|
||||
bool need_start_event;
|
||||
bool no_auto_events; // for relay binlog
|
||||
|
@ -123,6 +128,7 @@ public:
|
|||
void init(enum_log_type log_type_arg,
|
||||
enum cache_type io_cache_type_arg,
|
||||
bool no_auto_events_arg, ulong max_size);
|
||||
void init_pthread_objects();
|
||||
void cleanup();
|
||||
bool open(const char *log_name,enum_log_type log_type,
|
||||
const char *new_name, const char *index_file_name_arg,
|
||||
|
@ -158,8 +164,8 @@ public:
|
|||
int find_next_log(LOG_INFO* linfo, bool need_mutex);
|
||||
int get_current_log(LOG_INFO* linfo);
|
||||
uint next_file_id();
|
||||
bool is_open(bool need_mutex=0);
|
||||
|
||||
inline bool is_open() { return log_type != LOG_CLOSED; }
|
||||
inline char* get_index_fname() { return index_file_name;}
|
||||
inline char* get_log_fname() { return log_file_name; }
|
||||
inline pthread_mutex_t* get_log_lock() { return &LOCK_log; }
|
||||
|
@ -169,6 +175,7 @@ public:
|
|||
inline void unlock_index() { pthread_mutex_unlock(&LOCK_index);}
|
||||
inline IO_CACHE *get_index_file() { return &index_file;}
|
||||
inline uint32 get_open_count() { return open_count; }
|
||||
inline void set_no_rotate(bool no_rotate_arg) {no_rotate= no_rotate_arg;}
|
||||
};
|
||||
|
||||
/* character conversion tables */
|
||||
|
|
|
@ -84,7 +84,7 @@ int mysql_create_db(THD *thd, char *db, uint create_options, bool silent)
|
|||
}
|
||||
{
|
||||
mysql_update_log.write(thd,thd->query, thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
mysql_bin_log.write(&qinfo);
|
||||
|
@ -174,7 +174,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
|
|||
thd->query= path;
|
||||
}
|
||||
mysql_update_log.write(thd, thd->query, thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
mysql_bin_log.write(&qinfo);
|
||||
|
|
|
@ -172,7 +172,7 @@ cleanup:
|
|||
if (deleted && (error <= 0 || !transactional_table))
|
||||
{
|
||||
mysql_update_log.write(thd,thd->query, thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length,
|
||||
log_delayed);
|
||||
|
@ -476,7 +476,7 @@ bool multi_delete::send_eof()
|
|||
if (deleted && (error <= 0 || normal_tables))
|
||||
{
|
||||
mysql_update_log.write(thd,thd->query,thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length,
|
||||
log_delayed);
|
||||
|
@ -588,7 +588,7 @@ end:
|
|||
if (!error)
|
||||
{
|
||||
mysql_update_log.write(thd,thd->query,thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length,
|
||||
thd->tmp_table);
|
||||
|
|
|
@ -308,7 +308,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
|
|||
if ((info.copied || info.deleted) && (error <= 0 || !transactional_table))
|
||||
{
|
||||
mysql_update_log.write(thd, thd->query, thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length,
|
||||
log_delayed);
|
||||
|
@ -1143,7 +1143,7 @@ bool delayed_insert::handle_inserts(void)
|
|||
{
|
||||
int error;
|
||||
uint max_rows;
|
||||
bool using_ignore=0, using_bin_log=mysql_bin_log.is_open();
|
||||
bool using_ignore=0, using_bin_log=mysql_bin_log.is_open(1);
|
||||
delayed_row *row;
|
||||
DBUG_ENTER("handle_inserts");
|
||||
|
||||
|
@ -1361,7 +1361,7 @@ void select_insert::send_error(uint errcode,const char *err)
|
|||
if (last_insert_id)
|
||||
thd->insert_id(last_insert_id); // For binary log
|
||||
mysql_update_log.write(thd,thd->query,thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length,
|
||||
table->file->has_transactions());
|
||||
|
@ -1387,7 +1387,7 @@ bool select_insert::send_eof()
|
|||
thd->insert_id(last_insert_id); // For binary log
|
||||
/* Write to binlog before commiting transaction */
|
||||
mysql_update_log.write(thd,thd->query,thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length,
|
||||
table->file->has_transactions());
|
||||
|
|
|
@ -219,7 +219,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
|||
DBUG_RETURN(-1); // Can't allocate buffers
|
||||
}
|
||||
|
||||
if (!opt_old_rpl_compat && mysql_bin_log.is_open())
|
||||
if (!opt_old_rpl_compat && mysql_bin_log.is_open(1))
|
||||
{
|
||||
lf_info.thd = thd;
|
||||
lf_info.ex = ex;
|
||||
|
@ -281,7 +281,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
|||
{
|
||||
if (transactional_table)
|
||||
ha_autocommit_or_rollback(thd,error);
|
||||
if (!opt_old_rpl_compat && mysql_bin_log.is_open())
|
||||
if (!opt_old_rpl_compat && mysql_bin_log.is_open(1))
|
||||
{
|
||||
if (lf_info.wrote_create_file)
|
||||
{
|
||||
|
@ -315,7 +315,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
|||
|
||||
if (!log_delayed)
|
||||
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
if (opt_old_rpl_compat)
|
||||
{
|
||||
|
@ -607,7 +607,7 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, String &field_term,
|
|||
cache.read_function = _my_b_net_read;
|
||||
|
||||
need_end_io_cache = 1;
|
||||
if (!opt_old_rpl_compat && mysql_bin_log.is_open())
|
||||
if (!opt_old_rpl_compat && mysql_bin_log.is_open(1))
|
||||
cache.pre_read = cache.pre_close =
|
||||
(IO_CACHE_CALLBACK) log_loaded_block;
|
||||
}
|
||||
|
|
|
@ -2432,7 +2432,7 @@ mysql_execute_command(void)
|
|||
lex->sql_command == SQLCOM_REVOKE)))
|
||||
{
|
||||
mysql_update_log.write(thd, thd->query, thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
mysql_bin_log.write(&qinfo);
|
||||
|
@ -2452,7 +2452,7 @@ mysql_execute_command(void)
|
|||
if (!res)
|
||||
{
|
||||
mysql_update_log.write(thd, thd->query, thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
mysql_bin_log.write(&qinfo);
|
||||
|
|
|
@ -80,7 +80,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
|
|||
if (!error)
|
||||
{
|
||||
mysql_update_log.write(thd,thd->query,thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
mysql_bin_log.write(&qinfo);
|
||||
|
|
|
@ -269,7 +269,7 @@ int purge_master_logs(THD* thd, const char* to_log)
|
|||
const char* errmsg = 0;
|
||||
int res;
|
||||
|
||||
if (!mysql_bin_log.is_open())
|
||||
if (!mysql_bin_log.is_open(1))
|
||||
goto end;
|
||||
|
||||
mysql_bin_log.make_log_name(search_file_name, to_log);
|
||||
|
@ -335,7 +335,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (!mysql_bin_log.is_open())
|
||||
if (!mysql_bin_log.is_open(1))
|
||||
{
|
||||
errmsg = "Binary log is not open";
|
||||
my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
|
||||
|
@ -972,7 +972,7 @@ int change_master(THD* thd, MASTER_INFO* mi)
|
|||
|
||||
int reset_master(THD* thd)
|
||||
{
|
||||
if (!mysql_bin_log.is_open())
|
||||
if (!mysql_bin_log.is_open(1))
|
||||
{
|
||||
my_error(ER_FLUSH_MASTER_BINLOG_CLOSED, MYF(ME_BELL+ME_WAITTANG));
|
||||
return 1;
|
||||
|
@ -1010,7 +1010,7 @@ int show_binlog_events(THD* thd)
|
|||
if (send_fields(thd, field_list, 1))
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
LEX_MASTER_INFO *lex_mi = &thd->lex.mi;
|
||||
ha_rows event_count, limit_start, limit_end;
|
||||
|
@ -1110,7 +1110,7 @@ int show_binlog_info(THD* thd)
|
|||
String* packet = &thd->packet;
|
||||
packet->length(0);
|
||||
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
LOG_INFO li;
|
||||
mysql_bin_log.get_current_log(&li);
|
||||
|
@ -1128,7 +1128,7 @@ int show_binlog_info(THD* thd)
|
|||
|
||||
|
||||
/*
|
||||
Send a lost of all binary logs to client
|
||||
Send a list of all binary logs to client
|
||||
|
||||
SYNOPSIS
|
||||
show_binlogs()
|
||||
|
@ -1148,7 +1148,7 @@ int show_binlogs(THD* thd)
|
|||
String *packet = &thd->packet;
|
||||
uint length;
|
||||
|
||||
if (!mysql_bin_log.is_open())
|
||||
if (!mysql_bin_log.is_open(1))
|
||||
{
|
||||
//TODO: Replace with ER() error message
|
||||
send_error(net, 0, "You are not using binary logging");
|
||||
|
|
|
@ -235,7 +235,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||
if (!dont_log_query)
|
||||
{
|
||||
mysql_update_log.write(thd, thd->query,thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length,
|
||||
tmp_table_deleted && !some_tables_deleted);
|
||||
|
@ -766,7 +766,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
|
|||
{
|
||||
// Must be written before unlock
|
||||
mysql_update_log.write(thd,thd->query, thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length,
|
||||
test(create_info->options &
|
||||
|
@ -1548,7 +1548,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||
if (!error)
|
||||
{
|
||||
mysql_update_log.write(thd, thd->query, thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
mysql_bin_log.write(&qinfo);
|
||||
|
@ -1918,7 +1918,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||
goto err;
|
||||
}
|
||||
mysql_update_log.write(thd, thd->query,thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
mysql_bin_log.write(&qinfo);
|
||||
|
@ -2050,7 +2050,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||
}
|
||||
thd->proc_info="end";
|
||||
mysql_update_log.write(thd, thd->query,thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
mysql_bin_log.write(&qinfo);
|
||||
|
|
|
@ -317,7 +317,7 @@ int mysql_update(THD *thd,
|
|||
if (updated && (error <= 0 || !transactional_table))
|
||||
{
|
||||
mysql_update_log.write(thd,thd->query,thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length,
|
||||
log_delayed);
|
||||
|
@ -933,7 +933,7 @@ bool multi_update::send_eof()
|
|||
if (updated && (local_error <= 0 || !trans_safe))
|
||||
{
|
||||
mysql_update_log.write(thd,thd->query,thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
if (mysql_bin_log.is_open(1))
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length,
|
||||
log_delayed);
|
||||
|
|
Loading…
Reference in a new issue