[FEAT MERGE] impl skip tablet

This commit is contained in:
obdev 2024-02-07 01:09:40 +00:00 committed by ob-robot
parent 3a3e3ed86a
commit 1309d869b2
24 changed files with 498 additions and 33 deletions

View File

@ -367,6 +367,8 @@ void TestConcurrentT3M::run1()
addr.type_ = ObMetaDiskAddr::DiskType::BLOCK;
handle.get_obj()->set_tablet_addr(addr);
handle.get_obj()->is_inited_ = true; // to pass test
handle.get_obj()->table_store_addr_.addr_.set_none_addr();
ret = t3m_.compare_and_swap_tablet(key, handle, handle);
ASSERT_EQ(common::OB_SUCCESS, ret);
@ -591,6 +593,8 @@ TEST_F(TestTenantMetaMemMgr, test_tablet)
addr.size_ = 4096;
addr.type_ = ObMetaDiskAddr::DiskType::BLOCK;
handle.get_obj()->set_tablet_addr(addr);
handle.get_obj()->is_inited_ = true; // to pass test
handle.get_obj()->table_store_addr_.addr_.set_none_addr();
ret = t3m_.compare_and_swap_tablet(key, handle, handle);
ASSERT_EQ(common::OB_SUCCESS, ret);
@ -1199,6 +1203,9 @@ TEST_F(TestTenantMetaMemMgr, test_replace_tablet)
ASSERT_EQ(common::OB_ITEM_NOT_SETTED, ret);
ASSERT_TRUE(!tmp_handle.is_valid());
handle.get_obj()->is_inited_ = true; // to pass test
handle.get_obj()->table_store_addr_.addr_.set_none_addr();
ret = t3m_.compare_and_swap_tablet(key, handle, handle);
ASSERT_EQ(common::OB_SUCCESS, ret);
ASSERT_EQ(1, t3m_.tablet_map_.map_.size());
@ -1270,6 +1277,9 @@ TEST_F(TestTenantMetaMemMgr, test_replace_tablet)
addr.type_ = ObMetaDiskAddr::DiskType::BLOCK;
tablet->set_tablet_addr(addr);
tablet->is_inited_ = true; // to pass test
tablet->table_store_addr_.addr_.set_none_addr();
ret = t3m_.compare_and_swap_tablet(key, old_handle, handle);
ASSERT_EQ(common::OB_SUCCESS, ret);
ASSERT_EQ(1, t3m_.tablet_map_.map_.size());

View File

