Commit 976e1559 authored by Andrei Elkin's avatar Andrei Elkin

Bug #48463 backporting from 6.0-rpl to celosia a set of bugs

The mentioned on the bug report set of bugs fixes have not be pushed to the main trees.

Fixed with extracting commits done to 6.0-rpl tree and applying them to the main 5.1.
Notes.
1. part of changes - the mtr's specific - were packported to the main 5.0 tree for mtr v1
   as http://lists.mysql.com/commits/46562
   However, there is no that fix anymore in the mtr v2. (This fact was mailed to mtr maintaining
   people).

2. Bug@36929  crash in kill_zombie_dump_threads-> THD::awake() with replication tests
   is not backported because the base code of the patch is libevent and that was removed
   from the main trees due to its instability.

client/mysqlbinlog.cc:
  fixes for BUG#35546
mysql-test/suite/rpl/r/rpl_bug41902.result:
  the new tests result file is added.
mysql-test/suite/rpl/t/rpl_bug41902-slave.opt:
  conf file for bug41902 testing is added.
mysql-test/suite/rpl/t/rpl_bug41902.test:
  regression tests for Bug #41902 is added.
sql/log.cc:
  collection of changes due to Bug #48463.
sql/log.h:
  collection of changes due to Bug #48463.
sql/rpl_rli.h:
  collection of changes due to Bug #48463.
sql/slave.cc:
  collection of changes due to Bug #48463.
sql/sql_repl.cc:
  collection of changes due to Bug #48463.
