Commit 9b867a2a authored by unknown's avatar unknown

Replication: various small fixes specific to the new binlog format of 5.0

(including one which may explain autobuild's failure of yesterday)


client/mysqlbinlog.cc:
  - In mysqlbinlog, we should not reset the Format event when we see Rotate. If a binlog started with a Format event, it is not going to switch later to 4.0 format.
  I had already did the same fix in Rotate_log_event::exec_event() in replication.
  - Fix for a merge bug.
sql/log_event.cc:
  An event with an uninited catalog (read from a 4.x server) is not the same as an event with a NULL catalog
  (5.0 server which did not specify catalog), the difference is that they are not in the same format;
  so I introduce a way to know if the catalog has been inited or not. This fixes a rpl_trunc_binlog failure
  I had.
  When we leave Load_log_event::exec_event(), we must reset thd->catalog to 0, like we already do
  in Query_log_event::exec_event(). This fixes a Valgrind error which popped in rpl_charset (which may
  be what caused autobuild to crash yesterday).
  And a fix for event's parsing (the position was always computed right because start_dup==end is always true
  and will until we add new string members to Query_log_event.
sql/log_event.h:
  catalog_len changed from uint to int to allow -1, which means "not inited"
  (I preferred to do it like this rather than create a new bool var Query_log_event::catalog_inited
  like we have in Query_log_event::sql_mode_inited; that's because catalog will not use the whole range of int,
  so it's allowed to pick -1 as a special value and have only one var.
sql/slave.cc:
  comments
parent 1876125e
......@@ -418,18 +418,6 @@ Create_file event for file_id: %u\n",exv->file_id);
*/
ev= 0;
break;
case ROTATE_EVENT:
/* see comments in sql/slave.cc:process_io_rotate() */
if (description_event->binlog_version >= 4)
{
delete description_event;
/* start from format 3 (MySQL 4.0) again */
description_event= new Format_description_log_event(3);
if (!description_event || !description_event->is_valid())
die("Invalid Format_description log event; could be out of memory");
}
ev->print(result_file, short_form, last_event_info);
break;
default:
ev->print(result_file, short_form, last_event_info);
}
......@@ -1011,11 +999,13 @@ static int dump_local_log_entries(const char* logname)
if (!ev)
{
if (file->error)
{
fprintf(stderr,
"Could not read entry at offset %s:"
"Error in log format or read error\n",
llstr(old_off,llbuff));
error= 1;
}
// file->error == 0 means EOF, that's OK, we break in this case
break;
}
......
......@@ -1034,7 +1034,7 @@ int Query_log_event::write_data(IO_CACHE* file)
int8store(start, sql_mode);
start+= 8;
}
if (catalog)
if (catalog_len >= 0) // i.e. "catalog inited" (false for 4.0 events)
{
*(start++)= Q_CATALOG_CODE;
*(start++)= (uchar) catalog_len;
......@@ -1119,7 +1119,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
Query_log_event::Query_log_event(const char* buf, uint event_len,
const Format_description_log_event *description_event)
:Log_event(buf, description_event), data_buf(0), query(NULL),
catalog(NULL), db(NULL), catalog_len(0), status_vars_len(0),
db(NULL), catalog_len(-1), status_vars_len(0),
flags2_inited(0), sql_mode_inited(0)
{
ulong data_len;
......@@ -1214,9 +1214,10 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
not need (and want) to change start_dup (because this would cut the
previously marked status vars).
*/
pos++;
if (start_dup==end)
start_dup= ++pos;
pos+= catalog_len+1;
start_dup= pos;
pos+= catalog_len+1; // counting the end '\0'
break;
default:
/* That's why you must write status vars in growing order of code */
......@@ -1236,11 +1237,15 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
const char* tmp_buf= data_buf;
/* Now set event's pointers to point to bits of the new string */
if (catalog_len)
if (catalog_len >= 0) // we have seen a catalog (zero-length or not)
{
catalog= tmp_buf;
tmp_buf+= (uint) (end-start_dup); /* "seek" to db */
}
#ifndef DBUG_OFF
else
catalog= 0; // for DBUG_PRINT
#endif
db= tmp_buf;
query= tmp_buf + db_len + 1;
q_len = data_buf + data_len - query;
......@@ -1531,7 +1536,7 @@ end:
TEMPORARY TABLE don't suffer from these assignments to 0 as DROP TEMPORARY
TABLE uses the db.table syntax).
*/
thd->db= 0; // prevent db from being freed
thd->db= thd->catalog= 0; // prevent db from being freed
thd->query= 0; // just to be sure
thd->query_length= 0;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
......
......@@ -604,7 +604,7 @@ public:
concerned) from here.
*/
uint catalog_len; /* <= 255 char */
int catalog_len; // <= 255 char; -1 means uninited
/*
We want to be able to store a variable number of N-bit status vars:
......
......@@ -372,7 +372,7 @@ int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,
(starting from position 4):
Format_desc (of slave)
Rotate (of master)
Format_desc (of slave)
Format_desc (of master)
So the Format_desc which really describes the rest of the relay log is
the 3rd event (it can't be further than that, because we rotate the
relay log when we queue a Rotate event from the master).
......@@ -3873,7 +3873,10 @@ static int process_io_rotate(MASTER_INFO *mi, Rotate_log_event *rev)
mi->rli.relay_log.description_event_for_queue= new
Format_description_log_event(3);
}
/*
Rotate the relay log makes binlog format detection easier (at next slave
start or mysqlbinlog)
*/
rotate_relay_log(mi); /* will take the right mutexes */
DBUG_RETURN(0);
}
......
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