@ -115,7 +115,7 @@ int ObAllVirtualTableMgr::get_next_tablet()
if (nullptr == tablet_iter_) {
tablet_allocator_.set_tenant_id(MTL_ID());
ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*);
if (OB_ISNULL(tablet_iter_ = new (iter_buf_) ObTenantTabletIterator(*t3m, tablet_allocator_))) {
if (OB_ISNULL(tablet_iter_ = new (iter_buf_) ObTenantTabletIterator(*t3m, tablet_allocator_, nullptr/*no op*/))) {
ret = OB_ERR_UNEXPECTED;
SERVER_LOG(WARN, "fail to new tablet_iter_", K(ret));
}

View File

@ -116,7 +116,7 @@ int ObAllVirtualTabletCompactionInfo::get_next_tablet()
if (nullptr == tablet_iter_) {
tablet_allocator_.set_tenant_id(MTL_ID());
ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*);
if (OB_ISNULL(tablet_iter_ = new (iter_buf_) ObTenantTabletIterator(*t3m, tablet_allocator_))) {
if (OB_ISNULL(tablet_iter_ = new (iter_buf_) ObTenantTabletIterator(*t3m, tablet_allocator_, nullptr/*no op*/))) {
ret = OB_ERR_UNEXPECTED;
SERVER_LOG(WARN, "fail to new tablet_iter_", K(ret));
}

View File

@ -561,7 +561,7 @@ int ObAllVirtualTabletSSTableMacroInfo::get_next_tablet()
iter_allocator_.set_tenant_id(MTL_ID());
rowkey_allocator_.set_tenant_id(MTL_ID());
ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*);
if (OB_ISNULL(tablet_iter_ = new (iter_buf_) ObTenantTabletIterator(*t3m, tablet_allocator_))) {
if (OB_ISNULL(tablet_iter_ = new (iter_buf_) ObTenantTabletIterator(*t3m, tablet_allocator_, nullptr/*no op*/))) {
ret = OB_ERR_UNEXPECTED;
SERVER_LOG(WARN, "fail to new tablet_iter_", K(ret));
}

View File

@ -1068,7 +1068,7 @@ int ObBlockManager::mark_tenant_blocks(
LOG_WARN("fail to mark tenant meta blocks", K(ret));
} else {
ObArenaAllocator iter_allocator("MarkIter", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID());
ObTenantTabletIterator tablet_iter(*t3m, iter_allocator);
ObTenantTabletIterator tablet_iter(*t3m, iter_allocator, nullptr/*no op*/);
ObTabletHandle handle;
while (OB_SUCC(ret)) {
handle.reset();

View File

@ -435,7 +435,8 @@ int ObSharedMacroBlockMgr::defragment()
ObArenaAllocator task_allocator("SSTDefragTask", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID());
ObArenaAllocator iter_allocator("SSTDefragIter", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID());
ObFixedArray<MacroBlockId, ObIAllocator> macro_ids(task_allocator);
ObTenantTabletIterator tablet_iter(*(MTL(ObTenantMetaMemMgr*)), iter_allocator);
ObHasNestedTableFilterOp op;
ObTenantTabletIterator tablet_iter(*(MTL(ObTenantMetaMemMgr*)), iter_allocator, &op);
ObSSTableIndexBuilder *sstable_index_builder = nullptr;
ObIndexBlockRebuilder *index_block_rebuilder = nullptr;
int64_t rewrite_cnt = 0;

View File

@ -18,6 +18,7 @@
#include "storage/blocksstable/ob_block_manager.h"
#include "lib/task/ob_timer.h"
#include "storage/compaction/ob_compaction_util.h"
#include "storage/meta_mem/ob_tablet_pointer.h"
namespace oceanbase
{
@ -196,6 +197,15 @@ private:
bool is_inited_;
};
class ObHasNestedTableFilterOp final : public ObITabletFilterOp
{
public:
int do_filter(const ObTabletResidentInfo &info, bool &is_skipped) override {
is_skipped = !info.has_nested_table();
return OB_SUCCESS;
}
};
} // namespace blocksstable
} // namespace oceanbase

View File

@ -104,6 +104,8 @@ public:
int deserialize(const char *buf, const int64_t len, int64_t &pos);
int64_t get_serialize_size() const;
void reset();
int64_t get_ha_status() const { return ha_status_; }
void set_ha_status(int64_t ha_status) { ha_status_ = ha_status;}
bool is_none() const { return is_data_status_complete() && is_restore_status_full(); }
bool is_data_status_complete() const { return ObTabletDataStatus::is_complete(data_status_); }
bool is_restore_status_full() const { return ObTabletRestoreStatus::is_full(restore_status_); }

View File

@ -6007,6 +6007,28 @@ int ObLSTabletService::build_tablet_iter(ObHALSTabletIterator &iter)
return ret;
}
int ObLSTabletService::build_tablet_iter(ObLSTabletFastIter &iter, const bool except_ls_inner_tablet)
{
int ret = common::OB_SUCCESS;
GetAllTabletIDOperator op(iter.tablet_ids_, except_ls_inner_tablet);
iter.ls_tablet_service_ = this;
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
STORAGE_LOG(WARN, "not inited", K(ret), K_(is_inited));
} else if (OB_FAIL(tablet_id_set_.foreach(op))) {
STORAGE_LOG(WARN, "fail to get all tablet ids from set", K(ret));
} else if (OB_UNLIKELY(!iter.is_valid())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("iter is invalid", K(ret), K(iter));
}
if (OB_FAIL(ret)) {
iter.reset();
}
return ret;
}
int ObLSTabletService::set_allow_to_read_(ObLS *ls)
{
int ret = OB_SUCCESS;

View File

@ -78,6 +78,7 @@ class ObSingleRowGetter;
class ObLSTabletIterator;
class ObHALSTabletIDIterator;
class ObHALSTabletIterator;
class ObLSTabletFastIter;
class ObTabletMapKey;
struct ObStorageLogParam;
struct ObTabletCreateSSTableParam;
@ -411,6 +412,7 @@ public:
int build_tablet_iter(ObLSTabletIterator &iter, const bool except_ls_inner_tablet = false);
int build_tablet_iter(ObHALSTabletIDIterator &iter);
int build_tablet_iter(ObHALSTabletIterator &iter);
int build_tablet_iter(ObLSTabletFastIter &iter, const bool except_ls_inner_tablet = false);
// migration section
typedef common::ObFunction<int(const obrpc::ObCopyTabletInfo &tablet_info)> HandleTabletMetaFunc;
@ -783,6 +785,7 @@ private:
private:
friend class ObLSTabletIterator;
friend class ObTabletCreateMdsHelper;
friend class ObLSTabletFastIter;
ObLS *ls_;
ObTxDataMemtableMgr tx_data_memtable_mgr_;

View File

@ -47,10 +47,11 @@ ObTabletPointer::ObTabletPointer()
initial_state_(true),
ddl_kv_mgr_lock_(),
mds_table_handler_(),
old_version_chain_(nullptr)
old_version_chain_(nullptr),
attr_()
{
#if defined(__x86_64__) && !defined(ENABLE_OBJ_LEAK_CHECK)
static_assert(sizeof(ObTabletPointer) == 280, "The size of ObTabletPointer will affect the meta memory manager, and the necessity of adding new fields needs to be considered.");
static_assert(sizeof(ObTabletPointer) == 296, "The size of ObTabletPointer will affect the meta memory manager, and the necessity of adding new fields needs to be considered.");
#endif
}
@ -175,6 +176,9 @@ int ObTabletPointer::hook_obj(ObTablet *&t, ObMetaObjGuard<ObTablet> &guard)
obj_.ptr_ = t;
guard.set_obj(obj_);
ObMetaObjBufferHelper::set_in_map(reinterpret_cast<char *>(t), true/*in_map*/);
if (!is_attr_valid() && OB_FAIL(set_tablet_attr(*t))) { // only set tablet attr when first hook obj
STORAGE_LOG(WARN, "failed to update tablet attr", K(ret), K(guard));
}
}
if (OB_FAIL(ret) && OB_NOT_NULL(t)) {
@ -649,5 +653,58 @@ int ObTabletPointer::release_obj(ObTablet *&t)
return ret;
}
int ObTabletPointer::set_tablet_attr(ObTablet &tablet)
{
int ret = OB_SUCCESS;
attr_.reset();
if (OB_FAIL(tablet.calc_tablet_attr(attr_))) {
if (OB_ALLOCATE_MEMORY_FAILED == ret) {
ret = OB_SUCCESS; // the invalid attr is allowed
} else {
STORAGE_LOG(WARN, "failed to update tablet attr", K(ret), K(tablet));
}
}
return ret;
}
ObTabletResidentInfo::ObTabletResidentInfo(const ObTabletMapKey &key, ObTabletPointer &tablet_ptr)
: attr_(tablet_ptr.attr_), tablet_addr_(tablet_ptr.phy_addr_)
{
tablet_id_ = key.tablet_id_;
ls_id_ = key.ls_id_;
}
int64_t ObITabletFilterOp::total_skip_cnt_ = 0;
int64_t ObITabletFilterOp::total_tablet_cnt_ = 0;
int64_t ObITabletFilterOp::not_in_mem_tablet_cnt_ = 0;
int64_t ObITabletFilterOp::invalid_attr_tablet_cnt_ = 0;
ObITabletFilterOp::~ObITabletFilterOp()
{
total_skip_cnt_ += skip_cnt_;
total_tablet_cnt_ += total_cnt_;
not_in_mem_tablet_cnt_ += not_in_mem_cnt_;
invalid_attr_tablet_cnt_ += invalid_attr_cnt_;
LOG_INFO("zhuixin debug filter destructed",
K_(total_cnt), K_(skip_cnt), K_(not_in_mem_cnt), K_(invalid_attr_cnt),
K_(total_tablet_cnt), K_(total_skip_cnt), K_(not_in_mem_tablet_cnt), K_(invalid_attr_tablet_cnt));
}
int ObITabletFilterOp::operator()(const ObTabletResidentInfo &info, bool &is_skipped)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!info.is_valid())) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("try to skip tablet with invalid resident info", K(ret), K(info));
} else if (OB_FAIL((do_filter(info, is_skipped)))) {
LOG_WARN("fail to do filter", K(ret), K(info), K_(skip_cnt), K_(total_cnt));
} else if (is_skipped) {
++skip_cnt_;
}
++total_cnt_;
return ret;
}
} // namespace storage
} // namespace oceanbase

