Files
oceanbase/unittest/storage/blocksstable/test_block_sstable_struct.cpp
oceanbase-admin cea7de1475 init push
2021-05-31 22:56:52 +08:00

877 lines
33 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 <gtest/gtest.h>
#include "storage/blocksstable/ob_data_buffer.h"
#define protected public
#define private public
#include "storage/blocksstable/ob_macro_block_common_header.h"
#include "storage/blocksstable/ob_block_sstable_struct.h"
#include "./ob_macro_meta_generate.h"
namespace oceanbase {
using namespace common;
namespace blocksstable {
bool check_meta_entry(ObSuperBlockV2::MetaEntry& meta_entry, const int64_t block_idx, const int64_t log_seq,
const int64_t file_id, const int64_t file_size)
{
return meta_entry.block_index_ == block_idx && meta_entry.log_seq_ == log_seq && meta_entry.file_id_ == file_id &&
meta_entry.file_size_ == file_size;
}
struct SuperBlock20 {
SuperBlock20();
static const int64_t MAX_BACKUP_META_COUNT = 2;
static const int64_t SUPER_BLOCK_RESERVED_COUNT = 7;
static const int64_t MAX_SUPER_BLOCK_SIZE = 1 << 12;
int32_t header_size_;
int32_t version_;
int32_t magic_; // magic number
int32_t attr_; // reserved, set 0
int64_t create_timestamp_; // create timestamp
int64_t modify_timestamp_; // last modified timestamp
int64_t macro_block_size_;
int64_t total_macro_block_count_;
int64_t reserved_block_count_;
int64_t free_macro_block_count_;
int64_t first_macro_block_;
int64_t first_free_block_index_;
int64_t total_file_size_;
int64_t backup_meta_count_;
int64_t backup_meta_blocks_[MAX_BACKUP_META_COUNT];
int64_t macro_block_meta_entry_block_index_; // entry of macro block meta blocks.
int64_t partition_meta_entry_block_index_; // entry of partition meta blocks.
common::ObLogCursor replay_start_point_;
int64_t table_mgr_meta_entry_block_index_; // entry of table mgr macro block meta blocks.
int64_t partition_meta_log_seq_; // log seq of partition meta in checkpoint
int64_t table_mgr_meta_log_seq_; // log seq of table mgr meta in checkpoint
int64_t reserved_[SUPER_BLOCK_RESERVED_COUNT];
bool is_valid() const;
TO_STRING_KV(K_(header_size), K_(version), K_(magic), K_(attr), K_(create_timestamp), K_(modify_timestamp),
K_(macro_block_size), K_(total_macro_block_count), K_(reserved_block_count), K_(free_macro_block_count),
K_(first_macro_block), K_(first_free_block_index), K_(total_file_size), K_(backup_meta_count),
"backup_meta_blocks_", common::ObArrayWrap<int64_t>(backup_meta_blocks_, backup_meta_count_),
K_(macro_block_meta_entry_block_index), K_(partition_meta_entry_block_index),
K_(table_mgr_meta_entry_block_index), K_(partition_meta_log_seq), K_(table_mgr_meta_log_seq),
K_(replay_start_point));
NEED_SERIALIZE_AND_DESERIALIZE;
};
//================================SuperBlock======================================
SuperBlock20::SuperBlock20()
: header_size_(0),
version_(0),
magic_(0),
attr_(0),
create_timestamp_(0),
modify_timestamp_(0),
macro_block_size_(0),
total_macro_block_count_(0),
reserved_block_count_(0),
free_macro_block_count_(0),
first_macro_block_(0),
first_free_block_index_(0),
total_file_size_(0),
backup_meta_count_(0),
macro_block_meta_entry_block_index_(0),
partition_meta_entry_block_index_(0),
table_mgr_meta_entry_block_index_(0),
partition_meta_log_seq_(0),
table_mgr_meta_log_seq_(0)
{
memset(backup_meta_blocks_, 0, sizeof(backup_meta_blocks_));
memset(reserved_, 0, sizeof(reserved_));
}
bool SuperBlock20::is_valid() const
{
return header_size_ > 0 && version_ >= 0 && SUPER_BLOCK_MAGIC == magic_ && attr_ >= 0 && create_timestamp_ > 0 &&
modify_timestamp_ >= create_timestamp_ && macro_block_size_ > 0 && total_macro_block_count_ > 0 &&
reserved_block_count_ >= 0 && free_macro_block_count_ >= 0 && first_macro_block_ >= 0 &&
first_free_block_index_ > 0 && total_file_size_ >= macro_block_size_ && backup_meta_count_ > 0 &&
macro_block_meta_entry_block_index_ >= -1 && partition_meta_entry_block_index_ >= -1 &&
replay_start_point_.is_valid() && table_mgr_meta_entry_block_index_ >= -1 && partition_meta_log_seq_ >= 0 &&
table_mgr_meta_log_seq_ >= 0;
}
DEFINE_SERIALIZE(SuperBlock20)
{
int ret = OB_SUCCESS;
if (NULL == buf || buf_len - pos < header_size_) {
ret = OB_BUF_NOT_ENOUGH;
STORAGE_LOG(WARN, "serialize superblock failed.", KP(buf), K(buf_len), K(pos), K(header_size_), K(ret));
} else {
MEMCPY(buf + pos, this, sizeof(SuperBlock20));
pos += header_size_;
}
return ret;
}
DEFINE_DESERIALIZE(SuperBlock20)
{
int ret = OB_SUCCESS;
// read size first;
if (NULL == buf || data_len - pos < static_cast<int64_t>(sizeof(int32_t))) {
ret = OB_INVALID_ARGUMENT;
STORAGE_LOG(WARN, "invalid arguments.", KP(buf), K(data_len), K(pos), K(header_size_), K(ret));
} else {
int32_t header_size = *(reinterpret_cast<const int32_t*>(buf));
if (data_len - pos < header_size) {
ret = OB_BUF_NOT_ENOUGH;
STORAGE_LOG(ERROR, "data_len not enough for header size.", K(data_len), K(pos), K(header_size), K(ret));
} else {
MEMCPY(this, buf + pos, sizeof(SuperBlock20));
pos += header_size;
}
}
return ret;
}
DEFINE_GET_SERIALIZE_SIZE(SuperBlock20)
{
return sizeof(SuperBlock20);
}
struct SuperBlock14 {
SuperBlock14();
static const int64_t MAX_BACKUP_META_COUNT = 2;
static const int64_t SUPER_BLOCK_RESERVED_COUNT = 10;
static const int64_t MAX_SUPER_BLOCK_SIZE = 1 << 12;
int32_t header_size_;
int32_t version_;
int32_t magic_; // magic number
int32_t attr_; // reserved, set 0
int64_t create_timestamp_; // create timestamp
int64_t modify_timestamp_; // last modified timestamp
int64_t macro_block_size_;
int64_t total_macro_block_count_;
int64_t reserved_block_count_;
int64_t free_macro_block_count_;
int64_t first_macro_block_;
int64_t first_free_block_index_;
int64_t total_file_size_;
int64_t backup_meta_count_;
int64_t backup_meta_blocks_[MAX_BACKUP_META_COUNT];
int64_t macro_block_meta_entry_block_index_; // entry of macro block meta blocks.
int64_t partition_meta_entry_block_index_; // entry of partition meta blocks.
common::ObLogCursor replay_start_point_;
int64_t reserved_[SUPER_BLOCK_RESERVED_COUNT];
bool is_valid() const;
TO_STRING_KV(K_(header_size), K_(version), K_(magic), K_(attr), K_(create_timestamp), K_(modify_timestamp),
K_(macro_block_size), K_(total_macro_block_count), K_(reserved_block_count), K_(free_macro_block_count),
K_(first_macro_block), K_(first_free_block_index), K_(total_file_size), K_(backup_meta_count),
"backup_meta_blocks_", common::ObArrayWrap<int64_t>(backup_meta_blocks_, backup_meta_count_),
K_(macro_block_meta_entry_block_index), K_(partition_meta_entry_block_index), K_(replay_start_point));
NEED_SERIALIZE_AND_DESERIALIZE;
};
//================================SuperBlock======================================
SuperBlock14::SuperBlock14()
: header_size_(0),
version_(0),
magic_(0),
attr_(0),
create_timestamp_(0),
modify_timestamp_(0),
macro_block_size_(0),
total_macro_block_count_(0),
reserved_block_count_(0),
free_macro_block_count_(0),
first_macro_block_(0),
first_free_block_index_(0),
total_file_size_(0),
backup_meta_count_(0),
macro_block_meta_entry_block_index_(0),
partition_meta_entry_block_index_(0)
{
memset(backup_meta_blocks_, 0, sizeof(backup_meta_blocks_));
memset(reserved_, 0, sizeof(reserved_));
}
bool SuperBlock14::is_valid() const
{
return header_size_ > 0 && version_ >= 0 && SUPER_BLOCK_MAGIC == magic_ && attr_ >= 0 && create_timestamp_ > 0 &&
modify_timestamp_ >= create_timestamp_ && macro_block_size_ > 0 && total_macro_block_count_ > 0 &&
reserved_block_count_ >= 0 && free_macro_block_count_ >= 0 && first_macro_block_ >= 0 &&
first_free_block_index_ > 0 && total_file_size_ >= macro_block_size_ && backup_meta_count_ > 0 &&
macro_block_meta_entry_block_index_ >= -1 && partition_meta_entry_block_index_ >= -1 &&
replay_start_point_.is_valid();
}
DEFINE_SERIALIZE(SuperBlock14)
{
int ret = OB_SUCCESS;
if (NULL == buf || buf_len - pos < header_size_) {
ret = OB_BUF_NOT_ENOUGH;
STORAGE_LOG(WARN, "serialize superblock failed.", KP(buf), K(buf_len), K(pos), K(header_size_), K(ret));
} else {
MEMCPY(buf + pos, this, sizeof(SuperBlock14));
pos += header_size_;
}
return ret;
}
DEFINE_DESERIALIZE(SuperBlock14)
{
int ret = OB_SUCCESS;
// read size first;
if (NULL == buf || data_len - pos < static_cast<int64_t>(sizeof(int32_t))) {
ret = OB_INVALID_ARGUMENT;
STORAGE_LOG(WARN, "invalid arguments.", KP(buf), K(data_len), K(pos), K(header_size_), K(ret));
} else {
int32_t header_size = *(reinterpret_cast<const int32_t*>(buf));
if (data_len - pos < header_size) {
ret = OB_BUF_NOT_ENOUGH;
STORAGE_LOG(ERROR, "data_len not enough for header size.", K(data_len), K(pos), K(header_size), K(ret));
} else {
MEMCPY(this, buf + pos, sizeof(SuperBlock14));
pos += header_size;
}
}
return ret;
}
DEFINE_GET_SERIALIZE_SIZE(SuperBlock14)
{
return sizeof(SuperBlock14);
}
TEST(ObCommitLogSpec, normal)
{
// is_valid() test
ObCommitLogSpec log_spec;
log_spec.log_dir_ = "./";
log_spec.max_log_size_ = 2L * 1024L;
log_spec.log_sync_type_ = 0;
ASSERT_TRUE(log_spec.is_valid());
log_spec.log_dir_ = NULL;
ASSERT_FALSE(log_spec.is_valid());
// to_string() test
const char* out = to_cstring(log_spec);
ASSERT_STRNE(NULL, out);
}
TEST(ObStorageEnv, normal)
{
// to_string() test
ObStorageEnv env;
const char* out = to_cstring(env);
ASSERT_STRNE(NULL, out);
}
TEST(SuperBlock, normal)
{
int ret = OB_SUCCESS;
ObArenaAllocator allocator(ObModIds::TEST);
int64_t buf_len = ObSuperBlockHeader::OB_MAX_SUPER_BLOCK_SIZE;
char* buf = static_cast<char*>(allocator.alloc(buf_len));
ASSERT_TRUE(NULL != buf);
int64_t pos = 0;
ObSuperBlockV2 sb1;
ObSuperBlockV2 sb2;
sb1.reset();
sb1.header_.version_ = OB_SUPER_BLOCK_V2;
sb1.header_.magic_ = SUPER_BLOCK_MAGIC_V2;
sb1.header_.attr_ = 0;
sb1.content_.create_timestamp_ = ObTimeUtility::current_time();
sb1.content_.modify_timestamp_ = sb1.content_.create_timestamp_;
sb1.content_.macro_block_size_ = common::OB_DEFAULT_MACRO_BLOCK_SIZE;
sb1.content_.total_macro_block_count_ = 10;
sb1.content_.free_macro_block_count_ = 0;
sb1.content_.total_file_size_ = 10 * common::OB_DEFAULT_MACRO_BLOCK_SIZE;
sb1.content_.macro_block_meta_.reset();
sb1.content_.partition_meta_.reset();
sb1.content_.table_mgr_meta_.reset();
sb1.content_.replay_start_point_.file_id_ = 1;
sb1.content_.replay_start_point_.log_id_ = 0;
sb1.content_.replay_start_point_.offset_ = 0;
sb1.header_.super_block_size_ = static_cast<int32_t>(sb1.get_serialize_size());
// serialize and deserizlize success test
pos = 0;
ret = sb1.serialize(buf, buf_len, pos);
ASSERT_EQ(OB_SUCCESS, ret);
pos = 0;
ret = sb2.deserialize(buf, buf_len, pos);
ASSERT_EQ(OB_SUCCESS, ret);
ASSERT_EQ(0, memcmp(&sb1, &sb2, sizeof(sb1)));
// serialize boundary test
pos = 0;
ret = sb1.serialize(buf, 10, pos);
ASSERT_NE(OB_SUCCESS, ret);
// deserialize boundary test
pos = 0;
ret = sb2.deserialize(buf, 10, pos);
ASSERT_NE(OB_SUCCESS, ret);
// to_string() test
const char* out = to_cstring(sb1);
ASSERT_STRNE(NULL, out);
}
TEST(SuperBlock, upgrade_from_20)
{
const int64_t buf_len = SuperBlock20::MAX_SUPER_BLOCK_SIZE;
char buf[buf_len];
SuperBlock20 super_block;
ObSuperBlockV1 super_block_v1;
ObSuperBlockV2 super_block_v2;
const int64_t data_file_size = 100 * 1024 * 1024;
int64_t pos = 0;
ASSERT_GT(buf_len, sizeof(super_block_v1));
ASSERT_EQ(sizeof(super_block_v1), sizeof(super_block));
MEMSET(&super_block, 0, sizeof(SuperBlock20));
super_block.header_size_ = sizeof(SuperBlock20);
super_block.version_ = ObMacroBlockCommonHeader::MACRO_BLOCK_COMMON_HEADER_VERSION;
super_block.magic_ = SUPER_BLOCK_MAGIC;
super_block.attr_ = 0;
// first two blocks are superblock.
super_block.backup_meta_count_ = SuperBlock20::MAX_BACKUP_META_COUNT;
super_block.backup_meta_blocks_[0] = 0;
super_block.backup_meta_blocks_[1] = 1;
super_block.create_timestamp_ = ObTimeUtility::current_time();
super_block.modify_timestamp_ = super_block.create_timestamp_;
super_block.macro_block_size_ = common::OB_DEFAULT_MACRO_BLOCK_SIZE;
super_block.total_macro_block_count_ = data_file_size / common::OB_DEFAULT_MACRO_BLOCK_SIZE;
super_block.reserved_block_count_ = super_block.backup_meta_count_;
super_block.free_macro_block_count_ = 0;
super_block.first_macro_block_ = super_block.backup_meta_blocks_[1] + 1;
super_block.first_free_block_index_ = super_block.first_macro_block_;
super_block.total_file_size_ = lower_align(data_file_size, common::OB_DEFAULT_MACRO_BLOCK_SIZE);
super_block.macro_block_meta_entry_block_index_ = 10;
super_block.partition_meta_entry_block_index_ = 20;
super_block.table_mgr_meta_entry_block_index_ = 30;
super_block.partition_meta_log_seq_ = 40;
super_block.table_mgr_meta_log_seq_ = 50;
super_block.replay_start_point_.file_id_ = 60;
super_block.replay_start_point_.log_id_ = 70;
super_block.replay_start_point_.offset_ = 80;
ASSERT_EQ(OB_SUCCESS, serialization::encode_i64(buf, buf_len, pos, ob_crc64(&super_block, super_block.header_size_)));
ASSERT_EQ(OB_SUCCESS, super_block.serialize(buf, buf_len, pos));
ASSERT_EQ(sizeof(super_block) + serialization::encoded_length_i64(0), pos);
STORAGE_LOG(INFO, "succeed to serialize super block", K(buf_len), K(pos), K(super_block));
pos = 0;
ASSERT_EQ(OB_SUCCESS, super_block_v1.read_super_block_buf(buf, buf_len, pos));
STORAGE_LOG(INFO, "read super block v1", K(super_block), K(super_block_v1));
ASSERT_EQ(0, memcmp(&super_block_v1, &super_block, sizeof(super_block)));
ASSERT_EQ(OB_SUCCESS, super_block_v2.set_super_block(super_block_v1));
STORAGE_LOG(INFO, "convert from v1", K(super_block_v1), K(super_block_v2));
const int64_t super_block_size = super_block_v2.get_serialize_size();
ASSERT_EQ(super_block_size, super_block_v2.header_.super_block_size_);
ASSERT_EQ(OB_SUPER_BLOCK_V2, super_block_v2.header_.version_);
ASSERT_EQ(SUPER_BLOCK_MAGIC_V2, super_block_v2.header_.magic_);
ASSERT_EQ(0, super_block_v2.header_.attr_);
ASSERT_EQ(super_block.create_timestamp_, super_block_v2.content_.create_timestamp_);
ASSERT_EQ(super_block.modify_timestamp_, super_block_v2.content_.modify_timestamp_);
ASSERT_EQ(super_block.macro_block_size_, super_block_v2.content_.macro_block_size_);
ASSERT_EQ(super_block.total_macro_block_count_, super_block_v2.content_.total_macro_block_count_);
ASSERT_EQ(super_block.free_macro_block_count_, super_block_v2.content_.free_macro_block_count_);
ASSERT_EQ(super_block.total_file_size_, super_block_v2.content_.total_file_size_);
ASSERT_EQ(super_block.replay_start_point_.file_id_, super_block_v2.content_.replay_start_point_.file_id_);
ASSERT_EQ(super_block.replay_start_point_.log_id_, super_block_v2.content_.replay_start_point_.log_id_);
ASSERT_EQ(super_block.replay_start_point_.offset_, super_block_v2.content_.replay_start_point_.offset_);
ASSERT_TRUE(check_meta_entry(
super_block_v2.content_.macro_block_meta_, super_block.macro_block_meta_entry_block_index_, 0, 0, 0));
ASSERT_TRUE(check_meta_entry(super_block_v2.content_.partition_meta_,
super_block.partition_meta_entry_block_index_,
super_block.partition_meta_log_seq_,
0,
0));
ASSERT_TRUE(check_meta_entry(super_block_v2.content_.table_mgr_meta_,
super_block.table_mgr_meta_entry_block_index_,
super_block.table_mgr_meta_log_seq_,
0,
0));
}
TEST(SuperBlock, upgrade_from_14)
{
const int64_t buf_len = SuperBlock14::MAX_SUPER_BLOCK_SIZE;
char buf[buf_len];
SuperBlock14 super_block;
ObSuperBlockV1 super_block_v1;
ObSuperBlockV2 super_block_v2;
const int64_t data_file_size = 100 * 1024 * 1024;
int64_t pos = 0;
ASSERT_GT(buf_len, sizeof(super_block_v1));
ASSERT_EQ(sizeof(super_block_v1), sizeof(super_block));
MEMSET(&super_block, 0, sizeof(SuperBlock14));
super_block.header_size_ = sizeof(SuperBlock14);
super_block.version_ = ObMacroBlockCommonHeader::MACRO_BLOCK_COMMON_HEADER_VERSION;
super_block.magic_ = SUPER_BLOCK_MAGIC;
super_block.attr_ = 0;
// first two blocks are superblock.
super_block.backup_meta_count_ = SuperBlock14::MAX_BACKUP_META_COUNT;
super_block.backup_meta_blocks_[0] = 0;
super_block.backup_meta_blocks_[1] = 1;
super_block.create_timestamp_ = ObTimeUtility::current_time();
super_block.modify_timestamp_ = super_block.create_timestamp_;
super_block.macro_block_size_ = common::OB_DEFAULT_MACRO_BLOCK_SIZE;
super_block.total_macro_block_count_ = data_file_size / common::OB_DEFAULT_MACRO_BLOCK_SIZE;
super_block.reserved_block_count_ = super_block.backup_meta_count_;
super_block.free_macro_block_count_ = 0;
super_block.first_macro_block_ = super_block.backup_meta_blocks_[1] + 1;
super_block.first_free_block_index_ = super_block.first_macro_block_;
super_block.total_file_size_ = lower_align(data_file_size, common::OB_DEFAULT_MACRO_BLOCK_SIZE);
super_block.macro_block_meta_entry_block_index_ = 10;
super_block.partition_meta_entry_block_index_ = 20;
super_block.replay_start_point_.file_id_ = 60;
super_block.replay_start_point_.log_id_ = 70;
super_block.replay_start_point_.offset_ = 80;
ASSERT_EQ(OB_SUCCESS, serialization::encode_i64(buf, buf_len, pos, ob_crc64(&super_block, super_block.header_size_)));
ASSERT_EQ(OB_SUCCESS, super_block.serialize(buf, buf_len, pos));
ASSERT_EQ(sizeof(super_block) + serialization::encoded_length_i64(0), pos);
pos = 0;
ASSERT_EQ(OB_SUCCESS, super_block_v1.read_super_block_buf(buf, buf_len, pos));
STORAGE_LOG(INFO, "read super block v1", K(super_block), K(super_block_v1));
ASSERT_EQ(0, memcmp(&super_block_v1, &super_block, sizeof(super_block)));
ASSERT_EQ(OB_SUCCESS, super_block_v2.set_super_block(super_block_v1));
STORAGE_LOG(INFO, "convert from v1", K(super_block_v1), K(super_block_v2));
ASSERT_EQ(super_block_v2.get_serialize_size(), super_block_v2.header_.super_block_size_);
ASSERT_EQ(OB_SUPER_BLOCK_V2, super_block_v2.header_.version_);
ASSERT_EQ(SUPER_BLOCK_MAGIC_V2, super_block_v2.header_.magic_);
ASSERT_EQ(0, super_block_v2.header_.attr_);
ASSERT_EQ(super_block.create_timestamp_, super_block_v2.content_.create_timestamp_);
ASSERT_EQ(super_block.modify_timestamp_, super_block_v2.content_.modify_timestamp_);
ASSERT_EQ(super_block.macro_block_size_, super_block_v2.content_.macro_block_size_);
ASSERT_EQ(super_block.total_macro_block_count_, super_block_v2.content_.total_macro_block_count_);
ASSERT_EQ(super_block.free_macro_block_count_, super_block_v2.content_.free_macro_block_count_);
ASSERT_EQ(super_block.total_file_size_, super_block_v2.content_.total_file_size_);
ASSERT_EQ(super_block.replay_start_point_.file_id_, super_block_v2.content_.replay_start_point_.file_id_);
ASSERT_EQ(super_block.replay_start_point_.log_id_, super_block_v2.content_.replay_start_point_.log_id_);
ASSERT_EQ(super_block.replay_start_point_.offset_, super_block_v2.content_.replay_start_point_.offset_);
ASSERT_TRUE(check_meta_entry(
super_block_v2.content_.macro_block_meta_, super_block.macro_block_meta_entry_block_index_, 0, 0, 0));
ASSERT_TRUE(check_meta_entry(
super_block_v2.content_.partition_meta_, super_block.partition_meta_entry_block_index_, 0, 0, 0));
ASSERT_TRUE(check_meta_entry(super_block_v2.content_.table_mgr_meta_, 0, 0, 0, 0));
}
TEST(SuperBlock, set_super_block)
{
int ret = OB_SUCCESS;
const int64_t data_file_size = 100 * 1024 * 1024;
ObSuperBlockV1 src_v1;
ObSuperBlockV1 dst_v1;
ObSuperBlockV2 sb_v2;
MEMSET(&src_v1, 0, sizeof(src_v1));
MEMSET(&dst_v1, 0, sizeof(dst_v1));
MEMSET(&sb_v2, 0, sizeof(sb_v2));
src_v1.header_.super_block_size_ = sizeof(src_v1);
src_v1.header_.version_ = ObMacroBlockCommonHeader::MACRO_BLOCK_COMMON_HEADER_VERSION;
src_v1.header_.magic_ = SUPER_BLOCK_MAGIC;
src_v1.header_.attr_ = 0;
src_v1.backup_meta_count_ = ObSuperBlockV1::MAX_BACKUP_META_COUNT;
src_v1.backup_meta_blocks_[0] = 0;
src_v1.backup_meta_blocks_[1] = 1;
src_v1.create_timestamp_ = ObTimeUtility::current_time();
src_v1.modify_timestamp_ = ObTimeUtility::current_time();
src_v1.macro_block_size_ = common::OB_DEFAULT_MACRO_BLOCK_SIZE;
src_v1.total_macro_block_count_ = data_file_size / common::OB_DEFAULT_MACRO_BLOCK_SIZE;
src_v1.reserved_block_count_ = src_v1.backup_meta_count_;
src_v1.free_macro_block_count_ = 100;
src_v1.first_macro_block_ = src_v1.backup_meta_blocks_[1] + 1;
src_v1.first_free_block_index_ = src_v1.first_macro_block_;
src_v1.total_file_size_ = lower_align(data_file_size, common::OB_DEFAULT_MACRO_BLOCK_SIZE);
src_v1.macro_block_meta_entry_block_index_ = 10;
src_v1.partition_meta_entry_block_index_ = 20;
src_v1.table_mgr_meta_entry_block_index_ = 30;
src_v1.partition_meta_log_seq_ = 40;
src_v1.table_mgr_meta_log_seq_ = 50;
src_v1.replay_start_point_.file_id_ = 60;
src_v1.replay_start_point_.log_id_ = 70;
src_v1.replay_start_point_.offset_ = 80;
ret = sb_v2.set_super_block(src_v1);
ASSERT_EQ(OB_SUCCESS, ret);
ret = dst_v1.set_super_block(sb_v2);
ASSERT_EQ(OB_SUCCESS, ret);
ASSERT_EQ(src_v1.header_.super_block_size_, dst_v1.header_.super_block_size_);
ASSERT_EQ(src_v1.header_.version_, dst_v1.header_.version_);
ASSERT_EQ(src_v1.header_.magic_, dst_v1.header_.magic_);
ASSERT_EQ(src_v1.header_.attr_, dst_v1.header_.attr_);
ASSERT_EQ(src_v1.backup_meta_count_, dst_v1.backup_meta_count_);
ASSERT_EQ(src_v1.backup_meta_blocks_[0], dst_v1.backup_meta_blocks_[0]);
ASSERT_EQ(src_v1.backup_meta_blocks_[1], dst_v1.backup_meta_blocks_[1]);
ASSERT_EQ(src_v1.create_timestamp_, dst_v1.create_timestamp_);
ASSERT_EQ(src_v1.modify_timestamp_, dst_v1.modify_timestamp_);
ASSERT_EQ(src_v1.macro_block_size_, dst_v1.macro_block_size_);
ASSERT_EQ(src_v1.total_macro_block_count_, dst_v1.total_macro_block_count_);
ASSERT_EQ(src_v1.reserved_block_count_, dst_v1.reserved_block_count_);
ASSERT_EQ(src_v1.free_macro_block_count_, dst_v1.free_macro_block_count_);
ASSERT_EQ(src_v1.first_macro_block_, dst_v1.first_macro_block_);
ASSERT_EQ(src_v1.first_free_block_index_, dst_v1.first_free_block_index_);
ASSERT_EQ(src_v1.total_file_size_, dst_v1.total_file_size_);
ASSERT_EQ(src_v1.macro_block_meta_entry_block_index_, dst_v1.macro_block_meta_entry_block_index_);
ASSERT_EQ(src_v1.partition_meta_entry_block_index_, dst_v1.partition_meta_entry_block_index_);
ASSERT_EQ(src_v1.table_mgr_meta_entry_block_index_, dst_v1.table_mgr_meta_entry_block_index_);
ASSERT_EQ(src_v1.partition_meta_log_seq_, dst_v1.partition_meta_log_seq_);
ASSERT_EQ(src_v1.table_mgr_meta_log_seq_, dst_v1.table_mgr_meta_log_seq_);
ASSERT_EQ(src_v1.replay_start_point_.file_id_, dst_v1.replay_start_point_.file_id_);
ASSERT_EQ(src_v1.replay_start_point_.log_id_, dst_v1.replay_start_point_.log_id_);
ASSERT_EQ(src_v1.replay_start_point_.offset_, dst_v1.replay_start_point_.offset_);
}
TEST(ObLinkedMacroBlockHeader, normal)
{
// check() test
ObLinkedMacroBlockHeader link_header;
link_header.version_ = 1;
link_header.magic_ = 2;
link_header.attr_ = 1;
ASSERT_FALSE(link_header.is_valid());
link_header.header_size_ = sizeof(link_header);
link_header.version_ = LINKED_MACRO_BLOCK_HEADER_VERSION;
link_header.magic_ = MACRO_META_HEADER_MAGIC;
link_header.attr_ = ObMacroBlockCommonHeader::MacroMeta;
ASSERT_TRUE(link_header.is_valid());
// to_string() test
const char* out = to_cstring(link_header);
ASSERT_STRNE(NULL, out);
}
TEST(ObMicroBlockHeader, normal)
{
// to_string() test
ObMicroBlockHeader micro_header;
const char* out = to_cstring(micro_header);
ASSERT_STRNE(NULL, out);
}
TEST(ObMacroBlockCommonHeader, normal)
{
// check() test
ObMacroBlockCommonHeader common_header;
common_header.set_attr(ObMacroBlockCommonHeader::PartitionMeta);
ASSERT_TRUE(common_header.is_valid());
common_header.set_previous_block_index(-2);
ASSERT_FALSE(common_header.is_valid());
// to_string() test
const char* out = to_cstring(common_header);
ASSERT_STRNE(NULL, out);
// serialization length test
ASSERT_EQ(common_header.header_size_, common_header.get_serialize_size());
}
TEST(ObSSTableMacroBlockHeader, normal)
{
// to_string() test
ObSSTableMacroBlockHeader sstable_header;
const char* out = to_cstring(sstable_header);
ASSERT_STRNE(NULL, out);
}
TEST(ObMacroBlockMeta, serialize)
{
int ret = OB_SUCCESS;
ObArenaAllocator allocator(ObModIds::TEST);
int64_t buf_len = 0;
int64_t pos = 0;
char* buf = NULL;
ObMacroBlockMeta meta1;
ObMacroBlockMeta meta2;
// serialize and deserialize success test
ObMacroMetaGenerator::gen_meta(meta1, allocator);
buf_len = meta1.get_serialize_size();
buf = static_cast<char*>(allocator.alloc(buf_len));
ASSERT_STRNE(NULL, buf);
pos = 0;
ret = meta1.serialize(buf, buf_len, pos);
ASSERT_EQ(OB_SUCCESS, ret);
ObObj out_endkey[128];
meta2.endkey_ = out_endkey;
pos = 0;
ret = meta2.deserialize(buf, buf_len, pos);
ASSERT_EQ(ret, OB_SUCCESS);
ASSERT_TRUE(meta1 == meta2);
// serialize boundary
for (int64_t i = buf_len - 50; i < buf_len; ++i) {
pos = i;
ret = meta1.serialize(buf, buf_len, pos);
ASSERT_NE(OB_SUCCESS, ret);
}
}
TEST(ObMacroBlockMeta, deep_copy)
{
int ret = OB_SUCCESS;
int64_t column_num = 7;
ObArenaAllocator allocator(ObModIds::TEST);
ObMacroBlockMeta meta1;
ObMacroBlockMeta* meta2 = NULL;
ObMacroMetaGenerator::gen_meta(meta1, allocator);
ObRowkey rowkey(meta1.endkey_, column_num);
ObRowkey collation_free_rowkey;
int64_t deep_copy_size = sizeof(ObMacroBlockMeta) + 5 // compressor_
+ sizeof(uint16_t) * column_num // column_id_array_
+ sizeof(ObObjMeta) * column_num // column_type_array
+ sizeof(ObOrderType) * column_num // column_order_array_
+ sizeof(int64_t) * column_num // column_checksum_
+ sizeof(int64_t) * column_num // empty_read_cnt_
+ rowkey.get_deep_copy_size(); // endkey_
int64_t get_deep_copy_size = 0;
ASSERT_EQ(OB_SUCCESS, meta1.get_deep_copy_size(collation_free_rowkey, allocator, get_deep_copy_size));
deep_copy_size += collation_free_rowkey.get_deep_copy_size();
ASSERT_EQ(deep_copy_size, get_deep_copy_size);
// copy success test
ret = meta1.deep_copy(meta2, allocator);
ASSERT_EQ(ret, OB_SUCCESS);
ASSERT_TRUE(NULL != meta2);
ASSERT_TRUE(meta1 == *meta2);
// empty_read_cnt_ = NULL;
ObMacroBlockMeta* meta3 = NULL;
ASSERT_EQ(OB_SUCCESS, meta1.get_deep_copy_size(collation_free_rowkey, allocator, get_deep_copy_size));
ASSERT_EQ(deep_copy_size, get_deep_copy_size);
ret = meta1.deep_copy(meta3, allocator);
ASSERT_EQ(OB_SUCCESS, ret);
ASSERT_TRUE(NULL != meta3);
ASSERT_TRUE(meta1 == *meta3);
}
TEST(ObMacroBlockMeta, misc)
{
ObArenaAllocator allocator(ObModIds::TEST);
ObMacroBlockMeta meta;
ObMacroMetaGenerator::gen_meta(meta, allocator);
// to_string() test
const char* out = to_cstring(meta);
ASSERT_STRNE(NULL, out);
}
TEST(ObSSTableMeta, normal)
{
int ret = OB_SUCCESS;
ObArenaAllocator allocator(ObModIds::TEST);
int64_t buf_len = 0;
int64_t pos = 0;
char* buf = NULL;
ObSSTableMeta smeta1(allocator);
ObSSTableMeta smeta2(allocator);
smeta1.index_id_ = 3001;
smeta1.row_count_ = 2;
smeta1.occupy_size_ = 2 * 1024 * 1024;
smeta1.data_checksum_ = 12345;
smeta1.row_checksum_ = 12345;
smeta1.data_version_ = 1;
smeta1.rowkey_column_count_ = 2;
smeta1.table_type_ = 0;
smeta1.index_type_ = 0;
smeta1.available_version_ = 0;
smeta1.macro_block_count_ = 1;
smeta1.column_cnt_ = 10;
smeta1.checksum_method_ = blocksstable::CCM_VALUE_ONLY;
ObSSTableColumnMeta col_meta;
ASSERT_EQ(OB_SUCCESS, smeta1.column_metas_.reserve(smeta1.column_cnt_));
ASSERT_EQ(OB_SUCCESS, smeta1.new_column_metas_.reserve(smeta1.column_cnt_));
for (int64_t i = 0; i < smeta1.column_cnt_; ++i) {
col_meta.column_id_ = i + 1;
col_meta.column_default_checksum_ = i;
col_meta.column_checksum_ = i * 10;
smeta1.column_metas_.push_back(col_meta);
}
for (int64_t i = 0; i < smeta1.column_cnt_; ++i) {
col_meta.column_id_ = i + 1;
col_meta.column_default_checksum_ = i;
col_meta.column_checksum_ = i * 10;
smeta1.new_column_metas_.push_back(col_meta);
}
MacroBlockId block_id(0, 0, 0, 2);
ret = smeta1.macro_block_array_.push_back(block_id);
ASSERT_EQ(ret, OB_SUCCESS);
buf_len = smeta1.get_serialize_size();
buf = static_cast<char*>(allocator.alloc(buf_len));
ASSERT_STRNE(NULL, buf);
// serizlize and deserialize success
pos = 0;
ret = smeta1.serialize(buf, buf_len, pos);
ASSERT_EQ(OB_SUCCESS, ret);
ASSERT_EQ(smeta1.get_serialize_size(), pos);
pos = 0;
ret = smeta2.deserialize(buf, buf_len, pos);
ASSERT_EQ(ret, OB_SUCCESS);
ASSERT_TRUE(smeta1 == smeta2);
// serialize boundary test
for (int64_t i = 1; i < buf_len; ++i) {
pos = i;
ret = smeta1.serialize(buf, buf_len, pos);
ASSERT_NE(OB_SUCCESS, ret);
}
// deserialize boundary test
for (int64_t i = 1; i < buf_len; ++i) {
pos = i;
ret = smeta2.deserialize(buf, buf_len, pos);
ASSERT_NE(OB_SUCCESS, ret);
}
// to_string
const char* out = to_cstring(smeta1);
ASSERT_STRNE(NULL, out);
}
TEST(ObPartitionMeta, normal)
{
int ret = OB_SUCCESS;
ObArenaAllocator allocator(ObModIds::TEST);
int64_t buf_len = 0;
int64_t pos = 0;
char* buf = NULL;
ObPartitionMeta pmeta1;
ObPartitionMeta pmeta2;
memset(&pmeta1, 223, sizeof(pmeta1));
pmeta1.log_info_.assign_ptr("hello", static_cast<ObString::obstr_size_t>(strlen("hello")));
// serialize and deserialize boundary test
buf_len = pmeta1.get_serialize_size();
buf = static_cast<char*>(allocator.alloc(buf_len));
ASSERT_STRNE(NULL, buf);
for (int64_t i = 1; i < buf_len; ++i) {
pos = i;
ret = pmeta1.serialize(buf, buf_len, pos);
ASSERT_NE(OB_SUCCESS, ret);
}
// serialize and deserialize success test
pos = 0;
ret = pmeta1.serialize(buf, buf_len, pos);
ASSERT_EQ(ret, OB_SUCCESS);
ASSERT_EQ(pos, pmeta1.get_serialize_size());
pos = 0;
ret = pmeta2.deserialize(buf, buf_len, pos);
ASSERT_EQ(ret, OB_SUCCESS);
ASSERT_TRUE(pmeta1 == pmeta2);
pmeta2.reset();
pos = 0;
ret = pmeta2.deserialize(buf, buf_len, pos, allocator);
ASSERT_EQ(OB_SUCCESS, ret);
ASSERT_TRUE(pmeta1 == pmeta2);
// to_string
const char* out = to_cstring(pmeta1);
ASSERT_STRNE(NULL, out);
}
TEST(ObSSTableMeta, to_string)
{
int ret = OB_SUCCESS;
ObArenaAllocator allocator(ObModIds::TEST);
ObSSTableMeta sstable_meta(allocator);
MacroBlockId block_id(1);
const int64_t buf_len = 100;
char buf[buf_len];
int64_t pos = 0;
for (int64_t i = 0; i < 10000; ++i) {
sstable_meta.macro_block_count_++;
ret = sstable_meta.macro_block_array_.push_back(block_id);
ASSERT_EQ(OB_SUCCESS, ret);
}
pos = sstable_meta.to_string(buf, buf_len);
ASSERT_TRUE(pos <= buf_len);
}
TEST(ObPartitionMeta, deserialize_error)
{
ObArenaAllocator allocator(ObModIds::TEST);
common::ObLfFIFOAllocator fifo_allocator;
int64_t buf_len = 0;
int64_t pos = 0;
char* buf = NULL;
ObPartitionMeta pmeta1;
ObPartitionMeta pmeta2;
memset(&pmeta1, 223, sizeof(pmeta1));
pmeta1.log_info_.assign_ptr("hello", static_cast<ObString::obstr_size_t>(strlen("hello")));
ASSERT_EQ(
OB_SUCCESS, fifo_allocator.init(8 * 1024 * 1024, ObModIds::TEST, OB_SERVER_TENANT_ID, 1, 8 * 1024 * 1024 + 4096));
void* used = fifo_allocator.alloc(8 * 1024 * 1024 - 17 /*sizeof(SliceHeader)*/ - 1);
ASSERT_TRUE(NULL != used);
buf_len = pmeta1.get_serialize_size();
buf = static_cast<char*>(allocator.alloc(buf_len));
ASSERT_TRUE(NULL != buf);
pos = 0;
ASSERT_EQ(OB_SUCCESS, pmeta1.serialize(buf, buf_len, pos));
pos = 0;
ASSERT_EQ(OB_ALLOCATE_MEMORY_FAILED, pmeta2.deserialize(buf, buf_len, pos, fifo_allocator));
if (NULL != pmeta2.log_info_.ptr()) {
fifo_allocator.free(pmeta2.log_info_.ptr());
}
fifo_allocator.free(used);
}
} // namespace blocksstable
} // namespace oceanbase
int main(int argc, char** argv)
{
OB_LOGGER.set_log_level("INFO");
testing::InitGoogleTest(&argc, argv);
oceanbase::lib::set_memory_limit(40L << 30);
return RUN_ALL_TESTS();
}