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,
{
error("Could not construct local filename %s%s.",
target_dir_name,bname);
my_free(fname, MYF(0));
delete ce;
DBUG_RETURN(ERROR_STOP);
}
......@@ -446,9 +447,15 @@ Exit_status Load_log_processor::process_first_event(const char *bname,
rec.fname= fname;
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))
{
error("Out of memory.");
my_free(fname, MYF(0));
delete ce;
DBUG_RETURN(ERROR_STOP);
}
......@@ -828,7 +835,17 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
print_event_info->common_header_len=
glob_description_event->common_header_len;
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
(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);
static int binlog_rollback(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
to a log table.
......@@ -2778,8 +2807,10 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
{
uint length;
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)
{
/* Did not find the given entry; Return not found or error */
......@@ -2881,6 +2912,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
{
LOG_INFO linfo;
bool error=0;
int err;
const char* save_name;
DBUG_ENTER("reset_logs");
......@@ -2907,9 +2939,12 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
/* 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;
}
......@@ -2978,6 +3013,8 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
my_free((uchar*) save_name, MYF(0));
err:
if (error == 1)
name= const_cast<char*>(save_name);
VOID(pthread_mutex_unlock(&LOCK_thread_count));
pthread_mutex_unlock(&LOCK_index);
pthread_mutex_unlock(&LOCK_log);
......
......@@ -611,5 +611,6 @@ enum enum_binlog_format {
extern TYPELIB binlog_format_typelib;
int query_error_code(THD *thd, bool not_killed);
uint purge_log_get_error_code(int res);
#endif /* LOG_H */
......@@ -221,8 +221,14 @@ public:
int events_till_abort;
#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 uint slave_running;
......
......@@ -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"));
const char* old_msg = thd->enter_cond(start_cond,cond_lock,
"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);
pthread_mutex_lock(cond_lock); // re-acquire it as exit_cond() released
if (thd->killed)
{
if (start_lock)
pthread_mutex_unlock(start_lock);
DBUG_RETURN(thd->killed_errno());
}
}
}
if (start_lock)
......@@ -4653,9 +4657,6 @@ void rotate_relay_log(Master_info* mi)
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
LOCK_log, which may not be inited (if we're not a slave).
......@@ -4684,7 +4685,6 @@ 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;
}
......
......@@ -259,24 +259,11 @@ bool log_in_use(const char* log_name)
bool purge_error_message(THD* thd, int res)
{
uint errmsg= 0;
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;
}
uint errcode;
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;
}
my_ok(thd);
......@@ -861,9 +848,7 @@ impossible position";
}
else
{
DBUG_ASSERT(ret == 0 && signal_cnt != mysql_bin_log.signal_cnt ||
thd->killed);
DBUG_PRINT("wait",("binary log received update"));
DBUG_PRINT("wait",("binary log received update or a broadcast signal caught"));
}
} while (signal_cnt == mysql_bin_log.signal_cnt && !thd->killed);
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