View File

@ -29,11 +29,39 @@ class ObTablet;
class ObTabletDDLKvMgr;
typedef ObMetaObjGuard<ObTabletDDLKvMgr> ObDDLKvMgrHandle;
struct ObTabletAttr final
{
public:
ObTabletAttr()
:v_(0),
ha_status_(0)
{}
~ObTabletAttr() { reset(); }
void reset() { v_ = 0; ha_status_ = 0; }
bool is_valid() const { return valid_; }
TO_STRING_KV(K_(valid), K_(is_empty_shell), K_(has_transfer_table),
K_(has_next_tablet), K_(has_nested_table), K_(ha_status));
public:
union {
int64_t v_;
struct {
bool valid_ : 1; // valid_ = true means attr is filled
bool is_empty_shell_ : 1;
bool has_transfer_table_ : 1;
bool has_next_tablet_ : 1;
bool has_nested_table_: 1;
};
};
int64_t ha_status_;
};
class ObTabletPointer final
{
friend class ObTablet;
friend class ObLSTabletService;
friend class ObTenantMetaMemMgr;
friend class ObTabletResidentInfo;
public:
ObTabletPointer();
ObTabletPointer(const ObLSHandle &ls_handle,
@ -75,7 +103,7 @@ public:
int dump_meta_obj(ObMetaObjGuard<ObTablet> &guard, void *&free_obj);
// do not KPC memtable_mgr, may dead lock
TO_STRING_KV(K_(phy_addr), K_(obj), K_(ls_handle), K_(ddl_kv_mgr_handle),
TO_STRING_KV(K_(phy_addr), K_(obj), K_(ls_handle), K_(ddl_kv_mgr_handle), K_(attr),
K_(protected_memtable_mgr_handle), K_(ddl_info), K_(initial_state), KP_(old_version_chain));
public:
bool get_initial_state() const;
@ -94,6 +122,9 @@ public:
int release_memtable_and_mds_table_for_ls_offline(const ObTabletID &tablet_id);
int get_min_mds_ckpt_scn(share::SCN &scn);
ObLS *get_ls() const;
// the RW operations of tablet_attr are protected by lock guard of tablet_map_
int set_tablet_attr(ObTablet &tablet);
bool is_attr_valid() const { return attr_.is_valid(); }
private:
int wash_obj();
int add_tablet_to_old_version_chain(ObTablet *tablet);
@ -109,7 +140,51 @@ private:
ObByteLock ddl_kv_mgr_lock_; // 1B
mds::ObMdsTableHandler mds_table_handler_;// 48B
ObTablet *old_version_chain_; // 8B
DISALLOW_COPY_AND_ASSIGN(ObTabletPointer); // 272B
ObTabletAttr attr_; // 16B // protected by rw lock of tablet_map_
DISALLOW_COPY_AND_ASSIGN(ObTabletPointer); // 288B
};
struct ObTabletResidentInfo final {
ObTabletResidentInfo(ObTabletAttr &attr, ObTabletID &tablet_id, share::ObLSID &ls_id)
: attr_(attr), tablet_addr_(), tablet_id_(tablet_id), ls_id_(ls_id)
{}
ObTabletResidentInfo(const ObTabletMapKey &key, ObTabletPointer &tablet_ptr);
~ObTabletResidentInfo() = default;
bool is_valid() const { return attr_.valid_ && tablet_id_.is_valid() && tablet_addr_.is_valid(); }
bool has_transfer_table() const { return attr_.has_transfer_table_; }
bool is_empty_shell() const { return attr_.is_empty_shell_; }
bool has_next_tablet() const { return attr_.has_next_tablet_; }
bool has_nested_table() const { return attr_.has_nested_table_; }
TO_STRING_KV(K_(ls_id), K_(tablet_id), K_(tablet_addr), K_(attr));
public:
ObTabletAttr &attr_;
ObMetaDiskAddr tablet_addr_; // used to identify one tablet
ObTabletID tablet_id_;
share::ObLSID ls_id_;
};
class ObITabletFilterOp
{
public:
ObITabletFilterOp()
:skip_cnt_(0), total_cnt_(0), not_in_mem_cnt_(0), invalid_attr_cnt_(0)
{}
virtual ~ObITabletFilterOp();
int operator()(const ObTabletResidentInfo &info, bool &is_skipped);
virtual int do_filter(const ObTabletResidentInfo &info, bool &is_skipped) = 0;
void inc_not_in_memory_cnt() { ++total_cnt_; ++not_in_mem_cnt_; }
void inc_invalid_attr_cnt() { ++total_cnt_; ++invalid_attr_cnt_; }
private:
int64_t skip_cnt_;
int64_t total_cnt_;
int64_t not_in_mem_cnt_;
int64_t invalid_attr_cnt_;
static int64_t total_skip_cnt_;
static int64_t total_tablet_cnt_;
static int64_t not_in_mem_tablet_cnt_;
static int64_t invalid_attr_tablet_cnt_;
DISALLOW_COPY_AND_ASSIGN(ObITabletFilterOp);
};
} // namespace storage

View File

@ -206,6 +206,54 @@ int ObTabletPointerMap::try_get_in_memory_meta_obj(
return ret;
}
int ObTabletPointerMap::try_get_in_memory_meta_obj_with_filter(
const ObTabletMapKey &key,
ObITabletFilterOp &op,
ObTabletPointerHandle &ptr_hdl,
ObMetaObjGuard<ObTablet> &guard,
bool &is_in_memory)
{
int ret = OB_SUCCESS;
uint64_t hash_val = 0;
ObTabletPointer *t_ptr = nullptr;
is_in_memory = false;
if (OB_FAIL(ResourceMap::hash_func_(key, hash_val))) {
STORAGE_LOG(WARN, "fail to calc hash", K(ret), K(key));
} else {
common::ObBucketHashRLockGuard lock_guard(ResourceMap::bucket_lock_, hash_val);
if (OB_FAIL(ResourceMap::get_without_lock(key, ptr_hdl))) {
if (common::OB_ENTRY_NOT_EXIST != ret) {
STORAGE_LOG(WARN, "fail to get pointer handle", K(ret));
}
} else if (OB_ISNULL(t_ptr = ptr_hdl.get_resource_ptr())) {
ret = common::OB_ERR_UNEXPECTED;
STORAGE_LOG(WARN, "fail to get meta pointer", K(ret), KP(t_ptr), K(key));
} else if (OB_UNLIKELY(t_ptr->get_addr().is_none())) {
ret = OB_ITEM_NOT_SETTED;
STORAGE_LOG(DEBUG, "pointer addr is none, no object to be got", K(ret), K(key), KPC(t_ptr));
} else if (t_ptr->is_in_memory()) {
if (t_ptr->is_attr_valid()) { // try skip tablet with attr
ObTabletResidentInfo info(key, *t_ptr);
bool is_skipped = false;
if (OB_FAIL(op(info, is_skipped))) {
STORAGE_LOG(WARN, "fail to skip tablet", K(ret), KP(t_ptr), K(key), K(info));
} else if (is_skipped) {
ret = OB_NOT_THE_OBJECT;
}
} else {
op.inc_invalid_attr_cnt();
}
if (OB_SUCC(ret)) {
t_ptr->get_obj(guard);
is_in_memory = true;
}
} else {
op.inc_not_in_memory_cnt();
}
}
return ret;
}
int ObTabletPointerMap::get_meta_obj(
const ObTabletMapKey &key,
ObMetaObjGuard<ObTablet> &guard)
@ -235,6 +283,39 @@ int ObTabletPointerMap::get_meta_obj(
return ret;
}
int ObTabletPointerMap::get_meta_obj_with_filter(
const ObTabletMapKey &key,
ObITabletFilterOp &op,
ObMetaObjGuard<ObTablet> &guard)
{
int ret = common::OB_SUCCESS;
ObTabletPointerHandle ptr_hdl(*this);
bool is_in_memory = false;
guard.reset();
if (OB_UNLIKELY(!key.is_valid())) {
ret = common::OB_INVALID_ARGUMENT;
STORAGE_LOG(WARN, "invalid argument", K(ret), K(key));
} else if (OB_FAIL(try_get_in_memory_meta_obj_with_filter(key, op, ptr_hdl, guard, is_in_memory))) {
if (OB_ENTRY_NOT_EXIST == ret || OB_ITEM_NOT_SETTED == ret) {
STORAGE_LOG(DEBUG, "meta obj does not exist", K(ret), K(key));
} else if (OB_NOT_THE_OBJECT == ret) {
STORAGE_LOG(DEBUG, "this tablet has been skipped", K(ret), K(key));
} else {
STORAGE_LOG(WARN, "fail to try get in memory meta obj", K(ret), K(key));
}
} else if (OB_UNLIKELY(!is_in_memory)) {
if (OB_FAIL(load_and_hook_meta_obj(key, ptr_hdl, guard))) {
STORAGE_LOG(WARN, "fail to load and hook meta obj", K(ret), K(key));
} else {
EVENT_INC(ObStatEventIds::TABLET_CACHE_MISS);
}
} else {
EVENT_INC(ObStatEventIds::TABLET_CACHE_HIT);
}
return ret;
}
int ObTabletPointerMap::load_and_hook_meta_obj(
const ObTabletMapKey &key,
ObTabletPointerHandle &ptr_hdl,
@ -395,7 +476,8 @@ int ObTabletPointerMap::get_meta_obj_with_external_memory(
const ObTabletMapKey &key,
common::ObArenaAllocator &allocator,
ObMetaObjGuard<ObTablet> &guard,
const bool force_alloc_new)
const bool force_alloc_new,
ObITabletFilterOp *op)
{
int ret = common::OB_SUCCESS;
uint64_t hash_val = 0;
@ -403,7 +485,7 @@ int ObTabletPointerMap::get_meta_obj_with_external_memory(
ObTabletPointer *t_ptr = nullptr;
bool is_in_memory = false;
guard.reset();
if (OB_UNLIKELY(!key.is_valid())) {
if (OB_UNLIKELY(!key.is_valid() || (force_alloc_new && nullptr != op))) { /*only support filter when not force new*/
ret = common::OB_INVALID_ARGUMENT;
STORAGE_LOG(WARN, "invalid argument", K(ret), K(key));
} else if (OB_FAIL(ResourceMap::hash_func_(key, hash_val))) {
@ -415,7 +497,8 @@ int ObTabletPointerMap::get_meta_obj_with_external_memory(
STORAGE_LOG(WARN, "fail to get pointer handle", K(ret));
}
}
} else if (OB_FAIL(try_get_in_memory_meta_obj(key, ptr_hdl, guard, is_in_memory))) {
} else if ((nullptr == op && OB_FAIL(try_get_in_memory_meta_obj(key, ptr_hdl, guard, is_in_memory)))
|| (nullptr != op && OB_FAIL(try_get_in_memory_meta_obj_with_filter(key, *op, ptr_hdl, guard, is_in_memory)))) {
if (OB_ENTRY_NOT_EXIST == ret) {
STORAGE_LOG(DEBUG, "meta obj does not exist", K(ret), K(key));
} else {
@ -612,6 +695,9 @@ int ObTabletPointerMap::compare_and_swap_addr_and_object(
if (OB_SUCC(ret)) {
t_ptr->set_addr_with_reset_obj(new_addr);
t_ptr->set_obj(new_guard);
if (OB_FAIL(t_ptr->set_tablet_attr(*new_guard.get_obj()))) {
STORAGE_LOG(WARN, "failed to update tablet attr", K(ret), K(key), K(new_addr), K(new_guard));
}
}
}

View File

@ -33,11 +33,13 @@ public:
int erase(const ObTabletMapKey &key, ObMetaObjGuard<ObTablet> &guard);
int exist(const ObTabletMapKey &key, bool &is_exist);
int get_meta_obj(const ObTabletMapKey &key, ObMetaObjGuard<ObTablet> &guard);
int get_meta_obj_with_filter(const ObTabletMapKey &key, ObITabletFilterOp &op, ObMetaObjGuard<ObTablet> &guard);
int get_meta_obj_with_external_memory(
const ObTabletMapKey &key,
common::ObArenaAllocator &allocator,
ObMetaObjGuard<ObTablet> &guard,
const bool force_alloc_new = false);
const bool force_alloc_new,
ObITabletFilterOp *op);
int try_get_in_memory_meta_obj(const ObTabletMapKey &key, bool &success, ObMetaObjGuard<ObTablet> &guard);
int try_get_in_memory_meta_obj_and_addr(
const ObTabletMapKey &key,
@ -84,6 +86,12 @@ private:
ObTabletPointerHandle &ptr_hdl,
ObMetaObjGuard<ObTablet> &guard,
bool &is_in_memory);
int try_get_in_memory_meta_obj_with_filter(
const ObTabletMapKey &key,
ObITabletFilterOp &op,
ObTabletPointerHandle &ptr_hdl,
ObMetaObjGuard<ObTablet> &guard,
bool &is_in_memory);
int inner_erase(const ObTabletMapKey &key);
public:

View File

@ -1586,6 +1586,33 @@ int ObTenantMetaMemMgr::get_tablet(
return ret;
}
int ObTenantMetaMemMgr::get_tablet_with_filter(
const WashTabletPriority &priority,
const ObTabletMapKey &key,
ObITabletFilterOp &op,
ObTabletHandle &handle)
{
int ret = OB_SUCCESS;
handle.reset();
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObTenantMetaMemMgr hasn't been initialized", K(ret));
} else if (OB_UNLIKELY(!key.is_valid())) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument", K(ret), K(key));
} else if (OB_FAIL(tablet_map_.get_meta_obj_with_filter(key, op, handle))) {
if (OB_ENTRY_NOT_EXIST != ret && OB_ITEM_NOT_SETTED != ret && OB_NOT_THE_OBJECT != ret) {
LOG_WARN("fail to get tablet", K(ret), K(key));
}
} else if (OB_ISNULL(handle.get_obj())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("tablet is null", K(ret), K(key), K(handle));
} else {
handle.set_wash_priority(priority);
}
return ret;
}
int ObTenantMetaMemMgr::get_tablet_with_allocator(
const WashTabletPriority &priority,
const ObTabletMapKey &key,
@ -1601,7 +1628,7 @@ int ObTenantMetaMemMgr::get_tablet_with_allocator(
} else if (OB_UNLIKELY(!key.is_valid())) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument", K(ret), K(key), KP(&allocator));
} else if (OB_FAIL(tablet_map_.get_meta_obj_with_external_memory(key, allocator, handle, force_alloc_new))) {
} else if (OB_FAIL(tablet_map_.get_meta_obj_with_external_memory(key, allocator, handle, force_alloc_new, nullptr/*no_op*/))) {
if (OB_ENTRY_NOT_EXIST != ret) {
LOG_WARN("fail to get tablet", K(ret), K(key));
}
@ -1882,8 +1909,7 @@ int ObTenantMetaMemMgr::compare_and_swap_tablet(
if (OB_ISNULL(t_ptr = reinterpret_cast<ObTabletPointer *>(ptr_hdl.get_resource_ptr()))) {
ret = common::OB_ERR_UNEXPECTED;
LOG_WARN("fail to get tablet pointer", K(ret), K(key), K(ptr_hdl));
} else if (CLICK_FAIL(t_ptr->add_tablet_to_old_version_chain(
reinterpret_cast<ObTablet *>(old_handle.get_obj())))) {
} else if (CLICK_FAIL(t_ptr->add_tablet_to_old_version_chain(old_handle.get_obj()))) {
LOG_WARN("fail to add tablet to old version chain", K(ret), K(key), KPC(old_tablet));
}
}
@ -1902,7 +1928,6 @@ int ObTenantMetaMemMgr::compare_and_swap_tablet(
LOG_WARN("failed to check and set initial state", K(ret), K(key));
}
}
LOG_DEBUG("compare and swap object", K(ret), KPC(new_handle.get_obj()), K(lbt()));
return ret;
}
@ -2354,9 +2379,11 @@ int ObT3mTabletMapIterator::FetchTabletItemOp::operator()(TabletPair &pair)
ObTenantTabletIterator::ObTenantTabletIterator(
ObTenantMetaMemMgr &t3m,
common::ObArenaAllocator &allocator)
common::ObArenaAllocator &allocator,
ObITabletFilterOp *op)
: ObT3mTabletMapIterator(t3m),
allocator_(&allocator)
allocator_(&allocator),
op_(op)
{
}
@ -2377,7 +2404,7 @@ int ObTenantTabletIterator::get_next_tablet(ObTabletHandle &handle)
ret = OB_ERR_UNEXPECTED;
LOG_WARN("allocator_ is nullptr, which is not allowed", K(ret));
} else if (OB_FAIL(tablet_map_.get_meta_obj_with_external_memory(
key, *allocator_, handle)) && OB_ENTRY_NOT_EXIST != ret) {
key, *allocator_, handle, false/*force*/, op_)) && !ignore_err_code(ret)) {
LOG_WARN("fail to get tablet handle", K(ret), K(key));
}
if (OB_SUCC(ret) || ignore_err_code(ret)) {
@ -2389,7 +2416,7 @@ int ObTenantTabletIterator::get_next_tablet(ObTabletHandle &handle)
++idx_;
}
}
} while (ignore_err_code(ret)); // ignore deleted tablet
} while (ignore_err_code(ret)); // ignore deleted tablet or skipped tablet
}
return ret;
}

