diff --git a/mittest/logservice/env/mock_election.cpp b/mittest/logservice/env/mock_election.cpp index 1fe53d20f..7bfd95ae6 100644 --- a/mittest/logservice/env/mock_election.cpp +++ b/mittest/logservice/env/mock_election.cpp @@ -53,6 +53,13 @@ int MockElection::init(const int64_t id, const common::ObAddr &self) return ret; } +int MockElection::can_set_memberlist(const palf::LogConfigVersion &new_config_version) const +{ + int ret = OB_SUCCESS; + UNUSED(new_config_version); + return ret; +} + int MockElection::set_memberlist(const MemberList &new_member_list) { int ret = OB_SUCCESS; diff --git a/mittest/logservice/env/mock_election.h b/mittest/logservice/env/mock_election.h index e3723bffe..1ed0af639 100644 --- a/mittest/logservice/env/mock_election.h +++ b/mittest/logservice/env/mock_election.h @@ -25,6 +25,7 @@ public: virtual ~MockElection() { } int init(const int64_t id, const common::ObAddr &self); void stop() override final; + int can_set_memberlist(const palf::LogConfigVersion &new_config_version) const override final; // 设置成员列表 int set_memberlist(const MemberList &new_member_list) override final; // 获取选举当前的角色 diff --git a/mittest/logservice/test_ob_simple_log_arb.cpp b/mittest/logservice/test_ob_simple_log_arb.cpp index a306ac5b9..b760693d5 100755 --- a/mittest/logservice/test_ob_simple_log_arb.cpp +++ b/mittest/logservice/test_ob_simple_log_arb.cpp @@ -799,6 +799,51 @@ TEST_F(TestObSimpleLogClusterArbService, test_1f1a_create_palf_group) PALF_LOG(INFO, "end test_2f1a_degrade_upgrade", K(id)); } +// 1. 2F1A +// 2. lock_memberlist(just renew barrier) +// 3. submit and commit logs +// 4. kill leader +// 5. check committed_end_lsn +TEST_F(TestObSimpleLogClusterArbService, test_lock_memberlist_opt) +{ + SET_CASE_LOG_FILE(TEST_NAME, "test_lock_memberlist_opt"); + int ret = OB_SUCCESS; + const int64_t id = ATOMIC_AAF(&palf_id_, 1); + PALF_LOG(INFO, "begin test_repeat_lock_memberlist", K(id)); + int64_t leader_idx = 0, arb_replica_idx = 0; + PalfHandleImplGuard leader; + oceanbase::common::ObClusterVersion::get_instance().cluster_version_ = CLUSTER_VERSION_4_2_0_0; + EXPECT_EQ(OB_SUCCESS, create_paxos_group_with_arb(id, arb_replica_idx, leader_idx, leader)); + const int64_t CONFIG_CHANGE_TIMEOUT = 10 * 1000 * 1000L; // 10s + const int64_t another_f_idx = (leader_idx+1)%3; + + EXPECT_EQ(OB_SUCCESS, submit_log(leader, 10, id)); + EXPECT_UNTIL_EQ(leader.palf_handle_impl_->get_max_lsn(), leader.palf_handle_impl_->get_end_lsn()); + + // 2. renew_barrier + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->config_mgr_.renew_config_change_barrier()); + + // 3. submit and commit logs + EXPECT_EQ(OB_SUCCESS, submit_log(leader, 10, id)); + const LSN max_lsn = leader.palf_handle_impl_->get_max_lsn(); + EXPECT_UNTIL_EQ(leader.palf_handle_impl_->get_max_lsn(), leader.palf_handle_impl_->get_end_lsn()); + + // 4. kill leader + block_all_net(leader_idx); + + // 5. check committed_end_lsn + int64_t new_leader_idx = -1; + PalfHandleImplGuard new_leader; + EXPECT_EQ(OB_SUCCESS, get_leader(id, new_leader, new_leader_idx)); + EXPECT_UNTIL_EQ(leader.palf_handle_impl_->get_max_lsn(), leader.palf_handle_impl_->get_end_lsn()); + EXPECT_EQ(max_lsn, leader.palf_handle_impl_->get_end_lsn()); + unblock_all_net(leader_idx); + + leader.reset(); + new_leader.reset(); + delete_paxos_group(id); + PALF_LOG(INFO, "end test_lock_memberlist_opt", K(id)); +} } // end unittest } // end oceanbase diff --git a/src/logservice/palf/election/algorithm/election_impl.cpp b/src/logservice/palf/election/algorithm/election_impl.cpp index b46585e28..5044fba98 100644 --- a/src/logservice/palf/election/algorithm/election_impl.cpp +++ b/src/logservice/palf/election/algorithm/election_impl.cpp @@ -154,6 +154,21 @@ void ElectionImpl::stop() #undef PRINT_WRAPPER } +int ElectionImpl::can_set_memberlist(const palf::LogConfigVersion &new_config_version) const +{ + ELECT_TIME_GUARD(500_ms); + #define PRINT_WRAPPER KR(ret), K(*this), K(new_config_version) + int ret = common::OB_SUCCESS; + CHECK_ELECTION_ARGS(new_config_version); + LockGuard lock_guard(lock_); + CHECK_ELECTION_INIT(); + if (CLICK_FAIL(proposer_.can_set_memberlist(new_config_version))) { + LOG_SET_MEMBER(WARN, "can_set_memberlist failed"); + } + return ret; + #undef PRINT_WRAPPER +} + int ElectionImpl::set_memberlist(const MemberList &new_memberlist) { ELECT_TIME_GUARD(500_ms); diff --git a/src/logservice/palf/election/algorithm/election_impl.h b/src/logservice/palf/election/algorithm/election_impl.h index 44054abc6..6c2e5b97e 100644 --- a/src/logservice/palf/election/algorithm/election_impl.h +++ b/src/logservice/palf/election/algorithm/election_impl.h @@ -67,6 +67,7 @@ public: const ObFunction &cb = DefaultRoleChangeCallBack()); int revoke(const RoleChangeReason &reason) override; virtual void stop() override final; + virtual int can_set_memberlist(const palf::LogConfigVersion &new_config_version) const override final; virtual int set_memberlist(const MemberList &new_memberlist) override final; virtual int change_leader_to(const common::ObAddr &dest_addr) override final; /** diff --git a/src/logservice/palf/election/algorithm/election_proposer.cpp b/src/logservice/palf/election/algorithm/election_proposer.cpp index c923aee0c..4d6a06307 100644 --- a/src/logservice/palf/election/algorithm/election_proposer.cpp +++ b/src/logservice/palf/election/algorithm/election_proposer.cpp @@ -98,15 +98,16 @@ int ElectionProposer::init(const int64_t restart_counter) #undef PRINT_WRAPPER } -int ElectionProposer::set_member_list(const MemberList &new_member_list) +int ElectionProposer::can_set_memberlist(const palf::LogConfigVersion &new_config_version) const { - ELECT_TIME_GUARD(500_ms); - #define PRINT_WRAPPER K(*this), K(new_member_list) + #define PRINT_WRAPPER K(*this), K(new_config_version) int ret = OB_SUCCESS; - // 检查旧的成员组的信息是否一致 const MemberList ¤t_member_list = memberlist_with_states_.get_member_list(); - if (current_member_list.is_valid()) { - if (new_member_list.get_membership_version() < current_member_list.get_membership_version()) { + if (false == new_config_version.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_SET_MEMBER(ERROR, "invalid config_version"); + } else if (current_member_list.is_valid()) { + if (new_config_version < current_member_list.get_membership_version()) { ret = OB_INVALID_ARGUMENT; LOG_SET_MEMBER(ERROR, "new memberlsit's membership version is not greater than current"); } else if (check_leader()) { @@ -116,7 +117,19 @@ int ElectionProposer::set_member_list(const MemberList &new_member_list) } } } - if (OB_SUCC(ret)) { + return ret; + #undef PRINT_WRAPPER +} + +int ElectionProposer::set_member_list(const MemberList &new_member_list) +{ + ELECT_TIME_GUARD(500_ms); + #define PRINT_WRAPPER K(*this), K(new_member_list) + int ret = OB_SUCCESS; + // 检查旧的成员组的信息是否一致 + if (OB_FAIL(can_set_memberlist(new_member_list.get_membership_version()))) { + LOG_SET_MEMBER(WARN, "can_set_memberlist failed"); + } else { MemberList old_list = memberlist_with_states_.get_member_list(); if (CLICK_FAIL(memberlist_with_states_.set_member_list(new_member_list))) { LOG_SET_MEMBER(WARN, "set new member list failed"); diff --git a/src/logservice/palf/election/algorithm/election_proposer.h b/src/logservice/palf/election/algorithm/election_proposer.h index ceb2bd65b..fd2be2aa1 100644 --- a/src/logservice/palf/election/algorithm/election_proposer.h +++ b/src/logservice/palf/election/algorithm/election_proposer.h @@ -49,6 +49,14 @@ class ElectionProposer public: ElectionProposer(ElectionImpl *election); int init(const int64_t restart_counter); + /** + * @description: whether the new config version can be set to the election module + * @param {LogConfigVersion} &new_config_version + * @return {int} OB_INVALID_ARGUMENT : invalid or too small config_version + OB_OP_NOT_ALLOWED : current config_version hasn't been synchronized to any majority + * @Date: 2021-12-23 11:33:50 + */ + int can_set_memberlist(const palf::LogConfigVersion &new_config_version) const; /** * @description: 为选举设置新的成员列表 * @param {MemberList} &new_member_list diff --git a/src/logservice/palf/election/interface/election.h b/src/logservice/palf/election/interface/election.h index 81cea8143..5d785e7a9 100644 --- a/src/logservice/palf/election/interface/election.h +++ b/src/logservice/palf/election/interface/election.h @@ -63,6 +63,7 @@ class Election public: virtual ~Election() {} virtual void stop() = 0; + virtual int can_set_memberlist(const palf::LogConfigVersion &new_config_version) const = 0; // 设置成员列表 virtual int set_memberlist(const MemberList &new_member_list) = 0; // 获取选举当前的角色 diff --git a/src/logservice/palf/log_config_mgr.cpp b/src/logservice/palf/log_config_mgr.cpp index 69cc3ced7..1da8786cf 100755 --- a/src/logservice/palf/log_config_mgr.cpp +++ b/src/logservice/palf/log_config_mgr.cpp @@ -878,9 +878,8 @@ int LogConfigMgr::change_config_(const LogConfigChangeArgs &args, } case (ConfigChangeState::CHANGING): { if (is_reach_majority_()) { - (void) state_mgr_->reset_changing_config_with_arb(); + (void) after_config_log_majority_(proposal_id, config_version); state_ = INIT; - (void) update_match_lsn_map_(running_args_, log_ms_meta_.curr_); ms_ack_list_.reset(); resend_config_version_ = log_ms_meta_.curr_.config_.config_version_; last_submit_config_log_time_us_ = OB_INVALID_TIMESTAMP; @@ -2061,9 +2060,11 @@ int LogConfigMgr::receive_config_log(const common::ObAddr &leader, const LogConf int LogConfigMgr::ack_config_log(const common::ObAddr &sender, const int64_t proposal_id, - const LogConfigVersion &config_version) + const LogConfigVersion &config_version, + bool &is_majority) { int ret = OB_SUCCESS; + is_majority = false; SpinLockGuard guard(lock_); const bool is_in_memberlist = alive_paxos_memberlist_.contains(sender); if (IS_NOT_INIT) { @@ -2084,14 +2085,45 @@ int LogConfigMgr::ack_config_log(const common::ObAddr &sender, } else { ret = OB_SUCCESS; // NB: can set majority repeatedly. - bool majority = is_reach_majority_(); + is_majority = is_reach_majority_(); PALF_LOG(INFO, "ack_config_log success", KR(ret), K_(palf_id), K_(self), K(config_version), K(sender), - K(majority), K_(ms_ack_list), K(alive_paxos_replica_num_)); + K(is_majority), K_(ms_ack_list), K(alive_paxos_replica_num_)); } } return ret; } +int LogConfigMgr::after_config_log_majority(const int64_t proposal_id, + const LogConfigVersion &config_version) +{ + int ret = OB_SUCCESS; + SpinLockGuard guard(lock_); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + PALF_LOG(WARN, "LogConfigMgr not init", KR(ret)); + } else { + ret = after_config_log_majority_(proposal_id, config_version); + } + return ret; +} + +// do not change LogConfigMgr::state_ +int LogConfigMgr::after_config_log_majority_(const int64_t proposal_id, + const LogConfigVersion &config_version) +{ + int ret = OB_SUCCESS; + if (proposal_id != log_ms_meta_.proposal_id_ || + config_version != log_ms_meta_.curr_.config_.config_version_) { + ret = OB_STATE_NOT_MATCH; + PALF_LOG(WARN, "config_version has been changed", KR(ret), K_(palf_id), + K_(self), K_(log_ms_meta), K(proposal_id), K_(state), K(config_version)); + } else if (is_reach_majority_()) { + (void) state_mgr_->reset_changing_config_with_arb(); + (void) update_match_lsn_map_(running_args_, log_ms_meta_.curr_); + } + return ret; +} + int LogConfigMgr::try_resend_config_log_(const int64_t proposal_id) { int ret = OB_SUCCESS; diff --git a/src/logservice/palf/log_config_mgr.h b/src/logservice/palf/log_config_mgr.h index a2cf66eae..b965b0683 100755 --- a/src/logservice/palf/log_config_mgr.h +++ b/src/logservice/palf/log_config_mgr.h @@ -180,6 +180,12 @@ inline bool is_may_change_replica_num(const LogConfigChangeType type) return is_add_member_list(type) || is_remove_member_list(type) || CHANGE_REPLICA_NUM == type || FORCE_SINGLE_MEMBER == type; } +inline bool is_must_not_change_replica_num(const LogConfigChangeType type) +{ + return ADD_LEARNER == type || REMOVE_LEARNER == type || REPLACE_LEARNERS == type || + TRY_LOCK_CONFIG_CHANGE == type || UNLOCK_CONFIG_CHANGE == type; +} + inline bool is_paxos_member_list_change(const LogConfigChangeType type) { return (ADD_MEMBER == type || REMOVE_MEMBER == type @@ -462,8 +468,11 @@ public: // for PalfHandleImpl::ack_config_log virtual int ack_config_log(const common::ObAddr &sender, - const int64_t proposal_id, - const LogConfigVersion &config_version); + const int64_t proposal_id, + const LogConfigVersion &config_version, + bool &is_majority); + virtual int after_config_log_majority(const int64_t proposal_id, + const LogConfigVersion &config_version); int wait_config_log_persistence(const LogConfigVersion &config_version) const; // broadcast leader info to global learners, only called in leader active virtual int submit_broadcast_leader_info(const int64_t proposal_id) const; @@ -596,6 +605,9 @@ private: int pre_sync_config_log_and_mode_meta_(const common::ObMember &server, const int64_t proposal_id, const bool is_arb_replica); + int after_config_log_majority_(const int64_t proposal_id, + const LogConfigVersion &config_version); + private: // inner_config_meta_ is protected by RWLock in PalfHandleImpl, // any read/write ops to inner_config_meta_ should acquire RLock/WLock in PalfHandleImpl. diff --git a/src/logservice/palf/palf_handle_impl.cpp b/src/logservice/palf/palf_handle_impl.cpp index 5a852bc36..d1e3f5e3d 100755 --- a/src/logservice/palf/palf_handle_impl.cpp +++ b/src/logservice/palf/palf_handle_impl.cpp @@ -1236,8 +1236,9 @@ int PalfHandleImpl::wait_log_barrier_(const LogConfigChangeArgs &args, TimeoutChecker ¬_timeout) { int ret = OB_SUCCESS; + bool has_renew_barrier = false; while (OB_SUCC(ret) && OB_SUCC(not_timeout())) { - bool need_wlock = (false == state_mgr_.is_changing_config_with_arb()); + bool need_wlock = !has_renew_barrier; bool need_rlock = !need_wlock; if (DEGRADE_ACCEPTOR_TO_LEARNER != args.type_ && true == ATOMIC_LOAD(&has_higher_prio_config_change_)) { @@ -1248,10 +1249,17 @@ int PalfHandleImpl::wait_log_barrier_(const LogConfigChangeArgs &args, } if (true == need_wlock) { WLockGuard guard(lock_); + // if the reconfiguration request do not change memberlist or replica_num, + // it's safe to commit logs after the reconfiguration barrier before the + // reconfiguration log is committed. + const bool do_not_change_quorum = is_must_not_change_replica_num(args.type_); if (OB_FAIL(config_mgr_.renew_config_change_barrier())) { PALF_LOG(WARN, "renew_config_change_barrier failed", KR(ret), KPC(this), K(args)); - } else if (OB_FAIL(state_mgr_.set_changing_config_with_arb())) { + } else if (false == do_not_change_quorum && + OB_FAIL(state_mgr_.set_changing_config_with_arb())) { PALF_LOG(WARN, "set_changing_config_with_arb failed", KR(ret), KPC(this), K(args)); + } else { + has_renew_barrier = true; } } else if (true == need_rlock) { RLockGuard guard(lock_); @@ -1259,11 +1267,13 @@ int PalfHandleImpl::wait_log_barrier_(const LogConfigChangeArgs &args, PALF_LOG(WARN, "wait_log_barrier_ failed", KR(ret), KPC(this), K(args)); } else if (OB_EAGAIN == ret) { ret = OB_SUCCESS; - ob_usleep(10 * 1000); } else { break; } } + if (OB_SUCC(ret) && true == need_rlock) { + ob_usleep(10 * 1000); + } } return ret; } @@ -1357,12 +1367,30 @@ int PalfHandleImpl::one_stage_config_change_(const LogConfigChangeArgs &args, } } time_guard.click("precheck"); - // step 3: waiting for log barrier if a arbitration member exists + // step 3: check whether the new config info can be set to the election module + while (OB_SUCCESS == ret && OB_SUCC(not_timeout())) { + { + RLockGuard guard(lock_); + LogConfigVersion config_version; + if (OB_FAIL(config_mgr_.get_config_version(config_version))) { + PALF_LOG(WARN, "get_config_version failed", KR(ret), KPC(this), K(config_version)); + } else if (OB_FAIL(config_version.inc_update_version(proposal_id))) { + PALF_LOG(WARN, "inc_update_version failed", KR(ret), KPC(this), K(config_version)); + } else if (OB_FAIL(election_.can_set_memberlist(config_version))) { + ret = (OB_OP_NOT_ALLOW == ret)? OB_SUCCESS: ret; + } else { + break; + } + } + ob_usleep(50 * 1000); + } + time_guard.click("wait_ele"); + // step 4: waiting for log barrier if a arbitration member exists if (OB_SUCC(ret) && true == new_config_info.config_.arbitration_member_.is_valid()) { ret = wait_log_barrier_(args, new_config_info, not_timeout); } time_guard.click("wait_barrier"); - // step 4: motivate reconfiguration + // step 5: motivate reconfiguration while (OB_SUCCESS == ret && OB_SUCC(not_timeout())) { bool need_wlock = false; bool need_rlock = false; @@ -1387,7 +1415,7 @@ int PalfHandleImpl::one_stage_config_change_(const LogConfigChangeArgs &args, break; } if (false == need_rlock && false == need_wlock) { - const int64_t SLEEP_US = (state_mgr_.is_changing_config_with_arb())? 10 * 1000: 50 * 1000; + const int64_t SLEEP_US = (state_mgr_.is_changing_config_with_arb())? 1 * 1000: 50 * 1000; ob_usleep(SLEEP_US); } if (true == need_wlock) { @@ -4050,22 +4078,29 @@ int PalfHandleImpl::ack_config_log(const common::ObAddr &server, const LogConfigVersion &config_version) { int ret = OB_SUCCESS; - RLockGuard guard(lock_); - const int64_t &curr_proposal_id = state_mgr_.get_proposal_id(); - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - PALF_LOG(WARN, "PalfHandleImpl not init", KR(ret)); - } else if (msg_proposal_id != curr_proposal_id) { - PALF_LOG(WARN, "proposal_id does not match", KR(ret), KPC(this), K(msg_proposal_id), - K(server), K(curr_proposal_id)); - } else if (self_ != state_mgr_.get_leader()) { - ret = OB_STATE_NOT_MATCH; - PALF_LOG(WARN, "self is not leader, state not match", KR(ret), KPC(this), - K(server), K(msg_proposal_id), K(curr_proposal_id)); - } else if (OB_FAIL(config_mgr_.ack_config_log(server, msg_proposal_id, config_version))) { - PALF_LOG(WARN, "ObLogConfigMgr ack_config_log failed", KR(ret), KPC(this), K(server), K(msg_proposal_id), K(config_version)); - } else { - PALF_LOG(INFO, "ack_config_log success", KR(ret), KPC(this), K(server), K(msg_proposal_id), K(config_version)); + bool is_majority = false; + do { + RLockGuard guard(lock_); + const int64_t &curr_proposal_id = state_mgr_.get_proposal_id(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + PALF_LOG(WARN, "PalfHandleImpl not init", KR(ret)); + } else if (msg_proposal_id != curr_proposal_id) { + PALF_LOG(WARN, "proposal_id does not match", KR(ret), KPC(this), K(msg_proposal_id), + K(server), K(curr_proposal_id)); + } else if (self_ != state_mgr_.get_leader()) { + ret = OB_STATE_NOT_MATCH; + PALF_LOG(WARN, "self is not leader, state not match", KR(ret), KPC(this), + K(server), K(msg_proposal_id), K(curr_proposal_id)); + } else if (OB_FAIL(config_mgr_.ack_config_log(server, msg_proposal_id, config_version, is_majority))) { + PALF_LOG(WARN, "ObLogConfigMgr ack_config_log failed", KR(ret), KPC(this), K(server), K(msg_proposal_id), K(config_version)); + } else { + PALF_LOG(INFO, "ack_config_log success", KR(ret), KPC(this), K(server), K(msg_proposal_id), K(config_version)); + } + } while (0); + if (is_majority) { + WLockGuard guard(lock_); + (void) config_mgr_.after_config_log_majority(msg_proposal_id, config_version); } return ret; } @@ -4215,7 +4250,8 @@ int PalfHandleImpl::after_flush_config_change_meta_(const int64_t proposal_id, c PALF_LOG(WARN, "LogConfigMgr after_flush_config_log failed", K(ret), KPC(this), K(proposal_id), K(config_version)); } else if (self_ == leader) { - if (OB_FAIL(config_mgr_.ack_config_log(self_, proposal_id, config_version))) { + bool unused_bool = false; + if (OB_FAIL(config_mgr_.ack_config_log(self_, proposal_id, config_version, unused_bool))) { PALF_LOG(WARN, "ack_config_log failed", K(ret), KPC(this), K(config_version)); } } else if (false == leader.is_valid()) { diff --git a/unittest/logservice/mock_logservice_container/mock_election.h b/unittest/logservice/mock_logservice_container/mock_election.h index aeacd0548..1e4467c1e 100644 --- a/unittest/logservice/mock_logservice_container/mock_election.h +++ b/unittest/logservice/mock_logservice_container/mock_election.h @@ -36,6 +36,12 @@ public: } void stop() override final {} + int can_set_memberlist(const palf::LogConfigVersion &new_config_version) const override final + { + int ret = OB_SUCCESS; + UNUSED(new_config_version); + return ret; + } // 设置成员列表 int set_memberlist(const MemberList &new_member_list) override final { diff --git a/unittest/logservice/test_log_config_mgr.cpp b/unittest/logservice/test_log_config_mgr.cpp index fbce151fd..d9e32f966 100755 --- a/unittest/logservice/test_log_config_mgr.cpp +++ b/unittest/logservice/test_log_config_mgr.cpp @@ -1371,19 +1371,20 @@ TEST_F(TestLogConfigMgr, test_submit_start_working_log) EXPECT_EQ(OB_EAGAIN, cm.confirm_start_working_log(INIT_PROPOSAL_ID, INIT_ELE_EPOCH, sw_config_version)); EXPECT_GT(cm.last_submit_config_log_time_us_, 0); // ack defensive code - EXPECT_EQ(OB_STATE_NOT_MATCH, cm.ack_config_log(addr2, 2, expect_config_version)); - EXPECT_EQ(OB_STATE_NOT_MATCH, cm.ack_config_log(addr2, 1, LogConfigVersion())); + bool unused_bool = false; + EXPECT_EQ(OB_STATE_NOT_MATCH, cm.ack_config_log(addr2, 2, expect_config_version, unused_bool)); + EXPECT_EQ(OB_STATE_NOT_MATCH, cm.ack_config_log(addr2, 1, LogConfigVersion(), unused_bool)); // receive ack from learner - EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr4, 1, expect_config_version)); + EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr4, 1, expect_config_version, unused_bool)); EXPECT_EQ(0, cm.ms_ack_list_.get_count()); EXPECT_EQ(2, cm.resend_log_list_.get_member_number()); EXPECT_EQ(OB_EAGAIN, cm.confirm_start_working_log(INIT_PROPOSAL_ID, INIT_ELE_EPOCH, sw_config_version)); // receive ack from member - EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr1, 1, expect_config_version)); + EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr1, 1, expect_config_version, unused_bool)); EXPECT_EQ(1, cm.ms_ack_list_.get_count()); EXPECT_EQ(2, cm.resend_log_list_.get_member_number()); EXPECT_EQ(OB_EAGAIN, cm.confirm_start_working_log(INIT_PROPOSAL_ID, INIT_ELE_EPOCH, sw_config_version)); - EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr2, 1, expect_config_version)); + EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr2, 1, expect_config_version, unused_bool)); EXPECT_EQ(2, cm.ms_ack_list_.get_count()); EXPECT_EQ(1, cm.resend_log_list_.get_member_number()); // check if config log is committed @@ -1396,7 +1397,7 @@ TEST_F(TestLogConfigMgr, test_submit_start_working_log) cm.last_submit_config_log_time_us_ = 0; EXPECT_EQ(OB_SUCCESS, cm.try_resend_config_log_(1)); // receive ack from last member - EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr3, 1, expect_config_version)); + EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr3, 1, expect_config_version, unused_bool)); EXPECT_EQ(0, cm.ms_ack_list_.get_count()); EXPECT_EQ(0, cm.resend_log_list_.get_member_number()); } @@ -1618,13 +1619,14 @@ TEST_F(TestLogConfigMgr, test_degrade_upgrade_scenario) // member_list will not take effect after append_config_meta_ EXPECT_FALSE(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(addr2)); // self ack config log - EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr1, cm.log_ms_meta_.proposal_id_, cm.log_ms_meta_.curr_.config_.config_version_)); + bool unused_bool = false; + EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr1, cm.log_ms_meta_.proposal_id_, cm.log_ms_meta_.curr_.config_.config_version_, unused_bool)); // reach majority - 1 EXPECT_EQ(OB_EAGAIN, cm.change_config(args, INIT_PROPOSAL_ID, INIT_ELE_EPOCH, de_config_version)); EXPECT_EQ(1, cm.state_); EXPECT_FALSE(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(addr2)); // ack config log - EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr3, cm.log_ms_meta_.proposal_id_, cm.log_ms_meta_.curr_.config_.config_version_)); + EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr3, cm.log_ms_meta_.proposal_id_, cm.log_ms_meta_.curr_.config_.config_version_, unused_bool)); // degrade success, switch to INIT state EXPECT_EQ(OB_SUCCESS, cm.change_config(args, INIT_PROPOSAL_ID, INIT_ELE_EPOCH, de_config_version)); EXPECT_EQ(0, cm.state_); @@ -1638,13 +1640,13 @@ TEST_F(TestLogConfigMgr, test_degrade_upgrade_scenario) // member_list will not take effect after append_config_meta_ EXPECT_TRUE(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(addr2)); // self ack config log - EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr1, cm.log_ms_meta_.proposal_id_, cm.log_ms_meta_.curr_.config_.config_version_)); + EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr1, cm.log_ms_meta_.proposal_id_, cm.log_ms_meta_.curr_.config_.config_version_, unused_bool)); // reach majority - 1 EXPECT_EQ(OB_EAGAIN, cm.change_config(up_args, INIT_PROPOSAL_ID, INIT_ELE_EPOCH, up_config_version)); EXPECT_TRUE(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(addr2)); EXPECT_EQ(1, cm.state_); // ack config log - EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr3, cm.log_ms_meta_.proposal_id_, cm.log_ms_meta_.curr_.config_.config_version_)); + EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr3, cm.log_ms_meta_.proposal_id_, cm.log_ms_meta_.curr_.config_.config_version_, unused_bool)); // degrade success, switch to INIT state EXPECT_EQ(OB_SUCCESS, cm.change_config(args, INIT_PROPOSAL_ID, INIT_ELE_EPOCH, up_config_version)); EXPECT_EQ(0, cm.state_);