[BUG.FIX] fix ddl kv count bug.

This commit is contained in:
Tyshawn
2023-11-16 09:40:41 +00:00
committed by ob-robot
parent e34175cd2c
commit 6701143371
3 changed files with 94 additions and 1 deletions

View File

@ -169,7 +169,7 @@ public:
ddl_kvs_ = nullptr;
count_ = 0;
}
OB_INLINE bool count() const { return count_; }
OB_INLINE int64_t count() const { return count_; }
OB_INLINE bool empty() const { return 0 == count_; }
OB_INLINE bool is_valid() const { return 1 == count_ || (is_inited_ && count_ > 1 && nullptr != ddl_kvs_); }
OB_INLINE int64_t get_deep_copy_size() const { return count_ * sizeof(ObITable *); }

View File

@ -428,6 +428,13 @@ int ObTablet::init_for_merge(
ddl_kvs_ = ddl_kvs_addr;
ddl_kv_count_ = ddl_kv_count;
ALLOC_AND_INIT(allocator, table_store_addr_, (*this), param, (*old_table_store));
if (OB_UNLIKELY(ddl_kv_count_ != ddl_kv_count
|| ddl_kv_count != table_store_addr_.get_ptr()->get_ddl_memtable_count())) {
// This is defense code. If it runs at here, it must be a bug.
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("It encounters a ddl kv array bug, please pay attention", K(ret), K(ddl_kv_count), K(ddl_kv_count_),
"table store ddl kv count", table_store_addr_.get_ptr()->get_ddl_memtable_count());
}
}
if (FAILEDx(table_store_cache_.init(table_store_addr_.get_ptr()->get_major_sstables(),

View File

@ -27,6 +27,7 @@
#include "storage/tablet/ob_tablet_binding_helper.h"
#include "storage/tablet/ob_tablet_binding_info.h"
#include "storage/tablet/ob_tablet_table_store_flag.h"
#include "storage/ddl/ob_tablet_ddl_kv.h"
namespace oceanbase
{
@ -37,6 +38,17 @@ using namespace storage;
using namespace common;
using namespace share;
#define ALLOC_AND_INIT(allocator, addr, args...) \
do { \
if (OB_SUCC(ret)) { \
if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, addr.ptr_))) { \
LOG_WARN("fail to allocate and new object", K(ret)); \
} else if (OB_FAIL(addr.get_ptr()->init(allocator, args))) { \
LOG_WARN("fail to initialize tablet member", K(ret), K(addr)); \
} \
} \
} while (false) \
class ObTabletMetaV1 final
{
public:
@ -378,11 +390,23 @@ public:
virtual ~TestTablet();
virtual void SetUp();
virtual void TearDown();
void pull_ddl_memtables(ObIArray<ObITable *> &ddl_kvs)
{
for (int64_t i = 0; i < ddl_kv_count_; ++i) {
ASSERT_EQ(OB_SUCCESS, ddl_kvs.push_back(ddl_kvs_[i]));
}
std::cout<< "pull ddl memtables:" << ddl_kv_count_ << std::endl;
}
void reproducing_bug();
private:
ObArenaAllocator allocator_;
ObITable **ddl_kvs_;
volatile int64_t ddl_kv_count_;
};
TestTablet::TestTablet()
: ddl_kvs_(nullptr),
ddl_kv_count_(0)
{
}
@ -514,6 +538,68 @@ TEST_F(TestTablet, test_serialize_mig_param_compat)
}
class TestTableStore
{
public:
int init(ObArenaAllocator &allocator, TestTablet &tablet)
{
int ret = OB_SUCCESS;
ObArray<ObITable *> ddl_kvs;
tablet.pull_ddl_memtables(ddl_kvs);
ret = ddl_kvs_.init(allocator, ddl_kvs);
const int64_t count = ddl_kvs_.count();
std::cout<< "init table store:" << ddl_kvs.count() << ", " << count <<std::endl;
STORAGE_LOG(ERROR, "ddl kvs", K(ddl_kvs), K(ddl_kvs_));
return ret;
}
void reproducing_bug(ObArenaAllocator &allocator)
{
ObArray<ObITable *> ddl_kvs;
for (int64_t i = 0; i < 3; ++i) {
ObITable *ddl_kv = new ObDDLKV();
ddl_kv->key_.table_type_ = ObITable::TableType::DDL_MEM_SSTABLE;
ddl_kvs.push_back(ddl_kv);
}
ddl_kvs_.init(allocator, ddl_kvs);
const int64_t count = ddl_kvs_.count();
std::cout<< "table store reproducing_bug:" << ddl_kvs.count() << ", " << count <<std::endl;
}
TO_STRING_KV(K(ddl_kvs_));
private:
ObDDLKVArray ddl_kvs_;
};
void TestTablet::reproducing_bug()
{
int ret = OB_SUCCESS;
ObTabletComplexAddr<TestTableStore> table_store_addr;
ddl_kvs_ = static_cast<ObITable**>(allocator_.alloc(sizeof(ObITable*) * ObTablet::DDL_KV_ARRAY_SIZE));
ASSERT_TRUE(nullptr != ddl_kvs_);
ddl_kvs_[0] = new ObDDLKV();
ddl_kvs_[0]->key_.table_type_ = ObITable::TableType::DDL_MEM_SSTABLE;
ddl_kvs_[1] = new ObDDLKV();
ddl_kvs_[1]->key_.table_type_ = ObITable::TableType::DDL_MEM_SSTABLE;
ddl_kvs_[2] = new ObDDLKV();
ddl_kvs_[2]->key_.table_type_ = ObITable::TableType::DDL_MEM_SSTABLE;
std::cout<< "reproducing_bug 1:" << ddl_kv_count_ << std::endl;
ddl_kv_count_ = 3;
std::cout<< "reproducing_bug 2:" << ddl_kv_count_ << std::endl;
ALLOC_AND_INIT(allocator_, table_store_addr, (*this));
if (ddl_kv_count_ != table_store_addr.get_ptr()->ddl_kvs_.count()) {
std::cout<< "reproducing_bug 3:" << ddl_kv_count_ << ", " << table_store_addr.get_ptr()->ddl_kvs_.count() << std::endl;
// This is defense code. If it runs at here, it must be a bug. And, just abort to preserve the enviroment
// for debugging. Please remove me, after the problem is found.
ob_abort();
}
}
TEST_F(TestTablet, reproducing_bug_53174886)
{
TestTableStore table_store;
table_store.reproducing_bug(allocator_);
reproducing_bug();
}
} // end namespace unittest
} // end namespace oceanbase