View File

@ -243,6 +243,12 @@ public:
const WashTabletPriority &priority,
const ObTabletMapKey &key,
ObTabletHandle &handle);
int get_tablet_with_filter(
const WashTabletPriority &priority,
const ObTabletMapKey &key,
ObITabletFilterOp &op,
ObTabletHandle &handle);
// NOTE: This interface return tablet handle, which couldn't be used by compare_and_swap_tablet.
int get_tablet_with_allocator(
const WashTabletPriority &priority,
@ -540,7 +546,7 @@ protected:
typedef common::hash::HashMapPair<ObTabletMapKey, TabletValueStore *> TabletPair;
int fetch_tablet_item();
static bool ignore_err_code(const int ret) { return OB_ENTRY_NOT_EXIST == ret || OB_ITEM_NOT_SETTED == ret; }
static bool ignore_err_code(const int ret) { return OB_ENTRY_NOT_EXIST == ret || OB_ITEM_NOT_SETTED == ret || OB_NOT_THE_OBJECT == ret; }
private:
class FetchTabletItemOp final
{
@ -569,12 +575,14 @@ class ObTenantTabletIterator : public ObT3mTabletMapIterator,
public:
ObTenantTabletIterator(
ObTenantMetaMemMgr &t3m,
common::ObArenaAllocator &allocator);
common::ObArenaAllocator &allocator,
ObITabletFilterOp *op);
virtual ~ObTenantTabletIterator() = default;
virtual int get_next_tablet(ObTabletHandle &handle) override;
private:
common::ObArenaAllocator *allocator_;
storage::ObITabletFilterOp *op_;
};
class ObTenantInMemoryTabletIterator : public ObT3mTabletMapIterator,

