242 lines
8.7 KiB
C++
242 lines
8.7 KiB
C++
/**
|
|
* Copyright (c) 2021 OceanBase
|
|
* OceanBase CE is licensed under Mulan PubL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
|
* You may obtain a copy of Mulan PubL v2 at:
|
|
* http://license.coscl.org.cn/MulanPubL-2.0
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PubL v2 for more details.
|
|
*/
|
|
|
|
#include "lib/ob_errno.h"
|
|
#include "logservice/palf/log_define.h"
|
|
#include "share/ob_errno.h"
|
|
#include "share/ob_ls_id.h"
|
|
#include <cstdint>
|
|
#include <gtest/gtest.h>
|
|
#define private public
|
|
#include "logservice/restoreservice/ob_log_archive_piece_mgr.h"
|
|
#undef private
|
|
#include "fake_archive_piece_mgr.h"
|
|
#include "share/scn.h"
|
|
|
|
namespace oceanbase
|
|
{
|
|
using namespace palf;
|
|
namespace unittest
|
|
{
|
|
TEST(FakeArchivePieceContext, get_piece)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
const int64_t ONE_SECOND = 1000 * 1000 * 1000L;
|
|
const int64_t base_ts_1 = 1000 * ONE_SECOND;
|
|
share::SCN base_scn_1;
|
|
base_scn_1.convert_for_logservice(base_ts_1);
|
|
const int64_t piece_switch_interval = 10 * ONE_SECOND;
|
|
const int64_t ONE_MB = 1024 * 1024L;
|
|
FakeRounds rounds;
|
|
int64_t file_id = 1;
|
|
FakeArchiveComponent round1;
|
|
{
|
|
round1.state_ = FakeRoundState::STOP;
|
|
round1.round_id_ = 2;
|
|
round1.start_scn_.convert_for_logservice(1005 * ONE_SECOND);
|
|
round1.end_scn_.convert_for_logservice(1051 * ONE_SECOND);
|
|
round1.base_piece_id_ = 1;
|
|
round1.piece_switch_interval_ = piece_switch_interval;
|
|
round1.base_piece_scn_ = base_scn_1;
|
|
round1.min_piece_id_ = 1;
|
|
round1.max_piece_id_ = 6;
|
|
for (int64_t i = round1.min_piece_id_; OB_SUCC(ret) && i <= round1.max_piece_id_; i++) {
|
|
FakePieceComponent piece;
|
|
{
|
|
if (i == 3) {
|
|
piece.state_ = FakePieceState::EMPTY;
|
|
piece.piece_id_ = i;
|
|
piece.min_lsn_ = LSN((file_id - 1) * 64 * ONE_MB + 10240);
|
|
piece.max_lsn_ = LSN((file_id - 1) * 64 * ONE_MB + 10240);
|
|
} else {
|
|
piece.state_ = FakePieceState::FRONZEN;
|
|
piece.piece_id_ = i;
|
|
piece.min_file_id_ = file_id;
|
|
file_id = file_id + 10;
|
|
piece.max_file_id_ = file_id;
|
|
piece.min_lsn_ = LSN((piece.min_file_id_ - 1) * 64 * ONE_MB + 10240); // p1(1, 11), p2(11, 21), p3(EMPTY), p4(21, 31), p5(31, 41), p6(41, 51)
|
|
piece.max_lsn_ = LSN((piece.max_file_id_ - 1) * 64 * ONE_MB + 10240);
|
|
}
|
|
}
|
|
ret = round1.array_.push_back(piece);
|
|
EXPECT_EQ(OB_SUCCESS, ret);
|
|
CLOG_LOG(INFO, "COME HERE print", K(piece), K(round1.round_id_));
|
|
}
|
|
}
|
|
ret = rounds.array_.push_back(round1);
|
|
EXPECT_EQ(OB_SUCCESS, ret);
|
|
|
|
FakeArchiveComponent round2;
|
|
{
|
|
round2.state_ = FakeRoundState::STOP;
|
|
round2.round_id_ = 4;
|
|
round2.start_scn_.convert_for_logservice(1051 * ONE_SECOND);
|
|
round2.end_scn_.convert_for_logservice(1095 * ONE_SECOND);
|
|
round2.base_piece_id_ = 2;
|
|
round2.piece_switch_interval_ = piece_switch_interval;
|
|
round2.base_piece_scn_ = base_scn_1;
|
|
round2.min_piece_id_ = 7;
|
|
round2.max_piece_id_ = 11;
|
|
for (int64_t i = round2.min_piece_id_ ; OB_SUCC(ret) && i <= round2.max_piece_id_; i++) {
|
|
FakePieceComponent piece;
|
|
{
|
|
piece.state_ = FakePieceState::FRONZEN;
|
|
piece.piece_id_ = i;
|
|
piece.min_file_id_ = file_id;
|
|
file_id = file_id + 10;
|
|
piece.max_file_id_ = file_id;
|
|
piece.min_lsn_ = LSN((piece.min_file_id_ - 1) * 64 * ONE_MB + 10240); // p7(51, 61), p8(61, 71), p9(71, 81), p9(81, 91), p10(91, 101), p11(101, 111)
|
|
piece.max_lsn_ = LSN((piece.max_file_id_ - 1) * 64 * ONE_MB + 10240);
|
|
}
|
|
ret = round2.array_.push_back(piece);
|
|
EXPECT_EQ(OB_SUCCESS, ret);
|
|
CLOG_LOG(INFO, "COME HERE print", K(piece), K(round2.round_id_));
|
|
}
|
|
}
|
|
ret = rounds.array_.push_back(round2);
|
|
EXPECT_EQ(OB_SUCCESS, ret);
|
|
|
|
|
|
FakeArchiveComponent round3;
|
|
{
|
|
round3.state_ = FakeRoundState::STOP;
|
|
round3.round_id_ = 5;
|
|
round3.start_scn_.convert_for_logservice(1200 * ONE_SECOND);
|
|
round3.end_scn_.convert_for_logservice(1295 * ONE_SECOND);
|
|
round3.base_piece_id_ = 2;
|
|
round3.piece_switch_interval_ = piece_switch_interval;
|
|
round3.base_piece_scn_ = base_scn_1;
|
|
round3.min_piece_id_ = 20;
|
|
round3.max_piece_id_ = 25;
|
|
for (int64_t i = round3.min_piece_id_; OB_SUCC(ret) && i < round3.max_piece_id_; i++) {
|
|
FakePieceComponent piece;
|
|
{
|
|
piece.state_ = FakePieceState::FRONZEN;
|
|
piece.piece_id_ = i;
|
|
piece.min_file_id_ = file_id;
|
|
file_id = file_id + 10;
|
|
piece.max_file_id_ = file_id;
|
|
piece.min_lsn_ = LSN((piece.min_file_id_ - 1) * 64 * ONE_MB + 10240); // p20(111, 121), p22(121, 131), p23(131, 141), p24(141, 151), p25(NO file)
|
|
piece.max_lsn_ = LSN((piece.max_file_id_ - 1) * 64 * ONE_MB + 10240);
|
|
}
|
|
ret = round3.array_.push_back(piece);
|
|
EXPECT_EQ(OB_SUCCESS, ret);
|
|
CLOG_LOG(INFO, "COME HERE print", K(piece), K(round3.round_id_));
|
|
}
|
|
FakePieceComponent piece;
|
|
{
|
|
piece.state_ = FakePieceState::ACTIVE;
|
|
piece.piece_id_ = round3.max_piece_id_;
|
|
piece.min_file_id_ = 0;
|
|
piece.max_file_id_ = 0;
|
|
}
|
|
ret = round3.array_.push_back(piece);
|
|
EXPECT_EQ(OB_SUCCESS, ret);
|
|
}
|
|
ret = rounds.array_.push_back(round3);
|
|
EXPECT_EQ(OB_SUCCESS, ret);
|
|
|
|
|
|
FakeArchivePieceContext archive_context;
|
|
FakeArchivePieceContext *context = &archive_context;
|
|
ret = archive_context.init(share::ObLSID(1001), &rounds);
|
|
EXPECT_EQ(OB_SUCCESS, ret);
|
|
|
|
int64_t log_ts = 1021 * ONE_SECOND;
|
|
share::SCN scn;
|
|
scn.convert_for_logservice(log_ts);
|
|
palf::LSN lsn(64 * ONE_MB + ONE_MB);
|
|
const int64_t ONE_PIECE_MB = 10 * 64 * ONE_MB;
|
|
int64_t dest_id = 0;
|
|
int64_t round_id = 0;
|
|
int64_t piece_id = 0;
|
|
int64_t cur_file_id = 0;
|
|
int64_t offset = 0;
|
|
bool to_newest = false;
|
|
palf::LSN max_lsn;
|
|
CLOG_LOG(INFO, "print get piece 1", K(lsn));
|
|
ret = context->get_piece(scn, lsn, dest_id, round_id, piece_id, cur_file_id, offset, max_lsn, to_newest);
|
|
EXPECT_EQ(OB_SUCCESS, ret);
|
|
EXPECT_EQ(round_id, 2);
|
|
EXPECT_EQ(piece_id, 1);
|
|
EXPECT_EQ(cur_file_id, 2);
|
|
EXPECT_EQ(offset, 0);
|
|
|
|
lsn = LSN(23 * 64 * ONE_MB);
|
|
CLOG_LOG(INFO, "print get piece 2", K(lsn));
|
|
scn.convert_for_logservice(log_ts + 3);
|
|
ret = context->get_piece(scn, lsn, dest_id, round_id, piece_id, cur_file_id, offset, max_lsn, to_newest);
|
|
EXPECT_EQ(OB_SUCCESS, ret);
|
|
EXPECT_EQ(round_id, 2);
|
|
EXPECT_EQ(piece_id, 4);
|
|
EXPECT_EQ(cur_file_id, 24);
|
|
EXPECT_EQ(offset, 0);
|
|
|
|
lsn = LSN(122 * 64 * ONE_MB);
|
|
CLOG_LOG(INFO, "print get piece 3", K(lsn));
|
|
scn.convert_for_logservice(log_ts+20);
|
|
ret = archive_context.get_piece(scn, lsn, dest_id, round_id, piece_id, cur_file_id, offset, max_lsn, to_newest);
|
|
EXPECT_EQ(OB_ARCHIVE_ROUND_NOT_CONTINUOUS, ret);
|
|
|
|
archive_context.reset_locate_info();
|
|
log_ts = 1199 * ONE_SECOND;
|
|
CLOG_LOG(INFO, "print get piece 4", K(lsn));
|
|
scn.convert_for_logservice(log_ts);
|
|
ret = archive_context.get_piece(scn, lsn, dest_id, round_id, piece_id, cur_file_id, offset, max_lsn, to_newest);
|
|
EXPECT_EQ(OB_SUCCESS, ret);
|
|
EXPECT_EQ(round_id, 5);
|
|
EXPECT_EQ(piece_id, 22);
|
|
EXPECT_EQ(cur_file_id, 123);
|
|
EXPECT_EQ(offset, 0);
|
|
int64_t fake_offset = 102400;
|
|
palf::LSN fake_lsn(102400);
|
|
ret = archive_context.update_file_info(dest_id, round_id, piece_id, cur_file_id, fake_offset, fake_lsn);
|
|
EXPECT_EQ(OB_SUCCESS, ret);
|
|
lsn = lsn + 102400;
|
|
CLOG_LOG(INFO, "print get piece 6", K(lsn));
|
|
ret = archive_context.get_piece(scn, lsn, dest_id, round_id, piece_id, cur_file_id, offset, max_lsn, to_newest);
|
|
EXPECT_EQ(round_id, 5);
|
|
EXPECT_EQ(piece_id, 22);
|
|
EXPECT_EQ(cur_file_id, 123);
|
|
EXPECT_EQ(offset, fake_offset);
|
|
EXPECT_EQ(max_lsn, fake_lsn);
|
|
|
|
lsn = LSN(151 * 64 * ONE_MB + ONE_MB);
|
|
CLOG_LOG(INFO, "print get piece 7", K(lsn));
|
|
ret = archive_context.get_piece(scn, lsn, dest_id, round_id, piece_id, cur_file_id, offset, max_lsn, to_newest);
|
|
EXPECT_EQ(OB_ITER_END, ret);
|
|
|
|
// bad case, current piece hang, can not backward piece
|
|
lsn = LSN(10 * 64 * ONE_MB);
|
|
CLOG_LOG(INFO, "print get piece 8", K(lsn));
|
|
ret = archive_context.get_piece(scn, lsn, dest_id, round_id, piece_id, cur_file_id, offset, max_lsn, to_newest);
|
|
EXPECT_EQ(OB_ERR_OUT_OF_LOWER_BOUND, ret);
|
|
|
|
archive_context.reset_locate_info();
|
|
log_ts = 1010;
|
|
scn.convert_for_logservice(log_ts);
|
|
CLOG_LOG(INFO, "print get piece 9", K(lsn));
|
|
ret = archive_context.get_piece(scn, lsn, dest_id, round_id, piece_id, cur_file_id, offset, max_lsn, to_newest);
|
|
EXPECT_EQ(OB_SUCCESS, ret);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
OB_LOGGER.set_file_name("test_restore.log", true, false);
|
|
OB_LOGGER.set_log_level("INFO");
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
return RUN_ALL_TESTS();
|
|
}
|