#At file:///home/sven/bzr/b41961-post_header_len/5.1-rpl/ based on revid:sven@stripped
2711 Sven Sandberg 2009-01-08
BUG#41961: Some log_event types do not skip post-header when reading
Problem: when the server reads a log_event from file, it should read
the post-header lengths from the format_description_log_event. Some
event types which currently have post-header length 0 did not do this,
and instead had a hard-coded zero length for the post-header. That
means the current server version will not be able to read future
versions of these events.
Fix: make the reader functions read the post-header.
modified:
sql/log_event.cc
sql/log_event.h
per-file messages:
sql/log_event.cc
- Made Format_description_log_event constructor initialize all
post-header lengths explicitly, to make it easier to find them
in the source code. After this, it is no longer necessary to pass
the MY_ZEROFILL flag to my_malloc. I removed the flag since
that means valgrind will give a warning if a future event type
does not declare its length here.
- Made INTVAR, RAND, USER_VAR, and XID events skip post_header_len
when reading from file.
sql/log_event.h
Added explicit defines for the length of all event types.
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc 2008-11-12 17:51:47 +0000
+++ b/sql/log_event.cc 2009-01-08 14:28:45 +0000
@@ -3424,7 +3424,7 @@ Format_description_log_event(uint8 binlo
number_of_event_types= LOG_EVENT_TYPES;
/* we'll catch my_malloc() error in is_valid() */
post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
- MYF(MY_ZEROFILL));
+ MYF(0));
/*
This long list of assignments is not beautiful, but I see no way to
make it nicer, as the right members are #defines, not array members, so
@@ -3432,16 +3432,35 @@ Format_description_log_event(uint8 binlo
*/
if (post_header_len)
{
+ /* Note: all event types must explicitly fill in their lengths here. */
post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
post_header_len[QUERY_EVENT-1]= QUERY_HEADER_LEN;
+ post_header_len[STOP_EVENT-1]= STOP_HEADER_LEN;
post_header_len[ROTATE_EVENT-1]= ROTATE_HEADER_LEN;
+ post_header_len[INTVAR_EVENT-1]= INTVAR_HEADER_LEN;
post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
+ post_header_len[SLAVE_EVENT-1]= SLAVE_HEADER_LEN;
post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1];
+ post_header_len[RAND_EVENT-1]= RAND_HEADER_LEN;
+ post_header_len[USER_VAR_EVENT-1]= USER_VAR_HEADER_LEN;
post_header_len[FORMAT_DESCRIPTION_EVENT-1]= FORMAT_DESCRIPTION_HEADER_LEN;
+ post_header_len[XID_EVENT-1]= XID_HEADER_LEN;
+ post_header_len[BEGIN_LOAD_QUERY_EVENT-1]= post_header_len[APPEND_BLOCK_EVENT-1];
+ post_header_len[EXECUTE_LOAD_QUERY_EVENT-1]= EXECUTE_LOAD_QUERY_HEADER_LEN;
+ /*
+ The PRE_GA events are never be written to any binlog, but
+ their lengths are included in Format_description_log_event.
+ Hence, we need to be assign some value here, to avoid reading
+ uninitialized memory when the array is written to disk.
+ */
+ post_header_len[PRE_GA_WRITE_ROWS_EVENT-1] = 0;
+ post_header_len[PRE_GA_UPDATE_ROWS_EVENT-1] = 0;
+ post_header_len[PRE_GA_DELETE_ROWS_EVENT-1] = 0;
+
post_header_len[TABLE_MAP_EVENT-1]= TABLE_MAP_HEADER_LEN;
post_header_len[WRITE_ROWS_EVENT-1]= ROWS_HEADER_LEN;
post_header_len[UPDATE_ROWS_EVENT-1]= ROWS_HEADER_LEN;
@@ -3461,8 +3480,6 @@ Format_description_log_event(uint8 binlo
post_header_len[WRITE_ROWS_EVENT-1]=
post_header_len[UPDATE_ROWS_EVENT-1]=
post_header_len[DELETE_ROWS_EVENT-1]= 6;);
- post_header_len[BEGIN_LOAD_QUERY_EVENT-1]= post_header_len[APPEND_BLOCK_EVENT-1];
- post_header_len[EXECUTE_LOAD_QUERY_EVENT-1]= EXECUTE_LOAD_QUERY_HEADER_LEN;
post_header_len[INCIDENT_EVENT-1]= INCIDENT_HEADER_LEN;
}
break;
@@ -4813,7 +4830,8 @@ Intvar_log_event::Intvar_log_event(const
const Format_description_log_event* description_event)
:Log_event(buf, description_event)
{
- buf+= description_event->common_header_len;
+ buf+= description_event->common_header_len +
+ description_event->post_header_len[INTVAR_EVENT-1];
type= buf[I_TYPE_OFFSET];
val= uint8korr(buf+I_VAL_OFFSET);
}
@@ -4957,7 +4975,8 @@ Rand_log_event::Rand_log_event(const cha
const Format_description_log_event* description_event)
:Log_event(buf, description_event)
{
- buf+= description_event->common_header_len;
+ buf+= description_event->common_header_len +
+ description_event->post_header_len[RAND_EVENT-1];
seed1= uint8korr(buf+RAND_SEED1_OFFSET);
seed2= uint8korr(buf+RAND_SEED2_OFFSET);
}
@@ -5061,7 +5080,8 @@ Xid_log_event(const char* buf,
const Format_description_log_event *description_event)
:Log_event(buf, description_event)
{
- buf+= description_event->common_header_len;
+ buf+= description_event->common_header_len +
+ description_event->post_header_len[XID_EVENT-1];
memcpy((char*) &xid, buf, sizeof(xid));
}
@@ -5207,7 +5227,8 @@ User_var_log_event(const char* buf,
const Format_description_log_event* description_event)
:Log_event(buf, description_event)
{
- buf+= description_event->common_header_len;
+ buf+= description_event->common_header_len +
+ description_event->post_header_len[XID_EVENT-1];
name_len= uint4korr(buf);
name= (char *) buf + UV_NAME_LEN_SIZE;
buf+= UV_NAME_LEN_SIZE + name_len;
=== modified file 'sql/log_event.h'
--- a/sql/log_event.h 2008-09-29 05:36:42 +0000
+++ b/sql/log_event.h 2009-01-08 14:28:45 +0000
@@ -227,14 +227,20 @@ struct sql_ex_info
#define QUERY_HEADER_MINIMAL_LEN (4 + 4 + 1 + 2)
// where 5.0 differs: 2 for len of N-bytes vars.
#define QUERY_HEADER_LEN (QUERY_HEADER_MINIMAL_LEN + 2)
+#define STOP_HEADER_LEN 0
#define LOAD_HEADER_LEN (4 + 4 + 4 + 1 +1 + 4)
+#define SLAVE_HEADER_LEN 0
#define START_V3_HEADER_LEN (2 + ST_SERVER_VER_LEN + 4)
#define ROTATE_HEADER_LEN 8 // this is FROZEN (the Rotate post-header is frozen)
+#define INTVAR_HEADER_LEN 0
#define CREATE_FILE_HEADER_LEN 4
#define APPEND_BLOCK_HEADER_LEN 4
#define EXEC_LOAD_HEADER_LEN 4
#define DELETE_FILE_HEADER_LEN 4
+#define RAND_HEADER_LEN 0
+#define USER_VAR_HEADER_LEN 0
#define FORMAT_DESCRIPTION_HEADER_LEN (START_V3_HEADER_LEN+1+LOG_EVENT_TYPES)
+#define XID_HEADER_LEN 0
#define ROWS_HEADER_LEN 8
#define TABLE_MAP_HEADER_LEN 8
#define EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN (4 + 4 + 4 + 1)
| Thread |
|---|
| • bzr commit into mysql-5.1 branch (sven:2711) Bug#41961 | Sven Sandberg | 8 Jan |