summaryrefslogtreecommitdiff
path: root/sql/sql_binlog.cc
diff options
context:
space:
mode:
authorunknown <mkindahl@dl145h.mysql.com>2007-12-19 18:51:46 +0100
committerunknown <mkindahl@dl145h.mysql.com>2007-12-19 18:51:46 +0100
commit047ec78f2c0cddb8761641a54aea73a79253fb2d (patch)
treeb4347d5d5af8e563fdef89ebf94232b92415803c /sql/sql_binlog.cc
parent7213ca204dc3d10f751ca2507321eede1238d6cb (diff)
parent267b00d6820504f9db735593e144b274bfc073a4 (diff)
downloadmariadb-git-047ec78f2c0cddb8761641a54aea73a79253fb2d.tar.gz
Merge dl145h.mysql.com:/data0/mkindahl/mysql-5.1-rpl
into dl145h.mysql.com:/data0/mkindahl/mysql-5.1-rpl-merge mysql-test/include/have_multi_ndb.inc: Auto merged mysql-test/lib/mtr_cases.pl: Auto merged mysql-test/lib/mtr_report.pl: Auto merged mysql-test/suite/binlog/r/binlog_stm_blackhole.result: Auto merged mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result: Auto merged mysql-test/suite/rpl_ndb/t/disabled.def: Auto merged sql/ha_ndbcluster_binlog.cc: Auto merged sql/log.cc: Auto merged sql/log_event_old.cc: Auto merged sql/mysql_priv.h: Auto merged sql/mysqld.cc: Auto merged sql/rpl_rli.cc: Auto merged sql/set_var.cc: Auto merged sql/set_var.h: Auto merged sql/slave.cc: Auto merged sql/sql_binlog.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_string.cc: Auto merged mysql-test/Makefile.am: SCCS merged mysql-test/mysql-test-run.pl: Manual merge. mysql-test/suite/binlog/t/disabled.def: Manual merge. mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result: Manual merge. mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result: Manual merge. sql/log_event.cc: Manual merge. ,
Diffstat (limited to 'sql/sql_binlog.cc')
-rw-r--r--sql/sql_binlog.cc74
1 files changed, 57 insertions, 17 deletions
diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc
index 77c5155b41b..04f408453ea 100644
--- a/sql/sql_binlog.cc
+++ b/sql/sql_binlog.cc
@@ -17,15 +17,14 @@
#include "rpl_rli.h"
#include "base64.h"
-/*
+/**
Execute a BINLOG statement
- TODO: This currently assumes a MySQL 5.x binlog.
- When we'll have binlog with a different format, to execute the
- BINLOG command properly the server will need to know which format
- the BINLOG command's event is in. mysqlbinlog should then send
- the Format_description_log_event of the binlog it reads and the
- server thread should cache this format into
+ To execute the BINLOG command properly the server needs to know
+ which format the BINLOG command's event is in. Therefore, the first
+ BINLOG statement seen must be a base64 encoding of the
+ Format_description_log_event, as outputted by mysqlbinlog. This
+ Format_description_log_event is cached in
rli->description_event_for_exec.
*/
@@ -47,11 +46,24 @@ void mysql_client_binlog_statement(THD* thd)
/*
Allocation
*/
+
+ /*
+ If we do not have a Format_description_event, we create a dummy
+ one here. In this case, the first event we read must be a
+ Format_description_event.
+ */
+ my_bool have_fd_event= TRUE;
if (!thd->rli_fake)
+ {
thd->rli_fake= new Relay_log_info;
-
- const Format_description_log_event *desc=
- new Format_description_log_event(4);
+ have_fd_event= FALSE;
+ }
+ if (thd->rli_fake && !thd->rli_fake->relay_log.description_event_for_exec)
+ {
+ thd->rli_fake->relay_log.description_event_for_exec=
+ new Format_description_log_event(4);
+ have_fd_event= FALSE;
+ }
const char *error= 0;
char *buf= (char *) my_malloc(decoded_len, MYF(MY_WME));
@@ -60,7 +72,9 @@ void mysql_client_binlog_statement(THD* thd)
/*
Out of memory check
*/
- if (!(thd->rli_fake && desc && buf))
+ if (!(thd->rli_fake &&
+ thd->rli_fake->relay_log.description_event_for_exec &&
+ buf))
{
my_error(ER_OUTOFMEMORY, MYF(0), 1); /* needed 1 bytes */
goto end;
@@ -131,7 +145,28 @@ void mysql_client_binlog_statement(THD* thd)
goto end;
}
- ev= Log_event::read_log_event(bufptr, event_len, &error, desc);
+ /*
+ If we have not seen any Format_description_event, then we must
+ see one; it is the only statement that can be read in base64
+ without a prior Format_description_event.
+ */
+ if (!have_fd_event)
+ {
+ if (bufptr[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT)
+ have_fd_event= TRUE;
+ else
+ {
+ my_error(ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT,
+ MYF(0),
+ Log_event::get_type_str(
+ (Log_event_type)bufptr[EVENT_TYPE_OFFSET]));
+ goto end;
+ }
+ }
+
+ ev= Log_event::read_log_event(bufptr, event_len, &error,
+ thd->rli_fake->relay_log.
+ description_event_for_exec);
DBUG_PRINT("info",("binlog base64 err=%s", error));
if (!ev)
@@ -167,11 +202,10 @@ void mysql_client_binlog_statement(THD* thd)
Neither do we have to update the log positions, since that is
not used at all: the rli_fake instance is used only for error
reporting.
- */
+ */
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
- if (IF_DBUG(int err= ) ev->apply_event(thd->rli_fake))
+ if (apply_event_and_update_pos(ev, thd, thd->rli_fake, FALSE))
{
- DBUG_PRINT("info", ("apply_event() returned: %d", err));
/*
TODO: Maybe a better error message since the BINLOG statement
now contains several events.
@@ -181,7 +215,14 @@ void mysql_client_binlog_statement(THD* thd)
}
#endif
- delete ev;
+ /*
+ Format_description_log_event should not be deleted because it
+ will be used to read info about the relay log's format; it
+ will be deleted when the SQL thread does not need it,
+ i.e. when this thread terminates.
+ */
+ if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
+ delete ev;
ev= 0;
}
}
@@ -191,7 +232,6 @@ void mysql_client_binlog_statement(THD* thd)
send_ok(thd);
end:
- delete desc;
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
DBUG_VOID_RETURN;
}