Commit 244304fd authored by guilhem@mysql.com's avatar guilhem@mysql.com

Fix for BUG#3204 ""mysqlbinlog --read-from-remote-server this_binlog.001" prints all binlogs":

we now detect that the server is sending us a log which we did not request
by testing the info in the fake Rotate event.
I also changed code to not print the fake Rotate which describes the
log we asked for (it's always the first received event but old masters
may not send it).
parent 99d37415
...@@ -651,7 +651,7 @@ static int dump_remote_log_entries(const char* logname) ...@@ -651,7 +651,7 @@ static int dump_remote_log_entries(const char* logname)
{ {
char buf[128]; char buf[128];
char last_db[FN_REFLEN+1] = ""; char last_db[FN_REFLEN+1] = "";
uint len; uint len, logname_len;
NET* net = &mysql->net; NET* net = &mysql->net;
int old_format; int old_format;
DBUG_ENTER("dump_remote_log_entries"); DBUG_ENTER("dump_remote_log_entries");
...@@ -668,10 +668,10 @@ static int dump_remote_log_entries(const char* logname) ...@@ -668,10 +668,10 @@ static int dump_remote_log_entries(const char* logname)
} }
int4store(buf, position); int4store(buf, position);
int2store(buf + BIN_LOG_HEADER_SIZE, binlog_flags); int2store(buf + BIN_LOG_HEADER_SIZE, binlog_flags);
len = (uint) strlen(logname); logname_len = (uint) strlen(logname);
int4store(buf + 6, 0); int4store(buf + 6, 0);
memcpy(buf + 10, logname,len); memcpy(buf + 10, logname, logname_len);
if (simple_command(mysql, COM_BINLOG_DUMP, buf, len + 10, 1)) if (simple_command(mysql, COM_BINLOG_DUMP, buf, logname_len + 10, 1))
{ {
fprintf(stderr,"Got fatal error sending the log dump command\n"); fprintf(stderr,"Got fatal error sending the log dump command\n");
DBUG_RETURN(1); DBUG_RETURN(1);
...@@ -706,6 +706,37 @@ static int dump_remote_log_entries(const char* logname) ...@@ -706,6 +706,37 @@ static int dump_remote_log_entries(const char* logname)
Log_event_type type= ev->get_type_code(); Log_event_type type= ev->get_type_code();
if (!old_format || ( type != LOAD_EVENT && type != CREATE_FILE_EVENT)) if (!old_format || ( type != LOAD_EVENT && type != CREATE_FILE_EVENT))
{ {
/*
If this is a Rotate event, maybe it's the end of the requested binlog;
in this case we are done (stop transfer).
This is suitable for binlogs, not relay logs (but for now we don't read
relay logs remotely because the server is not able to do that). If one
day we read relay logs remotely, then we will have a problem with the
detection below: relay logs contain Rotate events which are about the
binlogs, so which would trigger the end-detection below.
*/
if (ev->get_type_code() == ROTATE_EVENT)
{
Rotate_log_event *rev= (Rotate_log_event *)ev;
/*
If this is a fake Rotate event, and not about our log, we can stop
transfer. If this a real Rotate event (so it's not about our log,
it's in our log describing the next log), we print it (because it's
part of our log) and then we will stop when we receive the fake one
soon.
*/
if (rev->when == 0)
{
if ((rev->ident_len != logname_len) ||
memcmp(rev->new_log_ident, logname, logname_len))
DBUG_RETURN(0);
/*
Otherwise, this is a fake Rotate for our log, at the very beginning
for sure. Skip it.
*/
continue;
}
}
if (process_event(&rec_count,last_db,ev,old_off,old_format)) if (process_event(&rec_count,last_db,ev,old_off,old_format))
DBUG_RETURN(1); DBUG_RETURN(1);
} }
......
...@@ -59,9 +59,6 @@ LOAD DATA LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/words.dat-2-1' INTO TABLE `t1` FI ...@@ -59,9 +59,6 @@ LOAD DATA LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/words.dat-2-1' INTO TABLE `t1` FI
LOAD DATA LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/words.dat-3-1' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' STARTING BY '' (word); LOAD DATA LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/words.dat-3-1' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' STARTING BY '' (word);
LOAD DATA LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/words.dat-4-1' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' STARTING BY '' (word); LOAD DATA LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/words.dat-4-1' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' STARTING BY '' (word);
LOAD DATA LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/words.dat-5-1' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' STARTING BY '' (word); LOAD DATA LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/words.dat-5-1' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' STARTING BY '' (word);
LOAD DATA LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/words.dat-6-1' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' STARTING BY '' (word);
SET TIMESTAMP=1000000000;
insert into t1 values ("Alas");
--- Broken LOAD DATA -- --- Broken LOAD DATA --
use test; use test;
......
...@@ -70,7 +70,6 @@ select "--- Remote --" as ""; ...@@ -70,7 +70,6 @@ select "--- Remote --" as "";
--enable_query_log --enable_query_log
# This is broken now # This is broken now
# By the way it seems that remote version fetches all events with name >= master-bin.000001
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 --exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
......
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