#At file:///home/andrei/MySQL/BZR/FIXES/rep2-bug48463-backporting/ based on revid:luis.soares@stripped
3144 Andrei Elkin 2009-11-20
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.
added:
mysql-test/suite/rpl/r/rpl_bug41902.result
mysql-test/suite/rpl/t/rpl_bug41902-slave.opt
mysql-test/suite/rpl/t/rpl_bug41902.test
modified:
client/mysqlbinlog.cc
sql/log.cc
sql/log.h
sql/rpl_rli.h
sql/slave.cc
sql/sql_repl.cc
=== modified file 'client/mysqlbinlog.cc'
--- a/client/mysqlbinlog.cc 2009-11-06 16:35:04 +0000
+++ b/client/mysqlbinlog.cc 2009-11-20 13:30:35 +0000
@@ -439,6 +439,7 @@ Exit_status Load_log_processor::process_
{
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_
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_IN
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
=== added file 'mysql-test/suite/rpl/r/rpl_bug41902.result'
--- a/mysql-test/suite/rpl/r/rpl_bug41902.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_bug41902.result 2009-11-20 13:30:35 +0000
@@ -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
=== added file 'mysql-test/suite/rpl/t/rpl_bug41902-slave.opt'
--- a/mysql-test/suite/rpl/t/rpl_bug41902-slave.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_bug41902-slave.opt 2009-11-20 13:30:35 +0000
@@ -0,0 +1 @@
+--loose-debug=-d,simulate_find_log_pos_error
=== added file 'mysql-test/suite/rpl/t/rpl_bug41902.test'
--- a/mysql-test/suite/rpl/t/rpl_bug41902.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_bug41902.test 2009-11-20 13:30:35 +0000
@@ -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
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2009-11-06 16:35:04 +0000
+++ b/sql/log.cc 2009-11-20 13:30:35 +0000
@@ -63,6 +63,35 @@ static int binlog_rollback(handlerton *h
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.
Errors and warnings are not reported to the client or SQL exception
@@ -2778,8 +2807,10 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO
{
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);
=== modified file 'sql/log.h'
--- a/sql/log.h 2009-10-07 21:13:07 +0000
+++ b/sql/log.h 2009-11-20 13:30:35 +0000
@@ -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 */
=== modified file 'sql/rpl_rli.h'
--- a/sql/rpl_rli.h 2009-10-09 13:26:37 +0000
+++ b/sql/rpl_rli.h 2009-11-20 13:30:35 +0000
@@ -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;
=== modified file 'sql/slave.cc'
--- a/sql/slave.cc 2009-11-13 10:17:53 +0000
+++ b/sql/slave.cc 2009-11-20 13:30:35 +0000
@@ -653,11 +653,15 @@ int start_slave_thread(pthread_handler h
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;
}
=== modified file 'sql/sql_repl.cc'
--- a/sql/sql_repl.cc 2009-11-13 10:17:53 +0000
+++ b/sql/sql_repl.cc 2009-11-20 13:30:35 +0000
@@ -259,24 +259,11 @@ bool log_in_use(const char* log_name)
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;
}
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);
Attachment: [text/bzr-bundle] bzr/aelkin@mysql.com-20091120133035-opb3nc32erqbmi1t.bundle
| Thread |
|---|
| • bzr commit into mysql-5.1-rep+2 branch (aelkin:3144) Bug#48463 | Andrei Elkin | 20 Nov |