View File

@ -190,7 +190,7 @@ int ObDiskUsageReportTask::count_tenant_data(const uint64_t tenant_id)
} else {
ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*);
ObArenaAllocator iter_allocator("DiskReport", OB_MALLOC_NORMAL_BLOCK_SIZE, tenant_id);
ObTenantTabletIterator tablet_iter(*t3m, iter_allocator);
ObTenantTabletIterator tablet_iter(*t3m, iter_allocator, nullptr/*no op*/);
ObTabletHandle tablet_handle;
while (OB_SUCC(ret) && OB_SUCC(tablet_iter.get_next_tablet(tablet_handle))) {
if (OB_UNLIKELY(!tablet_handle.is_valid())) {

View File

@ -1783,9 +1783,8 @@ int ObFetchLSMetaInfoP::process()
LOG_WARN("failed to get ls meta package", K(ret), K(arg_));
} else if (OB_FAIL(ObStorageHAUtils::get_server_version(result_.version_))) {
LOG_WARN("failed to get server version", K(ret), K_(arg));
} else {
// TODO(yangyi.yyy): do not check transfer table for now, fix in 4.3
result_.has_transfer_table_ = false;
} else if (OB_FAIL(check_has_transfer_logical_table_(ls))) {
LOG_WARN("failed to check has tranfer logical table", K(ret));
}
}
return ret;
@ -1794,11 +1793,12 @@ int ObFetchLSMetaInfoP::process()
int ObFetchLSMetaInfoP::check_has_transfer_logical_table_(storage::ObLS *ls)
{
int ret = OB_SUCCESS;
storage::ObLSTabletIterator tablet_iter(ObMDSGetTabletMode::READ_WITHOUT_CHECK);
ObHasTransferTableFilterOp op;
ObLSTabletFastIter tablet_iter(op, ObMDSGetTabletMode::READ_WITHOUT_CHECK);
if (OB_ISNULL(ls)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("ls not should be null", K(ret), KP(ls));
} else if (OB_FAIL(ls->build_tablet_iter(tablet_iter))) {
} else if (OB_FAIL(ls->build_tablet_iter(tablet_iter, true/*except_inner*/))) {
LOG_WARN("failed to build ls tablet iter", K(ret));
} else {
bool has_logical_table = true;
@ -1817,10 +1817,7 @@ int ObFetchLSMetaInfoP::check_has_transfer_logical_table_(storage::ObLS *ls)
} else if (OB_ISNULL(tablet = tablet_handle.get_obj())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("tablet should not be NULL", K(ret), KP(tablet));
} else if (tablet->get_tablet_meta().tablet_id_.is_ls_inner_tablet()) {
//do nothing
} else if (tablet->get_tablet_meta().has_transfer_table()) {
bool has_dependent_ls = false;
} else {
result_.has_transfer_table_ = true;
LOG_INFO("tablet still has logical table", K(tablet_handle));
break;

View File

@ -33,6 +33,7 @@
#include "storage/lob/ob_lob_rpc_struct.h"
#include "storage/blocksstable/ob_logic_macro_id.h"
#include "share/rpc/ob_async_rpc_proxy.h"
#include "storage/meta_mem/ob_tablet_pointer.h"
namespace oceanbase
{
@ -1333,6 +1334,16 @@ private:
int64_t data_size_;
};
class ObHasTransferTableFilterOp final : public ObITabletFilterOp
{
public:
int do_filter(const ObTabletResidentInfo &info, bool &is_skipped) override
{
is_skipped = !info.has_transfer_table();
return OB_SUCCESS;
}
};
} // storage
} // oceanbase

