oceanbase
1151 строка · 64.1 Кб
1/**
2* Copyright (c) 2021 OceanBase
3* OceanBase CE is licensed under Mulan PubL v2.
4* You can use this software according to the terms and conditions of the Mulan PubL v2.
5* You may obtain a copy of Mulan PubL v2 at:
6* http://license.coscl.org.cn/MulanPubL-2.0
7* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10* See the Mulan PubL v2 for more details.
11*/
12
13#include <cstdio>
14#include <gtest/gtest.h>
15#include <signal.h>
16#include <share/scn.h>
17#define private public
18#include "logservice/palf/log_config_mgr.h"
19#include "env/ob_simple_log_cluster_env.h"
20#undef private
21
22const std::string TEST_NAME = "config_change";
23
24using namespace oceanbase::common;
25using namespace oceanbase;
26namespace oceanbase
27{
28using namespace logservice;
29namespace unittest
30{
31class TestObSimpleLogClusterConfigChange : public ObSimpleLogClusterTestEnv
32{
33public:
34TestObSimpleLogClusterConfigChange() : ObSimpleLogClusterTestEnv()
35{}
36};
37
38int64_t ObSimpleLogClusterTestBase::member_cnt_ = 3;
39int64_t ObSimpleLogClusterTestBase::node_cnt_ = 7;
40std::string ObSimpleLogClusterTestBase::test_name_ = TEST_NAME;
41bool ObSimpleLogClusterTestBase::need_add_arb_server_ = false;
42
43bool check_children_valid(const std::vector<PalfHandleImplGuard*> &palf_list, const LogLearnerList &all_learner)
44{
45int ret = OB_SUCCESS;
46LogLearnerList all_children;
47for (auto palf : palf_list) {
48const LogLearnerList &self_children = palf->palf_handle_impl_->config_mgr_.children_;
49int64_t children_cnt = self_children.get_member_number();
50for (int i = 0; i < children_cnt; ++i) {
51LogLearner tmp_server;
52if (OB_FAIL(self_children.get_learner(i, tmp_server))) {
53} else if (OB_FAIL(all_children.add_learner(tmp_server))) {
54}
55}
56}
57bool bool_ret = all_children.learner_addr_equal(all_learner);
58PALF_LOG(INFO, "check_children", K(ret), K(all_children), K(all_learner));
59return bool_ret;
60}
61
62bool check_parent(const std::vector<PalfHandleImplGuard*> &palf_list, const LogLearnerList &all_learner, const ObAddr &parent)
63{
64bool bool_ret = true;
65for (auto palf : palf_list) {
66const ObAddr &self = palf->palf_handle_impl_->self_;
67if (all_learner.contains(self)) {
68const ObAddr &my_parent = palf->palf_handle_impl_->config_mgr_.parent_;
69if (my_parent.is_valid() && (my_parent == parent)) {
70continue;
71} else {
72bool_ret = false;
73break;
74}
75}
76}
77return bool_ret;
78}
79
80int check_log_sync(const std::vector<PalfHandleImplGuard*> &palf_list,
81const common::ObMemberList &member_list,
82const LogLearnerList &learner_list,
83PalfHandleImplGuard &leader)
84{
85int ret = OB_SUCCESS;
86const int64_t max_flushed_proposal_id = leader.palf_handle_impl_->sw_.max_flushed_log_pid_;
87const LSN max_flushed_end_lsn = leader.palf_handle_impl_->sw_.max_flushed_end_lsn_;
88PALF_LOG(INFO, "before check_log_sync", K(max_flushed_proposal_id), K(max_flushed_end_lsn));
89for (auto palf : palf_list) {
90const common::ObAddr parent_addr = palf->palf_handle_impl_->config_mgr_.parent_;
91// for paxos member, log must sync with leader
92// for learner, sync with parent's committed_end_lsn
93const int64_t this_max_flushed_proposal_id = palf->palf_handle_impl_->sw_.max_flushed_log_pid_;
94const LSN this_max_flushed_end_lsn = palf->palf_handle_impl_->sw_.max_flushed_end_lsn_;
95const common::ObAddr self = palf->palf_handle_impl_->self_;
96if (member_list.contains(self)) {
97PALF_LOG(INFO, "before check", K(max_flushed_proposal_id), K(max_flushed_end_lsn), K(this_max_flushed_proposal_id),
98K(this_max_flushed_end_lsn), K(self));
99EXPECT_EQ(max_flushed_proposal_id, this_max_flushed_proposal_id);
100EXPECT_EQ(max_flushed_end_lsn, this_max_flushed_end_lsn) \
101<< max_flushed_end_lsn.val_ << "," << this_max_flushed_end_lsn.val_;
102} else if (!learner_list.contains(self)) {
103} else if (!parent_addr.is_valid()) {
104ret = OB_ERR_UNEXPECTED;
105break;
106} else {
107for (auto parent: palf_list) {
108if (parent->palf_handle_impl_->self_ == parent_addr) {
109const LSN parent_committed_end_lsn = parent->palf_handle_impl_->sw_.committed_end_lsn_;
110EXPECT_EQ(parent_committed_end_lsn, this_max_flushed_end_lsn) \
111<< parent_committed_end_lsn.val_ << "," << this_max_flushed_end_lsn.val_;
112if (parent_committed_end_lsn != this_max_flushed_end_lsn) {
113PALF_LOG(ERROR, "log not sync", K(parent_addr), "self", palf->palf_handle_impl_->self_,
114K(parent_committed_end_lsn), K(this_max_flushed_end_lsn));
115}
116}
117}
118}
119}
120return ret;
121}
122
123MockLocCB loc_cb;
124
125TEST_F(TestObSimpleLogClusterConfigChange, split_brain)
126{
127SET_CASE_LOG_FILE(TEST_NAME, "split_brain");
128std::vector<PalfHandleImplGuard*> palf_list;
129int ret = OB_SUCCESS;
130const int64_t id = ATOMIC_AAF(&palf_id_, 1);
131PALF_LOG(INFO, "begin test split_brain", K(id));
132int64_t leader_idx = 0;
133// 1. A, B, C
134// 2. B block_net
135// 3. A, C, D
136// 4. A, D. delete C
137// 5. unblock_net B, create new C
138// 6. may be split-brain {B, C} {A, D}
139{
140PalfHandleImplGuard leader;
141const int64_t CONFIG_CHANGE_TIMEOUT = 10 * 1000 * 1000L; // 10s
142EXPECT_EQ(OB_SUCCESS, create_paxos_group(id, &loc_cb, leader_idx, leader));
143EXPECT_EQ(OB_SUCCESS, submit_log(leader, 200, id));
144PALF_LOG(INFO, "after submit_log");
145const int64_t follower_B_idx = (leader_idx + 1);
146const int64_t follower_C_idx = (leader_idx + 2);
147const int64_t follower_D_idx = (leader_idx + 3);
148// step 2
149EXPECT_EQ(OB_SUCCESS, get_cluster()[follower_B_idx]->simple_close(false));
150// step 3
151const ObAddr follower_b_addr = get_cluster()[follower_B_idx]->get_addr();
152PALF_LOG(INFO, "before remove member");
153EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(follower_b_addr, 1), 3, CONFIG_CHANGE_TIMEOUT));
154PALF_LOG(INFO, "after remove member");
155
156PalfHandleImplGuard new_leader;
157int64_t new_leader_idx;
158EXPECT_EQ(OB_SUCCESS, get_leader(id, new_leader, new_leader_idx));
159loc_cb.leader_ = get_cluster()[new_leader_idx]->get_addr();
160PALF_LOG(INFO, "set leader for loc_cb", "leader", loc_cb.leader_);
161
162LogConfigVersion config_version;
163ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
164EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[follower_D_idx]->get_addr(), 1), 3, config_version, CONFIG_CHANGE_TIMEOUT));
165EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
166// step 4
167EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(get_cluster()[follower_C_idx]->get_addr(), 1), 3, CONFIG_CHANGE_TIMEOUT));
168EXPECT_EQ(OB_SUCCESS, get_cluster()[follower_C_idx]->get_palf_env()->remove_palf_handle_impl(id));
169// step 5
170const int64_t node_id = follower_B_idx * 2 + get_node_idx_base();
171EXPECT_EQ(OB_SUCCESS, get_cluster()[follower_B_idx]->simple_init(get_test_name(), follower_b_addr, node_id, false));
172EXPECT_EQ(OB_SUCCESS, get_cluster()[follower_B_idx]->simple_start(false));
173EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
174PalfBaseInfo palf_base_info;
175IPalfHandleImpl* follower_C_handle = NULL;
176palf_base_info.generate_by_default();
177//PalfHandleImplGuard leader;
178palf_base_info.prev_log_info_.scn_ = share::SCN::min_scn();
179EXPECT_EQ(OB_SUCCESS, get_cluster()[follower_C_idx]->get_palf_env()->create_palf_handle_impl(id, palf::AccessMode::APPEND, palf_base_info, follower_C_handle));
180get_cluster()[follower_C_idx]->get_palf_env()->revert_palf_handle_impl(follower_C_handle);
181sleep(5);
182// check if split-brain happens
183int64_t leader_cnt = 0;
184EXPECT_EQ(OB_SUCCESS, get_cluster_palf_handle_guard(id, palf_list));
185for (auto palf: palf_list) {
186ObRole role;
187palf::ObReplicaState unused_state;
188palf->palf_handle_impl_->state_mgr_.get_role_and_state(role, unused_state);
189if (role == LEADER) {
190leader_cnt += 1;
191}
192}
193EXPECT_EQ(leader_cnt, 1);
194revert_cluster_palf_handle_guard(palf_list);
195}
196delete_paxos_group(id);
197PALF_LOG(INFO, "end test split_brain", K(id));
198}
199
200TEST_F(TestObSimpleLogClusterConfigChange, test_config_change_defensive)
201{
202SET_CASE_LOG_FILE(TEST_NAME, "config_change_defensive");
203int ret = OB_SUCCESS;
204PALF_LOG(INFO, "begin test_config_change_defensive");
205const int64_t id = ATOMIC_AAF(&palf_id_, 1);
206{
207int64_t leader_idx = 0;
208PalfHandleImplGuard leader;
209std::vector<PalfHandleImplGuard*> palf_list;
210const int64_t CONFIG_CHANGE_TIMEOUT = 10 * 1000 * 1000L; // 10s
211common::ObMember dummy_member;
212const LogConfigChangeArgs args(dummy_member, 1, STARTWORKING);
213EXPECT_EQ(OB_SUCCESS, create_paxos_group(id, &loc_cb, leader_idx, leader));
214EXPECT_EQ(OB_SUCCESS, get_cluster_palf_handle_guard(id, palf_list));
215const int64_t lag_follower_idx = (leader_idx+1)%3;
216const int64_t remove_follower_idx = (leader_idx+2)%3;
217block_net(leader_idx, lag_follower_idx);
218EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
219sleep(1);
220// remove member who is in majority
221EXPECT_EQ(OB_TIMEOUT, leader.palf_handle_impl_->remove_member(ObMember(palf_list[remove_follower_idx]->palf_handle_impl_->self_, 1), 2, CONFIG_CHANGE_TIMEOUT / 2));
222unblock_net(leader_idx, lag_follower_idx);
223EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
224EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[remove_follower_idx]->palf_handle_impl_->self_, 1), 2, CONFIG_CHANGE_TIMEOUT));
225
226int64_t new_leader_idx;
227PalfHandleImplGuard new_leader;
228EXPECT_EQ(OB_SUCCESS, get_leader(id, new_leader, new_leader_idx));
229loc_cb.leader_ = get_cluster()[new_leader_idx]->get_addr();
230PALF_LOG(INFO, "set leader for loc_cb", "leader", get_cluster()[new_leader_idx]->get_addr());
231
232LogConfigVersion config_version;
233ASSERT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->get_config_version(config_version));
234EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[remove_follower_idx]->palf_handle_impl_->self_, 1), 3, config_version, CONFIG_CHANGE_TIMEOUT));
235EXPECT_EQ(OB_SUCCESS, submit_log(leader, 10, id));
236// majority of members should be normal
237palf_list[lag_follower_idx]->palf_handle_impl_->disable_vote(false);
238EXPECT_EQ(OB_TIMEOUT, leader.palf_handle_impl_->remove_member(ObMember(palf_list[remove_follower_idx]->palf_handle_impl_->self_, 1), 2, CONFIG_CHANGE_TIMEOUT / 2));
239palf_list[lag_follower_idx]->palf_handle_impl_->enable_vote();
240
241block_net(leader_idx, lag_follower_idx);
242
243EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
244sleep(3);
245
246// add member without any logs
247// we will send config log to 3 before add_member(3, 4), so 3 can know who is leader and fetch log from it.
248// so just comment this line, after leader forbit fetch log req that comes from node who is not follower or
249// children of leader, we will uncomment this line
250// EXPECT_EQ(OB_TIMEOUT, leader.add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, CONFIG_CHANGE_TIMEOUT / 2));
251unblock_net(leader_idx, lag_follower_idx);
252ASSERT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->get_config_version(config_version));
253EXPECT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT));
254//test add_member_with_check
255EXPECT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->remove_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT));
256LogConfigVersion invalid_config_version;
257int64_t follower_idx = (new_leader_idx +1) % 3;
258EXPECT_EQ(OB_STATE_NOT_MATCH, new_leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, invalid_config_version, CONFIG_CHANGE_TIMEOUT));
259EXPECT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->get_config_version(config_version));
260EXPECT_EQ(OB_NOT_MASTER, palf_list[follower_idx]->palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT));
261EXPECT_EQ(true, config_version.is_valid());
262EXPECT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT));
263
264revert_cluster_palf_handle_guard(palf_list);
265}
266delete_paxos_group(id);
267PALF_LOG(INFO, "end test_config_change_defensive", K(id));
268}
269
270TEST_F(TestObSimpleLogClusterConfigChange, test_change_replica_num)
271{
272SET_CASE_LOG_FILE(TEST_NAME, "change_replica_num");
273int ret = OB_SUCCESS;
274const int64_t id = ATOMIC_FAA(&palf_id_, 1);
275PALF_LOG(INFO, "begin test_change_replica_num", K(id));
276{
277int64_t leader_idx = 0;
278PalfHandleImplGuard leader;
279const int64_t CONFIG_CHANGE_TIMEOUT = 10 * 1000 * 1000L; // 10s
280EXPECT_EQ(OB_SUCCESS, create_paxos_group(id, &loc_cb, leader_idx, leader));
281PalfHandleImplGuard new_leader;
282int64_t new_leader_idx;
283EXPECT_EQ(OB_SUCCESS, get_leader(id, new_leader, new_leader_idx));
284loc_cb.leader_ = get_cluster()[new_leader_idx]->get_addr();
285PALF_LOG(INFO, "set leader for loc_cb", "leader", get_cluster()[new_leader_idx]->get_addr());
286
287EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
288// 3->5
289EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->change_replica_num(get_member_list(), 3, 5, CONFIG_CHANGE_TIMEOUT));
290LogConfigVersion config_version;
291ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
292EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[4]->get_addr(), 1), 5, config_version, CONFIG_CHANGE_TIMEOUT));
293ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
294EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[5]->get_addr(), 1), 5, config_version, CONFIG_CHANGE_TIMEOUT));
295common::ObMemberList curr_member_list;
296int64_t curr_replica_num;
297EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(get_cluster()[4]->get_addr(), 1), 5, CONFIG_CHANGE_TIMEOUT));
298EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(get_cluster()[5]->get_addr(), 1), 5, CONFIG_CHANGE_TIMEOUT));
299EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_paxos_member_list(curr_member_list, curr_replica_num));
300// 5->3
301EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->change_replica_num(curr_member_list, curr_replica_num, 3, CONFIG_CHANGE_TIMEOUT));
302EXPECT_EQ(OB_SUCCESS, submit_log(leader, 200, id));
303// 3->4
304EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_paxos_member_list(curr_member_list, curr_replica_num));
305EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->change_replica_num(curr_member_list, curr_replica_num, 4, CONFIG_CHANGE_TIMEOUT));
306}
307delete_paxos_group(id);
308PALF_LOG(INFO, "end test_change_replica_num", K(id));
309}
310
311TEST_F(TestObSimpleLogClusterConfigChange, test_basic_config_change)
312{
313SET_CASE_LOG_FILE(TEST_NAME, "config_change");
314int ret = OB_SUCCESS;
315const int64_t id = ATOMIC_AAF(&palf_id_, 1);
316PALF_LOG(INFO, "begin test config change", K(id));
317{
318int64_t leader_idx = 0;
319std::vector<PalfHandleImplGuard*> palf_list;
320const int64_t CONFIG_CHANGE_TIMEOUT = 10 * 1000 * 1000L; // 10s
321PalfHandleImplGuard leader;
322EXPECT_EQ(OB_SUCCESS, create_paxos_group(id, &loc_cb, leader_idx, leader));
323PalfHandleImplGuard new_leader;
324int64_t new_leader_idx;
325EXPECT_EQ(OB_SUCCESS, get_leader(id, new_leader, new_leader_idx));
326loc_cb.leader_ = get_cluster()[new_leader_idx]->get_addr();
327PALF_LOG(INFO, "set leader for loc_cb", "leader", get_cluster()[new_leader_idx]->get_addr());
328EXPECT_EQ(OB_SUCCESS, get_cluster_palf_handle_guard(id, palf_list));
329// add member when no log
330LogConfigVersion config_version;
331ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
332EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT));
333EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT));
334EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[(leader_idx+1)%3]->palf_handle_impl_->self_, 1), 2, CONFIG_CHANGE_TIMEOUT));
335EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[(leader_idx+2)%3]->palf_handle_impl_->self_, 1), 1, CONFIG_CHANGE_TIMEOUT));
336ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
337EXPECT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->add_member(ObMember(palf_list[(leader_idx+1)%3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT));
338EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[(leader_idx+1)%3]->palf_handle_impl_->self_, 1), 2, config_version, CONFIG_CHANGE_TIMEOUT));
339ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
340EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[(leader_idx+2)%3]->palf_handle_impl_->self_, 1), 3, config_version, CONFIG_CHANGE_TIMEOUT));
341ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
342EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT));
343EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
344
345// add member when contains log
346ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
347EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[4]->palf_handle_impl_->self_, 1), 5, config_version, CONFIG_CHANGE_TIMEOUT));
348EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
349
350// remove member
351EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[4]->palf_handle_impl_->self_, 1), 4, CONFIG_CHANGE_TIMEOUT));
352
353EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
354
355
356EXPECT_EQ(OB_STATE_NOT_MATCH, leader.palf_handle_impl_->replace_member(ObMember(palf_list[5]->palf_handle_impl_->self_, 1),
357ObMember(palf_list[3]->palf_handle_impl_->self_, 1),
358config_version,
359CONFIG_CHANGE_TIMEOUT));
360ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
361// replace member
362EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->replace_member(ObMember(palf_list[5]->palf_handle_impl_->self_, 1),
363ObMember(palf_list[3]->palf_handle_impl_->self_, 1),
364config_version,
365CONFIG_CHANGE_TIMEOUT));
366
367ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
368// switch acceptor to learner
369EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->switch_acceptor_to_learner(ObMember(palf_list[5]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT));
370// add learner
371EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), CONFIG_CHANGE_TIMEOUT));
372EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(ObMember(palf_list[4]->palf_handle_impl_->self_, 1), CONFIG_CHANGE_TIMEOUT));
373EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(ObMember(palf_list[6]->palf_handle_impl_->self_, 1), CONFIG_CHANGE_TIMEOUT));
374
375EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
376revert_cluster_palf_handle_guard(palf_list);
377}
378delete_paxos_group(id);
379PALF_LOG(INFO, "end test config change", K(id));
380}
381
382TEST_F(TestObSimpleLogClusterConfigChange, test_basic_config_change_for_migration)
383{
384SET_CASE_LOG_FILE(TEST_NAME, "config_change_for_migration");
385int ret = OB_SUCCESS;
386const int64_t id = ATOMIC_AAF(&palf_id_, 1);
387PALF_LOG(INFO, "begin test config change", K(id));
388{
389int64_t leader_idx = 0;
390std::vector<PalfHandleImplGuard*> palf_list;
391const int64_t CONFIG_CHANGE_TIMEOUT = 10 * 1000 * 1000L; // 10s
392PalfHandleImplGuard leader;
393EXPECT_EQ(OB_SUCCESS, create_paxos_group(id, &loc_cb, leader_idx, leader));
394PalfHandleImplGuard new_leader;
395int64_t new_leader_idx;
396EXPECT_EQ(OB_SUCCESS, get_leader(id, new_leader, new_leader_idx));
397loc_cb.leader_ = get_cluster()[new_leader_idx]->get_addr();
398PALF_LOG(INFO, "set leader for loc_cb", "leader", get_cluster()[new_leader_idx]->get_addr());
399EXPECT_EQ(OB_SUCCESS, get_cluster_palf_handle_guard(id, palf_list));
400EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
401const common::ObAddr &addr2 = get_cluster()[(leader_idx+2)%3]->get_addr();
402const common::ObAddr &addr3 = get_cluster()[3]->get_addr();
403const common::ObAddr &addr4 = get_cluster()[4]->get_addr();
404const common::ObAddr &addr5 = get_cluster()[5]->get_addr();
405// 1. replicate an FULL replica
406{
407PALF_LOG(INFO, "CASE1: replicate an FULL replica", K(id));
408common::ObMember added_member = ObMember(addr3, 1);
409added_member.set_migrating();
410EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(added_member, CONFIG_CHANGE_TIMEOUT));
411EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(added_member));
412EXPECT_EQ(3, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_replica_num_);
413
414// clean
415EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_learner(added_member, CONFIG_CHANGE_TIMEOUT));
416EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(added_member));
417// add again
418EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(added_member, CONFIG_CHANGE_TIMEOUT));
419EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(added_member));
420
421LogConfigVersion config_version;
422ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
423EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->switch_learner_to_acceptor(added_member, 4, config_version, CONFIG_CHANGE_TIMEOUT));
424EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(added_member));
425// member with flag do not exist
426EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(added_member));
427EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(added_member.get_server()));
428EXPECT_EQ(4, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_replica_num_);
429// reentrant, do not get config_version again
430EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->switch_learner_to_acceptor(added_member, 4, config_version, CONFIG_CHANGE_TIMEOUT));
431// reset environment
432added_member.reset_migrating();
433EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(added_member, 3, CONFIG_CHANGE_TIMEOUT));
434}
435
436// 2. migrate an FULL replica (addr2 -> addr3)
437{
438PALF_LOG(INFO, "CASE2: migrate an FULL replica", K(id));
439common::ObMember added_member = ObMember(addr3, 1);
440added_member.set_migrating();
441common::ObMember replaced_member = ObMember(addr2, 1);
442EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(added_member, CONFIG_CHANGE_TIMEOUT));
443EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(added_member));
444EXPECT_EQ(3, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_replica_num_);
445LogConfigVersion config_version;
446ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
447LogConfigChangeArgs args(added_member, 0, config_version, SWITCH_LEARNER_TO_ACCEPTOR_AND_NUM);
448EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->one_stage_config_change_(args, CONFIG_CHANGE_TIMEOUT));
449EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(added_member));
450EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(added_member));
451EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(added_member.get_server()));
452EXPECT_EQ(4, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_replica_num_);
453
454ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
455EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->replace_member_with_learner(added_member, replaced_member, config_version, CONFIG_CHANGE_TIMEOUT));
456EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(added_member));
457// member with flag do not exist
458EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(added_member));
459EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(added_member.get_server()));
460EXPECT_EQ(3, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_replica_num_);
461EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(replaced_member.get_server()));
462// reentrant and check
463EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->replace_member_with_learner(added_member, replaced_member, config_version, CONFIG_CHANGE_TIMEOUT));
464EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(added_member));
465// member with flag do not exist
466EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(added_member));
467EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(added_member.get_server()));
468EXPECT_EQ(3, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_replica_num_);
469EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(replaced_member.get_server()));
470// reset environment
471added_member.reset_migrating();
472ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
473EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->replace_member(replaced_member, added_member, config_version, CONFIG_CHANGE_TIMEOUT));
474EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(added_member.get_server()));
475EXPECT_EQ(3, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_replica_num_);
476EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(replaced_member.get_server()));
477}
478
479// 3. replicate an READONLY replica
480{
481PALF_LOG(INFO, "CASE3: replicate an READONLY replica", K(id));
482// learner's addr must be different from members'
483common::ObMember migrating_member = ObMember(addr2, 1);
484EXPECT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->add_learner(migrating_member, CONFIG_CHANGE_TIMEOUT));
485
486common::ObMember added_migrating_learner = ObMember(addr3, 1);
487common::ObMember added_learner = ObMember(addr3, 1);
488added_migrating_learner.set_migrating();
489EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(added_migrating_learner, CONFIG_CHANGE_TIMEOUT));
490EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(added_migrating_learner));
491EXPECT_EQ(3, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_replica_num_);
492ObMemberList added_learners, removed_learners;
493EXPECT_EQ(OB_SUCCESS, added_learners.add_member(added_learner));
494EXPECT_EQ(OB_SUCCESS, removed_learners.add_member(added_migrating_learner));
495EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->replace_learners(added_learners, removed_learners, CONFIG_CHANGE_TIMEOUT));
496EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(added_learner));
497EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(added_migrating_learner));
498// reentrant and check
499EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->replace_learners(added_learners, removed_learners, CONFIG_CHANGE_TIMEOUT));
500EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(added_learner));
501EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(added_migrating_learner));
502// reset environment
503EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_learner(added_learner, CONFIG_CHANGE_TIMEOUT));
504}
505
506// 4. migrate an READONLY replica, addr4 -> addr3
507{
508PALF_LOG(INFO, "CASE4: migrate an READONLY replica", K(id));
509common::ObMember removed_learner = ObMember(addr4, 1);
510EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(removed_learner, CONFIG_CHANGE_TIMEOUT));
511EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(removed_learner));
512
513common::ObMember added_migrating_learner = ObMember(addr3, 1);
514common::ObMember added_learner = ObMember(addr3, 1);
515added_migrating_learner.set_migrating();
516EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(added_migrating_learner, CONFIG_CHANGE_TIMEOUT));
517EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(added_migrating_learner));
518EXPECT_EQ(3, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_replica_num_);
519ObMemberList added_learners, removed_learners;
520EXPECT_EQ(OB_SUCCESS, added_learners.add_member(added_learner));
521EXPECT_EQ(OB_SUCCESS, removed_learners.add_member(added_migrating_learner));
522EXPECT_EQ(OB_SUCCESS, removed_learners.add_member(removed_learner));
523EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->replace_learners(added_learners, removed_learners, CONFIG_CHANGE_TIMEOUT));
524EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(added_learner));
525EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(added_migrating_learner));
526EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(removed_learner));
527// reentrant and check
528EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->replace_learners(added_learners, removed_learners, CONFIG_CHANGE_TIMEOUT));
529EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(added_learner));
530EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(added_migrating_learner));
531EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(removed_learner));
532// reset environment
533EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_learner(added_learner, CONFIG_CHANGE_TIMEOUT));
534}
535// 5. replace_learners (addr3, addr4) -> (addr3, addr5)
536{
537PALF_LOG(INFO, "CASE5: replace_learners", K(id));
538const common::ObMember member2 = ObMember(addr2, 1);
539const common::ObMember member3 = ObMember(addr3, 1);
540const common::ObMember member4 = ObMember(addr4, 1);
541const common::ObMember member5 = ObMember(addr5, 1);
542EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(member3, CONFIG_CHANGE_TIMEOUT));
543EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(member4, CONFIG_CHANGE_TIMEOUT));
544EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(member3));
545EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(member4));
546
547ObMemberList added_learners, removed_learners;
548EXPECT_EQ(OB_SUCCESS, added_learners.add_member(member3));
549EXPECT_EQ(OB_SUCCESS, added_learners.add_member(member5));
550EXPECT_EQ(OB_SUCCESS, removed_learners.add_member(member2));
551EXPECT_EQ(OB_SUCCESS, removed_learners.add_member(member4));
552EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->replace_learners(added_learners, removed_learners, CONFIG_CHANGE_TIMEOUT));
553EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(member3));
554EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(member5));
555EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(member2));
556EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(member4));
557// reentrant and check
558EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->replace_learners(added_learners, removed_learners, CONFIG_CHANGE_TIMEOUT));
559EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(member3));
560EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(member5));
561EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(member2));
562EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(member4));
563// reset environment
564EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_learner(member3, CONFIG_CHANGE_TIMEOUT));
565EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_learner(member5, CONFIG_CHANGE_TIMEOUT));
566EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(member3));
567EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(member5));
568}
569// 6. defensive
570{
571PALF_LOG(INFO, "CASE6: defensive", K(id));
572const common::ObMember member2 = ObMember(addr2, 1);
573const common::ObMember member3 = ObMember(addr3, 1);
574const common::ObMember member4 = ObMember(addr4, 1);
575const common::ObMember member5 = ObMember(addr5, 1);
576common::ObMember migrating_member3 = member3;
577migrating_member3.set_migrating();
578
579EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(migrating_member3, CONFIG_CHANGE_TIMEOUT));
580EXPECT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->add_learner(member3, CONFIG_CHANGE_TIMEOUT));
581LogConfigVersion config_version;
582ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
583EXPECT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->add_member(member3, 4, config_version, CONFIG_CHANGE_TIMEOUT));
584EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_learner(member3, CONFIG_CHANGE_TIMEOUT));
585EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(migrating_member3));
586EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_learner(migrating_member3, CONFIG_CHANGE_TIMEOUT));
587EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.learnerlist_.contains(migrating_member3));
588
589EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(migrating_member3, CONFIG_CHANGE_TIMEOUT));
590ObMemberList added_learners, removed_learners;
591EXPECT_EQ(OB_SUCCESS, added_learners.add_member(member3));
592EXPECT_EQ(OB_SUCCESS, removed_learners.add_member(member4));
593EXPECT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->replace_learners(added_learners, removed_learners, CONFIG_CHANGE_TIMEOUT));
594
595common::ObMember migrating_member2 = member2;
596migrating_member2.set_migrating();
597EXPECT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->remove_member(migrating_member2, 2, CONFIG_CHANGE_TIMEOUT));
598}
599EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
600revert_cluster_palf_handle_guard(palf_list);
601}
602delete_paxos_group(id);
603PALF_LOG(INFO, "end test config change", K(id));
604}
605
606TEST_F(TestObSimpleLogClusterConfigChange, test_replace_member)
607{
608SET_CASE_LOG_FILE(TEST_NAME, "replace_member");
609int ret = OB_SUCCESS;
610const int64_t id = ATOMIC_AAF(&palf_id_, 1);
611PALF_LOG(INFO, "begin test replace_member", K(id));
612{
613std::vector<PalfHandleImplGuard*> palf_list;
614int64_t leader_idx = 0;
615PalfHandleImplGuard leader;
616const int64_t CONFIG_CHANGE_TIMEOUT = 10 * 1000 * 1000L; // 10s
617EXPECT_EQ(OB_SUCCESS, create_paxos_group(id, &loc_cb, leader_idx, leader));
618PalfHandleImplGuard new_leader;
619int64_t new_leader_idx;
620EXPECT_EQ(OB_SUCCESS, get_leader(id, new_leader, new_leader_idx));
621loc_cb.leader_ = get_cluster()[new_leader_idx]->get_addr();
622PALF_LOG(INFO, "set leader for loc_cb", "leader", get_cluster()[new_leader_idx]->get_addr());
623EXPECT_EQ(OB_SUCCESS, get_cluster_palf_handle_guard(id, palf_list));
624EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
625// replace member when no log
626LogConfigVersion config_version;
627ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
628EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT));
629EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT));
630EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[(leader_idx+1)%3]->palf_handle_impl_->self_, 1), 2, CONFIG_CHANGE_TIMEOUT));
631EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[(leader_idx+2)%3]->palf_handle_impl_->self_, 1), 1, CONFIG_CHANGE_TIMEOUT));
632ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
633EXPECT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->add_member(ObMember(palf_list[(leader_idx+1)%3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT));
634EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[(leader_idx+1)%3]->palf_handle_impl_->self_, 1), 2, config_version, CONFIG_CHANGE_TIMEOUT));
635ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
636EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[(leader_idx+2)%3]->palf_handle_impl_->self_, 1), 3, config_version, CONFIG_CHANGE_TIMEOUT));
637ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
638EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT));
639EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
640
641// add member when contains log
642ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
643EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[4]->palf_handle_impl_->self_, 1), 5, config_version, CONFIG_CHANGE_TIMEOUT));
644EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
645
646// remove member
647EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[4]->palf_handle_impl_->self_, 1), 4, CONFIG_CHANGE_TIMEOUT));
648
649EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
650
651// replace member
652ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
653EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->replace_member(ObMember(palf_list[5]->palf_handle_impl_->self_, 1),
654ObMember(palf_list[3]->palf_handle_impl_->self_, 1),
655config_version,
656CONFIG_CHANGE_TIMEOUT));
657
658// switch acceptor to learner
659EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->switch_acceptor_to_learner(ObMember(palf_list[5]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT));
660// add learner
661EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), CONFIG_CHANGE_TIMEOUT));
662EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(ObMember(palf_list[4]->palf_handle_impl_->self_, 1), CONFIG_CHANGE_TIMEOUT));
663EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(ObMember(palf_list[6]->palf_handle_impl_->self_, 1), CONFIG_CHANGE_TIMEOUT));
664
665EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
666revert_cluster_palf_handle_guard(palf_list);
667}
668delete_paxos_group(id);
669PALF_LOG(INFO, "end test replace_member", K(id));
670}
671
672TEST_F(TestObSimpleLogClusterConfigChange, learner)
673{
674SET_CASE_LOG_FILE(TEST_NAME, "learner");
675int ret = OB_SUCCESS;
676const int64_t id = ATOMIC_AAF(&palf_id_, 1);
677int64_t leader_idx = 0;
678int64_t log_ts = 1;
679PalfHandleImplGuard leader;
680LogLearnerList all_learner;
681std::vector<PalfHandleImplGuard*> palf_list;
682std::vector<ObRegion> region_list;
683common::ObRegion default_region(DEFAULT_REGION_NAME);
684LogMemberRegionMap region_map;
685EXPECT_EQ(OB_SUCCESS, region_map.init("localmap", OB_MAX_MEMBER_NUMBER));
686region_list.push_back(ObRegion("BEIJING"));
687region_list.push_back(ObRegion("SHANGHAI"));
688region_list.push_back(ObRegion("TIANJIN"));
689region_list.push_back(ObRegion("SHENZHEN"));
690region_list.push_back(ObRegion("GUANGZHOU"));
691const ObMemberList &node_list = get_node_list();
692const int64_t CONFIG_CHANGE_TIMEOUT = 10 * 1000 * 1000L; // 10s
693EXPECT_EQ(OB_SUCCESS, create_paxos_group(id, &loc_cb, leader_idx, leader));
694EXPECT_EQ(OB_SUCCESS, get_cluster_palf_handle_guard(id, palf_list));
695loc_cb.leader_ = get_cluster()[leader_idx]->get_addr();
696PALF_LOG(INFO, "set leader for loc_cb", "leader", get_cluster()[leader_idx]->get_addr());
697
698EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
699// case 1: set region and switch_acceptor_to_learner
700// add_learner
701for (int64_t i = 3; i < ObSimpleLogClusterTestBase::node_cnt_; ++i) {
702PalfHandleImplGuard tmp_handle;
703common::ObMember added_learner;
704EXPECT_EQ(OB_SUCCESS, node_list.get_member_by_index(i, added_learner));
705LogLearner learner(added_learner.get_server(), 1);
706EXPECT_EQ(OB_SUCCESS, all_learner.add_learner(learner));
707EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(added_learner, CONFIG_CHANGE_TIMEOUT));
708}
709// check children_cnt
710while (false == check_children_valid(palf_list, all_learner))
711{
712sleep(1);
713PALF_LOG(INFO, "check_children_valid 1");
714}
715// change region of one follower
716bool has_change_region = false;
717int64_t diff_region_follower_idx = -1;
718int64_t another_follower_idx = -1;
719for (int i = 0; i < ObSimpleLogClusterTestBase::member_cnt_; i++) {
720const bool not_leader = palf_list[i]->palf_handle_impl_->self_ != leader.palf_handle_impl_->self_;
721if (!has_change_region && not_leader) {
722EXPECT_EQ(OB_SUCCESS, palf_list[i]->palf_handle_impl_->set_region(region_list[0]));
723region_map.insert(palf_list[i]->palf_handle_impl_->self_, region_list[0]);
724has_change_region = true;
725diff_region_follower_idx = i;
726} else {
727if (not_leader) {
728another_follower_idx = i;
729}
730region_map.insert(palf_list[0]->palf_handle_impl_->self_, default_region);
731}
732}
733// notify leader region of follower i has changed
734EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->set_paxos_member_region_map(region_map));
735// check children_cnt again
736while (false == check_children_valid(palf_list, all_learner))
737{
738sleep(1);
739PALF_LOG(INFO, "check_children_valid 2");
740}
741// after setting region of a follower, parents of all learners should be another follower
742EXPECT_GE(another_follower_idx, 0);
743EXPECT_LE(another_follower_idx, 2);
744ObAddr curr_parent = palf_list[another_follower_idx]->palf_handle_impl_->self_;
745while (false == check_parent(palf_list, all_learner, curr_parent))
746{
747sleep(1);
748PALF_LOG(INFO, "check_parent 1");
749}
750// continue submitting log
751EXPECT_EQ(OB_SUCCESS, submit_log(leader, 20, id));
752PALF_LOG(INFO, "all_learner", K(all_learner));
753// EXPECT_EQ(OB_SUCCESS, check_log_sync(palf_list, get_member_list(), all_learner, leader));
754
755// switch current unique parent to learner
756EXPECT_EQ(OB_SUCCESS, all_learner.add_learner(LogLearner(curr_parent, 1)));
757EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->switch_acceptor_to_learner(ObMember(curr_parent, 1), 2, CONFIG_CHANGE_TIMEOUT));
758// after switch follower 1 to learner, a learner will be registered to leader, and other learners will
759// be registerd to this learner
760while (false == check_children_valid(palf_list, all_learner))
761{
762sleep(1);
763PALF_LOG(INFO, "check_children_valid 3");
764}
765// check learner topology
766ObAddr leaderschild;
767PalfHandleImplGuard leaderschild_handle;
768LogLearnerList expect_children;
769EXPECT_EQ(1, leader.palf_handle_impl_->config_mgr_.children_.get_member_number());
770EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->config_mgr_.children_.get_server_by_index(0, leaderschild));
771EXPECT_EQ(OB_SUCCESS, get_palf_handle_guard(palf_list, leaderschild, leaderschild_handle));
772expect_children = all_learner;
773EXPECT_EQ(OB_SUCCESS, expect_children.remove_learner(leaderschild));
774EXPECT_TRUE(expect_children.learner_addr_equal(leaderschild_handle.palf_handle_impl_->config_mgr_.children_));
775EXPECT_EQ(OB_SUCCESS, submit_log(leader, 20, id));
776// EXPECT_EQ(OB_SUCCESS, check_log_sync(palf_list, get_member_list(), all_learner, leader));
777// learners' regions are different from paxos member, so parent of all learners is leader
778// set regions
779for (int64_t i = 3; i < ObSimpleLogClusterTestBase::node_cnt_; ++i) {
780PalfHandleImplGuard tmp_handle;
781common::ObMember learner;
782EXPECT_EQ(OB_SUCCESS, node_list.get_member_by_index(i, learner));
783EXPECT_EQ(OB_SUCCESS, get_palf_handle_guard(palf_list, learner.get_server(), tmp_handle));
784EXPECT_EQ(OB_SUCCESS, tmp_handle.palf_handle_impl_->set_region(region_list[i-2]));
785}
786sleep(1);
787// check children_cnt
788while (false == check_children_valid(palf_list, all_learner))
789{
790sleep(1);
791PALF_LOG(INFO, "check_children_valid 4");
792}
793while (false == check_parent(palf_list, all_learner, leader.palf_handle_impl_->self_))
794{
795sleep(1);
796PALF_LOG(INFO, "check_parent 2");
797}
798
799// switch leader, after switching leader, the parent of all learners is the new leader
800const int64_t new_leader_idx = diff_region_follower_idx;
801PalfHandleImplGuard new_leader;
802EXPECT_EQ(OB_SUCCESS, switch_leader(id, 0, new_leader));
803
804while (false == check_children_valid(palf_list, all_learner))
805{
806sleep(1);
807PALF_LOG(INFO, "check_children_valid 5");
808}
809while (false == check_parent(palf_list, all_learner, new_leader.palf_handle_impl_->self_))
810{
811sleep(1);
812PALF_LOG(INFO, "check_parent 3");
813}
814
815revert_cluster_palf_handle_guard(palf_list);
816PALF_LOG(INFO, "end test learner", K(id));
817}
818
819TEST_F(TestObSimpleLogClusterConfigChange, test_config_change_lock)
820{
821SET_CASE_LOG_FILE(TEST_NAME, "config_change_lock");
822int ret = OB_SUCCESS;
823const int64_t id = ATOMIC_AAF(&palf_id_, 1);
824PALF_LOG(INFO, "begin test config change", K(id));
825int64_t leader_idx = 0;
826int64_t log_ts = 1;
827PalfHandleImplGuard leader;
828std::vector<PalfHandleImplGuard*> palf_list;
829const int64_t CONFIG_CHANGE_TIMEOUT = 10 * 1000 * 1000L; // 10s
830ASSERT_EQ(OB_SUCCESS, create_paxos_group(id, &loc_cb, leader_idx, leader));
831ASSERT_EQ(OB_SUCCESS, get_cluster_palf_handle_guard(id, palf_list));
832
833ASSERT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
834loc_cb.leader_ = get_cluster()[leader_idx]->get_addr();
835PALF_LOG(INFO, "set leader for loc_cb", "leader", loc_cb.leader_);
836int64_t lock_owner_out = -1;
837bool lock_stat = false;
838//ASSERT_EQ(OB_NOT_SUPPORTED, leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat));
839//ASSERT_EQ(OB_NOT_SUPPORTED, leader.palf_handle_impl_->try_lock_config_change(1, CONFIG_CHANGE_TIMEOUT));
840//ASSERT_EQ(OB_NOT_SUPPORTED, leader.palf_handle_impl_->unlock_config_change(1, CONFIG_CHANGE_TIMEOUT));
841//oceanbase::common::ObClusterVersion::get_instance().cluster_version_ = CLUSTER_VERSION_4_2_0_0;
842ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat));
843ASSERT_EQ(OB_INVALID_CONFIG_CHANGE_LOCK_OWNER, lock_owner_out);
844ASSERT_EQ(false, lock_stat);
845
846//invalid arguments
847ASSERT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->try_lock_config_change(-1, CONFIG_CHANGE_TIMEOUT));
848ASSERT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->try_lock_config_change(1, 0));
849ASSERT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->unlock_config_change(-1, CONFIG_CHANGE_TIMEOUT));
850ASSERT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->unlock_config_change(1, 0));
851
852//test try lock
853ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->try_lock_config_change(1, CONFIG_CHANGE_TIMEOUT));
854ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->try_lock_config_change(1, CONFIG_CHANGE_TIMEOUT));
855ASSERT_EQ(OB_TRY_LOCK_CONFIG_CHANGE_CONFLICT, leader.palf_handle_impl_->try_lock_config_change(2, CONFIG_CHANGE_TIMEOUT));
856
857ASSERT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
858
859ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat));
860ASSERT_EQ(1, lock_owner_out);
861ASSERT_EQ(true, lock_stat);
862
863//test unlock
864ASSERT_EQ(OB_STATE_NOT_MATCH, leader.palf_handle_impl_->unlock_config_change(2, CONFIG_CHANGE_TIMEOUT));
865ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->unlock_config_change(1, CONFIG_CHANGE_TIMEOUT));
866ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->unlock_config_change(1, CONFIG_CHANGE_TIMEOUT));
867ASSERT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
868
869ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat));
870ASSERT_EQ(1, lock_owner_out);
871ASSERT_EQ(false, lock_stat);
872
873//changing stat, test locking stat
874ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->try_lock_config_change(3, CONFIG_CHANGE_TIMEOUT));
875ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat));
876ASSERT_EQ(3, lock_owner_out);
877ASSERT_EQ(true, lock_stat);
878
879//block add_member
880
881LogConfigVersion config_version;
882ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
883
884//ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), CONFIG_CHANGE_TIMEOUT));
885ASSERT_EQ(OB_EAGAIN, leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT));
886ASSERT_EQ(OB_EAGAIN, leader.palf_handle_impl_->remove_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT));
887ASSERT_EQ(OB_EAGAIN, leader.palf_handle_impl_->remove_member(ObMember(palf_list[2]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT));
888ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
889ASSERT_EQ(OB_EAGAIN, leader.palf_handle_impl_->add_member(ObMember(palf_list[2]->palf_handle_impl_->self_, 1), 3, config_version, CONFIG_CHANGE_TIMEOUT));
890ASSERT_EQ(OB_EAGAIN, leader.palf_handle_impl_->switch_acceptor_to_learner(ObMember(palf_list[2]->palf_handle_impl_->self_, 1), 2, CONFIG_CHANGE_TIMEOUT));
891ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
892ASSERT_EQ(OB_EAGAIN, leader.palf_handle_impl_->switch_learner_to_acceptor(ObMember(palf_list[2]->palf_handle_impl_->self_, 1), 3, config_version, CONFIG_CHANGE_TIMEOUT));
893ASSERT_EQ(OB_EAGAIN, leader.palf_handle_impl_->change_replica_num(get_member_list(), 3, 4, CONFIG_CHANGE_TIMEOUT));
894
895
896ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->unlock_config_change(3, CONFIG_CHANGE_TIMEOUT));
897ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat));
898ASSERT_EQ(3, lock_owner_out);
899ASSERT_EQ(false, lock_stat);
900
901ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
902ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT));
903ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT));
904ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[2]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT));
905ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
906ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[2]->palf_handle_impl_->self_, 1), 3, config_version, CONFIG_CHANGE_TIMEOUT));
907ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->switch_acceptor_to_learner(ObMember(palf_list[2]->palf_handle_impl_->self_, 1), 2, CONFIG_CHANGE_TIMEOUT));
908ASSERT_EQ(OB_STATE_NOT_MATCH, leader.palf_handle_impl_->switch_learner_to_acceptor(ObMember(palf_list[2]->palf_handle_impl_->self_, 1), 3, config_version, CONFIG_CHANGE_TIMEOUT));
909ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
910ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->switch_learner_to_acceptor(ObMember(palf_list[2]->palf_handle_impl_->self_, 1), 3, config_version, CONFIG_CHANGE_TIMEOUT));
911ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->change_replica_num(get_member_list(), 3, 4, CONFIG_CHANGE_TIMEOUT));
912ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->change_replica_num(get_member_list(), 4, 3, CONFIG_CHANGE_TIMEOUT));
913
914//switch leader
915
916ASSERT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
917revert_cluster_palf_handle_guard(palf_list);
918PALF_LOG(INFO, "end test config change lock", K(id));
919}
920
921TEST_F(TestObSimpleLogClusterConfigChange, test_switch_leader)
922{
923SET_CASE_LOG_FILE(TEST_NAME, "switch_leader");
924int ret = OB_SUCCESS;
925const int64_t id = ATOMIC_AAF(&palf_id_, 1);
926PALF_LOG(INFO, "begin test switch_leader", K(id));
927int64_t leader_idx = 0;
928PalfHandleImplGuard leader;
929std::vector<PalfHandleImplGuard*> palf_list;
930oceanbase::common::ObClusterVersion::get_instance().cluster_version_ = CLUSTER_VERSION_4_2_0_0;
931EXPECT_EQ(OB_SUCCESS, create_paxos_group(id, leader_idx, leader));
932ASSERT_EQ(OB_SUCCESS, get_cluster_palf_handle_guard(id, palf_list));
933EXPECT_EQ(OB_SUCCESS, submit_log(leader, 200, id));
934// try lock config change
935//
936const int64_t follower_idx = (leader_idx+1)%3;
937const int64_t CONFIG_CHANGE_TIMEOUT = 10 * 1000 * 1000L; // 10s
938
939int64_t lock_owner_out = -1;
940bool lock_stat = false;
941ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->try_lock_config_change(1, CONFIG_CHANGE_TIMEOUT));
942ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat));
943ASSERT_EQ(1, lock_owner_out);
944ASSERT_EQ(true, lock_stat);
945
946PalfHandleImplGuard new_leader;
947const int64_t new_leader_idx = (leader_idx+1)%3;
948PalfHandleImplGuard &follower = *palf_list[new_leader_idx];
949ASSERT_EQ(OB_NOT_MASTER, follower.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat));
950EXPECT_EQ(OB_SUCCESS, switch_leader(id, new_leader_idx, new_leader));
951sleep(5);
952ObRole role;
953int64_t curr_proposal_id = 0;
954bool is_pending_stat = false;
955EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_role(role, curr_proposal_id, is_pending_stat));
956EXPECT_EQ(ObRole::FOLLOWER, role);
957
958lock_owner_out = -1;
959lock_stat = false;
960
961ASSERT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat));
962ASSERT_EQ(1, lock_owner_out);
963ASSERT_EQ(true, lock_stat);
964EXPECT_EQ(OB_SUCCESS, submit_log(new_leader, 200, id));
965
966
967ASSERT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->unlock_config_change(1, CONFIG_CHANGE_TIMEOUT));
968sleep(3);
969//switch leader during lock_config_change
970
971LogConfigChangeArgs args(2, ConfigChangeLockType::LOCK_PAXOS_MEMBER_CHANGE, TRY_LOCK_CONFIG_CHANGE);
972LogConfigVersion config_version;
973const int64_t proposal_id = new_leader.palf_handle_impl_->state_mgr_.get_proposal_id();
974const int64_t leader_epoch = new_leader.palf_handle_impl_->state_mgr_.get_leader_epoch();
975ASSERT_EQ(OB_EAGAIN, new_leader.palf_handle_impl_->config_mgr_.change_config(args, proposal_id, leader_epoch, config_version));
976ASSERT_EQ(LogConfigMgr::ConfigChangeState::CHANGING, new_leader.palf_handle_impl_->config_mgr_.state_);
977ASSERT_EQ(OB_EAGAIN, new_leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat));
978//block_net
979const int64_t follower_idx1 = (new_leader_idx+1)%3;
980const int64_t follower_idx2 = (new_leader_idx+2)%3;
981block_net(follower_idx1, new_leader_idx, true);
982block_net(follower_idx2, new_leader_idx, true);
983//send info to follower
984ASSERT_EQ(OB_EAGAIN, new_leader.palf_handle_impl_->config_mgr_.change_config(args, proposal_id, leader_epoch, config_version));
985sleep(1);
986
987unblock_net(follower_idx1, new_leader_idx);
988unblock_net(follower_idx2, new_leader_idx);
989PalfHandleImplGuard old_leader;
990EXPECT_EQ(OB_SUCCESS, switch_leader(id, leader_idx, old_leader));
991
992EXPECT_EQ(OB_SUCCESS, old_leader.palf_handle_impl_->get_role(role, curr_proposal_id, is_pending_stat));
993EXPECT_EQ(ObRole::LEADER, role);
994
995//check config change stat
996sleep(1);
997ASSERT_EQ(OB_SUCCESS, old_leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat));
998ASSERT_EQ(2, lock_owner_out);
999ASSERT_EQ(true, lock_stat);
1000
1001
1002revert_cluster_palf_handle_guard(palf_list);
1003PALF_LOG(INFO, "end test switch_leader", K(id));
1004}
1005
1006// 1. 3F(beijing), 4R(shanghai)
1007// 2. the client submits logs to F replicas, but R replicas can not receive logs
1008// 3. switch a R to F, the R replica must be one of the children of another R.
1009// Due to step 2, the R will not receive the reconfiguration log
1010// 4. enable the remaining R re-register parents
1011// 5. check loop between R replicas
1012TEST_F(TestObSimpleLogClusterConfigChange, learner_loop)
1013{
1014SET_CASE_LOG_FILE(TEST_NAME, "learner_loop");
1015int ret = OB_SUCCESS;
1016const int64_t CONFIG_CHANGE_TIMEOUT = 10 * 1000 * 1000L; // 10s
1017const int64_t id = ATOMIC_AAF(&palf_id_, 1);
1018int64_t leader_idx = 0;
1019PalfHandleImplGuard leader;
1020LogLearnerList all_learner;
1021const ObMemberList &node_list = get_node_list();
1022std::vector<PalfHandleImplGuard*> palf_list;
1023common::ObRegion beijing_region("BEIJING");
1024common::ObRegion shanghai_region("SHANGHAI");
1025
1026EXPECT_EQ(OB_SUCCESS, create_paxos_group(id, &loc_cb, leader_idx, leader));
1027EXPECT_EQ(OB_SUCCESS, get_cluster_palf_handle_guard(id, palf_list));
1028loc_cb.leader_ = get_cluster()[leader_idx]->get_addr();
1029
1030// 1. init
1031for (int64_t i = 3; i < ObSimpleLogClusterTestBase::node_cnt_; ++i) {
1032common::ObMember added_learner;
1033EXPECT_EQ(OB_SUCCESS, node_list.get_member_by_index(i, added_learner));
1034LogLearner learner(added_learner.get_server(), 1);
1035EXPECT_EQ(OB_SUCCESS, all_learner.add_learner(learner));
1036EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(added_learner, CONFIG_CHANGE_TIMEOUT));
1037}
1038
1039// set region, version 42x
1040// for (int i = 0; i < ObSimpleLogClusterTestBase::node_cnt_; i++) {
1041// const common::ObAddr addr = palf_list[i]->palf_handle_impl_->self_;
1042// if (leader.palf_handle_impl_->config_mgr_.alive_paxos_memberlist_.contains(addr)) {
1043// get_cluster()[0]->get_locality_manager()->set_server_region(addr, beijing_region);
1044// } else {
1045// get_cluster()[0]->get_locality_manager()->set_server_region(addr, shanghai_region);
1046// }
1047// }
1048// for (auto palf_handle: palf_list) { palf_handle->palf_handle_impl_->update_self_region_(); }
1049
1050// set region, version 421, master
1051LogMemberRegionMap region_map;
1052EXPECT_EQ(OB_SUCCESS, region_map.init("localmap", OB_MAX_MEMBER_NUMBER));
1053for (int i = 0; i < ObSimpleLogClusterTestBase::member_cnt_; i++) {
1054const common::ObAddr addr = palf_list[i]->palf_handle_impl_->self_;
1055if (leader.palf_handle_impl_->config_mgr_.alive_paxos_memberlist_.contains(addr)) {
1056EXPECT_EQ(OB_SUCCESS, palf_list[i]->palf_handle_impl_->set_region(beijing_region));
1057region_map.insert(addr, beijing_region);
1058} else {
1059EXPECT_EQ(OB_SUCCESS, palf_list[i]->palf_handle_impl_->set_region(shanghai_region));
1060region_map.insert(addr, shanghai_region);
1061}
1062}
1063// notify leader region of follower i has changed
1064EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->set_paxos_member_region_map(region_map));
1065
1066// check topo
1067EXPECT_UNTIL_EQ(true, check_children_valid(palf_list, all_learner));
1068EXPECT_UNTIL_EQ(1, leader.palf_handle_impl_->config_mgr_.children_.get_member_number());
1069EXPECT_UNTIL_EQ(0, palf_list[1]->palf_handle_impl_->config_mgr_.children_.get_member_number());
1070EXPECT_UNTIL_EQ(0, palf_list[2]->palf_handle_impl_->config_mgr_.children_.get_member_number());
1071ObAddr same_parent, any_child;
1072int64_t any_child_idx = -1;
1073for (int i = 0; i < ObSimpleLogClusterTestBase::node_cnt_; i++)
1074{
1075const common::ObAddr addr = palf_list[i]->palf_handle_impl_->self_;
1076if (leader.palf_handle_impl_->config_mgr_.children_.contains(addr)) {
1077EXPECT_UNTIL_EQ(palf_list[i]->palf_handle_impl_->config_mgr_.parent_, leader.palf_handle_impl_->self_);
1078same_parent = addr;
1079PALF_LOG(INFO, "SAME_PARENT", K(id), K(addr), K(same_parent));
1080break;
1081}
1082}
1083EXPECT_TRUE(same_parent.is_valid());
1084for (int i = 0; i < ObSimpleLogClusterTestBase::node_cnt_; i++)
1085{
1086const common::ObAddr addr = palf_list[i]->palf_handle_impl_->self_;
1087if (all_learner.contains(addr) && addr != same_parent) {
1088EXPECT_UNTIL_EQ(same_parent, palf_list[i]->palf_handle_impl_->config_mgr_.parent_);
1089any_child = addr;
1090any_child_idx = i;
1091PALF_LOG(INFO, "CHECK_PARENT", K(id), K(addr), K(same_parent));
1092}
1093}
1094// 2. replicating logs to all F replicas
1095EXPECT_NE(-1, any_child_idx);
1096EXPECT_UNTIL_EQ(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.config_version_,
1097palf_list[any_child_idx]->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.config_version_);
1098EXPECT_UNTIL_EQ(leader.palf_handle_impl_->get_max_lsn().val_, leader.palf_handle_impl_->get_end_lsn().val_);
1099for (int i = 0; i < ObSimpleLogClusterTestBase::node_cnt_; i++) {
1100const common::ObAddr &addr = palf_list[i]->palf_handle_impl_->self_;
1101if (true == all_learner.contains(addr)) {
1102block_pcode(i, ObRpcPacketCode::OB_LOG_PUSH_REQ);
1103}
1104}
1105EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
1106EXPECT_UNTIL_EQ(leader.palf_handle_impl_->get_max_lsn().val_, leader.palf_handle_impl_->get_end_lsn().val_);
1107
1108// 3. switch a R replica to F
1109LogConfigVersion config_version;
1110ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version));
1111EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->switch_learner_to_acceptor(ObMember(any_child, -1), 4, config_version, CONFIG_CHANGE_TIMEOUT));
1112
1113// 4. enable the remaining R re-register parents
1114leader.palf_handle_impl_->config_mgr_.children_.reset();
1115for (auto palf_handle: palf_list) {
1116const common::ObAddr addr = palf_handle->palf_handle_impl_->self_;
1117if (true == all_learner.contains(addr) && addr != any_child) {
1118palf_handle->palf_handle_impl_->config_mgr_.retire_parent_();
1119palf_handle->palf_handle_impl_->config_mgr_.register_parent_();
1120}
1121}
1122
1123// 5. check loop
1124for (int i = 0; i < ObSimpleLogClusterTestBase::node_cnt_; i++) {
1125const common::ObAddr &addr = palf_list[i]->palf_handle_impl_->self_;
1126if (true == all_learner.contains(addr)) {
1127block_pcode(i, ObRpcPacketCode::OB_LOG_PUSH_REQ);
1128}
1129}
1130sleep(2);
1131
1132EXPECT_EQ(OB_SUCCESS, all_learner.remove_learner(any_child));
1133for (auto palf_handle: palf_list) {
1134const common::ObAddr addr = palf_handle->palf_handle_impl_->self_;
1135if (true == all_learner.contains(addr)) {
1136EXPECT_UNTIL_EQ(true, palf_handle->palf_handle_impl_->config_mgr_.parent_.is_valid());
1137EXPECT_UNTIL_EQ(false, palf_handle->palf_handle_impl_->config_mgr_.children_.contains(palf_handle->palf_handle_impl_->config_mgr_.parent_));
1138}
1139}
1140
1141revert_cluster_palf_handle_guard(palf_list);
1142PALF_LOG(INFO, "end test learner_loop", K(id));
1143}
1144
1145} // end unittest
1146} // end oceanbase
1147
1148int main(int argc, char **argv)
1149{
1150RUN_SIMPLE_LOG_CLUSTER_TEST(TEST_NAME);
1151}
1152