parent 625ddcd5
...@@ -439,6 +439,7 @@ Exit_status Load_log_processor::process_first_event(const char *bname, ...@@ -439,6 +439,7 @@ Exit_status Load_log_processor::process_first_event(const char *bname,
{ {
error("Could not construct local filename %s%s.", error("Could not construct local filename %s%s.",
target_dir_name,bname); target_dir_name,bname);
my_free(fname, MYF(0));
delete ce; delete ce;
DBUG_RETURN(ERROR_STOP); DBUG_RETURN(ERROR_STOP);
} }
...@@ -446,9 +447,15 @@ Exit_status Load_log_processor::process_first_event(const char *bname, ...@@ -446,9 +447,15 @@ Exit_status Load_log_processor::process_first_event(const char *bname,
rec.fname= fname; rec.fname= fname;
rec.event= ce; rec.event= ce;
/*
fname is freed in process_event()
after Execute_load_query_log_event or Execute_load_log_event
will have been processed, otherwise in Load_log_processor::destroy()
*/
if (set_dynamic(&file_names, (uchar*)&rec, file_id)) if (set_dynamic(&file_names, (uchar*)&rec, file_id))
{ {
error("Out of memory."); error("Out of memory.");
my_free(fname, MYF(0));
delete ce; delete ce;
DBUG_RETURN(ERROR_STOP); DBUG_RETURN(ERROR_STOP);
} }
...@@ -828,7 +835,17 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, ...@@ -828,7 +835,17 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
print_event_info->common_header_len= print_event_info->common_header_len=
glob_description_event->common_header_len; glob_description_event->common_header_len;
ev->print(result_file, print_event_info); ev->print(result_file, print_event_info);
ev->temp_buf= 0; // as the event ref is zeroed if (!remote_opt)
{
ev->free_temp_buf(); // free memory allocated in dump_local_log_entries
}
else
{
/*
disassociate but not free dump_remote_log_entries time memory
*/
ev->temp_buf= 0;
}
/* /*
We don't want this event to be deleted now, so let's hide it (I We don't want this event to be deleted now, so let's hide it (I
(Guilhem) should later see if this triggers a non-serious Valgrind (Guilhem) should later see if this triggers a non-serious Valgrind
......
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
stop slave;
SET @@debug="d,simulate_find_log_pos_error";
reset slave;
ERROR HY000: Target log not found in binlog index
show warnings;
Level Code Message
Error 1373 Target log not found in binlog index
Error 1371 Failed purging old relay logs: Failed during log reset
SET @@debug="";
reset slave;
change master to master_host='dummy';
SET @@debug="d,simulate_find_log_pos_error";
change master to master_host='dummy';
ERROR HY000: Target log not found in binlog index
SET @@debug="";
reset slave;
change master to master_host='dummy';
SET @@debug="d,simulate_find_log_pos_error";
reset master;
ERROR HY000: Target log not found in binlog index
SET @@debug="";
reset master;
SET @@debug="d,simulate_find_log_pos_error";
purge binary logs to 'master-bin.000001';
ERROR HY000: Target log not found in binlog index
SET @@debug="";
purge binary logs to 'master-bin.000001';
End of the tests
--loose-debug=-d,simulate_find_log_pos_error
# Test for Bug #41902 MYSQL_BIN_LOG::reset_logs() doesn't call my_error()
# in face of an error
#
source include/have_debug.inc;
source include/master-slave.inc;
#
# test checks that
# a. there is no crash when find_log_pos() returns with an error
# that tests expect to receive;
# b. in the case of multiple error messages the first error message is
# reported to the user and others are available as warnings.
#
connection slave;
stop slave;
SET @@debug="d,simulate_find_log_pos_error";
--error ER_UNKNOWN_TARGET_BINLOG
reset slave;
show warnings;
SET @@debug="";
reset slave;
change master to master_host='dummy';
SET @@debug="d,simulate_find_log_pos_error";
--error ER_UNKNOWN_TARGET_BINLOG
change master to master_host='dummy';
SET @@debug="";
reset slave;
change master to master_host='dummy';
connection master;
SET @@debug="d,simulate_find_log_pos_error";
--error ER_UNKNOWN_TARGET_BINLOG
reset master;
SET @@debug="";
reset master;
SET @@debug="d,simulate_find_log_pos_error";
--error ER_UNKNOWN_TARGET_BINLOG
purge binary logs to 'master-bin.000001';
SET @@debug="";
purge binary logs to 'master-bin.000001';
--disable_query_log
call mtr.add_suppression("Failed to locate old binlog or relay log files");
call mtr.add_suppression("MYSQL_LOG::purge_logs was called with file ./master-bin.000001 not listed in the index");
connection slave;
call mtr.add_suppression("Failed to locate old binlog or relay log files");
call mtr.add_suppression("MYSQL_LOG::purge_logs was called with file ./master-bin.000001 not listed in the index");
--enable_query_log
--echo End of the tests
...@@ -62,6 +62,35 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all); ...@@ -62,6 +62,35 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all);
static int binlog_rollback(handlerton *hton, THD *thd, bool all); static int binlog_rollback(handlerton *hton, THD *thd, bool all);
static int binlog_prepare(handlerton *hton, THD *thd, bool all); static int binlog_prepare(handlerton *hton, THD *thd, bool all);
/**
purge logs, master and slave sides both, related error code
convertor.
Called from @c purge_error_message(), @c MYSQL_BIN_LOG::reset_logs()
@param res an internal to purging routines error code
@return the user level error code ER_*
*/
uint purge_log_get_error_code(int res)
{
uint errcode= 0;
switch (res) {
case 0: break;
case LOG_INFO_EOF: errcode= ER_UNKNOWN_TARGET_BINLOG; break;
case LOG_INFO_IO: errcode= ER_IO_ERR_LOG_INDEX_READ; break;
case LOG_INFO_INVALID:errcode= ER_BINLOG_PURGE_PROHIBITED; break;
case LOG_INFO_SEEK: errcode= ER_FSEEK_FAIL; break;
case LOG_INFO_MEM: errcode= ER_OUT_OF_RESOURCES; break;
case LOG_INFO_FATAL: errcode= ER_BINLOG_PURGE_FATAL_ERR; break;
case LOG_INFO_IN_USE: errcode= ER_LOG_IN_USE; break;
case LOG_INFO_EMFILE: errcode= ER_BINLOG_PURGE_EMFILE; break;
default: errcode= ER_LOG_PURGE_UNKNOWN_ERR; break;
}
return errcode;
}
/** /**
Silence all errors and warnings reported when performing a write Silence all errors and warnings reported when performing a write
to a log table. to a log table.
...@@ -2778,8 +2807,10 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name, ...@@ -2778,8 +2807,10 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
{ {
uint length; uint length;
my_off_t offset= my_b_tell(&index_file); my_off_t offset= my_b_tell(&index_file);
/* If we get 0 or 1 characters, this is the end of the file */
DBUG_EXECUTE_IF("simulate_find_log_pos_error",
error= LOG_INFO_EOF; break;);
/* If we get 0 or 1 characters, this is the end of the file */
if ((length= my_b_gets(&index_file, fname, FN_REFLEN)) <= 1) if ((length= my_b_gets(&index_file, fname, FN_REFLEN)) <= 1)
{ {
/* Did not find the given entry; Return not found or error */ /* Did not find the given entry; Return not found or error */
...@@ -2881,6 +2912,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd) ...@@ -2881,6 +2912,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
{ {
LOG_INFO linfo; LOG_INFO linfo;
bool error=0; bool error=0;
int err;
const char* save_name; const char* save_name;
DBUG_ENTER("reset_logs"); DBUG_ENTER("reset_logs");
...@@ -2907,9 +2939,12 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd) ...@@ -2907,9 +2939,12 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
/* First delete all old log files */ /* First delete all old log files */
if (find_log_pos(&linfo, NullS, 0)) if ((err= find_log_pos(&linfo, NullS, 0)) != 0)
{ {
error=1; uint errcode= purge_log_get_error_code(err);
sql_print_error("Failed to locate old binlog or relay log files");
my_message(errcode, ER(errcode), MYF(0));
error= 1;
goto err; goto err;
} }
...@@ -2978,6 +3013,8 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd) ...@@ -2978,6 +3013,8 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
my_free((uchar*) save_name, MYF(0)); my_free((uchar*) save_name, MYF(0));
err: err:
if (error == 1)
name= const_cast<char*>(save_name);
VOID(pthread_mutex_unlock(&LOCK_thread_count)); VOID(pthread_mutex_unlock(&LOCK_thread_count));
pthread_mutex_unlock(&LOCK_index); pthread_mutex_unlock(&LOCK_index);
pthread_mutex_unlock(&LOCK_log); pthread_mutex_unlock(&LOCK_log);
......
...@@ -611,5 +611,6 @@ enum enum_binlog_format { ...@@ -611,5 +611,6 @@ enum enum_binlog_format {
extern TYPELIB binlog_format_typelib; extern TYPELIB binlog_format_typelib;
int query_error_code(THD *thd, bool not_killed); int query_error_code(THD *thd, bool not_killed);
uint purge_log_get_error_code(int res);
#endif /* LOG_H */ #endif /* LOG_H */
...@@ -221,8 +221,14 @@ public: ...@@ -221,8 +221,14 @@ public:
int events_till_abort; int events_till_abort;
#endif #endif
/* if not set, the value of other members of the structure are undefined */ /*
bool inited; inited changes its value within LOCK_active_mi-guarded critical
sections at times of start_slave_threads() (0->1) and end_slave() (1->0).
Readers may not acquire the mutex while they realize potential concurrency
issue.
If not set, the value of other members of the structure are undefined.
*/
volatile bool inited;
volatile bool abort_slave; volatile bool abort_slave;
volatile uint slave_running; volatile uint slave_running;
......
...@@ -653,11 +653,15 @@ int start_slave_thread(pthread_handler h_func, pthread_mutex_t *start_lock, ...@@ -653,11 +653,15 @@ int start_slave_thread(pthread_handler h_func, pthread_mutex_t *start_lock,
DBUG_PRINT("sleep",("Waiting for slave thread to start")); DBUG_PRINT("sleep",("Waiting for slave thread to start"));
const char* old_msg = thd->enter_cond(start_cond,cond_lock, const char* old_msg = thd->enter_cond(start_cond,cond_lock,
"Waiting for slave thread to start"); "Waiting for slave thread to start");
pthread_cond_wait(start_cond,cond_lock); pthread_cond_wait(start_cond, cond_lock);
thd->exit_cond(old_msg); thd->exit_cond(old_msg);
pthread_mutex_lock(cond_lock); // re-acquire it as exit_cond() released pthread_mutex_lock(cond_lock); // re-acquire it as exit_cond() released
if (thd->killed) if (thd->killed)
{
if (start_lock)
pthread_mutex_unlock(start_lock);
DBUG_RETURN(thd->killed_errno()); DBUG_RETURN(thd->killed_errno());
}
} }
} }
if (start_lock) if (start_lock)
...@@ -4653,9 +4657,6 @@ void rotate_relay_log(Master_info* mi) ...@@ -4653,9 +4657,6 @@ void rotate_relay_log(Master_info* mi)
DBUG_EXECUTE_IF("crash_before_rotate_relaylog", abort();); DBUG_EXECUTE_IF("crash_before_rotate_relaylog", abort(););
/* We don't lock rli->run_lock. This would lead to deadlocks. */
pthread_mutex_lock(&mi->run_lock);
/* /*
We need to test inited because otherwise, new_file() will attempt to 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). LOCK_log, which may not be inited (if we're not a slave).
...@@ -4684,7 +4685,6 @@ void rotate_relay_log(Master_info* mi) ...@@ -4684,7 +4685,6 @@ void rotate_relay_log(Master_info* mi)
*/ */
rli->relay_log.harvest_bytes_written(&rli->log_space_total); rli->relay_log.harvest_bytes_written(&rli->log_space_total);
end: end:
pthread_mutex_unlock(&mi->run_lock);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -259,24 +259,11 @@ bool log_in_use(const char* log_name) ...@@ -259,24 +259,11 @@ bool log_in_use(const char* log_name)
bool purge_error_message(THD* thd, int res) bool purge_error_message(THD* thd, int res)
{ {
uint errmsg= 0; uint errcode;
switch (res) {
case 0: break;
case LOG_INFO_EOF: errmsg= ER_UNKNOWN_TARGET_BINLOG; break;
case LOG_INFO_IO: errmsg= ER_IO_ERR_LOG_INDEX_READ; break;
case LOG_INFO_INVALID:errmsg= ER_BINLOG_PURGE_PROHIBITED; break;
case LOG_INFO_SEEK: errmsg= ER_FSEEK_FAIL; break;
case LOG_INFO_MEM: errmsg= ER_OUT_OF_RESOURCES; break;
case LOG_INFO_FATAL: errmsg= ER_BINLOG_PURGE_FATAL_ERR; break;
case LOG_INFO_IN_USE: errmsg= ER_LOG_IN_USE; break;
case LOG_INFO_EMFILE: errmsg= ER_BINLOG_PURGE_EMFILE; break;
default: errmsg= ER_LOG_PURGE_UNKNOWN_ERR; break;
}
if (errmsg) if ((errcode= purge_log_get_error_code(res)) != 0)
{ {
my_message(errmsg, ER(errmsg), MYF(0)); my_message(errcode, ER(errcode), MYF(0));
return TRUE; return TRUE;
} }
my_ok(thd); my_ok(thd);
...@@ -861,9 +848,7 @@ impossible position"; ...@@ -861,9 +848,7 @@ impossible position";
} }
else else
{ {
DBUG_ASSERT(ret == 0 && signal_cnt != mysql_bin_log.signal_cnt || DBUG_PRINT("wait",("binary log received update or a broadcast signal caught"));
thd->killed);
DBUG_PRINT("wait",("binary log received update"));
} }
} while (signal_cnt == mysql_bin_log.signal_cnt && !thd->killed); } while (signal_cnt == mysql_bin_log.signal_cnt && !thd->killed);
pthread_mutex_unlock(log_lock); pthread_mutex_unlock(log_lock);
......
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