oceanbase/unittest/storage/test_reserved_data_mgr.cpp
gm 4a92b6d7df reformat source code
according to code styles, 'AccessModifierOffset' should be -2.
2021-06-17 10:40:36 +08:00

776 lines
30 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 "storage/ob_reserved_data_mgr.h"
#include "blocksstable/ob_data_file_prepare.h"
#include "lib/container/ob_iarray.h"
using namespace oceanbase::storage;
using namespace oceanbase::blocksstable;
using namespace oceanbase::common;
using namespace oceanbase::lib;
namespace oceanbase {
namespace unittest {
class TestRecoveryDataMgr : public TestDataFilePrepare {
public:
TestRecoveryDataMgr();
virtual ~TestRecoveryDataMgr() = default;
virtual void SetUp() override;
virtual void TearDown() override;
private:
int prepare_pg_meta(const int64_t replay_log_ts, const int64_t publish_version, ObPartitionGroupMeta& meta);
int prepare_pgpartition_store_meta(ObPGPartitionStoreMeta& partition_store_meta);
int generate_table_key(const ObITable::TableType& type, common::ObVersionRange& trans_version_range,
const int64_t major_version, const uint64 table_id, ObITable::TableKey& table_key);
int create_sstable(
const ObITable::TableKey& table_key, const blocksstable::ObSSTableBaseMeta& meta, ObTableHandle& handle);
int fake_sstable(const bool is_major_sstable, common::ObVersionRange& trans_version_range,
const int64_t major_version, const uint64_t table_id, const int64_t schema_version, ObTableHandle& handle,
const ObLogTsRange& log_ts_range);
private:
ObPartitionKey pg_key_;
common::ObArenaAllocator allocator_;
};
TestRecoveryDataMgr::TestRecoveryDataMgr()
: TestDataFilePrepare("TestRecoveryDataMgr"), pg_key_(combine_id(1, 3000), 0, 0)
{}
void TestRecoveryDataMgr::SetUp()
{
TestDataFilePrepare::SetUp();
}
void TestRecoveryDataMgr::TearDown()
{
TestDataFilePrepare::TearDown();
}
int TestRecoveryDataMgr::prepare_pg_meta(
const int64_t replay_log_ts, const int64_t publish_version, ObPartitionGroupMeta& meta)
{
int ret = OB_SUCCESS;
meta.pg_key_ = pg_key_;
meta.replica_type_ = ObReplicaType::REPLICA_TYPE_FULL;
meta.storage_info_.get_data_info().set_last_replay_log_ts(replay_log_ts);
meta.storage_info_.get_data_info().set_publish_version(publish_version);
ret = meta.storage_info_.get_clog_info().init(1, ObMemberList(), 0, 0, true);
return ret;
}
int TestRecoveryDataMgr::prepare_pgpartition_store_meta(ObPGPartitionStoreMeta& partition_store_meta)
{
int ret = OB_SUCCESS;
partition_store_meta.pkey_ = pg_key_;
partition_store_meta.create_schema_version_ = 1;
partition_store_meta.create_timestamp_ = 1;
partition_store_meta.data_table_id_ = pg_key_.get_table_id();
partition_store_meta.multi_version_start_ = 1;
partition_store_meta.replica_type_ = REPLICA_TYPE_FULL;
return ret;
}
int TestRecoveryDataMgr::generate_table_key(const ObITable::TableType& type,
common::ObVersionRange& trans_version_range, const int64_t major_version, const uint64 table_id,
ObITable::TableKey& table_key)
{
int ret = OB_SUCCESS;
table_key.table_type_ = type;
table_key.table_id_ = table_id;
table_key.pkey_ = pg_key_;
table_key.trans_version_range_ = trans_version_range;
table_key.version_ = major_version;
table_key.log_ts_range_.max_log_ts_ = table_key.log_ts_range_.end_log_ts_;
return ret;
}
int TestRecoveryDataMgr::create_sstable(
const ObITable::TableKey& table_key, const blocksstable::ObSSTableBaseMeta& meta, ObTableHandle& handle)
{
int ret = OB_SUCCESS;
ObSSTable* table = NULL;
void* buf = nullptr;
if (!meta.is_valid() || (!ObITable::is_sstable(table_key.table_type_))) {
ret = OB_INVALID_ARGUMENT;
STORAGE_LOG(WARN, "invalid args", K(ret), K(table_key), K(meta));
} else if (OB_ISNULL(buf = allocator_.alloc(sizeof(ObSSTable)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
STORAGE_LOG(WARN, "fail to allocate memory for sstable", K(ret));
} else if (FALSE_IT(table = new (buf) ObSSTable())) {
STORAGE_LOG(WARN, "failed to new table", K(ret));
} else if (OB_FAIL(table->init(table_key))) {
STORAGE_LOG(WARN, "failed to init sstable", K(ret), K(table_key));
} else if (OB_FAIL(table->open(meta))) {
STORAGE_LOG(WARN, "failed to open table", K(ret));
} else if (OB_FAIL(handle.set_table(table))) {
STORAGE_LOG(WARN, "failed to set table to handle", K(ret));
}
return ret;
}
int TestRecoveryDataMgr::fake_sstable(const bool is_major_sstable, common::ObVersionRange& trans_version_range,
const int64_t major_version, const uint64_t table_id, const int64_t schema_version, ObTableHandle& handle,
const ObLogTsRange& log_ts_range)
{
int ret = OB_SUCCESS;
blocksstable::ObSSTableBaseMeta meta;
blocksstable::ObSSTableColumnMeta fake_column_meta;
ObITable::TableKey table_key;
ObITable::TableType type;
ObSSTable* sstable = NULL;
if (is_major_sstable) {
type = ObITable::MAJOR_SSTABLE;
meta.logical_data_version_ = major_version;
} else {
type = ObITable::MULTI_VERSION_MINOR_SSTABLE;
meta.logical_data_version_ = trans_version_range.snapshot_version_;
}
meta.sstable_format_version_ = ObSSTableBaseMeta::SSTABLE_FORMAT_VERSION_6;
meta.schema_version_ = schema_version;
meta.rowkey_column_count_ = 1;
meta.column_cnt_ = 1;
meta.column_metas_.set_capacity(static_cast<int32_t>(meta.column_cnt_));
meta.set_allocator(allocator_);
meta.column_metas_.push_back(fake_column_meta);
meta.multi_version_rowkey_type_ = storage::ObMultiVersionRowkeyHelpper::MVRC_OLD_VERSION;
handle.reset();
table_key.log_ts_range_ = log_ts_range;
if (OB_FAIL(generate_table_key(type, trans_version_range, major_version, table_id, table_key))) {
} else if (OB_FAIL(create_sstable(table_key, meta, handle))) {
STORAGE_LOG(WARN, "Failed to create sstable", K(ret));
} else if (OB_ISNULL(sstable = static_cast<ObSSTable*>(handle.get_table()))) {
ret = OB_ERR_SYS;
STORAGE_LOG(WARN, "Failed to get sstable", K(ret));
} else if (OB_FAIL(sstable->close())) {
STORAGE_LOG(WARN, "Failed to close sstable", K(ret));
}
return ret;
}
TEST_F(TestRecoveryDataMgr, enable_write_slog)
{
ObRecoveryDataMgr mgr_;
ASSERT_EQ(OB_SUCCESS, mgr_.init(pg_key_));
const ObAddr self_addr(ObAddr::IPV4, "127.0.0.1", 80);
ObStorageFile* file = nullptr;
ObStoreFileSystem& file_system = get_file_system();
ASSERT_EQ(OB_SUCCESS, file_system.alloc_file(file));
ASSERT_EQ(OB_SUCCESS, file->init(self_addr, 1, 0, ObStorageFile::FileType::TENANT_DATA));
ObStorageFileHandle file_handle;
ObStorageFileWithRef file_with_ref;
file_with_ref.file_ = file;
file_handle.set_storage_file_with_ref(file_with_ref);
ASSERT_EQ(OB_SUCCESS, mgr_.set_storage_file_handle(file_handle));
ObPGSSTableMgr sstable_mgr;
ASSERT_EQ(OB_SUCCESS, mgr_.enable_write_slog(sstable_mgr));
STORAGE_LOG(INFO, "enable_write_slog finished");
}
TEST_F(TestRecoveryDataMgr, serialize)
{
ObRecoveryDataMgr mgr_;
// int ObPGSSTableMgr::add_sstables(const bool in_slog_trans, ObTablesHandle &tables_handle)
ObPGSSTableMgr sstable_mgr;
ObPartitionGroupMeta pg_meta;
ObTablesHandle handle;
ObTableHandle handle_s;
ObVersion version;
ObLogTsRange log_ts_range;
ObVersionRange version_range;
// int ObPartitionKey::init(const uint64_t table_id, const int64_t partition_id, const int64_t partition_cnt)
ObPartitionKey pg_key;
const ObAddr self_addr(ObAddr::IPV4, "127.0.0.01", 80);
ObStorageFile* file = nullptr;
ObStoreFileSystem& file_system = get_file_system();
ObStorageFileHandle file_handle;
ObStorageFileWithRef file_with_ref;
common::ObMalloc allocator;
ObPGPartitionStoreMeta fake_meta;
ObFixedArray<ObPGPartitionStoreMeta> partition_store_metas(allocator);
common::ObVersionRange trans_version_range;
ObITable *table1, *table2, *table3;
int64_t table_id;
int64_t snapshot_version;
bool in_slog_trans = false;
bool use_inc_macro_block_slog = false;
bool is_major_sstable = true;
int64_t major_version = 2;
int64_t shcema_version = 2;
ASSERT_EQ(OB_SUCCESS, prepare_pg_meta(0, 0, pg_meta));
ASSERT_EQ(OB_SUCCESS, prepare_pgpartition_store_meta(fake_meta));
ASSERT_EQ(OB_SUCCESS, partition_store_metas.init(1));
ASSERT_EQ(OB_SUCCESS, partition_store_metas.push_back(fake_meta));
ASSERT_EQ(OB_SUCCESS, file_system.alloc_file(file));
ASSERT_EQ(OB_SUCCESS, file->init(self_addr, 1, 0, ObStorageFile::FileType::TENANT_DATA));
ASSERT_EQ(OB_SUCCESS, sstable_mgr.init(pg_key_));
ASSERT_EQ(OB_SUCCESS, sstable_mgr.enable_write_log());
file_with_ref.file_ = file;
file_handle.set_storage_file_with_ref(file_with_ref);
ASSERT_EQ(OB_SUCCESS, sstable_mgr.set_storage_file_handle(file_handle));
ASSERT_EQ(OB_SUCCESS, mgr_.init(pg_key_));
ASSERT_EQ(OB_SUCCESS, mgr_.set_storage_file_handle(file_handle));
ASSERT_EQ(OB_SUCCESS, mgr_.enable_write_slog(sstable_mgr));
// create sstable
trans_version_range.base_version_ = 0;
trans_version_range.multi_version_start_ = 100;
trans_version_range.snapshot_version_ = 100;
// table 1
table_id = combine_id(1, 3000);
major_version = 1;
shcema_version = 1;
// ASSERT_EQ(OB_SUCCESS, fake_sstable(true, trans_version_range, 1, pg_key_.get_table_id(), 1, handle_s,
// log_ts_range));
ASSERT_EQ(OB_SUCCESS,
fake_sstable(
is_major_sstable, trans_version_range, major_version, table_id, shcema_version, handle_s, log_ts_range));
ASSERT_EQ(OB_SUCCESS, sstable_mgr.add_sstable(in_slog_trans, handle_s));
table1 = handle_s.get_table();
// table 2
handle_s.reset();
table_id = combine_id(2, 3000);
major_version = 2;
shcema_version = 2;
// ASSERT_EQ(OB_SUCCESS, fake_sstable(true, trans_version_range, 1, pg_key_.get_table_id(), 1, handle_s,
// log_ts_range));
ASSERT_EQ(OB_SUCCESS,
fake_sstable(
is_major_sstable, trans_version_range, major_version, table_id, shcema_version, handle_s, log_ts_range));
ASSERT_EQ(OB_SUCCESS, sstable_mgr.add_sstable(in_slog_trans, handle_s));
table2 = handle_s.get_table();
// table 3
handle_s.reset();
table_id = combine_id(3, 3000);
major_version = 3;
shcema_version = 3;
// ASSERT_EQ(OB_SUCCESS, fake_sstable(true, trans_version_range, 1, pg_key_.get_table_id(), 1, handle_s,
// log_ts_range));
ASSERT_EQ(OB_SUCCESS,
fake_sstable(
is_major_sstable, trans_version_range, major_version, table_id, shcema_version, handle_s, log_ts_range));
ASSERT_EQ(OB_SUCCESS, sstable_mgr.add_sstable(in_slog_trans, handle_s));
table3 = handle_s.get_table();
// restore point 1 : <1, table1>, <2, table2>
handle.reset();
snapshot_version = 1;
ASSERT_EQ(OB_SUCCESS, handle.add_table(table1));
ASSERT_EQ(OB_SUCCESS, handle.add_table(table2));
ASSERT_EQ(OB_SUCCESS, mgr_.add_restore_point(snapshot_version, pg_meta, partition_store_metas, handle));
// STORAGE_LOG(INFO, "restore point 1 add success");
// restore point 2 : <3, table3>
handle.reset();
snapshot_version = 2;
ASSERT_EQ(OB_SUCCESS, handle.add_table(table3));
ASSERT_EQ(OB_SUCCESS, mgr_.add_restore_point(snapshot_version, pg_meta, partition_store_metas, handle));
// STORAGE_LOG(INFO, "restore point 2 add success");
// serialize
char* buf = NULL;
int64_t serialize_size = 0;
int64_t pos = 0;
bool is_exist = false;
ASSERT_EQ(OB_SUCCESS, mgr_.serialize(allocator, buf, serialize_size));
// STORAGE_LOG(INFO, "serialize success", K(serialize_size), K(buf), K(strlen(buf)));
// deserialize
ObRecoveryDataMgr mgr2_;
ASSERT_EQ(OB_SUCCESS, mgr2_.init(pg_key_));
ASSERT_EQ(OB_SUCCESS, mgr2_.set_storage_file_handle(file_handle));
ASSERT_EQ(OB_SUCCESS, mgr2_.deserialize(buf, serialize_size, pos));
ObTablesHandle tmp_handle;
ASSERT_EQ(OB_SUCCESS, sstable_mgr.get_all_sstables(tmp_handle));
// STORAGE_LOG(INFO, "deserialize success", K(tmp_handle));
ASSERT_EQ(OB_SUCCESS, mgr2_.enable_write_slog(sstable_mgr));
// STORAGE_LOG(INFO, "finish replay success");
ASSERT_EQ(mgr_.get_recovery_point_cnt(), mgr2_.get_recovery_point_cnt());
snapshot_version = 1;
table_id = combine_id(1, 3000);
ASSERT_EQ(OB_SUCCESS, mgr2_.check_restore_point_exist(1, is_exist));
ASSERT_EQ(true, is_exist);
handle.reset();
ASSERT_EQ(OB_SUCCESS, mgr2_.get_restore_point_read_tables(table_id, snapshot_version, handle));
ASSERT_EQ(1, handle.get_count());
ASSERT_EQ(1, (static_cast<ObSSTable*>(handle.get_table(0)))->get_logical_data_version());
STORAGE_LOG(INFO, "serialize finished");
}
TEST_F(TestRecoveryDataMgr, test_add_restore_point_data)
{
ObRecoveryDataMgr mgr_, mgr2_;
ASSERT_EQ(OB_SUCCESS, mgr_.init(pg_key_));
ASSERT_EQ(OB_SUCCESS, mgr2_.init(pg_key_));
const ObAddr self_addr(ObAddr::IPV4, "127.0.0.1", 80);
common::ObMalloc allocator;
ObPGPartitionStoreMeta fake_meta;
ObStorageFile* file = nullptr;
ObStoreFileSystem& file_system = get_file_system();
ASSERT_EQ(OB_SUCCESS, file_system.alloc_file(file));
ASSERT_EQ(OB_SUCCESS, file->init(self_addr, 1, 0, ObStorageFile::FileType::TENANT_DATA));
ObStorageFileHandle file_handle;
ObStorageFileWithRef file_with_ref;
file_with_ref.file_ = file;
file_handle.set_storage_file_with_ref(file_with_ref);
ASSERT_EQ(OB_SUCCESS, mgr_.set_storage_file_handle(file_handle));
ASSERT_EQ(OB_SUCCESS, mgr2_.set_storage_file_handle(file_handle));
ObPGSSTableMgr sstable_mgr;
ASSERT_EQ(OB_SUCCESS, mgr_.enable_write_slog(sstable_mgr));
ASSERT_EQ(OB_SUCCESS, mgr2_.enable_write_slog(sstable_mgr));
ObPartitionGroupMeta pg_meta;
ObTablesHandle handle;
ObTableHandle handle_s;
ObFixedArray<ObPGPartitionStoreMeta> partition_store_metas(allocator);
ObVersionRange trans_version_range;
ObVersion version;
ObLogTsRange log_ts_range;
int64_t table_id;
bool is_major_sstable = true;
int64_t major_version = 2;
int64_t shcema_version = 2;
ASSERT_EQ(OB_SUCCESS, prepare_pgpartition_store_meta(fake_meta));
ASSERT_EQ(OB_SUCCESS, partition_store_metas.init(1));
ASSERT_EQ(OB_SUCCESS, partition_store_metas.push_back(fake_meta));
trans_version_range.base_version_ = 0;
trans_version_range.multi_version_start_ = 100;
trans_version_range.snapshot_version_ = 100;
// case 1: <tableid, [sstable1, sstabe2]>
ObTablesHandle res_handle;
bool is_exist = false;
// table 1
table_id = combine_id(1, 3000);
major_version = 1;
shcema_version = 1;
ASSERT_EQ(OB_SUCCESS,
fake_sstable(
is_major_sstable, trans_version_range, major_version, table_id, shcema_version, handle_s, log_ts_range));
ASSERT_EQ(OB_SUCCESS, handle.add_table(handle_s));
// table 2
handle_s.reset();
major_version = 2;
shcema_version = 2;
ASSERT_EQ(OB_SUCCESS,
fake_sstable(
is_major_sstable, trans_version_range, major_version, table_id, shcema_version, handle_s, log_ts_range));
ASSERT_EQ(OB_SUCCESS, handle.add_table(handle_s));
// add and check
ASSERT_EQ(OB_SUCCESS, prepare_pg_meta(300, 250, pg_meta));
ASSERT_EQ(OB_SUCCESS, mgr_.add_restore_point(1, pg_meta, partition_store_metas, handle));
ASSERT_EQ(OB_ENTRY_EXIST, mgr_.add_restore_point(1, pg_meta, partition_store_metas, handle));
ASSERT_EQ(OB_SUCCESS, mgr_.check_restore_point_exist(100, is_exist));
ASSERT_EQ(false, is_exist);
ASSERT_EQ(OB_SUCCESS, mgr_.check_restore_point_exist(1, is_exist));
ASSERT_EQ(true, is_exist);
ASSERT_EQ(OB_SUCCESS, mgr_.get_restore_point_read_tables(table_id, 1, res_handle));
ASSERT_EQ(res_handle.get_count(), handle.get_count());
// case 2: replay add
ObRecoveryPointData point_data;
ASSERT_EQ(OB_SUCCESS, point_data.init(1, pg_meta, partition_store_metas));
ASSERT_EQ(OB_SUCCESS, point_data.add_sstables(handle));
// the data exist, will not be inserted.
ASSERT_EQ(1, mgr_.get_recovery_point_cnt());
ASSERT_EQ(OB_SUCCESS, mgr_.replay_add_recovery_point(ObRecoveryPointType::RESTORE_POINT, point_data));
ASSERT_EQ(1, mgr_.get_recovery_point_cnt());
ObRecoveryPointData point_data2;
ASSERT_EQ(OB_SUCCESS, point_data2.init(2, pg_meta, partition_store_metas));
ASSERT_EQ(OB_SUCCESS, point_data2.add_sstables(handle));
ASSERT_EQ(OB_SUCCESS, mgr_.replay_add_recovery_point(ObRecoveryPointType::RESTORE_POINT, point_data2));
// case 3: replay remove
ObRecoveryPointData point_data3;
ASSERT_EQ(OB_SUCCESS, point_data3.init(4, pg_meta, partition_store_metas));
ASSERT_EQ(OB_SUCCESS, point_data3.add_sstables(handle));
ASSERT_EQ(OB_SUCCESS, mgr_.replay_add_recovery_point(ObRecoveryPointType::RESTORE_POINT, point_data3));
is_exist = false;
ASSERT_EQ(OB_SUCCESS, mgr_.check_restore_point_exist(4, is_exist));
ASSERT_EQ(true, is_exist);
ASSERT_EQ(OB_SUCCESS, mgr_.replay_remove_recovery_point(ObRecoveryPointType::RESTORE_POINT, 4));
ASSERT_EQ(OB_SUCCESS, mgr_.check_restore_point_exist(4, is_exist));
ASSERT_EQ(false, is_exist);
// case 4: add <tableid, [sstable]>
handle.reset();
handle_s.reset();
ASSERT_EQ(OB_SUCCESS,
fake_sstable(
is_major_sstable, trans_version_range, major_version, table_id, shcema_version, handle_s, log_ts_range));
ASSERT_EQ(OB_SUCCESS, handle.add_table(handle_s));
ASSERT_EQ(OB_SUCCESS, mgr_.add_restore_point(3, pg_meta, partition_store_metas, handle));
STORAGE_LOG(INFO, "add restore point data finished");
}
TEST_F(TestRecoveryDataMgr, test_remove_restore_point)
{
ObRecoveryDataMgr mgr_;
ASSERT_EQ(OB_SUCCESS, mgr_.init(pg_key_));
const ObAddr self_addr(ObAddr::IPV4, "127.0.0.1", 80);
ObStorageFile* file = nullptr;
ObStoreFileSystem& file_system = get_file_system();
ASSERT_EQ(OB_SUCCESS, file_system.alloc_file(file));
ASSERT_EQ(OB_SUCCESS, file->init(self_addr, 1, 0, ObStorageFile::FileType::TENANT_DATA));
ObStorageFileHandle file_handle;
ObStorageFileWithRef file_with_ref;
file_with_ref.file_ = file;
file_handle.set_storage_file_with_ref(file_with_ref);
ASSERT_EQ(OB_SUCCESS, mgr_.set_storage_file_handle(file_handle));
ObPGSSTableMgr sstable_mgr;
ASSERT_EQ(OB_SUCCESS, mgr_.enable_write_slog(sstable_mgr));
ObPartitionGroupMeta pg_meta;
ObTablesHandle handle;
ObTableHandle handle_s;
ObITable::TableKey key;
ObSSTable table1;
common::ObMalloc allocator;
ObPGPartitionStoreMeta fake_meta;
ObFixedArray<ObPGPartitionStoreMeta> partition_store_metas(allocator);
ObVersionRange trans_version_range;
ObVersion version;
ObLogTsRange log_ts_range;
int64_t table_id;
bool is_major_sstable = true;
int64_t major_version = 2;
int64_t shcema_version = 2;
ASSERT_EQ(OB_SUCCESS, prepare_pgpartition_store_meta(fake_meta));
ASSERT_EQ(OB_SUCCESS, partition_store_metas.init(1));
ASSERT_EQ(OB_SUCCESS, partition_store_metas.push_back(fake_meta));
trans_version_range.base_version_ = 0;
trans_version_range.multi_version_start_ = 100;
trans_version_range.snapshot_version_ = 100;
// table 1
table_id = combine_id(1, 3000);
major_version = 1;
shcema_version = 1;
ASSERT_EQ(OB_SUCCESS,
fake_sstable(
is_major_sstable, trans_version_range, major_version, table_id, shcema_version, handle_s, log_ts_range));
ASSERT_EQ(OB_SUCCESS, handle.add_table(handle_s));
// table 2
handle_s.reset();
major_version = 2;
shcema_version = 2;
ASSERT_EQ(OB_SUCCESS,
fake_sstable(
is_major_sstable, trans_version_range, major_version, table_id, shcema_version, handle_s, log_ts_range));
ASSERT_EQ(OB_SUCCESS, handle.add_table(handle_s));
ASSERT_EQ(OB_SUCCESS, prepare_pg_meta(300, 250, pg_meta));
ASSERT_EQ(OB_SUCCESS, mgr_.add_restore_point(1, pg_meta, partition_store_metas, handle));
// table 3
handle_s.reset();
major_version = 3;
shcema_version = 3;
ASSERT_EQ(OB_SUCCESS,
fake_sstable(
is_major_sstable, trans_version_range, major_version, table_id, shcema_version, handle_s, log_ts_range));
ASSERT_EQ(OB_SUCCESS, handle.add_table(handle_s));
ASSERT_EQ(OB_SUCCESS, prepare_pg_meta(400, 350, pg_meta));
ASSERT_EQ(OB_SUCCESS, mgr_.add_restore_point(2, pg_meta, partition_store_metas, handle));
ObArray<int64_t> array;
array.reset();
array.push_back(1);
array.push_back(2);
ASSERT_EQ(2, mgr_.get_recovery_point_cnt());
ASSERT_EQ(OB_SUCCESS, mgr_.remove_unneed_restore_point(array, INT64_MAX));
ASSERT_EQ(2, mgr_.get_recovery_point_cnt());
array.reset();
array.push_back(2);
ASSERT_EQ(OB_SUCCESS, mgr_.remove_unneed_restore_point(array, INT64_MAX));
ASSERT_EQ(1, mgr_.get_recovery_point_cnt());
// table 4
handle_s.reset();
major_version = 4;
shcema_version = 4;
ASSERT_EQ(OB_SUCCESS,
fake_sstable(
is_major_sstable, trans_version_range, major_version, table_id, shcema_version, handle_s, log_ts_range));
ASSERT_EQ(OB_SUCCESS, handle.add_table(handle_s));
ASSERT_EQ(OB_SUCCESS, prepare_pg_meta(500, 450, pg_meta));
ASSERT_EQ(OB_SUCCESS, mgr_.add_restore_point(3, pg_meta, partition_store_metas, handle));
// table 5
handle_s.reset();
major_version = 5;
shcema_version = 5;
ASSERT_EQ(OB_SUCCESS,
fake_sstable(
is_major_sstable, trans_version_range, major_version, table_id, shcema_version, handle_s, log_ts_range));
ASSERT_EQ(OB_SUCCESS, handle.add_table(handle_s));
ASSERT_EQ(OB_SUCCESS, prepare_pg_meta(600, 550, pg_meta));
ASSERT_EQ(OB_SUCCESS, mgr_.add_restore_point(4, pg_meta, partition_store_metas, handle));
// table 6
handle_s.reset();
major_version = 6;
shcema_version = 6;
ASSERT_EQ(OB_SUCCESS,
fake_sstable(
is_major_sstable, trans_version_range, major_version, table_id, shcema_version, handle_s, log_ts_range));
ASSERT_EQ(OB_SUCCESS, handle.add_table(handle_s));
ASSERT_EQ(OB_SUCCESS, prepare_pg_meta(700, 650, pg_meta));
ASSERT_EQ(OB_SUCCESS, mgr_.add_restore_point(1, pg_meta, partition_store_metas, handle));
ASSERT_EQ(4, mgr_.get_recovery_point_cnt());
array.reset();
array.push_back(1);
array.push_back(3);
ASSERT_EQ(OB_SUCCESS, mgr_.remove_unneed_restore_point(array, INT64_MAX));
ASSERT_EQ(2, mgr_.get_recovery_point_cnt());
ObTablesHandle res_handle;
ASSERT_EQ(OB_ENTRY_NOT_EXIST, mgr_.get_restore_point_read_tables(pg_key_.get_table_id(), 2, res_handle));
res_handle.reset();
ASSERT_EQ(OB_SUCCESS, mgr_.get_restore_point_read_tables(pg_key_.get_table_id(), 1, res_handle));
ASSERT_EQ(OB_SUCCESS, mgr_.replay_remove_recovery_point(ObRecoveryPointType::RESTORE_POINT, 1));
ASSERT_EQ(1, mgr_.get_recovery_point_cnt());
ASSERT_EQ(OB_SUCCESS, mgr_.replay_remove_recovery_point(ObRecoveryPointType::RESTORE_POINT, 3));
ASSERT_EQ(0, mgr_.get_recovery_point_cnt());
STORAGE_LOG(INFO, "test_remove_restore_point finished");
}
TEST_F(TestRecoveryDataMgr, test_add_backup_point_data)
{
ObRecoveryDataMgr mgr_, mgr2_;
ASSERT_EQ(OB_SUCCESS, mgr_.init(pg_key_));
ASSERT_EQ(OB_SUCCESS, mgr2_.init(pg_key_));
const ObAddr self_addr(ObAddr::IPV4, "127.0.0.1", 80);
common::ObMalloc allocator;
ObPGPartitionStoreMeta fake_meta;
ObStorageFile* file = nullptr;
ObStoreFileSystem& file_system = get_file_system();
ASSERT_EQ(OB_SUCCESS, file_system.alloc_file(file));
ASSERT_EQ(OB_SUCCESS, file->init(self_addr, 1, 0, ObStorageFile::FileType::TENANT_DATA));
ObStorageFileHandle file_handle;
ObStorageFileWithRef file_with_ref;
file_with_ref.file_ = file;
file_handle.set_storage_file_with_ref(file_with_ref);
ASSERT_EQ(OB_SUCCESS, mgr_.set_storage_file_handle(file_handle));
ASSERT_EQ(OB_SUCCESS, mgr2_.set_storage_file_handle(file_handle));
ObPGSSTableMgr sstable_mgr;
ASSERT_EQ(OB_SUCCESS, mgr_.enable_write_slog(sstable_mgr));
ASSERT_EQ(OB_SUCCESS, mgr2_.enable_write_slog(sstable_mgr));
ObPartitionGroupMeta pg_meta, res_pg_meta;
ObTablesHandle handle, res_handle;
ObTableHandle handle_s;
ObFixedArray<ObPGPartitionStoreMeta> partition_store_metas(allocator);
ObVersionRange trans_version_range;
ObVersion version;
ObLogTsRange log_ts_range;
int64_t table_id;
bool is_major_sstable = true;
int64_t major_version = 2;
int64_t shcema_version = 2;
int64_t table_snapshot = 0;
int64_t replay_log_ts = 0;
int64_t backup_point_version = 1;
ASSERT_EQ(OB_SUCCESS, prepare_pgpartition_store_meta(fake_meta));
ASSERT_EQ(OB_SUCCESS, partition_store_metas.init(1));
ASSERT_EQ(OB_SUCCESS, partition_store_metas.push_back(fake_meta));
trans_version_range.base_version_ = 0;
trans_version_range.multi_version_start_ = 0;
trans_version_range.snapshot_version_ = 0;
// case 1: <tableid, [sstable1, sstabe2]>
// table 1
table_id = combine_id(1, 3000);
major_version = 1;
shcema_version = 1;
table_snapshot = 1;
trans_version_range.multi_version_start_ = table_snapshot;
trans_version_range.snapshot_version_ = table_snapshot;
ASSERT_EQ(OB_SUCCESS,
fake_sstable(
is_major_sstable, trans_version_range, major_version, table_id, shcema_version, handle_s, log_ts_range));
ASSERT_EQ(OB_SUCCESS, handle.add_table(handle_s));
// add and check
replay_log_ts = 1;
ASSERT_EQ(OB_SUCCESS, prepare_pg_meta(replay_log_ts, 250, pg_meta));
ASSERT_EQ(OB_SUCCESS, mgr_.add_backup_point(backup_point_version, pg_meta, partition_store_metas, handle));
int64_t query_snapshot = 1;
ASSERT_EQ(OB_SUCCESS, mgr_.get_backup_point_data(query_snapshot, res_pg_meta, res_handle));
ASSERT_EQ(replay_log_ts, res_pg_meta.storage_info_.get_data_info().get_last_replay_log_ts());
ASSERT_EQ(handle.get_count(), res_handle.get_count());
// case 2: replay add
ObRecoveryPointData point_data;
pg_meta.reset();
handle_s.reset();
handle.reset();
replay_log_ts = 2;
table_snapshot = 2;
backup_point_version = 2;
ASSERT_EQ(OB_SUCCESS,
fake_sstable(
is_major_sstable, trans_version_range, major_version, table_id, shcema_version, handle_s, log_ts_range));
ASSERT_EQ(OB_SUCCESS, handle.add_table(handle_s));
ASSERT_EQ(OB_SUCCESS, prepare_pg_meta(replay_log_ts, 250, pg_meta));
ASSERT_EQ(OB_SUCCESS, point_data.init(backup_point_version, pg_meta, partition_store_metas));
ASSERT_EQ(OB_SUCCESS, point_data.add_sstables(handle));
ASSERT_EQ(OB_SUCCESS, mgr_.replay_add_recovery_point(ObRecoveryPointType::BACKUP, point_data));
ObRecoveryPointData point_data2;
ASSERT_EQ(OB_SUCCESS, point_data2.init(backup_point_version, pg_meta, partition_store_metas));
ASSERT_EQ(OB_SUCCESS, point_data2.add_sstables(handle));
// will not be inserted, because of the same table_snapshot
ASSERT_EQ(OB_SUCCESS, mgr_.replay_add_recovery_point(ObRecoveryPointType::BACKUP, point_data2));
// case 3: replay remove
// the backup point with the snapshot version of 2 will be deleted.
ASSERT_EQ(2, mgr_.get_recovery_point_cnt());
ASSERT_EQ(OB_SUCCESS, mgr_.replay_remove_recovery_point(ObRecoveryPointType::BACKUP, table_snapshot));
ASSERT_EQ(1, mgr_.get_recovery_point_cnt());
STORAGE_LOG(INFO, "add backup point data finished");
}
TEST_F(TestRecoveryDataMgr, test_remove_backup_point)
{
ObRecoveryDataMgr mgr_;
ASSERT_EQ(OB_SUCCESS, mgr_.init(pg_key_));
const ObAddr self_addr(ObAddr::IPV4, "127.0.0.1", 80);
ObStorageFile* file = nullptr;
ObStoreFileSystem& file_system = get_file_system();
ASSERT_EQ(OB_SUCCESS, file_system.alloc_file(file));
ASSERT_EQ(OB_SUCCESS, file->init(self_addr, 1, 0, ObStorageFile::FileType::TENANT_DATA));
ObStorageFileHandle file_handle;
ObStorageFileWithRef file_with_ref;
file_with_ref.file_ = file;
file_handle.set_storage_file_with_ref(file_with_ref);
ASSERT_EQ(OB_SUCCESS, mgr_.set_storage_file_handle(file_handle));
ObPGSSTableMgr sstable_mgr;
ASSERT_EQ(OB_SUCCESS, mgr_.enable_write_slog(sstable_mgr));
ObPartitionGroupMeta pg_meta;
ObTablesHandle handle;
ObTableHandle handle_s;
ObITable::TableKey key;
ObSSTable table1;
common::ObMalloc allocator;
ObPGPartitionStoreMeta fake_meta;
ObFixedArray<ObPGPartitionStoreMeta> partition_store_metas(allocator);
ObVersionRange trans_version_range;
ObVersion version;
ObLogTsRange log_ts_range;
int64_t table_id;
bool is_major_sstable = true;
int64_t major_version = 2;
int64_t shcema_version = 2;
int64_t table_snapshot = 0;
int64_t replay_log_ts = 0;
int64_t backup_point_version = 1;
ASSERT_EQ(OB_SUCCESS, prepare_pgpartition_store_meta(fake_meta));
ASSERT_EQ(OB_SUCCESS, partition_store_metas.init(1));
ASSERT_EQ(OB_SUCCESS, partition_store_metas.push_back(fake_meta));
trans_version_range.base_version_ = 0;
trans_version_range.multi_version_start_ = 0;
trans_version_range.snapshot_version_ = 0;
// table 1
table_id = combine_id(1, 3000);
major_version = 1;
shcema_version = 1;
table_snapshot = 1;
trans_version_range.multi_version_start_ = table_snapshot;
trans_version_range.snapshot_version_ = table_snapshot;
ASSERT_EQ(OB_SUCCESS,
fake_sstable(
is_major_sstable, trans_version_range, major_version, table_id, shcema_version, handle_s, log_ts_range));
ASSERT_EQ(OB_SUCCESS, handle.add_table(handle_s));
// table 2
handle_s.reset();
major_version = 2;
shcema_version = 2;
table_snapshot = 2;
trans_version_range.multi_version_start_ = table_snapshot;
trans_version_range.snapshot_version_ = table_snapshot;
ASSERT_EQ(OB_SUCCESS,
fake_sstable(
is_major_sstable, trans_version_range, major_version, table_id, shcema_version, handle_s, log_ts_range));
ASSERT_EQ(OB_SUCCESS, handle.add_table(handle_s));
replay_log_ts = 1;
ASSERT_EQ(OB_SUCCESS, prepare_pg_meta(replay_log_ts, 250, pg_meta));
ASSERT_EQ(OB_SUCCESS, mgr_.add_backup_point(backup_point_version, pg_meta, partition_store_metas, handle));
// table 3
handle_s.reset();
major_version = 3;
shcema_version = 3;
table_snapshot = 3;
trans_version_range.multi_version_start_ = table_snapshot;
trans_version_range.snapshot_version_ = table_snapshot;
ASSERT_EQ(OB_SUCCESS,
fake_sstable(
is_major_sstable, trans_version_range, major_version, table_id, shcema_version, handle_s, log_ts_range));
ASSERT_EQ(OB_SUCCESS, handle.add_table(handle_s));
replay_log_ts = 2;
backup_point_version = 2;
ASSERT_EQ(OB_SUCCESS, prepare_pg_meta(replay_log_ts, 350, pg_meta));
ASSERT_EQ(OB_SUCCESS, mgr_.add_backup_point(backup_point_version, pg_meta, partition_store_metas, handle));
ObArray<int64_t> array;
array.push_back(1);
ASSERT_EQ(2, mgr_.get_recovery_point_cnt());
ASSERT_EQ(OB_SUCCESS, mgr_.remove_unneed_backup_point(array, 4));
ASSERT_EQ(1, mgr_.get_recovery_point_cnt());
STORAGE_LOG(INFO, "test_remove_backup_point finished");
}
} // namespace unittest
} // namespace oceanbase
int main(int argc, char** argv)
{
system("rm -f test_reserved_data.log*");
OB_LOGGER.set_file_name("test_reserved_data.log");
OB_LOGGER.set_log_level("INFO");
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}