Changed from router->binlog_lock to router->lock for transaction safety code and cleaned up code.

This commit is contained in:
Markus Makela
2015-10-23 14:54:08 +03:00
parent 40ffe21dd8
commit 63f4bc3aec
5 changed files with 121 additions and 115 deletions

View File

@ -34,6 +34,7 @@
* 23/06/15 Massimiliano Pinto Addition of MASTER_SERVER_CFG struct * 23/06/15 Massimiliano Pinto Addition of MASTER_SERVER_CFG struct
* 24/06/15 Massimiliano Pinto Added BLRM_UNCONFIGURED state * 24/06/15 Massimiliano Pinto Added BLRM_UNCONFIGURED state
* 05/08/15 Massimiliano Pinto Initial implementation of transaction safety * 05/08/15 Massimiliano Pinto Initial implementation of transaction safety
* 23/10/15 Markus Makela Added current_safe_event
* *
* @endverbatim * @endverbatim
*/ */

View File

@ -47,6 +47,7 @@
* saved master responses * saved master responses
* 23/08/2015 Massimiliano Pinto Added strerror_r * 23/08/2015 Massimiliano Pinto Added strerror_r
* 30/09/2015 Massimiliano Pinto Addition of send_slave_heartbeat option * 30/09/2015 Massimiliano Pinto Addition of send_slave_heartbeat option
* 23/10/2015 Markus Makela Added current_safe_event
* *
* @endverbatim * @endverbatim
*/ */

View File

@ -37,6 +37,7 @@
* This is the current supported condition for detecting * This is the current supported condition for detecting
* MariaDB 10 transaction start point. * MariaDB 10 transaction start point.
* It's no longer using QUERY_EVENT with BEGIN * It's no longer using QUERY_EVENT with BEGIN
* 23/10/15 Markus Makela Added current_safe_event
* *
* @endverbatim * @endverbatim
*/ */

View File

