diff --git a/server/modules/routing/binlogrouter/blr.c b/server/modules/routing/binlogrouter/blr.c index 2e581d1c0..fce007d14 100644 --- a/server/modules/routing/binlogrouter/blr.c +++ b/server/modules/routing/binlogrouter/blr.c @@ -124,6 +124,8 @@ static void stats_func(void *); static bool rses_begin_locked_router_action(ROUTER_SLAVE *); static void rses_end_locked_router_action(ROUTER_SLAVE *); GWBUF *blr_cache_read_response(ROUTER_INSTANCE *router, char *response); +/* Set checksum value in router instance from a master reply or saved buffer */ +extern void blr_set_checksum(ROUTER_INSTANCE *instance, GWBUF *buf); static SPINLOCK instlock; static ROUTER_INSTANCE *instances; @@ -828,6 +830,18 @@ createInstance(SERVICE *service, char **options) /* Read any cached response messages */ blr_cache_read_master_data(inst); + /** + * The value of master checksum is known only at registration time, so + * as soon as replication succeds the value is updated. + * Set now the binlog checksum from the saved value. + * This is very useful in case of possible failure in the + * registration phase for any reason: master is down, wrong password etc. + * In this case a connecting slave will get the checksum value + * from previous registration instead of default one (CRC32) + * which can be wrong if slave has binlog_checksum = NONE. + */ + blr_set_checksum(inst, inst->saved_master.chksum2); + /* Find latest binlog file or create a new one (000001) */ if (blr_file_init(inst) == 0) { diff --git a/server/modules/routing/binlogrouter/blr_master.c b/server/modules/routing/binlogrouter/blr_master.c index c2e8234f8..ae0d1c352 100644 --- a/server/modules/routing/binlogrouter/blr_master.c +++ b/server/modules/routing/binlogrouter/blr_master.c @@ -513,16 +513,9 @@ blr_master_response(ROUTER_INSTANCE *router, GWBUF *buf) break; case BLRM_CHKSUM2: { - char *val = blr_extract_column(buf, 1); + // Set checksum from master reply + blr_set_checksum(router, buf); - if (val && strncasecmp(val, "NONE", 4) == 0) - { - router->master_chksum = false; - } - if (val) - { - MXS_FREE(val); - } // Response to the master_binlog_checksum, should be stored if (router->saved_master.chksum2) { @@ -2619,3 +2612,25 @@ void blr_notify_all_slaves(ROUTER_INSTANCE *router) MXS_DEBUG("Notified %d slaves about new data.", notified); } } + +/** + * Set checksum value in router instance + * + * @param inst The router instance + * @param buf The buffer with checksum value + */ +void blr_set_checksum(ROUTER_INSTANCE *inst, GWBUF *buf) +{ + if (buf) + { + char *val = blr_extract_column(buf, 1); + if (val && strncasecmp(val, "NONE", 4) == 0) + { + inst->master_chksum = false; + } + if (val) + { + MXS_FREE(val); + } + } +}