View File

@ -5566,6 +5566,51 @@ int ObTablet::get_storage_schema_for_transfer_in(
return ret;
}
int ObTablet::calc_tablet_attr(ObTabletAttr &attr)
{
int ret = OB_SUCCESS;
attr.reset();
attr.has_transfer_table_ = tablet_meta_.has_transfer_table();
attr.is_empty_shell_ = table_store_addr_.addr_.is_none();
attr.has_next_tablet_ = tablet_meta_.has_next_tablet_;
attr.ha_status_ = tablet_meta_.ha_status_.get_ha_status();
attr.has_nested_table_ = false;
ObTabletMemberWrapper<ObTabletTableStore> wrapper;
const ObTabletTableStore *table_store = nullptr;
ObTableStoreIterator table_iter;
if (attr.is_empty_shell_) { // skip empty shell
} else if (OB_FAIL(fetch_table_store(wrapper))) {
LOG_WARN("fail to fetch table store", K(ret));
} else if (OB_FAIL(wrapper.get_member(table_store))) {
LOG_WARN("fail to get table store from wrapper", K(ret), K(wrapper));
} else if (OB_FAIL(table_store->get_all_sstable(table_iter))) {
LOG_WARN("fail to get all sstable iterator", K(ret), KPC(table_store));
} else {
ObITable *table = nullptr;
while (OB_SUCC(ret) && OB_SUCC(table_iter.get_next(table))) {
if (OB_ISNULL(table) || OB_UNLIKELY(!table->is_sstable())) {
ret = OB_ERR_UNEXPECTED;
} else if (static_cast<ObSSTable *>(table)->is_small_sstable()) {
attr.has_nested_table_ = true;
break;
}
}
if (OB_ITER_END == ret) {
ret = OB_SUCCESS;
}
}
if (OB_SUCC(ret)) {
attr.valid_ = true;
} else {
attr.reset();
}
return ret;
}
int ObTablet::check_and_set_initial_state()
{
int ret = OB_SUCCESS;

View File

@ -816,6 +816,7 @@ private:
int mark_mds_table_switched_to_empty_shell_();
int fetch_autoinc_seq(ObTabletMemberWrapper<share::ObTabletAutoincSeq> &wrapper) const;
int handle_transfer_replace_(const ObBatchUpdateTableStoreParam &param);
int calc_tablet_attr(ObTabletAttr &attr);
private:
// ObTabletDDLKvMgr::MAX_DDL_KV_CNT_IN_STORAGE
// Array size is too large, need to shrink it if possible

View File

@ -139,6 +139,16 @@ int ObLSTabletIterator::get_next_ddl_kv_mgr(ObDDLKvMgrHandle &ddl_kv_mgr_handle)
}
int ObLSTabletIterator::get_tablet_ids(ObIArray<ObTabletID> &ids)
{
int ret = OB_SUCCESS;
ids.reset();
if (OB_FAIL(ids.assign(tablet_ids_))) {
LOG_WARN("fail to get tablet ids", K(ret));
}
return ret;
}
ObHALSTabletIDIterator::ObHALSTabletIDIterator(
const share::ObLSID &ls_id,
const bool need_initial_state)
@ -242,5 +252,63 @@ int ObHALSTabletIterator::get_next_tablet(ObTabletHandle &handle)
return ret;
}
ObLSTabletFastIter::ObLSTabletFastIter(ObITabletFilterOp &op, const ObMDSGetTabletMode mode)
: ls_tablet_service_(nullptr),
tablet_ids_(),
idx_(0),
mode_(mode),
op_(op)
{
}
bool ObLSTabletFastIter::is_valid() const
{
return nullptr != ls_tablet_service_
&& mode_ <= ObMDSGetTabletMode::READ_WITHOUT_CHECK; // READ_READABLE_COMMITED is not supported
}
void ObLSTabletFastIter::reset()
{
ls_tablet_service_ = nullptr;
tablet_ids_.reset();
idx_ = 0;
}
int ObLSTabletFastIter::get_next_tablet(ObTabletHandle &handle)
{
int ret = OB_SUCCESS;
handle.reset();
ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*);
if (OB_ISNULL(t3m)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("tenant meta mem mgr is nullptr", K(ret), KP(t3m));
} else {
do {
if (OB_UNLIKELY(tablet_ids_.count() == idx_)) {
ret = OB_ITER_END;
} else {
const common::ObTabletID &tablet_id = tablet_ids_.at(idx_);
const ObTabletMapKey key(ls_tablet_service_->ls_->get_ls_id(), tablet_id);
if (OB_FAIL(t3m->get_tablet_with_filter(WashTabletPriority::WTP_LOW, key, op_, handle))) {
if (OB_ENTRY_NOT_EXIST != ret && OB_ITEM_NOT_SETTED != ret && OB_NOT_THE_OBJECT != ret) {
LOG_WARN("fail to get tablet", K(ret), K_(idx), K(key));
} else {
++idx_;
}
} else {
handle.set_wash_priority(WashTabletPriority::WTP_LOW);
++idx_;
}
}
} while (OB_ENTRY_NOT_EXIST == ret || OB_ITEM_NOT_SETTED == ret || OB_NOT_THE_OBJECT == ret);
}
return ret;
}
} // namespace storage
} // namespace oceanbase

