diff options
Diffstat (limited to 'sql/wsrep_sst.cc')
-rw-r--r-- | sql/wsrep_sst.cc | 116 |
1 files changed, 84 insertions, 32 deletions
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index 3ebbedaa04c..ba6bb18bf37 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -34,14 +34,8 @@ char wsrep_defaults_file[FN_REFLEN * 2 + 10 + sizeof(WSREP_SST_OPT_CONF) + sizeof(WSREP_SST_OPT_EXTRA_CONF)] = {0}; -const char* wsrep_sst_method = WSREP_SST_DEFAULT; -const char* wsrep_sst_receive_address = WSREP_SST_ADDRESS_AUTO; -const char* wsrep_sst_donor = ""; - char* wsrep_sst_auth = NULL; - // container for real auth string static const char* sst_auth_real = NULL; -my_bool wsrep_sst_donor_rejects_queries = FALSE; bool wsrep_sst_method_check (sys_var *self, THD* thd, set_var* var) { @@ -175,10 +169,9 @@ bool wsrep_sst_auth_update (sys_var *self, THD* thd, enum_var_type type) return sst_auth_real_set (wsrep_sst_auth); } -void wsrep_sst_auth_init (const char* value) +void wsrep_sst_auth_init () { - if (wsrep_sst_auth == value) wsrep_sst_auth = NULL; - if (value) sst_auth_real_set (value); + sst_auth_real_set(wsrep_sst_auth); } bool wsrep_sst_donor_check (sys_var *self, THD* thd, set_var* var) @@ -264,52 +257,110 @@ void wsrep_sst_complete (const wsrep_uuid_t* sst_uuid, mysql_mutex_unlock (&LOCK_wsrep_sst); } -void wsrep_sst_received (wsrep_t* const wsrep, +/* + If wsrep provider is loaded, inform that the new state snapshot + has been received. Also update the local checkpoint. + + @param wsrep [IN] wsrep handle + @param uuid [IN] Initial state UUID + @param seqno [IN] Initial state sequence number + @param state [IN] Always NULL, also ignored by wsrep provider (?) + @param state_len [IN] Always 0, also ignored by wsrep provider (?) + @param implicit [IN] Whether invoked implicitly due to SST + (true) or explicitly because if change + in wsrep_start_position by user (false). + @return false Success + true Error + +*/ +bool wsrep_sst_received (wsrep_t* const wsrep, const wsrep_uuid_t& uuid, - wsrep_seqno_t const seqno, + const wsrep_seqno_t seqno, const void* const state, - size_t const state_len) + const size_t state_len, + const bool implicit) { - wsrep_get_SE_checkpoint(local_uuid, local_seqno); + /* + To keep track of whether the local uuid:seqno should be updated. Also, note + that local state (uuid:seqno) is updated/checkpointed only after we get an + OK from wsrep provider. By doing so, the values remain consistent across + the server & wsrep provider. + */ + bool do_update= false; + + // Get the locally stored uuid:seqno. + if (wsrep_get_SE_checkpoint(local_uuid, local_seqno)) + { + return true; + } - if (memcmp(&local_uuid, &uuid, sizeof(wsrep_uuid_t)) || - local_seqno < seqno || seqno < 0) + if (memcmp(&local_uuid, &uuid, sizeof(wsrep_uuid_t)) || + local_seqno < seqno) + { + do_update= true; + } + else if (local_seqno > seqno) + { + WSREP_WARN("SST position can't be set in past. Requested: %lld, Current: " + " %lld.", (long long)seqno, (long long)local_seqno); + /* + If we are here because of SET command, simply return true (error) instead of + aborting. + */ + if (implicit) { - wsrep_set_SE_checkpoint(uuid, seqno); - local_uuid = uuid; - local_seqno = seqno; + WSREP_WARN("Can't continue."); + unireg_abort(1); } - else if (local_seqno > seqno) + else { - WSREP_WARN("SST postion is in the past: %lld, current: %lld. " - "Can't continue.", - (long long)seqno, (long long)local_seqno); - unireg_abort(1); + return true; } + } #ifdef GTID_SUPPORT - wsrep_init_sidno(uuid); + wsrep_init_sidno(uuid); #endif /* GTID_SUPPORT */ - if (wsrep) + if (wsrep) + { + int const rcode(seqno < 0 ? seqno : 0); + wsrep_gtid_t const state_id= {uuid, + (rcode ? WSREP_SEQNO_UNDEFINED : seqno)}; + + wsrep_status_t ret= wsrep->sst_received(wsrep, &state_id, state, + state_len, rcode); + + if (ret != WSREP_OK) { - int const rcode(seqno < 0 ? seqno : 0); - wsrep_gtid_t const state_id = { - uuid, (rcode ? WSREP_SEQNO_UNDEFINED : seqno) - }; + return true; + } + } - wsrep->sst_received(wsrep, &state_id, state, state_len, rcode); + // Now is the good time to update the local state and checkpoint. + if (do_update) + { + if (wsrep_set_SE_checkpoint(uuid, seqno)) + { + return true; } + + local_uuid= uuid; + local_seqno= seqno; + } + + return false; } // Let applier threads to continue -void wsrep_sst_continue () +bool wsrep_sst_continue () { if (sst_needed) { WSREP_INFO("Signalling provider to continue."); - wsrep_sst_received (wsrep, local_uuid, local_seqno, NULL, 0); + return wsrep_sst_received (wsrep, local_uuid, local_seqno, NULL, 0, true); } + return false; } struct sst_thread_arg @@ -340,6 +391,7 @@ static int sst_scan_uuid_seqno (const char* str, wsrep_uuid_t* uuid, wsrep_seqno_t* seqno) { int offt = wsrep_uuid_scan (str, strlen(str), uuid); + errno= 0; /* Reset the errno */ if (offt > 0 && strlen(str) > (unsigned int)offt && ':' == str[offt]) { *seqno = strtoll (str + offt + 1, NULL, 10); |