diff options
author | Nirbhay Choubey <nirbhay@mariadb.com> | 2016-05-31 20:37:00 -0400 |
---|---|---|
committer | Nirbhay Choubey <nirbhay@mariadb.com> | 2016-05-31 20:37:00 -0400 |
commit | de7eafc7ce1af2f61952f6d0efb41c408c2765c6 (patch) | |
tree | 830ac44a78c0670532b74be92f096d1f5c273d67 /sql/wsrep_sst.cc | |
parent | eb86c32225db2a76c6f256130e7bb316900a9408 (diff) | |
download | mariadb-git-de7eafc7ce1af2f61952f6d0efb41c408c2765c6.tar.gz |
MDEV-6368: assertion xid_seqno > trx_sys_cur_xid_seqno
- Validate the specified wsrep_start_position value by also
checking the return status of wsrep->sst_received. This also
ensures that changes in wsrep_start_position is not allowed
when the node is not in JOINING state.
- Do not allow decrease in seqno within same UUID.
- The initial checkpoint in SEs should be [0...:-1].
Diffstat (limited to 'sql/wsrep_sst.cc')
-rw-r--r-- | sql/wsrep_sst.cc | 104 |
1 files changed, 81 insertions, 23 deletions
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index 3ebbedaa04c..4fb162f9995 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -264,52 +264,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; - if (memcmp(&local_uuid, &uuid, sizeof(wsrep_uuid_t)) || - local_seqno < seqno || seqno < 0) + // 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) + { + 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 |