View File

@ -42,6 +42,7 @@ public:
int get_next_tablet(ObTabletHandle &handle);
int get_next_tablet_addr(ObTabletMapKey &key, ObMetaDiskAddr &addr);
int get_next_ddl_kv_mgr(ObDDLKvMgrHandle &handle);
int get_tablet_ids(ObIArray<common::ObTabletID> &ids);
void reset();
bool is_valid() const;
@ -99,6 +100,29 @@ private:
ObHALSTabletIDIterator tablet_id_iter_;
};
class ObLSTabletFastIter final
{
friend class ObLSTabletService;
public:
ObLSTabletFastIter(ObITabletFilterOp &op,
const ObMDSGetTabletMode mode);
~ObLSTabletFastIter() = default;
int get_next_tablet(ObTabletHandle &handle);
bool is_valid() const;
void reset();
TO_STRING_KV(K_(idx), K_(mode));
private:
ObLSTabletService *ls_tablet_service_;
common::ObSEArray<common::ObTabletID, ObTabletCommon::DEFAULT_ITERATOR_TABLET_ID_CNT> tablet_ids_;
int64_t idx_;
ObMDSGetTabletMode mode_;
ObITabletFilterOp &op_;
DISALLOW_COPY_AND_ASSIGN(ObLSTabletFastIter);
};
} // namespace storage
} // namespace oceanbase

