#At file:///home/lsoares/Workspace/bzr/work/bugfixing/push/mysql-5.5-bugteam/ based on revid:magnus.blaudd@stripped
3215 Luis Soares 2010-10-07 [merge]
Automerge from mysql-5.1-bugteam.
modified:
sql/log_event.cc
sql/log_event.h
sql/rpl_rli.h
sql/slave.cc
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc 2010-08-23 22:31:12 +0000
+++ b/sql/log_event.cc 2010-10-07 09:54:56 +0000
@@ -1239,7 +1239,7 @@ Log_event* Log_event::read_log_event(con
break;
#ifdef HAVE_REPLICATION
case SLAVE_EVENT: /* can never happen (unused event) */
- ev = new Slave_log_event(buf, event_len);
+ ev = new Slave_log_event(buf, event_len, description_event);
break;
#endif /* HAVE_REPLICATION */
case CREATE_FILE_EVENT:
@@ -1327,8 +1327,10 @@ Log_event* Log_event::read_log_event(con
(because constructor is "void") ; so instead we leave the pointer we
wanted to allocate (e.g. 'query') to 0 and we test it in is_valid().
Same for Format_description_log_event, member 'post_header_len'.
+
+ SLAVE_EVENT is never used, so it should not be read ever.
*/
- if (!ev || !ev->is_valid())
+ if (!ev || !ev->is_valid() || (event_type == SLAVE_EVENT))
{
DBUG_PRINT("error",("Found invalid event in binary log"));
@@ -6112,8 +6114,12 @@ void Slave_log_event::init_from_mem_pool
/** This code is not used, so has not been updated to be format-tolerant. */
-Slave_log_event::Slave_log_event(const char* buf, uint event_len)
- :Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0)
+/* We are using description_event so that slave does not crash on Log_event
+ constructor */
+Slave_log_event::Slave_log_event(const char* buf,
+ uint event_len,
+ const Format_description_log_event* description_event)
+ :Log_event(buf,description_event),mem_pool(0),master_host(0)
{
if (event_len < LOG_EVENT_HEADER_LEN)
return;
=== modified file 'sql/log_event.h'
--- a/sql/log_event.h 2010-07-15 13:47:50 +0000
+++ b/sql/log_event.h 2010-10-07 09:54:56 +0000
@@ -1846,7 +1846,9 @@ public:
void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
- Slave_log_event(const char* buf, uint event_len);
+ Slave_log_event(const char* buf,
+ uint event_len,
+ const Format_description_log_event *description_event);
~Slave_log_event();
int get_data_size();
bool is_valid() const { return master_host != 0; }
=== modified file 'sql/rpl_rli.h'
--- a/sql/rpl_rli.h 2010-03-31 14:05:33 +0000
+++ b/sql/rpl_rli.h 2010-10-07 09:54:56 +0000
@@ -97,6 +97,16 @@ public:
*/
MYSQL_BIN_LOG relay_log;
LOG_INFO linfo;
+
+ /*
+ cur_log
+ Pointer that either points at relay_log.get_log_file() or
+ &rli->cache_buf, depending on whether the log is hot or there was
+ the need to open a cold relay_log.
+
+ cache_buf
+ IO_CACHE used when opening cold relay logs.
+ */
IO_CACHE cache_buf,*cur_log;
/*
=== modified file 'sql/slave.cc'
--- a/sql/slave.cc 2010-07-29 12:32:11 +0000
+++ b/sql/slave.cc 2010-10-07 09:54:56 +0000
@@ -4727,12 +4727,66 @@ static Log_event* next_event(Relay_log_i
DBUG_ASSERT(rli->cur_log_fd == -1);
/*
- Read pointer has to be at the start since we are the only
- reader.
- We must keep the LOCK_log to read the 4 first bytes, as this is a hot
- log (same as when we call read_log_event() above: for a hot log we
- take the mutex).
+ When the SQL thread is [stopped and] (re)started the
+ following may happen:
+
+ 1. Log was hot at stop time and remains hot at restart
+
+ SQL thread reads again from hot_log (SQL thread was
+ reading from the active log when it was stopped and the
+ very same log is still active on SQL thread restart).
+
+ In this case, my_b_seek is performed on cur_log, while
+ cur_log points to relay_log.get_log_file();
+
+ 2. Log was hot at stop time but got cold before restart
+
+ The log was hot when SQL thread stopped, but it is not
+ anymore when the SQL thread restarts.
+
+ In this case, the SQL thread reopens the log, using
+ cache_buf, ie, cur_log points to &cache_buf, and thence
+ its coordinates are reset.
+
+ 3. Log was already cold at stop time
+
+ The log was not hot when the SQL thread stopped, and, of
+ course, it will not be hot when it restarts.
+
+ In this case, the SQL thread opens the cold log again,
+ using cache_buf, ie, cur_log points to &cache_buf, and
+ thence its coordinates are reset.
+
+ 4. Log was hot at stop time, DBA changes to previous cold
+ log and restarts SQL thread
+
+ The log was hot when the SQL thread was stopped, but the
+ user changed the coordinates of the SQL thread to
+ restart from a previous cold log.
+
+ In this case, at start time, cur_log points to a cold
+ log, opened using &cache_buf as cache, and coordinates
+ are reset. However, as it moves on to the next logs, it
+ will eventually reach the hot log. If the hot log is the
+ same at the time the SQL thread was stopped, then
+ coordinates were not reset - the cur_log will point to
+ relay_log.get_log_file(), and not a freshly opened
+ IO_CACHE through cache_buf. For this reason we need to
+ deploy a my_b_seek before calling check_binlog_magic at
+ this point of the code (see: BUG#55263 for more
+ details).
+
+ NOTES:
+ - We must keep the LOCK_log to read the 4 first bytes, as
+ this is a hot log (same as when we call read_log_event()
+ above: for a hot log we take the mutex).
+
+ - Because of scenario #4 above, we need to have a
+ my_b_seek here. Otherwise, we might hit the assertion
+ inside check_binlog_magic.
*/
+
+ my_b_seek(cur_log, (my_off_t) 0);
if (check_binlog_magic(cur_log,&errmsg))
{
if (!hot_log)
Attachment: [text/bzr-bundle] bzr/luis.soares@oracle.com-20101007095456-msopu5n73avi2cui.bundle
| Thread |
|---|
| • bzr commit into mysql-5.5-bugteam branch (luis.soares:3215) | Luis Soares | 7 Oct |