oceanbase
550 строк · 25.8 Кб
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 "lib/ob_define.h"
14#include "lib/ob_errno.h"
15#include <cstdio>
16#include <gtest/gtest.h>
17#include <signal.h>
18#include <stdexcept>
19#define private public
20#define protected public
21#include "env/ob_simple_log_cluster_env.h"
22#undef private
23#undef protected
24#include "logservice/palf/log_reader_utils.h"
25#include "logservice/palf/log_define.h"
26#include "logservice/palf/log_group_entry_header.h"
27#include "logservice/palf/log_io_worker.h"
28#include "logservice/palf/lsn.h"
29
30const std::string TEST_NAME = "log_restart";
31using namespace oceanbase::common;
32using namespace oceanbase;
33namespace oceanbase
34{
35using namespace logservice;
36namespace unittest
37{
38class TestObSimpleLogClusterRestart : public ObSimpleLogClusterTestEnv
39{
40public:
41TestObSimpleLogClusterRestart() : ObSimpleLogClusterTestEnv()
42{
43int ret = init();
44if (OB_SUCCESS != ret) {
45throw std::runtime_error("TestObSimpleLogClusterLogEngine init failed");
46}
47}
48~TestObSimpleLogClusterRestart()
49{
50destroy();
51}
52int init()
53{
54return OB_SUCCESS;
55}
56void destroy()
57{}
58int64_t id_;
59PalfHandleImplGuard leader_;
60};
61
62int64_t ObSimpleLogClusterTestBase::member_cnt_ = 1;
63int64_t ObSimpleLogClusterTestBase::node_cnt_ = 1;
64std::string ObSimpleLogClusterTestBase::test_name_ = TEST_NAME;
65bool ObSimpleLogClusterTestBase::need_add_arb_server_ = false;
66constexpr int64_t timeout_ts_us = 3 * 1000 * 1000;
67
68
69TEST_F(TestObSimpleLogClusterRestart, read_block_in_flashback)
70{
71disable_hot_cache_ = true;
72SET_CASE_LOG_FILE(TEST_NAME, "read_block_in_flashback");
73OB_LOGGER.set_log_level("TRACE");
74const int64_t id = ATOMIC_AAF(&palf_id_, 1);
75int64_t leader_idx = 0;
76PalfHandleImplGuard leader;
77PalfEnv *palf_env = NULL;
78EXPECT_EQ(OB_SUCCESS, create_paxos_group(id, leader_idx, leader));
79
80EXPECT_EQ(OB_SUCCESS, submit_log(leader, 2 * 32 + 2, id, MAX_LOG_BODY_SIZE));
81EXPECT_EQ(OB_SUCCESS, wait_until_has_committed(leader, leader.get_palf_handle_impl()->get_max_lsn()));
82
83block_id_t min_block_id, max_block_id;
84LogStorage *log_storage = &leader.get_palf_handle_impl()->log_engine_.log_storage_;
85EXPECT_EQ(OB_SUCCESS, log_storage->get_block_id_range(min_block_id, max_block_id));
86EXPECT_EQ(2, max_block_id);
87SCN scn;
88char block_name_tmp[OB_MAX_FILE_NAME_LENGTH];
89EXPECT_EQ(OB_SUCCESS, block_id_to_tmp_string(max_block_id, block_name_tmp, OB_MAX_FILE_NAME_LENGTH));
90char block_name[OB_MAX_FILE_NAME_LENGTH];
91EXPECT_EQ(OB_SUCCESS, block_id_to_string(max_block_id, block_name, OB_MAX_FILE_NAME_LENGTH));
92::renameat(log_storage->block_mgr_.dir_fd_, block_name, log_storage->block_mgr_.dir_fd_, block_name_tmp);
93EXPECT_EQ(-1, ::openat(log_storage->block_mgr_.dir_fd_, block_name, LOG_READ_FLAG));
94EXPECT_EQ(OB_NEED_RETRY, read_log(leader));
95EXPECT_EQ(OB_NEED_RETRY, log_storage->get_block_min_scn(max_block_id, scn));
96
97// 测试边界场景,read_log_tail_为文件中间,最后一个文件完全被flashback掉, 此时log_tail_是最后一个文件头
98log_storage->log_tail_ = LSN(2*PALF_BLOCK_SIZE);
99EXPECT_EQ(OB_NEED_RETRY, read_log(leader));
100EXPECT_EQ(OB_NEED_RETRY, log_storage->get_block_min_scn(max_block_id, scn));
101
102// 测试边界场景,read_log_tail_最后一个文件头,最后一个文件完全被flashback掉
103log_storage->log_tail_ = LSN(2*PALF_BLOCK_SIZE);
104log_storage->readable_log_tail_ = LSN(2*PALF_BLOCK_SIZE);
105EXPECT_EQ(OB_ITER_END, read_log(leader));
106EXPECT_EQ(OB_ERR_OUT_OF_UPPER_BOUND, log_storage->get_block_min_scn(max_block_id, scn));
107
108// 不太好模拟这种场景,考虑引入debug sync
109// // 测试边界场景,readable_log_tail_还没改变前检验是否可读通过,直接读文件时报错文件不存在。
110// log_storage->log_tail_ = LSN(3*PALF_BLOCK_SIZE);
111// log_storage->readable_log_tail_ = LSN(3*PALF_BLOCK_SIZE);
112// // 设置max_block_id_为1是为了构造check_read_out_of_bound返回OB_ERR_OUT_OF_UPPER_BOUND的场景
113// log_storage->block_mgr_.max_block_id_ = 1;
114// // log_storage返回OB_ERR_OUT_OF_UPPER_BOUND, iterator将其转换为OB_ITER_END
115// EXPECT_EQ(OB_ITER_END, read_log(leader));
116// EXPECT_EQ(OB_ERR_OUT_OF_UPPER_BOUND, log_storage->get_block_min_scn(max_block_id, scn));
117}
118
119TEST_F(TestObSimpleLogClusterRestart, restart_when_first_log_block_is_empty)
120{
121SET_CASE_LOG_FILE(TEST_NAME, "restart_when_first_log_block_is_empty");
122OB_LOGGER.set_log_level("TRACE");
123const int64_t id = ATOMIC_AAF(&palf_id_, 1);
124int64_t leader_idx = 0;
125// 创建日志流后不写入任何数据
126{
127PalfHandleImplGuard leader;
128EXPECT_EQ(OB_SUCCESS, create_paxos_group(id, leader_idx, leader));
129}
130EXPECT_EQ(OB_SUCCESS, restart_paxos_groups());
131// 测试truncate场景
132{
133PalfHandleImplGuard leader;
134EXPECT_EQ(OB_SUCCESS, get_leader(id, leader, leader_idx));
135EXPECT_EQ(LSN(PALF_INITIAL_LSN_VAL), leader.palf_handle_impl_->get_max_lsn());
136EXPECT_EQ(OB_SUCCESS, submit_log(leader, 1, id, MAX_LOG_BODY_SIZE));
137EXPECT_EQ(OB_SUCCESS, wait_lsn_until_flushed(leader.palf_handle_impl_->get_max_lsn(), leader));
138EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->log_engine_.truncate(LSN(0)));
139}
140EXPECT_EQ(OB_SUCCESS, restart_paxos_groups());
141LSN rebuild_lsn(2*PALF_BLOCK_SIZE);
142// 测试rebuild场景
143{
144PalfHandleImplGuard leader;
145EXPECT_EQ(OB_SUCCESS, get_leader(id, leader, leader_idx));
146EXPECT_EQ(LSN(PALF_INITIAL_LSN_VAL), leader.palf_handle_impl_->get_max_lsn());
147EXPECT_EQ(OB_SUCCESS, submit_log(leader, 40, id, MAX_LOG_BODY_SIZE));
148EXPECT_EQ(OB_SUCCESS, wait_until_has_committed(leader, leader.palf_handle_impl_->get_max_lsn()));
149PalfBaseInfo base_info;
150base_info.generate_by_default();
151base_info.curr_lsn_ = rebuild_lsn;
152base_info.prev_log_info_.accum_checksum_ = 10000;
153base_info.prev_log_info_.log_id_ = 100;
154base_info.prev_log_info_.lsn_ = rebuild_lsn - 4096;
155base_info.prev_log_info_.log_proposal_id_ = 2;
156base_info.prev_log_info_.scn_ = leader.palf_handle_impl_->get_max_scn();
157
158leader.palf_handle_impl_->state_mgr_.role_ = FOLLOWER;
159EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->disable_sync());
160EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->advance_base_info(base_info, true));
161while (leader.palf_handle_impl_->log_engine_.log_storage_.get_end_lsn() != rebuild_lsn) {
162sleep(1);
163PALF_LOG(INFO, "has not finish rebuild", K(leader.palf_handle_impl_->log_engine_.log_storage_));
164}
165}
166EXPECT_EQ(OB_SUCCESS, restart_paxos_groups());
167// 测试flashback场景
168{
169PalfHandleImplGuard leader;
170EXPECT_EQ(OB_SUCCESS, get_leader(id, leader, leader_idx));
171EXPECT_EQ(rebuild_lsn, leader.palf_handle_impl_->get_max_lsn());
172EXPECT_EQ(OB_SUCCESS, submit_log(leader, 1, id, MAX_LOG_BODY_SIZE));
173EXPECT_EQ(OB_SUCCESS, wait_until_has_committed(leader, leader.palf_handle_impl_->get_max_lsn()));
174int64_t mode_version;
175switch_append_to_flashback(leader, mode_version);
176EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->flashback(mode_version, SCN::min_scn(), 10*1000*1000));
177}
178EXPECT_EQ(OB_SUCCESS, restart_paxos_groups());
179{
180PalfHandleImplGuard leader;
181EXPECT_EQ(OB_SUCCESS, get_leader(id, leader, leader_idx));
182EXPECT_EQ(rebuild_lsn, leader.palf_handle_impl_->get_max_lsn());
183int64_t mode_version;
184switch_flashback_to_append(leader, mode_version);
185EXPECT_EQ(OB_SUCCESS, submit_log(leader, 1, id, MAX_LOG_BODY_SIZE));
186EXPECT_EQ(OB_SUCCESS, wait_until_has_committed(leader, leader.palf_handle_impl_->get_max_lsn()));
187}
188}
189
190TEST_F(TestObSimpleLogClusterRestart, test_restart)
191{
192SET_CASE_LOG_FILE(TEST_NAME, "test_restart");
193int64_t id = ATOMIC_AAF(&palf_id_, 1);
194int64_t leader_idx = 0;
195char meta_fd[OB_MAX_FILE_NAME_LENGTH] = {'\0'};
196char log_fd[OB_MAX_FILE_NAME_LENGTH] = {'\0'};
197ObServerLogBlockMgr *pool = NULL;
198{
199PalfHandleImplGuard leader;
200EXPECT_EQ(OB_SUCCESS, create_paxos_group(id, leader_idx, leader));
201EXPECT_EQ(OB_SUCCESS, submit_log(leader, 1, id, MAX_LOG_BODY_SIZE));
202wait_lsn_until_flushed(leader.palf_handle_impl_->get_max_lsn(), leader);
203LogEngine *log_engine = &leader.palf_handle_impl_->log_engine_;
204char *meta_log_dir = log_engine->log_meta_storage_.block_mgr_.log_dir_;
205char *log_dir = log_engine->log_storage_.block_mgr_.log_dir_;
206EXPECT_EQ(OB_SUCCESS, get_log_pool(leader_idx, pool));
207char *pool_dir = pool->log_pool_path_;
208snprintf(meta_fd, OB_MAX_FILE_NAME_LENGTH, "mv %s/%d %s/%d", meta_log_dir, 0, pool_dir, 10000000);
209snprintf(log_fd, OB_MAX_FILE_NAME_LENGTH, "mv %s/%d %s/%d", log_dir, 0, pool_dir, 100000001);
210system(meta_fd);
211}
212OB_LOGGER.set_log_level("TRACE");
213sleep(1);
214EXPECT_EQ(OB_ERR_UNEXPECTED, restart_paxos_groups());
215system(log_fd);
216PALF_LOG(INFO, "first restart_paxos_groups, after meta dir is empty while log dir is not");
217EXPECT_EQ(OB_SUCCESS, restart_paxos_groups());
218
219// 验证切文件过程中宕机重启
220{
221PalfHandleImplGuard leader;
222EXPECT_EQ(OB_SUCCESS, create_paxos_group(id, leader_idx, leader));
223EXPECT_EQ(OB_SUCCESS, get_leader(id, leader, leader_idx));
224EXPECT_EQ(OB_SUCCESS, submit_log(leader, 33, id, MAX_LOG_BODY_SIZE));
225wait_lsn_until_flushed(leader.palf_handle_impl_->get_max_lsn(), leader);
226block_id_t min_block_id, max_block_id;
227LogStorage *log_storage = &leader.palf_handle_impl_->log_engine_.log_storage_;
228LogStorage *meta_storage = &leader.get_palf_handle_impl()->log_engine_.log_meta_storage_;
229EXPECT_EQ(OB_SUCCESS, log_storage->get_block_id_range(min_block_id, max_block_id));
230EXPECT_EQ(1, max_block_id);
231// 模拟只switch block,但没有更新manifest, 此时manifest依旧是1, 宕机重启后由于2号文件为空,manifest会被更新为2
232EXPECT_EQ(OB_SUCCESS, log_storage->truncate(LSN(PALF_BLOCK_SIZE)));
233EXPECT_EQ(OB_SUCCESS, log_storage->update_manifest_(1));
234EXPECT_EQ(PALF_BLOCK_SIZE, log_storage->curr_block_writable_size_);
235EXPECT_EQ(1, lsn_2_block(meta_storage->log_block_header_.min_lsn_, PALF_BLOCK_SIZE));
236}
237PALF_LOG(INFO, "second restart_paxos_groups after restart in process of switch block");
238EXPECT_EQ(OB_SUCCESS, restart_paxos_groups());
239{
240PalfHandleImplGuard leader;
241EXPECT_EQ(OB_SUCCESS, get_leader(id, leader, leader_idx));
242//检查manifest是否为3
243EXPECT_EQ(OB_SUCCESS, submit_log(leader, 1, id, MAX_LOG_BODY_SIZE));
244LogStorage *meta_storage = &leader.get_palf_handle_impl()->log_engine_.log_meta_storage_;
245EXPECT_EQ(2, lsn_2_block(meta_storage->log_block_header_.min_lsn_, PALF_BLOCK_SIZE));
246}
247PALF_LOG(INFO, "third restart_paxos_groups");
248EXPECT_EQ(OB_SUCCESS, restart_paxos_groups());
249// 验证重启后新建日志流
250{
251PalfHandleImplGuard leader;
252id = ATOMIC_AAF(&palf_id_, 1);
253EXPECT_EQ(OB_SUCCESS, create_paxos_group(id, leader_idx, leader));
254EXPECT_EQ(OB_SUCCESS, submit_log(leader, 66, id, MAX_LOG_BODY_SIZE));
255wait_lsn_until_flushed(leader.palf_handle_impl_->get_max_lsn(), leader);
256EXPECT_EQ(OB_ITER_END, read_log(leader));
257}
258// 验证truncate或flashback过程中,修改完manifest后,删除文件前宕机重启(删除1个文件)
259{
260PalfHandleImplGuard leader;
261EXPECT_EQ(OB_SUCCESS, get_leader(id, leader, leader_idx));
262block_id_t min_block_id, max_block_id;
263// 此时manifest为3
264LogStorage *log_storage = &leader.palf_handle_impl_->log_engine_.log_storage_;
265LogStorage *meta_storage = &leader.get_palf_handle_impl()->log_engine_.log_meta_storage_;
266EXPECT_EQ(OB_SUCCESS, log_storage->get_block_id_range(min_block_id, max_block_id));
267EXPECT_EQ(2, max_block_id);
268EXPECT_EQ(3, lsn_2_block(meta_storage->log_block_header_.min_lsn_, PALF_BLOCK_SIZE));
269// truncate 或 flashback会先更新manifest为2
270EXPECT_EQ(OB_SUCCESS, log_storage->update_manifest_(2));
271EXPECT_EQ(2, lsn_2_block(meta_storage->log_block_header_.min_lsn_, PALF_BLOCK_SIZE));
272}
273PALF_LOG(INFO, "fourth restart_paxos_groups after modify manifest while not delete block");
274// 验证truncate或flashback过程中,修改完manifest后,truncaet/flashback正好将最后一个文件清空
275EXPECT_EQ(OB_SUCCESS, restart_paxos_groups());
276{
277PalfHandleImplGuard leader;
278EXPECT_EQ(OB_SUCCESS, get_leader(id, leader, leader_idx));
279block_id_t min_block_id, max_block_id;
280// 此时manifest为2
281LogStorage *log_storage = &leader.palf_handle_impl_->log_engine_.log_storage_;
282LogStorage *meta_storage = &leader.get_palf_handle_impl()->log_engine_.log_meta_storage_;
283EXPECT_EQ(OB_SUCCESS, log_storage->get_block_id_range(min_block_id, max_block_id));
284EXPECT_EQ(2, max_block_id);
285// 尽管manifest为2,但在这种场景下,2号文件是可以删除的
286EXPECT_EQ(2, lsn_2_block(meta_storage->log_block_header_.min_lsn_, PALF_BLOCK_SIZE));
287EXPECT_EQ(OB_SUCCESS, log_storage->truncate(LSN(2*PALF_BLOCK_SIZE)));
288EXPECT_EQ(OB_SUCCESS, log_storage->update_manifest_(2));
289}
290PALF_LOG(INFO, "five restart_paxos_groups after modify manifest and last block is empty");
291EXPECT_EQ(OB_SUCCESS, restart_paxos_groups());
292{
293PalfHandleImplGuard leader;
294EXPECT_EQ(OB_SUCCESS, get_leader(id, leader, leader_idx));
295block_id_t min_block_id, max_block_id;
296// 重启之后,由于磁盘上最大的文件为2,同时该文件为空,此时会更新manifest为3
297LogStorage *log_storage = &leader.palf_handle_impl_->log_engine_.log_storage_;
298LogStorage *meta_storage = &leader.get_palf_handle_impl()->log_engine_.log_meta_storage_;
299EXPECT_EQ(OB_SUCCESS, log_storage->get_block_id_range(min_block_id, max_block_id));
300EXPECT_EQ(2, max_block_id);
301EXPECT_EQ(3, lsn_2_block(meta_storage->log_block_header_.min_lsn_, PALF_BLOCK_SIZE));
302EXPECT_EQ(OB_SUCCESS, submit_log(leader, 1, id, MAX_LOG_BODY_SIZE));
303wait_lsn_until_flushed(leader.palf_handle_impl_->get_max_lsn(), leader);
304EXPECT_EQ(3, lsn_2_block(meta_storage->log_block_header_.min_lsn_, PALF_BLOCK_SIZE));
305}
306PALF_LOG(INFO, "six restart_paxos_groups");
307// 验证base lsn 大于持久化的committed 位点
308{
309PalfHandleImplGuard leader;
310EXPECT_EQ(OB_SUCCESS, get_leader(id, leader, leader_idx));
311LogStorage *log_storage = &leader.palf_handle_impl_->log_engine_.log_storage_;
312LogIOWorker *iow = leader.palf_handle_impl_->log_engine_.log_io_worker_;
313int64_t epoch = leader.palf_handle_impl_->log_engine_.palf_epoch_;
314int64_t palf_id = leader.palf_handle_impl_->palf_id_;
315EXPECT_EQ(OB_SUCCESS, submit_log(leader, 29, id, MAX_LOG_BODY_SIZE));
316EXPECT_EQ(OB_SUCCESS, wait_lsn_until_flushed(leader.palf_handle_impl_->get_max_lsn(), leader));
317// 预期log_tail接近文件2的尾部
318EXPECT_LE(LSN(3*PALF_BLOCK_SIZE) - log_storage->log_tail_, 5*1024*1024);
319EXPECT_EQ(OB_SUCCESS, wait_until_has_committed(leader, leader.palf_handle_impl_->get_end_lsn()));
320sleep(1);
321EXPECT_EQ(OB_SUCCESS, submit_log(leader, 1, id, 1000));
322wait_lsn_until_flushed(leader.palf_handle_impl_->get_max_lsn(), leader);
323EXPECT_EQ(OB_SUCCESS, wait_lsn_until_flushed(leader.palf_handle_impl_->get_max_lsn(), leader));
324IOTaskConsumeCond cond(palf_id, epoch);
325EXPECT_EQ(OB_SUCCESS, iow->submit_io_task(&cond));
326EXPECT_EQ(OB_SUCCESS, submit_log(leader, 10, id, MAX_LOG_BODY_SIZE));
327while (1) {
328if (leader.palf_handle_impl_->sw_.last_submit_end_lsn_ < leader.palf_handle_impl_->get_max_lsn()) {
329usleep(5000);
330leader.palf_handle_impl_->sw_.freeze_mode_ = FEEDBACK_FREEZE_MODE;
331leader.palf_handle_impl_->sw_.feedback_freeze_last_log_();
332PALF_LOG(INFO, "has log in sw", "last_submit_end_lsn", leader.palf_handle_impl_->sw_.last_submit_end_lsn_,
333"max_lsn", leader.palf_handle_impl_->get_max_lsn());
334} else {
335break;
336}
337}
338cond.cond_.signal();
339EXPECT_EQ(OB_SUCCESS, wait_lsn_until_flushed(leader.palf_handle_impl_->get_max_lsn(), leader));
340PALF_LOG(INFO, "after wait_lsn_until_flushed", "end_lsn:", leader.palf_handle_impl_->get_end_lsn(),
341"max_lsn:", leader.palf_handle_impl_->get_end_lsn());
342EXPECT_EQ(OB_SUCCESS, wait_until_has_committed(leader, leader.palf_handle_impl_->get_max_lsn()));
343EXPECT_GE(leader.palf_handle_impl_->get_max_lsn(), LSN(3*PALF_BLOCK_SIZE));
344EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->set_base_lsn(LSN(3*PALF_BLOCK_SIZE)));
345}
346EXPECT_EQ(OB_SUCCESS, restart_paxos_groups());
347PALF_LOG(INFO, "seven restart_paxos_groups after committed lsn is smaller than base lsn");
348// 验证rebuild过程中持久化palf_base_info后,宕机重启
349{
350PalfHandleImplGuard leader;
351EXPECT_EQ(OB_SUCCESS, get_leader(id, leader, leader_idx));
352LogStorage *log_storage = &leader.palf_handle_impl_->log_engine_.log_storage_;
353LogIOWorker *iow = leader.palf_handle_impl_->log_engine_.log_io_worker_;
354int64_t epoch = leader.palf_handle_impl_->log_engine_.palf_epoch_;
355int64_t palf_id = leader.palf_handle_impl_->palf_id_;
356EXPECT_EQ(OB_SUCCESS, submit_log(leader, 10, id, MAX_LOG_BODY_SIZE));
357EXPECT_EQ(OB_SUCCESS, wait_until_has_committed(leader, leader.palf_handle_impl_->get_end_lsn()));
358sleep(1);
359EXPECT_EQ(OB_SUCCESS, submit_log(leader, 1, id, 1000));
360wait_lsn_until_flushed(leader.palf_handle_impl_->get_max_lsn(), leader);
361EXPECT_EQ(OB_SUCCESS, wait_lsn_until_flushed(leader.palf_handle_impl_->get_max_lsn(), leader));
362IOTaskConsumeCond cond(palf_id, epoch);
363EXPECT_EQ(OB_SUCCESS, iow->submit_io_task(&cond));
364EXPECT_EQ(OB_SUCCESS, submit_log(leader, 10, id, MAX_LOG_BODY_SIZE));
365while (1) {
366if (leader.palf_handle_impl_->sw_.last_submit_end_lsn_ < leader.palf_handle_impl_->get_max_lsn()) {
367usleep(5000);
368leader.palf_handle_impl_->sw_.freeze_mode_ = FEEDBACK_FREEZE_MODE;
369leader.palf_handle_impl_->sw_.feedback_freeze_last_log_();
370PALF_LOG(INFO, "has log in sw", "last_submit_end_lsn", leader.palf_handle_impl_->sw_.last_submit_end_lsn_,
371"max_lsn", leader.palf_handle_impl_->get_max_lsn());
372} else {
373break;
374}
375}
376cond.cond_.signal();
377EXPECT_EQ(OB_SUCCESS, wait_lsn_until_flushed(leader.palf_handle_impl_->get_max_lsn(), leader));
378PALF_LOG(INFO, "after wait_lsn_until_flushed", "end_lsn:", leader.palf_handle_impl_->get_end_lsn(),
379"max_lsn:", leader.palf_handle_impl_->get_end_lsn());
380EXPECT_EQ(OB_SUCCESS, wait_until_has_committed(leader, leader.palf_handle_impl_->get_max_lsn()));
381EXPECT_GE(leader.palf_handle_impl_->get_max_lsn(), LSN(3*PALF_BLOCK_SIZE));
382PalfBaseInfo base_info;
383EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_base_info(
384leader.palf_handle_impl_->get_max_lsn(), base_info));
385LogSnapshotMeta snapshot;
386base_info.prev_log_info_.lsn_ = LSN(10*PALF_BLOCK_SIZE - 10*1024);
387EXPECT_EQ(OB_SUCCESS, snapshot.generate(LSN(10*PALF_BLOCK_SIZE), base_info.prev_log_info_));
388FlushMetaCbCtx meta_ctx;
389meta_ctx.type_ = SNAPSHOT_META;
390meta_ctx.base_lsn_ = snapshot.base_lsn_;
391EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->log_engine_.submit_flush_snapshot_meta_task(meta_ctx, snapshot));
392sleep(2);
393}
394EXPECT_EQ(OB_SUCCESS, restart_paxos_groups());
395PALF_LOG(INFO, "seven restart_paxos_groups after committed lsn is smaller than base lsn");
396{
397PalfHandleImplGuard leader;
398EXPECT_EQ(OB_SUCCESS, get_leader(id, leader, leader_idx));
399EXPECT_EQ(LSN(10*PALF_BLOCK_SIZE), leader.palf_handle_impl_->get_max_lsn());
400EXPECT_EQ(LSN(10*PALF_BLOCK_SIZE), leader.palf_handle_impl_->log_engine_.log_storage_.get_end_lsn());
401EXPECT_EQ(OB_SUCCESS, submit_log(leader, 10, id, 1000));
402EXPECT_EQ(OB_SUCCESS, wait_lsn_until_flushed(leader.palf_handle_impl_->get_max_lsn(), leader));
403}
404}
405
406TEST_F(TestObSimpleLogClusterRestart, advance_base_lsn_with_restart)
407{
408SET_CASE_LOG_FILE(TEST_NAME, "advance_base_lsn_with_restart");
409OB_LOGGER.set_log_level("INFO");
410const int64_t id = ATOMIC_AAF(&palf_id_, 1);
411PALF_LOG(INFO, "start advance_base_lsn", K(id));
412int64_t leader_idx = 0;
413int64_t log_ts = 1;
414{
415PalfHandleImplGuard leader;
416EXPECT_EQ(OB_SUCCESS, create_paxos_group(id, leader_idx, leader));
417EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id));
418sleep(2);
419LSN log_tail =
420leader.palf_handle_impl_->log_engine_.log_meta_storage_.log_tail_;
421int count = (LSN(PALF_META_BLOCK_SIZE) - log_tail)/4096;
422for (int64_t i = 0; i < count; i++) {
423EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->enable_vote());
424}
425while (LSN(PALF_META_BLOCK_SIZE) !=
426leader.palf_handle_impl_->log_engine_.log_meta_storage_.log_tail_)
427{
428sleep(1);
429}
430sleep(1);
431EXPECT_EQ(LSN(PALF_META_BLOCK_SIZE), leader.palf_handle_impl_->log_engine_.log_meta_storage_.log_tail_);
432EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->log_engine_.log_meta_storage_.block_mgr_.switch_next_block(1));
433}
434EXPECT_EQ(OB_SUCCESS, restart_paxos_groups());
435{
436PalfHandleImplGuard leader;
437EXPECT_EQ(OB_SUCCESS, get_leader(id, leader, leader_idx));
438EXPECT_LT(LSN(PALF_META_BLOCK_SIZE), leader.palf_handle_impl_->log_engine_.log_meta_storage_.log_tail_);
439EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->set_base_lsn(LSN(0)));
440sleep(1);
441EXPECT_LT(LSN(PALF_META_BLOCK_SIZE) + 4096, leader.palf_handle_impl_->log_engine_.log_meta_storage_.log_tail_);
442}
443}
444
445TEST_F(TestObSimpleLogClusterRestart, restart_and_clear_tmp_files)
446{
447SET_CASE_LOG_FILE(TEST_NAME, "restart_and_clear_tmp_files");
448ObTimeGuard guard("restart_and_clear_tmp_files", 0);
449const int64_t id = ATOMIC_AAF(&palf_id_, 1);
450int64_t leader_idx = 0;
451std::string logserver_dir;
452{
453PalfHandleImplGuard leader;
454EXPECT_EQ(OB_SUCCESS, create_paxos_group(id, leader_idx, leader));
455guard.click("create");
456logserver_dir = leader.palf_env_impl_->log_dir_;
457EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, leader_idx, 1 * 1024 * 1024));
458guard.click("submit_log");
459while (leader.palf_handle_impl_->get_end_lsn()
460< LSN(100 * 1024 * 1024ul)) {
461usleep(100 * 1000);
462}
463}
464const std::string base_dir = logserver_dir;
465const std::string tmp_1_dir = base_dir + "/10000.tmp/log/";
466const std::string mkdir_tmp_1 = "mkdir -p " + tmp_1_dir;
467const std::string dir_2 = base_dir + "/10000000";
468const std::string dir_normal_file = base_dir + "/10000000/log/1";
469const std::string dir_normal_file1 = base_dir + "/10000000/meta/";
470const std::string mkdir_2 = "mkdir -p " + dir_normal_file;
471const std::string mkdir_3 = "mkdir -p " + dir_normal_file1;
472system(mkdir_tmp_1.c_str());
473system(mkdir_2.c_str());
474system(mkdir_3.c_str());
475int ret = OB_SUCCESS;
476guard.click("mkdir");
477EXPECT_EQ(OB_ERR_UNEXPECTED, restart_paxos_groups());
478CLOG_LOG(INFO, "after restart_paxos_groups after exist tmp dir");
479guard.click("restart");
480const std::string rm_dir_2 = "rm -rf " + dir_2;
481system(rm_dir_2.c_str());
482guard.click("rm_dir");
483if (OB_FAIL(restart_paxos_groups())) {
484PALF_LOG(ERROR, "restart_paxos_groups failed", K(ret));
485} else {
486{
487CLOG_LOG(INFO, "after restart_paxos_groups after remove tmp dir");
488guard.click("restart");
489bool result = false;
490EXPECT_EQ(OB_SUCCESS,
491common::FileDirectoryUtils::is_exists(tmp_1_dir.c_str(), result));
492EXPECT_EQ(result, false);
493PalfHandleImplGuard leader1;
494EXPECT_EQ(OB_SUCCESS, get_leader(id, leader1, leader_idx));
495guard.click("get_leader");
496LogStorage *log_storage =
497&leader1.palf_handle_impl_->log_engine_.log_storage_;
498LSN lsn_origin_log_tail = log_storage->get_log_tail_guarded_by_lock_();
499EXPECT_EQ(OB_SUCCESS, submit_log(leader1, 10, leader_idx, 1 * 1024 * 1024));
500while (log_storage->log_tail_ == lsn_origin_log_tail) {
501usleep(1 * 1000);
502PALF_LOG(INFO, "log_tail is same", KPC(log_storage), K(lsn_origin_log_tail));
503}
504guard.click("submit_log");
505EXPECT_EQ(OB_ITER_END, read_log(leader1));
506guard.click("read_log");
507PALF_LOG(INFO, "finish read_log", KPC(log_storage), K(lsn_origin_log_tail), KPC(leader1.palf_handle_impl_));
508}
509// 验证tenant下有临时文件的场景,该临时文件需要归还给log_pool
510{
511PalfHandleImplGuard leader1;
512int64_t leader_idx1 = 0;
513EXPECT_EQ(OB_SUCCESS, get_leader(id, leader1, leader_idx1));
514std::string palf_log_dir = leader1.palf_handle_impl_->log_engine_.log_storage_.block_mgr_.log_dir_;
515ObISimpleLogServer *i_server = get_cluster()[leader_idx1];
516ObSimpleLogServer *server = dynamic_cast<ObSimpleLogServer*>(i_server);
517std::string log_pool = server->log_block_pool_.log_pool_path_;
518const block_id_t min_block_id = server->log_block_pool_.min_block_id_;
519char src[1024] = {'\0'};
520char dest[1024] = {'\0'};
521block_id_to_tmp_string(10000, dest, 1024);
522block_id_to_string(min_block_id, src, 1024);
523std::string src_str = log_pool + "/" + src;
524std::string dest_str = palf_log_dir + "/" + dest;
525std::string mv_system = "mv " + src_str + " " + dest_str;
526system(mv_system.c_str());
527bool result1 = false;
528EXPECT_EQ(OB_SUCCESS,
529common::FileDirectoryUtils::is_exists(dest_str.c_str(), result1));
530EXPECT_EQ(true, result1);
531leader1.reset();
532EXPECT_EQ(OB_SUCCESS, restart_paxos_groups());
533EXPECT_EQ(OB_SUCCESS,
534common::FileDirectoryUtils::is_exists(dest_str.c_str(), result1));
535EXPECT_EQ(false, result1);
536}
537EXPECT_EQ(OB_SUCCESS, remove_dir());
538EXPECT_EQ(OB_SUCCESS, restart_paxos_groups());
539}
540EXPECT_EQ(OB_SUCCESS, ret);
541PALF_LOG(INFO, "end test restart", K(id), K(guard));
542}
543
544} // namespace unittest
545} // namespace oceanbase
546
547int main(int argc, char **argv)
548{
549RUN_SIMPLE_LOG_CLUSTER_TEST(TEST_NAME);
550}
551