summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorLuis Soares <luis.soares@oracle.com>2010-12-07 15:46:10 +0000
committerLuis Soares <luis.soares@oracle.com>2010-12-07 15:46:10 +0000
commit529024d1e19da983114477e9a19b3f6f9c05c3fe (patch)
treea44f1d5145deec8be358b7b93ce2461bc788dd43 /sql
parent1151e0fcd9302f6a321cfb2c1a4d317dd03c599f (diff)
parent1f5dc357377fa26160160a54df24ef5343cab18e (diff)
downloadmariadb-git-529024d1e19da983114477e9a19b3f6f9c05c3fe.tar.gz
BUG#46166
Automerged bzr bundle from bug report.
Diffstat (limited to 'sql')
-rw-r--r--sql/handler.cc6
-rw-r--r--sql/log.cc152
-rw-r--r--sql/log.h16
-rw-r--r--sql/mysql_priv.h2
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/rpl_injector.cc6
-rw-r--r--sql/slave.cc11
-rw-r--r--sql/slave.h2
-rw-r--r--sql/sql_load.cc7
-rw-r--r--sql/sql_parse.cc50
10 files changed, 185 insertions, 69 deletions
diff --git a/sql/handler.cc b/sql/handler.cc
index 1525ca53bca..18381bc552c 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1192,7 +1192,11 @@ int ha_commit_trans(THD *thd, bool all)
error=ha_commit_one_phase(thd, all) ? (cookie ? 2 : 1) : 0;
DBUG_EXECUTE_IF("crash_commit_before_unlog", DBUG_SUICIDE(););
if (cookie)
- tc_log->unlog(cookie, xid);
+ if(tc_log->unlog(cookie, xid))
+ {
+ error= 2;
+ goto end;
+ }
DBUG_EXECUTE_IF("crash_commit_after", DBUG_SUICIDE(););
end:
if (rw_trans)
diff --git a/sql/log.cc b/sql/log.cc
index cff69b4cf51..46dcec2e2cd 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1871,10 +1871,11 @@ static int find_uniq_filename(char *name)
*end='.';
length= (size_t) (end-start+1);
- if (!(dir_info = my_dir(buff,MYF(MY_DONT_SORT))))
+ if ((DBUG_EVALUATE_IF("error_unique_log_filename", 1,
+ !(dir_info = my_dir(buff,MYF(MY_DONT_SORT))))))
{ // This shouldn't happen
strmov(end,".1"); // use name+1
- DBUG_RETURN(0);
+ DBUG_RETURN(1);
}
file_info= dir_info->dir_entry;
for (i=dir_info->number_off_files ; i-- ; file_info++)
@@ -1888,8 +1889,7 @@ static int find_uniq_filename(char *name)
my_dirend(dir_info);
*end++='.';
- sprintf(end,"%06ld",max_found+1);
- DBUG_RETURN(0);
+ DBUG_RETURN((sprintf(end,"%06ld",max_found+1) < 0));
}
@@ -2101,6 +2101,8 @@ int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
{
if (find_uniq_filename(new_name))
{
+ my_printf_error(ER_NO_UNIQUE_LOGFILE, ER(ER_NO_UNIQUE_LOGFILE),
+ MYF(ME_FATALERROR), log_name);
sql_print_error(ER(ER_NO_UNIQUE_LOGFILE), log_name);
return 1;
}
@@ -3066,7 +3068,8 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
if (!thd->slave_thread)
need_start_event=1;
if (!open_index_file(index_file_name, 0, FALSE))
- open(save_name, log_type, 0, io_cache_type, no_auto_events, max_size, 0, FALSE);
+ if ((error= open(save_name, log_type, 0, io_cache_type, no_auto_events, max_size, 0, FALSE)))
+ goto err;
my_free((uchar*) save_name, MYF(0));
err:
@@ -3728,17 +3731,23 @@ bool MYSQL_BIN_LOG::is_active(const char *log_file_name_arg)
incapsulation 3) allows external access to the class without
a lock (which is not possible with private new_file_without_locking
method).
+
+ @retval
+ nonzero - error
*/
-void MYSQL_BIN_LOG::new_file()
+int MYSQL_BIN_LOG::new_file()
{
- new_file_impl(1);
+ return new_file_impl(1);
}
-
-void MYSQL_BIN_LOG::new_file_without_locking()
+/*
+ @retval
+ nonzero - error
+ */
+int MYSQL_BIN_LOG::new_file_without_locking()
{
- new_file_impl(0);
+ return new_file_impl(0);
}
@@ -3747,19 +3756,23 @@ void MYSQL_BIN_LOG::new_file_without_locking()
@param need_lock Set to 1 if caller has not locked LOCK_log
+ @retval
+ nonzero - error
+
@note
The new file name is stored last in the index file
*/
-void MYSQL_BIN_LOG::new_file_impl(bool need_lock)
+int MYSQL_BIN_LOG::new_file_impl(bool need_lock)
{
- char new_name[FN_REFLEN], *new_name_ptr, *old_name;
+ int error= 0, close_on_error= FALSE;
+ char new_name[FN_REFLEN], *new_name_ptr, *old_name, *file_to_open;
DBUG_ENTER("MYSQL_BIN_LOG::new_file_impl");
if (!is_open())
{
DBUG_PRINT("info",("log is closed"));
- DBUG_VOID_RETURN;
+ DBUG_RETURN(error);
}
if (need_lock)
@@ -3797,7 +3810,7 @@ void MYSQL_BIN_LOG::new_file_impl(bool need_lock)
We have to do this here and not in open as we want to store the
new file name in the current binary log file.
*/
- if (generate_new_name(new_name, name))
+ if ((error= generate_new_name(new_name, name)))
goto end;
new_name_ptr=new_name;
@@ -3811,7 +3824,13 @@ void MYSQL_BIN_LOG::new_file_impl(bool need_lock)
*/
Rotate_log_event r(new_name+dirname_length(new_name),
0, LOG_EVENT_OFFSET, is_relay_log ? Rotate_log_event::RELAY_LOG : 0);
- r.write(&log_file);
+ if(DBUG_EVALUATE_IF("fault_injection_new_file_rotate_event", (error=close_on_error=TRUE), FALSE) ||
+ (error= r.write(&log_file)))
+ {
+ close_on_error= TRUE;
+ my_printf_error(ER_ERROR_ON_WRITE, ER(ER_CANT_OPEN_FILE), MYF(ME_FATALERROR), name, errno);
+ goto end;
+ }
bytes_written += r.data_written;
}
/*
@@ -3839,17 +3858,56 @@ void MYSQL_BIN_LOG::new_file_impl(bool need_lock)
*/
/* reopen index binlog file, BUG#34582 */
- if (!open_index_file(index_file_name, 0, FALSE))
- open(old_name, log_type, new_name_ptr,
- io_cache_type, no_auto_events, max_size, 1, FALSE);
+ file_to_open= index_file_name;
+ error= open_index_file(index_file_name, 0, FALSE);
+ if (!error)
+ {
+ /* reopen the binary log file. */
+ file_to_open= new_name_ptr;
+ error= open(old_name, log_type, new_name_ptr, io_cache_type,
+ no_auto_events, max_size, 1, FALSE);
+ }
+
+ /* handle reopening errors */
+ if (error)
+ {
+ my_printf_error(ER_CANT_OPEN_FILE, ER(ER_CANT_OPEN_FILE),
+ MYF(ME_FATALERROR), file_to_open, error);
+ close_on_error= TRUE;
+ }
+
my_free(old_name,MYF(0));
end:
+
+ if (error && close_on_error /* rotate or reopen failed */)
+ {
+ /*
+ Close whatever was left opened.
+
+ We are keeping the behavior as it exists today, ie,
+ we disable logging and move on (see: BUG#51014).
+
+ TODO: as part of WL#1790 consider other approaches:
+ - kill mysql (safety);
+ - try multiple locations for opening a log file;
+ - switch server to protected/readonly mode
+ - ...
+ */
+ close(LOG_CLOSE_INDEX);
+ sql_print_error("Could not open %s for logging (error %d). "
+ "Turning logging off for the whole duration "
+ "of the MySQL server process. To turn it on "
+ "again: fix the cause, shutdown the MySQL "
+ "server and restart it.",
+ new_name_ptr, errno);
+ }
+
if (need_lock)
pthread_mutex_unlock(&LOCK_log);
pthread_mutex_unlock(&LOCK_index);
- DBUG_VOID_RETURN;
+ DBUG_RETURN(error);
}
@@ -3872,8 +3930,7 @@ bool MYSQL_BIN_LOG::append(Log_event* ev)
bytes_written+= ev->data_written;
DBUG_PRINT("info",("max_size: %lu",max_size));
if ((uint) my_b_append_tell(&log_file) > max_size)
- new_file_without_locking();
-
+ error= new_file_without_locking();
err:
pthread_mutex_unlock(&LOCK_log);
signal_update(); // Safe as we don't call close
@@ -3902,8 +3959,7 @@ bool MYSQL_BIN_LOG::appendv(const char* buf, uint len,...)
} while ((buf=va_arg(args,const char*)) && (len=va_arg(args,uint)));
DBUG_PRINT("info",("max_size: %lu",max_size));
if ((uint) my_b_append_tell(&log_file) > max_size)
- new_file_without_locking();
-
+ error= new_file_without_locking();
err:
if (!error)
signal_update();
@@ -4252,7 +4308,7 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
if (!error)
{
signal_update();
- rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
+ error= rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
}
}
@@ -4448,7 +4504,9 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
if (flush_and_sync())
goto err;
signal_update();
- rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
+ if ((error= rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED)))
+ goto err;
+
}
error=0;
@@ -4531,8 +4589,19 @@ bool general_log_write(THD *thd, enum enum_server_command command,
return FALSE;
}
-void MYSQL_BIN_LOG::rotate_and_purge(uint flags)
+/**
+ @note
+ If rotation fails, for instance the server was unable
+ to create a new log file, we still try to write an
+ incident event to the current log.
+
+ @retval
+ nonzero - error
+*/
+int MYSQL_BIN_LOG::rotate_and_purge(uint flags)
{
+ int error= 0;
+ DBUG_ENTER("MYSQL_BIN_LOG::rotate_and_purge");
#ifdef HAVE_REPLICATION
bool check_purge= false;
#endif
@@ -4541,26 +4610,38 @@ void MYSQL_BIN_LOG::rotate_and_purge(uint flags)
if ((flags & RP_FORCE_ROTATE) ||
(my_b_tell(&log_file) >= (my_off_t) max_size))
{
- new_file_without_locking();
+ if ((error= new_file_without_locking()))
+ /**
+ Be conservative... There are possible lost events (eg,
+ failing to log the Execute_load_query_log_event
+ on a LOAD DATA while using a non-transactional
+ table)!
+
+ We give it a shot and try to write an incident event anyway
+ to the current log.
+ */
+ if (!write_incident(current_thd, FALSE))
+ flush_and_sync();
+
#ifdef HAVE_REPLICATION
check_purge= true;
#endif
}
if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))
pthread_mutex_unlock(&LOCK_log);
-
#ifdef HAVE_REPLICATION
/*
NOTE: Run purge_logs wo/ holding LOCK_log
as it otherwise will deadlock in ndbcluster_binlog_index_purge_file
*/
- if (check_purge && expire_logs_days)
+ if (!error && check_purge && expire_logs_days)
{
time_t purge_time= my_time(0) - expire_logs_days*24*60*60;
if (purge_time >= 0)
purge_logs_before_date(purge_time);
}
#endif
+ DBUG_RETURN(error);
}
uint MYSQL_BIN_LOG::next_file_id()
@@ -4759,7 +4840,7 @@ bool MYSQL_BIN_LOG::write_incident(THD *thd, bool lock)
if (!error && !(error= flush_and_sync()))
{
signal_update();
- rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
+ error= rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
}
pthread_mutex_unlock(&LOCK_log);
}
@@ -4871,7 +4952,8 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event,
pthread_mutex_unlock(&LOCK_prep_xids);
}
else
- rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
+ if (rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED))
+ goto err;
}
VOID(pthread_mutex_unlock(&LOCK_log));
@@ -5676,7 +5758,7 @@ int TC_LOG_MMAP::sync()
cookie points directly to the memory where xid was logged.
*/
-void TC_LOG_MMAP::unlog(ulong cookie, my_xid xid)
+int TC_LOG_MMAP::unlog(ulong cookie, my_xid xid)
{
PAGE *p=pages+(cookie/tc_log_page_size);
my_xid *x=(my_xid *)(data+cookie);
@@ -5694,6 +5776,7 @@ void TC_LOG_MMAP::unlog(ulong cookie, my_xid xid)
if (p->waiters == 0) // the page is in pool and ready to rock
pthread_cond_signal(&COND_pool); // ping ... for overflow()
pthread_mutex_unlock(&p->lock);
+ return 0;
}
void TC_LOG_MMAP::close()
@@ -5935,8 +6018,9 @@ int TC_LOG_BINLOG::log_xid(THD *thd, my_xid xid)
DBUG_RETURN(!binlog_end_trans(thd, trx_data, &xle, TRUE));
}
-void TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)
+int TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)
{
+ DBUG_ENTER("TC_LOG_BINLOG::unlog");
pthread_mutex_lock(&LOCK_prep_xids);
DBUG_ASSERT(prepared_xids > 0);
if (--prepared_xids == 0) {
@@ -5944,7 +6028,7 @@ void TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)
pthread_cond_signal(&COND_prep_xids);
}
pthread_mutex_unlock(&LOCK_prep_xids);
- rotate_and_purge(0); // as ::write() did not rotate
+ DBUG_RETURN(rotate_and_purge(0)); // as ::write() did not rotate
}
int TC_LOG_BINLOG::recover(IO_CACHE *log, Format_description_log_event *fdle)
diff --git a/sql/log.h b/sql/log.h
index 8f1ed7ee90c..2b0bc6111b3 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -39,7 +39,7 @@ class TC_LOG
virtual int open(const char *opt_name)=0;
virtual void close()=0;
virtual int log_xid(THD *thd, my_xid xid)=0;
- virtual void unlog(ulong cookie, my_xid xid)=0;
+ virtual int unlog(ulong cookie, my_xid xid)=0;
};
class TC_LOG_DUMMY: public TC_LOG // use it to disable the logging
@@ -49,7 +49,7 @@ public:
int open(const char *opt_name) { return 0; }
void close() { }
int log_xid(THD *thd, my_xid xid) { return 1; }
- void unlog(ulong cookie, my_xid xid) { }
+ int unlog(ulong cookie, my_xid xid) { return 0; }
};
#ifdef HAVE_MMAP
@@ -94,7 +94,7 @@ class TC_LOG_MMAP: public TC_LOG
int open(const char *opt_name);
void close();
int log_xid(THD *thd, my_xid xid);
- void unlog(ulong cookie, my_xid xid);
+ int unlog(ulong cookie, my_xid xid);
int recover();
private:
@@ -283,8 +283,8 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
new_file() is locking. new_file_without_locking() does not acquire
LOCK_log.
*/
- void new_file_without_locking();
- void new_file_impl(bool need_lock);
+ int new_file_without_locking();
+ int new_file_impl(bool need_lock);
public:
MYSQL_LOG::generate_name;
@@ -314,7 +314,7 @@ public:
int open(const char *opt_name);
void close();
int log_xid(THD *thd, my_xid xid);
- void unlog(ulong cookie, my_xid xid);
+ int unlog(ulong cookie, my_xid xid);
int recover(IO_CACHE *log, Format_description_log_event *fdle);
#if !defined(MYSQL_CLIENT)
int flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event);
@@ -354,7 +354,7 @@ public:
bool open_index_file(const char *index_file_name_arg,
const char *log_name, bool need_mutex);
/* Use this to start writing a new log file */
- void new_file();
+ int new_file();
void reset_gathered_updates(THD *thd);
bool write(Log_event* event_info); // binary log write
@@ -379,7 +379,7 @@ public:
void make_log_name(char* buf, const char* log_ident);
bool is_active(const char* log_file_name);
int update_log_index(LOG_INFO* linfo, bool need_update_threads);
- void rotate_and_purge(uint flags);
+ int rotate_and_purge(uint flags);
bool flush_and_sync();
int purge_logs(const char *to_log, bool included,
bool need_mutex, bool need_update_threads,
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 709a49b2036..526133c20c6 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1063,7 +1063,7 @@ uint cached_table_definitions(void);
void kill_mysql(void);
void close_connection(THD *thd, uint errcode, bool lock);
bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
- bool *write_to_binlog);
+ int *write_to_binlog);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
bool check_access(THD *thd, ulong access, const char *db, ulong *save_priv,
bool no_grant, bool no_errors, bool schema_db);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 3a33d06fb01..1a3a0886c1f 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2839,7 +2839,7 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
case SIGHUP:
if (!abort_loop)
{
- bool not_used;
+ int not_used;
mysql_print_status(); // Print some debug info
reload_acl_and_cache((THD*) 0,
(REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
diff --git a/sql/rpl_injector.cc b/sql/rpl_injector.cc
index 43f4e7d849d..b797621d696 100644
--- a/sql/rpl_injector.cc
+++ b/sql/rpl_injector.cc
@@ -229,8 +229,7 @@ int injector::record_incident(THD *thd, Incident incident)
Incident_log_event ev(thd, incident);
if (int error= mysql_bin_log.write(&ev))
return error;
- mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
- return 0;
+ return mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
}
int injector::record_incident(THD *thd, Incident incident, LEX_STRING const message)
@@ -238,6 +237,5 @@ int injector::record_incident(THD *thd, Incident incident, LEX_STRING const mess
Incident_log_event ev(thd, incident, message);
if (int error= mysql_bin_log.write(&ev))
return error;
- mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
- return 0;
+ return mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
}
diff --git a/sql/slave.cc b/sql/slave.cc
index 644aade517c..96319de5427 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -3398,8 +3398,7 @@ static int process_io_rotate(Master_info *mi, Rotate_log_event *rev)
Rotate the relay log makes binlog format detection easier (at next slave
start or mysqlbinlog)
*/
- rotate_relay_log(mi); /* will take the right mutexes */
- DBUG_RETURN(0);
+ DBUG_RETURN(rotate_relay_log(mi) /* will take the right mutexes */);
}
/*
@@ -4482,10 +4481,11 @@ err:
is void).
*/
-void rotate_relay_log(Master_info* mi)
+int rotate_relay_log(Master_info* mi)
{
DBUG_ENTER("rotate_relay_log");
Relay_log_info* rli= &mi->rli;
+ int error= 0;
/* We don't lock rli->run_lock. This would lead to deadlocks. */
pthread_mutex_lock(&mi->run_lock);
@@ -4501,7 +4501,8 @@ void rotate_relay_log(Master_info* mi)
}
/* If the relay log is closed, new_file() will do nothing. */
- rli->relay_log.new_file();
+ if ((error= rli->relay_log.new_file()))
+ goto end;
/*
We harvest now, because otherwise BIN_LOG_HEADER_SIZE will not immediately
@@ -4519,7 +4520,7 @@ void rotate_relay_log(Master_info* mi)
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
end:
pthread_mutex_unlock(&mi->run_lock);
- DBUG_VOID_RETURN;
+ DBUG_RETURN(error);
}
diff --git a/sql/slave.h b/sql/slave.h
index f356d28b626..da14b3ab4b0 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -189,7 +189,7 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset,
const char** errmsg);
void set_slave_thread_options(THD* thd);
void set_slave_thread_default_charset(THD *thd, Relay_log_info const *rli);
-void rotate_relay_log(Master_info* mi);
+int rotate_relay_log(Master_info* mi);
int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli);
pthread_handler_t handle_slave_io(void *arg);
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 4b68f2a3821..f2aedf5d0aa 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -567,6 +567,13 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
transactional_table,
errcode);
}
+
+ /*
+ Flushing the IO CACHE while writing the execute load query log event
+ may result in error (for instance, because the max_binlog_size has been
+ reached, and rotation of the binary log failed).
+ */
+ error= error || mysql_bin_log.get_log_file()->error;
}
if (error)
goto err;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 7cf64134d70..c81bd36cfad 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1474,7 +1474,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#endif
case COM_REFRESH:
{
- bool not_used;
+ int not_used;
status_var_increment(thd->status_var.com_stat[SQLCOM_FLUSH]);
ulong options= (ulong) (uchar) packet[0];
if (check_global_access(thd,RELOAD_ACL))
@@ -3227,7 +3227,11 @@ end_with_restore_list:
{
Incident_log_event ev(thd, incident);
(void) mysql_bin_log.write(&ev); /* error is ignored */
- mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
+ if (mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE))
+ {
+ res= 1;
+ break;
+ }
}
DBUG_PRINT("debug", ("Just after generate_incident()"));
}
@@ -4051,7 +4055,7 @@ end_with_restore_list:
lex->no_write_to_binlog= 1;
case SQLCOM_FLUSH:
{
- bool write_to_binlog;
+ int write_to_binlog;
if (check_global_access(thd,RELOAD_ACL))
goto error;
@@ -4068,12 +4072,22 @@ end_with_restore_list:
/*
Presumably, RESET and binlog writing doesn't require synchronization
*/
- if (!lex->no_write_to_binlog && write_to_binlog)
+
+ if (write_to_binlog > 0) // we should write
+ {
+ if (!lex->no_write_to_binlog)
+ res= write_bin_log(thd, FALSE, thd->query(), thd->query_length());
+ } else if (write_to_binlog < 0)
{
- if ((res= write_bin_log(thd, FALSE, thd->query(), thd->query_length())))
- break;
- }
- my_ok(thd);
+ /*
+ We should not write, but rather report error because
+ reload_acl_and_cache binlog interactions failed
+ */
+ res= 1;
+ }
+
+ if (!res)
+ my_ok(thd);
}
break;
@@ -6862,7 +6876,10 @@ void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields,
@param thd Thread handler (can be NULL!)
@param options What should be reset/reloaded (tables, privileges, slave...)
@param tables Tables to flush (if any)
- @param write_to_binlog True if we can write to the binlog.
+ @param write_to_binlog < 0 if there was an error while interacting with the binary log inside
+ reload_acl_and_cache,
+ 0 if we should not write to the binary log,
+ > 0 if we can write to the binlog.
@note Depending on 'options', it may be very bad to write the
query to the binlog (e.g. FLUSH SLAVE); this is a
@@ -6876,11 +6893,11 @@ void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields,
*/
bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
- bool *write_to_binlog)
+ int *write_to_binlog)
{
bool result=0;
select_errors=0; /* Write if more errors */
- bool tmp_write_to_binlog= 1;
+ int tmp_write_to_binlog= *write_to_binlog= 1;
DBUG_ASSERT(!thd || !thd->in_sub_stmt);
@@ -6943,12 +6960,16 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
tmp_write_to_binlog= 0;
if( mysql_bin_log.is_open() )
{
- mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
+ if (mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE))
+ *write_to_binlog= -1;
}
#ifdef HAVE_REPLICATION
+ int rotate_error= 0;
pthread_mutex_lock(&LOCK_active_mi);
- rotate_relay_log(active_mi);
+ rotate_error= rotate_relay_log(active_mi);
pthread_mutex_unlock(&LOCK_active_mi);
+ if (rotate_error)
+ *write_to_binlog= -1;
#endif
/* flush slow and general logs */
@@ -7059,7 +7080,8 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
#endif
if (options & REFRESH_USER_RESOURCES)
reset_mqh((LEX_USER *) NULL, 0); /* purecov: inspected */
- *write_to_binlog= tmp_write_to_binlog;
+ if (*write_to_binlog != -1)
+ *write_to_binlog= tmp_write_to_binlog;
/*
If the query was killed then this function must fail.
*/