Made sending of events more strict

The decision to send an event to a slave can now only be made in one place.
This will force all events to pass the same checks before they are sent to
the slaves.
This commit is contained in:
Markus Makela
2016-04-07 17:51:17 +03:00
parent aa7e3461c8
commit 52ef8987cb

View File

@ -1914,39 +1914,25 @@ blr_distribute_binlog_record(ROUTER_INSTANCE *router, REP_HEADER *hdr, uint8_t *
spinlock_acquire(&router->binlog_lock); spinlock_acquire(&router->binlog_lock);
slave_event_action_t slave_action = SLAVE_FORCE_CATCHUP; slave_event_action_t slave_action = SLAVE_FORCE_CATCHUP;
const bool same_file = strcmp(slave->binlogfile, router->binlog_name) == 0;
const bool rotate = hdr->event_type == ROTATE_EVENT &&
strcmp(slave->binlogfile, router->prevbinlog);
if (router->trx_safe && slave->binlog_pos == router->current_safe_event && if (router->trx_safe && (same_file || rotate) &&
(strcmp(slave->binlogfile, router->binlog_name) == 0 || slave->binlog_pos == router->current_safe_event)
(hdr->event_type == ROTATE_EVENT &&
strcmp(slave->binlogfile, router->prevbinlog))))
{ {
/** /** Slave needs the current event being distributed */
* Slave needs the current event being distributed
*/
slave_action = SLAVE_SEND_EVENT; slave_action = SLAVE_SEND_EVENT;
} }
else if (slave->binlog_pos == router->last_event_pos && else if (!router->trx_safe && (same_file || rotate) &&
(strcmp(slave->binlogfile, router->binlog_name) == 0 || slave->binlog_pos == router->last_event_pos)
(hdr->event_type == ROTATE_EVENT &&
strcmp(slave->binlogfile, router->prevbinlog))))
{ {
if (router->trx_safe) /** Transaction safety is off */
{
MXS_ERROR("Slave %s:%d, server ID %u: Sending event from an "
"incomplete transaction from file %s. Slave position: %u "
"Caller role: %s Current safe event: %lu Event type: %x",
slave->dcb->remote, ntohs((slave->dcb->ipv4).sin_port),
slave->serverid, slave->binlogfile, slave->binlog_pos,
ROLETOSTR(role), router->current_safe_event, hdr->event_type);
}
/**
* Transaction safety is off or there are no pending transactions
*/
slave_action = SLAVE_SEND_EVENT; slave_action = SLAVE_SEND_EVENT;
} }
else if (slave->binlog_pos == hdr->next_pos else if (same_file)
&& strcmp(slave->binlogfile, router->binlog_name) == 0) {
if (slave->binlog_pos == hdr->next_pos)
{ {
/* /*
* Slave has already read record from file, no * Slave has already read record from file, no
@ -1954,20 +1940,44 @@ blr_distribute_binlog_record(ROUTER_INSTANCE *router, REP_HEADER *hdr, uint8_t *
*/ */
slave_action = SLAVE_EVENT_ALREADY_SENT; slave_action = SLAVE_EVENT_ALREADY_SENT;
} }
else if ((slave->binlog_pos > hdr->next_pos - hdr->event_size) else if ((slave->binlog_pos > hdr->next_pos - hdr->event_size))
&& strcmp(slave->binlogfile, router->binlog_name) == 0)
{ {
/* /*
* The slave is ahead of the master, this should never * The slave is ahead of the master, this should never
* happen. Force the slave to catchup mode in order to * happen. Force the slave to catchup mode in order to
* try to resolve the issue. * try to resolve the issue.
*/ */
MXS_ERROR("Slave %d is ahead of expected position %s@%lu. " MXS_ERROR("Slave %s:%d server ID %d is ahead of expected position %s@%u. "
"Expected position %d", "Expected position %d", slave->dcb->remote,
slave->serverid, slave->binlogfile, ntohs((slave->dcb->ipv4).sin_port), slave->serverid,
(unsigned long)slave->binlog_pos, slave->binlogfile, slave->binlog_pos,
hdr->next_pos - hdr->event_size); hdr->next_pos - hdr->event_size);
} }
else
{
MXS_ERROR("Slave %s:%d server ID %d is at position %u when "
"it should be at %u.", slave->dcb->remote,
ntohs((slave->dcb->ipv4).sin_port), slave->serverid,
slave->binlog_pos, hdr->next_pos - hdr->event_size);
}
}
else if (rotate)
{
/** Slave is more than one binlog file behind */
MXS_ERROR("Slave %s:%d server ID %d is behind more than one binlog file "
"from the master. Slave is using '%s' with position %d "
"when master binlog file is '%s'.", slave->dcb->remote,
ntohs((slave->dcb->ipv4).sin_port), slave->serverid,
slave->binlogfile, slave->binlog_pos, router->binlog_name);
}
else
{
/** Slave is using unexpected binlog file */
MXS_ERROR("Slave %s:%d server ID %d is using an unexpected binlog file '%s' with "
"position %d. Master binlog file is '%s'.", slave->dcb->remote,
ntohs((slave->dcb->ipv4).sin_port), slave->serverid,
slave->binlogfile, slave->binlog_pos, router->binlog_name);
}
spinlock_release(&router->binlog_lock); spinlock_release(&router->binlog_lock);