mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
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.
This commit is contained in:
@ -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,
|
|||||||
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,
|
|||||||
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
|
||||||
|
34
mysql-test/suite/rpl/r/rpl_bug41902.result
Normal file
34
mysql-test/suite/rpl/r/rpl_bug41902.result
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
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
|
1
mysql-test/suite/rpl/t/rpl_bug41902-slave.opt
Normal file
1
mysql-test/suite/rpl/t/rpl_bug41902-slave.opt
Normal file
@ -0,0 +1 @@
|
|||||||
|
--loose-debug=-d,simulate_find_log_pos_error
|
61
mysql-test/suite/rpl/t/rpl_bug41902.test
Normal file
61
mysql-test/suite/rpl/t/rpl_bug41902.test
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
# 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
|
43
sql/log.cc
43
sql/log.cc
@ -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,
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
|
|
||||||
/* 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)
|
|||||||
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 {
|
|||||||
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:
|
|||||||
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;
|
||||||
|
|
||||||
|
10
sql/slave.cc
10
sql/slave.cc
@ -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)
|
|||||||
|
|
||||||
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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
|
|
||||||
bool purge_error_message(THD* thd, int res)
|
bool purge_error_message(THD* thd, int res)
|
||||||
{
|
{
|
||||||
uint errmsg= 0;
|
uint errcode;
|
||||||
|
|
||||||
switch (res) {
|
if ((errcode= purge_log_get_error_code(res)) != 0)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
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";
|
|||||||
}
|
}
|
||||||
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);
|
||||||
|
Reference in New Issue
Block a user