[BUG.FIX] fix ddl kv count bug.
This commit is contained in:
@ -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 *); }
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user