patch 4.0
This commit is contained in:
285
src/storage/ob_super_block_struct.cpp
Normal file
285
src/storage/ob_super_block_struct.cpp
Normal file
@ -0,0 +1,285 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX STORAGE
|
||||
|
||||
#include "storage/ob_super_block_struct.h"
|
||||
#include "storage/blocksstable/ob_block_sstable_struct.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace storage
|
||||
{
|
||||
|
||||
using namespace oceanbase::common;
|
||||
using namespace oceanbase::blocksstable;
|
||||
|
||||
const MacroBlockId ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK(0, MacroBlockId::EMPTY_ENTRY_BLOCK_INDEX, 0);
|
||||
|
||||
// ========================== ObServerSuperBlock ==============================
|
||||
|
||||
ObServerSuperBlockHeader::ObServerSuperBlockHeader()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
bool ObServerSuperBlockHeader::is_valid() const
|
||||
{
|
||||
return version_ == SERVER_SUPER_BLOCK_VERSION
|
||||
&& magic_ == SERVER_SUPER_BLOCK_MAGIC && body_size_ > 0;
|
||||
}
|
||||
|
||||
void ObServerSuperBlockHeader::reset()
|
||||
{
|
||||
version_ = 0;
|
||||
magic_ = 0;
|
||||
body_size_ = 0;
|
||||
body_crc_ = 0;
|
||||
}
|
||||
|
||||
DEFINE_SERIALIZE(ObServerSuperBlockHeader)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (NULL == buf || buf_len - pos < sizeof(ObServerSuperBlockHeader)) {
|
||||
ret = OB_BUF_NOT_ENOUGH;
|
||||
LOG_WARN("serialize superblock failed.", K(ret), KP(buf), K(buf_len), K(pos), "header_size",
|
||||
sizeof(ObServerSuperBlockHeader));
|
||||
} else {
|
||||
MEMCPY(buf + pos, this, sizeof(ObServerSuperBlockHeader));
|
||||
pos += sizeof(ObServerSuperBlockHeader);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEFINE_DESERIALIZE(ObServerSuperBlockHeader)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (NULL == buf || data_len - pos < sizeof(ObServerSuperBlockHeader)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid arguments.", K(ret), KP(buf), K(data_len), K(pos), "header_size",
|
||||
sizeof(ObServerSuperBlockHeader));
|
||||
} else {
|
||||
MEMCPY(this, buf + pos, sizeof(ObServerSuperBlockHeader));
|
||||
pos += sizeof(ObServerSuperBlockHeader);
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_UNLIKELY(SERVER_SUPER_BLOCK_VERSION != version_ || SERVER_SUPER_BLOCK_MAGIC != magic_)) {
|
||||
ret = OB_ERR_SYS;
|
||||
LOG_ERROR("version or magic not match", K(ret), K(*this));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEFINE_GET_SERIALIZE_SIZE(ObServerSuperBlockHeader)
|
||||
{
|
||||
return sizeof(ObServerSuperBlockHeader);
|
||||
}
|
||||
|
||||
ServerSuperBlockBody::ServerSuperBlockBody()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
bool ServerSuperBlockBody::is_valid() const
|
||||
{
|
||||
return create_timestamp_ > 0 && modify_timestamp_ >= create_timestamp_ &&
|
||||
macro_block_size_ > 0 && total_macro_block_count_ > 0 &&
|
||||
total_file_size_ >= macro_block_size_ && replay_start_point_.is_valid() &&
|
||||
tenant_meta_entry_.is_valid();
|
||||
}
|
||||
|
||||
void ServerSuperBlockBody::reset()
|
||||
{
|
||||
create_timestamp_ = 0;
|
||||
modify_timestamp_ = 0;
|
||||
macro_block_size_ = 0;
|
||||
total_macro_block_count_ = 0;
|
||||
total_file_size_ = 0;
|
||||
replay_start_point_.reset();
|
||||
tenant_meta_entry_.reset();
|
||||
}
|
||||
|
||||
OB_SERIALIZE_MEMBER(ServerSuperBlockBody, create_timestamp_,
|
||||
modify_timestamp_, macro_block_size_, total_macro_block_count_, total_file_size_,
|
||||
replay_start_point_, tenant_meta_entry_);
|
||||
|
||||
ObServerSuperBlock::ObServerSuperBlock() : header_(), body_() {}
|
||||
|
||||
bool ObServerSuperBlock::is_valid() const
|
||||
{
|
||||
return header_.is_valid() && body_.is_valid();
|
||||
}
|
||||
|
||||
int64_t ObServerSuperBlock::get_serialize_size() const
|
||||
{
|
||||
return header_.get_serialize_size() + body_.get_serialize_size();
|
||||
}
|
||||
|
||||
int ObServerSuperBlock::serialize(char *buf, const int64_t buf_size, int64_t &pos) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t new_pos = pos;
|
||||
|
||||
if (OB_ISNULL(buf) || buf_size <= 0) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid args", K(ret), KP(buf), K(buf_size));
|
||||
} else if (!is_valid()) {
|
||||
ret = OB_ERR_SYS;
|
||||
LOG_WARN("cannot write invalid super block", K(ret), K(*this));
|
||||
} else {
|
||||
MEMSET(buf + pos, 0, buf_size - pos);
|
||||
if (OB_FAIL(header_.serialize(buf, buf_size, new_pos))) {
|
||||
LOG_WARN("failed to encode super block header", K(ret), K(buf_size), K(new_pos), K(*this));
|
||||
} else if (OB_FAIL(body_.serialize(buf, buf_size, new_pos))) {
|
||||
LOG_WARN("failed to encode super block content", K(ret), K(buf_size), K(new_pos), K(*this));
|
||||
} else {
|
||||
pos = new_pos;
|
||||
LOG_INFO("succeed to serialize super block buf", K(buf_size), K(pos), K(*this));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObServerSuperBlock::deserialize(const char *buf, const int64_t buf_size, int64_t &pos)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int32_t calc_crc = 0;
|
||||
if (OB_ISNULL(buf) || buf_size <= 0 || pos < 0) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid args", K(ret), KP(buf), K(buf_size));
|
||||
} else if (is_valid()) {
|
||||
ret = OB_INIT_TWICE;
|
||||
LOG_ERROR("cannot read super block twice", K(ret), K(*this));
|
||||
} else if (OB_FAIL(header_.deserialize(buf, buf_size, pos))) {
|
||||
LOG_WARN("failed to decode header", K(ret), KP(buf), K(buf_size), K(pos));
|
||||
} else if (OB_UNLIKELY(header_.body_crc_ !=
|
||||
(calc_crc = static_cast<int32_t>(ob_crc64(buf + pos, header_.body_size_))))) {
|
||||
ret = OB_CHECKSUM_ERROR;
|
||||
LOG_WARN("failed to check crc", K(ret), KP(buf), K(buf_size), K(pos), K_(header), K(calc_crc));
|
||||
} else if (OB_FAIL(body_.deserialize(buf, buf_size, pos))) {
|
||||
LOG_WARN("failed to decode body", K(ret), KP(buf), K(buf_size), K(pos));
|
||||
} else if (OB_UNLIKELY(!is_valid())) {
|
||||
ret = OB_INVALID_DATA;
|
||||
LOG_WARN("invalid data, ", K(ret), K(*this));
|
||||
} else {
|
||||
LOG_INFO("load server superblock success.", K(buf_size), K(pos), K(*this));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObServerSuperBlock::reset()
|
||||
{
|
||||
header_.reset();
|
||||
body_.reset();
|
||||
}
|
||||
|
||||
int ObServerSuperBlock::construct_header()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(!body_.is_valid())) {
|
||||
ret = OB_INVALID_DATA;
|
||||
LOG_WARN("super block body invalid", K(ret), K_(body));
|
||||
} else {
|
||||
// calculate crc of content serialized buffer
|
||||
int64_t pos = 0;
|
||||
int64_t body_buf_len = body_.get_serialize_size();
|
||||
char *body_buf = static_cast<char *>(ob_malloc(body_buf_len, "SuperBlock"));
|
||||
if (OB_ISNULL(body_buf)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to allocate memory for body", K(ret));
|
||||
} else if (OB_FAIL(body_.serialize(body_buf, body_buf_len, pos))) {
|
||||
LOG_WARN("fail to serialize super block body", K(ret));
|
||||
} else {
|
||||
header_.version_ = ObServerSuperBlockHeader::SERVER_SUPER_BLOCK_VERSION;
|
||||
header_.magic_ = SERVER_SUPER_BLOCK_MAGIC;
|
||||
header_.body_size_ = body_buf_len;
|
||||
header_.body_crc_ = static_cast<int32_t>(ob_crc64(body_buf, body_buf_len));
|
||||
ob_free(body_buf);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObServerSuperBlock::format_startup_super_block(
|
||||
const int64_t macro_block_size, const int64_t data_file_size)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (macro_block_size <= 0 || data_file_size <= 0 || data_file_size < macro_block_size) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument", K(ret), K(macro_block_size), K(data_file_size));
|
||||
} else {
|
||||
reset();
|
||||
body_.create_timestamp_ = ObTimeUtility::current_time();
|
||||
body_.modify_timestamp_ = body_.create_timestamp_;
|
||||
body_.macro_block_size_ = macro_block_size;
|
||||
body_.total_macro_block_count_ = data_file_size / macro_block_size;
|
||||
body_.total_file_size_ = lower_align(data_file_size, macro_block_size);
|
||||
body_.tenant_meta_entry_ = ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK;
|
||||
|
||||
body_.replay_start_point_.file_id_ = 1;
|
||||
body_.replay_start_point_.log_id_ = 1; // Due to the design of slog, the log_id_'s initial value must be 1
|
||||
body_.replay_start_point_.offset_ = 0;
|
||||
|
||||
if (OB_FAIL(construct_header())) {
|
||||
LOG_WARN("fail to construct super block header", K(ret), K_(body));
|
||||
} else {
|
||||
LOG_INFO("success to format super block", K(*this));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ========================== ObTenantSuperBlock ==============================
|
||||
|
||||
ObTenantSuperBlock::ObTenantSuperBlock()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
ObTenantSuperBlock::ObTenantSuperBlock(const uint64_t tenant_id, const bool is_hidden)
|
||||
: tenant_id_(tenant_id), is_hidden_(is_hidden)
|
||||
{
|
||||
replay_start_point_.file_id_ = 1;
|
||||
replay_start_point_.log_id_ = 1; // // Due to the design of slog, the log_id_'s initial value must be 1
|
||||
replay_start_point_.offset_ = 0;
|
||||
tablet_meta_entry_ = ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK;
|
||||
ls_meta_entry_ = ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK;
|
||||
}
|
||||
|
||||
void ObTenantSuperBlock::reset()
|
||||
{
|
||||
tenant_id_ = OB_INVALID_TENANT_ID;
|
||||
replay_start_point_.reset();
|
||||
ls_meta_entry_.reset();
|
||||
tablet_meta_entry_.reset();
|
||||
is_hidden_= false;
|
||||
}
|
||||
|
||||
bool ObTenantSuperBlock::is_valid() const
|
||||
{
|
||||
return OB_INVALID_TENANT_ID != tenant_id_ &&
|
||||
replay_start_point_.is_valid() &&
|
||||
ls_meta_entry_.is_valid() && tablet_meta_entry_.is_valid();
|
||||
}
|
||||
|
||||
OB_SERIALIZE_MEMBER(ObTenantSuperBlock,
|
||||
tenant_id_,
|
||||
replay_start_point_,
|
||||
ls_meta_entry_,
|
||||
tablet_meta_entry_,
|
||||
is_hidden_);
|
||||
|
||||
} // end namespace storage
|
||||
} // end namespace oceanbase
|
||||
Reference in New Issue
Block a user