mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
Automerge from mysql-5.1-bugteam into mysql-5.5-bugteam.
This commit is contained in:
commit
e760a4d8ab
4 changed files with 82 additions and 10 deletions
|
@ -1244,7 +1244,7 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
|
|||
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:
|
||||
|
@ -1332,8 +1332,10 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
|
|||
(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"));
|
||||
|
||||
|
@ -6117,8 +6119,12 @@ void Slave_log_event::init_from_mem_pool(int data_size)
|
|||
|
||||
|
||||
/** 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;
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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;
|
||||
|
||||
/*
|
||||
|
|
64
sql/slave.cc
64
sql/slave.cc
|
@ -4726,12 +4726,66 @@ static Log_event* next_event(Relay_log_info* rli)
|
|||
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)
|
||||
|
|
Loading…
Reference in a new issue