summaryrefslogtreecommitdiff
path: root/sql/sql_binlog.cc
diff options
context:
space:
mode:
authorunknown <Dao-Gang.Qu@sun.com>2009-10-14 09:39:05 +0800
committerunknown <Dao-Gang.Qu@sun.com>2009-10-14 09:39:05 +0800
commitf9c6730258a9f5776608967fcc1f10183710c76f (patch)
treee6614a71219b99d66068dcb6d5cf7ab23c031151 /sql/sql_binlog.cc
parent610213149cc4cd00f402387d9f687e6375956d15 (diff)
downloadmariadb-git-f9c6730258a9f5776608967fcc1f10183710c76f.tar.gz
Bug#46640: output from mysqlbinlog command in 5.1 breaks replication
The BINLOG statement was sharing too much code with the slave SQL thread, introduced with the patch for Bug#32407. This caused statements to be logged with the wrong server_id, the id stored inside the events of the BINLOG statement rather than the id of the running server. Fix by rearranging code a bit so that only relevant parts of the code are executed by the BINLOG statement, and the server_id of the server executing the statements will not be overrided by the server_id stored in the 'format description BINLOG statement'. mysql-test/extra/binlog_tests/binlog.test: Added test to verify if the server_id stored in the 'format description BINLOG statement' will override the server_id of the server executing the statements. mysql-test/suite/binlog/r/binlog_row_binlog.result: Test result for bug#46640 mysql-test/suite/binlog/r/binlog_stm_binlog.result: Test result for bug#46640 sql/log_event.cc: Moved rows_event_stmt_clean() call from update_pos() to apply_event(). This in any case makes more sense, and is needed as update_pos() is no longer called when executing BINLOG statements. Moved setting of rli->relay_log.description_event_for_exec from Format_description_log_event::do_update_pos() to Format_description_log_event::do_apply_event() sql/log_event_old.cc: Moved rows_event_stmt_clean() call from update_pos() to apply_event(). This in any case makes more sense, and is needed as update_pos() is no longer called when executing BINLOG statements. sql/slave.cc: The skip flag is no longer needed, as the code path for BINLOG statement has been cleaned up. sql/sql_binlog.cc: Don't invoke the update_pos() code path for the BINLOG statement, as it contains code that is redundant and/or harmful (especially setting thd->server_id).
Diffstat (limited to 'sql/sql_binlog.cc')
-rw-r--r--sql/sql_binlog.cc51
1 files changed, 27 insertions, 24 deletions
diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc
index 96e99b57e3c..ee51480411b 100644
--- a/sql/sql_binlog.cc
+++ b/sql/sql_binlog.cc
@@ -56,17 +56,20 @@ void mysql_client_binlog_statement(THD* thd)
Format_description_event.
*/
my_bool have_fd_event= TRUE;
- if (!thd->rli_fake)
+ int err;
+ Relay_log_info *rli;
+ rli= thd->rli_fake;
+ if (!rli)
{
- thd->rli_fake= new Relay_log_info;
+ rli= thd->rli_fake= new Relay_log_info;
#ifdef HAVE_purify
- thd->rli_fake->is_fake= TRUE;
+ rli->is_fake= TRUE;
#endif
have_fd_event= FALSE;
}
- if (thd->rli_fake && !thd->rli_fake->relay_log.description_event_for_exec)
+ if (rli && !rli->relay_log.description_event_for_exec)
{
- thd->rli_fake->relay_log.description_event_for_exec=
+ rli->relay_log.description_event_for_exec=
new Format_description_log_event(4);
have_fd_event= FALSE;
}
@@ -78,16 +81,16 @@ void mysql_client_binlog_statement(THD* thd)
/*
Out of memory check
*/
- if (!(thd->rli_fake &&
- thd->rli_fake->relay_log.description_event_for_exec &&
+ if (!(rli &&
+ rli->relay_log.description_event_for_exec &&
buf))
{
my_error(ER_OUTOFMEMORY, MYF(0), 1); /* needed 1 bytes */
goto end;
}
- thd->rli_fake->sql_thd= thd;
- thd->rli_fake->no_storage= TRUE;
+ rli->sql_thd= thd;
+ rli->no_storage= TRUE;
for (char const *strptr= thd->lex->comment.str ;
strptr < thd->lex->comment.str + thd->lex->comment.length ; )
@@ -170,8 +173,7 @@ void mysql_client_binlog_statement(THD* thd)
}
ev= Log_event::read_log_event(bufptr, event_len, &error,
- thd->rli_fake->relay_log.
- description_event_for_exec);
+ rli->relay_log.description_event_for_exec);
DBUG_PRINT("info",("binlog base64 err=%s", error));
if (!ev)
@@ -209,18 +211,10 @@ void mysql_client_binlog_statement(THD* thd)
reporting.
*/
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
- if (apply_event_and_update_pos(ev, thd, thd->rli_fake, FALSE))
- {
- delete ev;
- /*
- TODO: Maybe a better error message since the BINLOG statement
- now contains several events.
- */
- my_error(ER_UNKNOWN_ERROR, MYF(0), "Error executing BINLOG statement");
- goto end;
- }
+ err= ev->apply_event(rli);
+#else
+ err= 0;
#endif
-
/*
Format_description_log_event should not be deleted because it
will be used to read info about the relay log's format; it
@@ -228,8 +222,17 @@ void mysql_client_binlog_statement(THD* thd)
i.e. when this thread terminates.
*/
if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
- delete ev;
+ delete ev;
ev= 0;
+ if (err)
+ {
+ /*
+ TODO: Maybe a better error message since the BINLOG statement
+ now contains several events.
+ */
+ my_error(ER_UNKNOWN_ERROR, MYF(0), "Error executing BINLOG statement");
+ goto end;
+ }
}
}
@@ -238,7 +241,7 @@ void mysql_client_binlog_statement(THD* thd)
my_ok(thd);
end:
- thd->rli_fake->clear_tables_to_lock();
+ rli->clear_tables_to_lock();
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
DBUG_VOID_RETURN;
}