@ -47,6 +47,7 @@
* MariaDB 10 transaction start point. * MariaDB 10 transaction start point.
* It's no longer using QUERY_EVENT with BEGIN * It's no longer using QUERY_EVENT with BEGIN
* 25/09/2015 Massimiliano Pinto Addition of lastEventReceived for slaves * 25/09/2015 Massimiliano Pinto Addition of lastEventReceived for slaves
* 23/10/15 Markus Makela Added current_safe_event
* *
* @endverbatim * @endverbatim
*/ */
@ -1061,12 +1062,12 @@ int n_bufs = -1, pn_bufs = -1;
if (router->trx_safe == 0 || (router->trx_safe && router->pending_transaction == 0)) { if (router->trx_safe == 0 || (router->trx_safe && router->pending_transaction == 0)) {
/* no pending transaction: set current_pos to binlog_position */ /* no pending transaction: set current_pos to binlog_position */
spinlock_acquire(&router->binlog_lock); spinlock_acquire(&router->lock);
router->binlog_position = router->current_pos; router->binlog_position = router->current_pos;
router->current_safe_event = router->current_pos; router->current_safe_event = router->current_pos;
spinlock_release(&router->binlog_lock); spinlock_release(&router->lock);
} }
/** /**
@ -1281,12 +1282,12 @@ int n_bufs = -1, pn_bufs = -1;
*/ */
if (router->trx_safe == 0 || (router->trx_safe && router->pending_transaction == 0)) { if (router->trx_safe == 0 || (router->trx_safe && router->pending_transaction == 0)) {
spinlock_acquire(&router->binlog_lock); spinlock_acquire(&router->lock);
router->binlog_position = router->current_pos; router->binlog_position = router->current_pos;
router->current_safe_event = router->current_pos; router->current_safe_event = router->current_pos;
spinlock_release(&router->binlog_lock); spinlock_release(&router->lock);
/* Now distribute events */ /* Now distribute events */
blr_distribute_binlog_record(router, &hdr, ptr); blr_distribute_binlog_record(router, &hdr, ptr);
@ -1311,11 +1312,11 @@ int n_bufs = -1, pn_bufs = -1;
REP_HEADER new_hdr; REP_HEADER new_hdr;
int i=0; int i=0;
spinlock_acquire(&router->binlog_lock); spinlock_acquire(&router->lock);
pos = router->binlog_position; pos = router->binlog_position;
spinlock_release(&router->binlog_lock); spinlock_release(&router->lock);
while ((record = blr_read_events_from_pos(router, pos, &new_hdr)) != NULL) { while ((record = blr_read_events_from_pos(router, pos, &new_hdr)) != NULL) {
@ -1325,7 +1326,7 @@ int n_bufs = -1, pn_bufs = -1;
/* distribute event */ /* distribute event */
blr_distribute_binlog_record(router, &new_hdr, raw_data); blr_distribute_binlog_record(router, &new_hdr, raw_data);
spinlock_acquire(&router->binlog_lock); spinlock_acquire(&router->lock);
/** The current safe position is only updated /** The current safe position is only updated
* if it points to the event we just distributed. */ * if it points to the event we just distributed. */
@ -1336,7 +1337,7 @@ int n_bufs = -1, pn_bufs = -1;
pos = new_hdr.next_pos; pos = new_hdr.next_pos;
spinlock_release(&router->binlog_lock); spinlock_release(&router->lock);
gwbuf_free(record); gwbuf_free(record);
} }
@ -1590,6 +1591,14 @@ MYSQL_session *auth_info;
return auth_info; return auth_info;
} }
/** Actions that can be taken when an event is being distributed to the slaves*/
typedef enum
{
SLAVE_SEND_EVENT, /*< Send the event to the slave */
SLAVE_FORCE_CATCHUP, /*< Force the slave into catchup mode */
SLAVE_EVENT_ALREADY_SENT /*< The slave already has the event, don't send it */
} slave_event_action_t;
/** /**
* Distribute the binlog record we have just received to all the registered slaves. * Distribute the binlog record we have just received to all the registered slaves.
* *
@ -1605,10 +1614,6 @@ uint8_t *buf;
ROUTER_SLAVE *slave, *nextslave; ROUTER_SLAVE *slave, *nextslave;
int action; int action;
spinlock_acquire(&router->binlog_lock);
uint64_t current_safe_event = router->current_safe_event;
spinlock_release(&router->binlog_lock);
spinlock_acquire(&router->lock); spinlock_acquire(&router->lock);
slave = router->slaves; slave = router->slaves;
while (slave) while (slave)
@ -1647,13 +1652,11 @@ int action;
slave->stats.n_actions[action-1]++; slave->stats.n_actions[action-1]++;
spinlock_release(&slave->catch_lock); spinlock_release(&slave->catch_lock);
bool sendevent = false;
bool forcecatchup = false;
bool alreadysent = false;
if (action == 1) if (action == 1)
{ {
if(router->trx_safe && slave->binlog_pos == current_safe_event && slave_event_action_t slave_action = SLAVE_FORCE_CATCHUP;
if(router->trx_safe && slave->binlog_pos == router->current_safe_event &&
(strcmp(slave->binlogfile, router->binlog_name) == 0 || (strcmp(slave->binlogfile, router->binlog_name) == 0 ||
(hdr->event_type == ROTATE_EVENT && (hdr->event_type == ROTATE_EVENT &&
strcmp(slave->binlogfile, router->prevbinlog)))) strcmp(slave->binlogfile, router->prevbinlog))))
@ -1661,7 +1664,7 @@ int action;
/** /**
* Slave needs the current event being distributed * Slave needs the current event being distributed
*/ */
sendevent = true; slave_action = SLAVE_SEND_EVENT;
} }
else if (slave->binlog_pos == router->last_written && else if (slave->binlog_pos == router->last_written &&
(strcmp(slave->binlogfile, router->binlog_name) == 0 || (strcmp(slave->binlogfile, router->binlog_name) == 0 ||
@ -1672,7 +1675,7 @@ int action;
* Transaction safety is off or there are no pending transactions * Transaction safety is off or there are no pending transactions
*/ */
sendevent = true; slave_action = SLAVE_SEND_EVENT;
} }
else if (slave->binlog_pos == hdr->next_pos else if (slave->binlog_pos == hdr->next_pos
&& strcmp(slave->binlogfile, router->binlog_name) == 0) && strcmp(slave->binlogfile, router->binlog_name) == 0)
@ -1681,7 +1684,7 @@ int action;
* Slave has already read record from file, no * Slave has already read record from file, no
* need to distrbute this event * need to distrbute this event
*/ */
alreadysent = true; 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) && strcmp(slave->binlogfile, router->binlog_name) == 0)
@ -1697,19 +1700,17 @@ int action;
slave->serverid, slave->binlogfile, slave->serverid, slave->binlogfile,
(unsigned long)slave->binlog_pos, (unsigned long)slave->binlog_pos,
hdr->next_pos - hdr->event_size))); hdr->next_pos - hdr->event_size)));
forcecatchup = true;
}
else
{
/*
* The slave is not at the position it should be. Force it into
* catchup mode rather than send this event.
*/
forcecatchup = true;
} }
if(sendevent) /*
* If slave_action is SLAVE_FORCE_CATCHUP then
* the slave is not at the position it should be. Force it into
* catchup mode rather than send this event.
*/
switch(slave_action)
{ {
case SLAVE_SEND_EVENT:
/* /*
* The slave should be up to date, check that the binlog * The slave should be up to date, check that the binlog
* position matches the event we have to distribute or * position matches the event we have to distribute or
@ -1753,20 +1754,21 @@ int action;
slave->cstate &= ~CS_BUSY; slave->cstate &= ~CS_BUSY;
} }
spinlock_release(&slave->catch_lock); spinlock_release(&slave->catch_lock);
} break;
else if (alreadysent)
{ case SLAVE_EVENT_ALREADY_SENT:
spinlock_acquire(&slave->catch_lock); spinlock_acquire(&slave->catch_lock);
slave->cstate &= ~CS_BUSY; slave->cstate &= ~CS_BUSY;
spinlock_release(&slave->catch_lock); spinlock_release(&slave->catch_lock);
} break;
else if (forcecatchup)
{ case SLAVE_FORCE_CATCHUP:
spinlock_acquire(&slave->catch_lock); spinlock_acquire(&slave->catch_lock);
slave->cstate &= ~(CS_UPTODATE|CS_BUSY); slave->cstate &= ~(CS_UPTODATE|CS_BUSY);
slave->cstate |= CS_EXPECTCB; slave->cstate |= CS_EXPECTCB;
spinlock_release(&slave->catch_lock); spinlock_release(&slave->catch_lock);
poll_fake_write_event(slave->dcb); poll_fake_write_event(slave->dcb);
break;
} }
} }
else if (action == 3) else if (action == 3)

View File

@ -58,6 +58,7 @@
* 25/09/2015 Massimiliano Pinto Addition of slave heartbeat: * 25/09/2015 Massimiliano Pinto Addition of slave heartbeat:
* the period set during registration is checked * the period set during registration is checked
* and heartbeat event might be sent to the affected slave. * and heartbeat event might be sent to the affected slave.
* 23/10/15 Markus Makela Added current_safe_event
* *
* @endverbatim * @endverbatim
*/ */