Bugfix: inconsistent determination of meta root between sec meta iterator and meta tree builder

This commit is contained in:
ND501 2025-01-01 19:15:41 +00:00 committed by ob-robot
parent cd7e3e25e8
commit 0dc6ceda7b
4 changed files with 44 additions and 22 deletions

View File

@ -35,6 +35,8 @@
namespace oceanbase
{
ERRSIM_POINT_DEF(EN_COMPACTION_DISABLE_SHARED_MACRO);
ERRSIM_POINT_DEF(EN_SSTABLE_SINGLE_ROOT_TREE);
ERRSIM_POINT_DEF(EN_SSTABLE_META_IN_TAIL);
using namespace common;
using namespace storage;
using namespace compaction;
@ -1599,8 +1601,7 @@ int ObSSTableIndexBuilder::close_with_macro_seq(
STORAGE_LOG(DEBUG, "sstable has no data", K(ret));
} else if (OB_FAIL(sort_roots())) {
STORAGE_LOG(WARN, "fail to sort roots", K(ret));
} else if (check_version_for_small_sstable(index_store_desc_.get_desc()) &&
0 == nested_offset && device_handle_ == nullptr) {
} else if (0 == nested_offset && device_handle_ == nullptr) {
const bool is_single_block = check_single_block();
if (is_single_block) {
ObSpaceOptimizationMode tmp_mode = optimization_mode_;
@ -1609,7 +1610,7 @@ int ObSSTableIndexBuilder::close_with_macro_seq(
tmp_mode = DISABLE;
}
#ifdef ERRSIM
if (EN_COMPACTION_DISABLE_SHARED_MACRO) {
if (OB_SUCCESS != EN_COMPACTION_DISABLE_SHARED_MACRO) {
tmp_mode = DISABLE;
FLOG_INFO("ERRSIM EN_COMPACTION_DISABLE_SHARED_MACRO", KR(ret));
}
@ -1629,6 +1630,9 @@ int ObSSTableIndexBuilder::close_with_macro_seq(
STORAGE_LOG(WARN, "the optimization mode is invalid", K(ret), K(optimization_mode_));
break;
}
} else {
res.nested_offset_ = nested_offset;
res.nested_size_ = nested_size;
}
} else {
// if nested_offset is not 0, this sstable is reused-small-sstable, we don't
@ -1690,13 +1694,6 @@ int ObSSTableIndexBuilder::close_with_macro_seq(
return ret;
}
bool ObSSTableIndexBuilder::check_version_for_small_sstable(
const ObDataStoreDesc &index_desc)
{
return !index_desc.is_major_merge_type() ||
index_desc.get_major_working_cluster_version() >= DATA_VERSION_4_1_0_0;
}
int ObSSTableIndexBuilder::check_and_rewrite_sstable(ObSSTableMergeRes &res)
{
int ret = OB_SUCCESS;
@ -3437,7 +3434,30 @@ int ObMetaIndexBlockBuilder::close(
int ret = OB_SUCCESS;
ObIndexTreeInfo tree_info;
ObMicroBlockDesc micro_block_desc;
if (OB_UNLIKELY(!is_inited_)) {
int64_t single_root_tree_block_size_limit = ROOT_BLOCK_SIZE_LIMIT;
bool allow_meta_in_tail = !roots[0]->is_backup_task(); // backup can't send read io
#ifdef ERRSIM
int tp_ret = EN_SSTABLE_SINGLE_ROOT_TREE;
if (OB_SIZE_OVERFLOW == tp_ret) {
single_root_tree_block_size_limit = 64;
FLOG_INFO("ERRSIM EN_SSTABLE_SINGLE_ROOT_TREE", K(tp_ret), K(single_root_tree_block_size_limit));
} else if (OB_BUF_NOT_ENOUGH == tp_ret) {
single_root_tree_block_size_limit = ROOT_BLOCK_SIZE_LIMIT * 10; // 160K
FLOG_INFO("ERRSIM EN_SSTABLE_SINGLE_ROOT_TREE", K(tp_ret), K(single_root_tree_block_size_limit));
}
if (OB_SUCCESS != EN_SSTABLE_META_IN_TAIL && OB_SUCCESS != EN_COMPACTION_DISABLE_SHARED_MACRO) {
allow_meta_in_tail = false;
FLOG_INFO("EN_SSTABLE_META_IN_TAIL succeed", K(allow_meta_in_tail));
}
FLOG_INFO("errsim meta tree builder",
K(ret), K(EN_SSTABLE_SINGLE_ROOT_TREE), K(EN_SSTABLE_META_IN_TAIL), K(EN_COMPACTION_DISABLE_SHARED_MACRO),
K(single_root_tree_block_size_limit), K(allow_meta_in_tail));
#endif
if (OB_FAIL(ret)) {
} else if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
STORAGE_LOG(WARN, "invalid ObMetaIndexBlockBuilder", K(ret), K(is_inited_));
} else if (OB_UNLIKELY(is_closed_)) {
@ -3446,9 +3466,9 @@ int ObMetaIndexBlockBuilder::close(
} else if (OB_FAIL(build_micro_block(micro_block_desc))) {
STORAGE_LOG(WARN, "fail to build micro block of meta", K(ret));
} else if (index_block_aggregator_.get_row_count() <= 0 &&
micro_block_desc.get_block_size() <= ROOT_BLOCK_SIZE_LIMIT) {
// meta block's size is smaller than ROOT_BLOCK_SIZE_LIMIT, all meta data
// will be stored in root
micro_block_desc.get_block_size() <= single_root_tree_block_size_limit) {
// Meta block's size is smaller than ROOT_BLOCK_SIZE_LIMIT, all meta data
// will be stored in root.
if (OB_FAIL(ObBaseIndexBlockBuilder::close(allocator, tree_info))) {
STORAGE_LOG(WARN, "fail to close index tree of meta", K(ret));
} else if (OB_FAIL(build_single_node_tree(allocator, micro_block_desc,
@ -3456,10 +3476,9 @@ int ObMetaIndexBlockBuilder::close(
STORAGE_LOG(WARN, "fail to build single node tree of meta", K(ret));
}
} else if (index_block_aggregator_.get_row_count() <= 0 && 1 == micro_block_desc.row_count_
&& ObSSTableIndexBuilder::check_version_for_small_sstable(*index_store_desc_)
&& !roots[0]->is_backup_task()) {
// this sstable only has one data block, but the size of meta data exceeds ROOT_BLOCK_SIZE_LIMIT,
// so sstable's root points to the tail of its data block (macro meta row)
&& allow_meta_in_tail) {
// This sstable only has one data block, but the size of meta data exceeds ROOT_BLOCK_SIZE_LIMIT,
// so sstable's root points to the tail of its data block (macro meta row).
if (OB_FAIL(build_single_macro_row_desc(roots, index_block_loader, nested_size, nested_offset, allocator))) {
STORAGE_LOG(WARN, "fail to build single marcro row descn", K(ret), K(nested_size), K(nested_offset));
} else if (OB_FAIL(ObBaseIndexBlockBuilder::close(allocator, tree_info))) {
@ -3468,7 +3487,12 @@ int ObMetaIndexBlockBuilder::close(
block_desc = tree_info.root_desc_;
}
} else {
if (micro_block_desc.row_count_ > 0 && OB_FAIL(append_micro_block(micro_block_desc))) {
// Multi-level meta tree, cannot be small sstable.
if (OB_UNLIKELY(!(nested_offset == 0 && nested_size == OB_DEFAULT_MACRO_BLOCK_SIZE))) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("fail to build meta tree, should not be small sstable",
K(ret), K(nested_offset), K(nested_size), K(common::lbt()));
} else if (micro_block_desc.row_count_ > 0 && OB_FAIL(append_micro_block(micro_block_desc))) {
STORAGE_LOG(WARN, "fail to append micro block of meta to macro block", K(ret));
} else if (OB_FAIL(ObBaseIndexBlockBuilder::close(allocator, tree_info))) {
STORAGE_LOG(WARN, "fail to close index tree of meta", K(ret));

View File

@ -644,7 +644,6 @@ public:
TO_STRING_KV(K(roots_.count()));
public:
static bool check_version_for_small_sstable(const ObDataStoreDesc &index_desc);
static int load_single_macro_block(
const ObDataMacroBlockMeta &macro_meta,
const int64_t nested_size,

View File

@ -258,7 +258,7 @@ int ObSSTableSecMetaIterator::get_next(ObDataMacroBlockMeta &macro_meta)
} else {
const ObSSTableMacroInfo &macro_info = sstable_meta_hdl_.get_sstable_meta().get_macro_info();
const int64_t data_block_count = sstable_meta_hdl_.get_sstable_meta().get_basic_meta().get_data_macro_block_count();
if (!macro_info.is_meta_root() && 1 == data_block_count) {
if (macro_meta.get_macro_id() == ObIndexBlockRowHeader::DEFAULT_IDX_ROW_MACRO_ID) {
// this means macro meta root block is larger than 16KB but read from the end of data block
// So the macro id parsed from macro meta is empty, which actually should be same to the
// data block id read in open_next_micro_block

View File

@ -360,7 +360,6 @@ int ObMicroBlockAdaptiveSplitter::check_need_split(const int64_t micro_size,
is_split = true;
}
}
return ret;
}