View File

@ -261,6 +261,9 @@ TEST_F(TestMetaPointerMap, test_meta_pointer_map)
phy_addr.offset_ = 0;
phy_addr.size_ = 4096;
phy_addr.type_ = ObMetaDiskAddr::DiskType::BLOCK;
old_tablet->is_inited_ = true;
old_tablet->table_store_addr_.addr_.set_none_addr(); // mock empty_shell to pass test
ret = tablet_map_.compare_and_swap_addr_and_object(key, phy_addr, handle, handle);
ASSERT_EQ(common::OB_SUCCESS, ret);
@ -271,6 +274,9 @@ TEST_F(TestMetaPointerMap, test_meta_pointer_map)
tablet_obj.pool_ = &MTL(ObTenantMetaMemMgr*)->tablet_buffer_pool_;
ObTabletHandle tablet_handle;
tablet_handle.set_obj(tablet_obj);
tablet->is_inited_ = true;
tablet->table_store_addr_.addr_.set_none_addr(); // mock empty_shell to pass test
ret = tablet_map_.compare_and_swap_addr_and_object(key, phy_addr, handle, tablet_handle);
ASSERT_EQ(common::OB_SUCCESS, ret);
ASSERT_EQ(1, tablet_map_.map_.size());
@ -344,6 +350,10 @@ TEST_F(TestMetaPointerMap, test_erase_and_load_concurrency)
phy_addr.offset_ = 0;
phy_addr.size_ = 4096;
phy_addr.type_ = ObMetaDiskAddr::DiskType::BLOCK;
old_tablet->is_inited_ = true;
old_tablet->table_store_addr_.addr_.set_none_addr(); // mock empty_shell to pass test
ret = tablet_map_.compare_and_swap_addr_and_object(key, phy_addr, handle, handle);
ASSERT_EQ(common::OB_SUCCESS, ret);