Delete Table Index In QueryEngine

This commit is contained in:
ZenoWang
2023-08-24 04:48:41 +00:00
committed by ob-robot
parent 5af6f9b31f
commit bcab8c659b
6 changed files with 74 additions and 357 deletions

View File

@ -21,37 +21,11 @@ namespace memtable
{ {
using namespace common; using namespace common;
ObQueryEngine::TableIndex * const ObQueryEngine::PLACE_HOLDER =
(ObQueryEngine::TableIndex *)0x1;
// modify buf size in ob_keybtree.h together, otherwise there may be memory waste or overflow. // modify buf size in ob_keybtree.h together, otherwise there may be memory waste or overflow.
STATIC_ASSERT(sizeof(ObQueryEngine::Iterator<keybtree::BtreeIterator<ObStoreRowkeyWrapper, ObMvccRow *>>) <= 5120, "Iterator size exceeded"); STATIC_ASSERT(sizeof(ObQueryEngine::Iterator<keybtree::BtreeIterator<ObStoreRowkeyWrapper, ObMvccRow *>>) <= 5120, "Iterator size exceeded");
STATIC_ASSERT(sizeof(keybtree::Iterator<ObStoreRowkeyWrapper, ObMvccRow *>) == 376, "Iterator size changed"); STATIC_ASSERT(sizeof(keybtree::Iterator<ObStoreRowkeyWrapper, ObMvccRow *>) == 376, "Iterator size changed");
int ObQueryEngine::TableIndex::init() void ObQueryEngine::check_cleanout(bool &is_all_cleanout,
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(is_inited_)) {
ret = OB_INIT_TWICE;
TRANS_LOG(WARN, "init twice", K(this));
} else if (OB_FAIL(keybtree_.init())) {
TRANS_LOG(WARN, "keybtree init fail", KR(ret));
} else {
is_inited_ = true;
}
if (OB_FAIL(ret)) {
destroy();
}
return ret;
}
void ObQueryEngine::TableIndex::destroy()
{
is_inited_ = false;
keybtree_.destroy();
}
void ObQueryEngine::TableIndex::check_cleanout(bool &is_all_cleanout,
bool &is_all_delay_cleanout, bool &is_all_delay_cleanout,
int64_t &count) int64_t &count)
{ {
@ -88,7 +62,7 @@ void ObQueryEngine::TableIndex::check_cleanout(bool &is_all_cleanout,
} }
} }
void ObQueryEngine::TableIndex::dump2text(FILE* fd) void ObQueryEngine::dump2text(FILE* fd)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
Iterator<BtreeIterator> iter; Iterator<BtreeIterator> iter;
@ -127,7 +101,7 @@ void ObQueryEngine::TableIndex::dump2text(FILE* fd)
} }
} }
int ObQueryEngine::TableIndex::dump_keyhash(FILE *fd) const int ObQueryEngine::dump_keyhash(FILE *fd) const
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
const bool print_bucket_node = true; const bool print_bucket_node = true;
@ -145,52 +119,36 @@ int ObQueryEngine::TableIndex::dump_keyhash(FILE *fd) const
return ret; return ret;
} }
int ObQueryEngine::TableIndex::dump_keybtree(FILE* fd) int ObQueryEngine::dump_keybtree(FILE* fd)
{ {
keybtree_.dump(fd); keybtree_.dump(fd);
return OB_SUCCESS; return OB_SUCCESS;
} }
int64_t ObQueryEngine::TableIndex::hash_size() const int64_t ObQueryEngine::hash_size() const
{ {
int64_t arr_size = keyhash_.get_arr_size(); int64_t arr_size = keyhash_.get_arr_size();
return arr_size; return arr_size;
} }
int64_t ObQueryEngine::TableIndex::hash_alloc_memory() const int64_t ObQueryEngine::hash_alloc_memory() const
{ {
int64_t alloc_mem = keyhash_.get_alloc_memory(); int64_t alloc_mem = keyhash_.get_alloc_memory();
return alloc_mem; return alloc_mem;
} }
int64_t ObQueryEngine::TableIndex::btree_size() const int64_t ObQueryEngine::btree_size() const
{ {
int64_t obj_cnt = keybtree_.size(); int64_t obj_cnt = keybtree_.size();
return obj_cnt; return obj_cnt;
} }
int64_t ObQueryEngine::TableIndex::btree_alloc_memory() const int64_t ObQueryEngine::btree_alloc_memory() const
{ {
int64_t alloc_mem = sizeof(KeyBtree); int64_t alloc_mem = sizeof(KeyBtree);
return alloc_mem; return alloc_mem;
} }
bool ObQueryEngine::is_partition_memtable_empty(const uint64_t table_id) const
{
bool b_ret = false;
int ret = OB_SUCCESS;
TableIndex *node_ptr = nullptr;
if (OB_TABLE_NOT_EXIST == (ret = (get_table_index(node_ptr)))) {
b_ret = true;
} else {
b_ret = false;
}
return b_ret;
}
int ObQueryEngine::init(const uint64_t tenant_id) int ObQueryEngine::init(const uint64_t tenant_id)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
@ -200,6 +158,8 @@ int ObQueryEngine::init(const uint64_t tenant_id)
} else if (OB_UNLIKELY(is_inited_)) { } else if (OB_UNLIKELY(is_inited_)) {
TRANS_LOG(WARN, "init twice", K(this)); TRANS_LOG(WARN, "init twice", K(this));
ret = OB_INIT_TWICE; ret = OB_INIT_TWICE;
} else if (OB_FAIL(keybtree_.init())) {
TRANS_LOG(WARN, "keybtree init fail", KR(ret));
} else { } else {
tenant_id_ = tenant_id; tenant_id_ = tenant_id;
is_inited_ = true; is_inited_ = true;
@ -214,11 +174,10 @@ void ObQueryEngine::destroy()
{ {
if (IS_NOT_INIT) { if (IS_NOT_INIT) {
// do nothing // do nothing
} else if (OB_NOT_NULL(index_) && NOT_PLACE_HOLDER(index_)) { } else {
index_->destroy(); keybtree_.destroy();
memstore_allocator_.free(index_);
index_ = nullptr;
btree_allocator_.reset(); btree_allocator_.reset();
keyhash_.destroy();
} }
is_inited_ = false; is_inited_ = false;
} }
@ -234,20 +193,14 @@ int ObQueryEngine::set(const ObMemtableKey *key, ObMvccRow *value)
ret = OB_INVALID_ARGUMENT; ret = OB_INVALID_ARGUMENT;
TRANS_LOG(WARN, "invalid param when query_engine set", KR(ret), KP(key), KP(value)); TRANS_LOG(WARN, "invalid param when query_engine set", KR(ret), KP(key), KP(value));
} else { } else {
TableIndex *node_ptr = nullptr; ObStoreRowkeyWrapper key_wrapper(key->get_rowkey());
if (OB_UNLIKELY(OB_TABLE_NOT_EXIST == (ret = (get_table_index(node_ptr))))) { if (OB_FAIL(hash_ret = keyhash_.insert(&key_wrapper, value))) {
ret = set_table_index(key->get_rowkey()->get_obj_cnt(), node_ptr); if (OB_ENTRY_EXIST != hash_ret) {
} TRANS_LOG(WARN, "put to keyhash fail", "hash_ret", hash_ret, "key", key);
if (OB_SUCC(ret) && OB_NOT_NULL(node_ptr)) {
ObStoreRowkeyWrapper key_wrapper(key->get_rowkey());
if (OB_FAIL(hash_ret = node_ptr->get_keyhash().insert(&key_wrapper, value))) {
if (OB_ENTRY_EXIST != hash_ret) {
TRANS_LOG(WARN, "put to keyhash fail", "hash_ret", hash_ret, "key", key);
}
ret = hash_ret;
} else {
value->set_hash_indexed();
} }
ret = hash_ret;
} else {
value->set_hash_indexed();
} }
} }
if (OB_FAIL(ret) && OB_ENTRY_EXIST != ret) { if (OB_FAIL(ret) && OB_ENTRY_EXIST != ret) {
@ -267,27 +220,18 @@ int ObQueryEngine::get(const ObMemtableKey *parameter_key, ObMvccRow *&row, ObMe
ret = OB_INVALID_ARGUMENT; ret = OB_INVALID_ARGUMENT;
TRANS_LOG(WARN, "invalid param", KP(parameter_key)); TRANS_LOG(WARN, "invalid param", KP(parameter_key));
} else { } else {
TableIndex *node_ptr = nullptr; const ObStoreRowkeyWrapper parameter_key_wrapper(parameter_key->get_rowkey());
if (OB_FAIL(get_table_index(node_ptr))) { const ObStoreRowkeyWrapper *copy_inner_key_wrapper = nullptr;
// FIXME fengshuo.fs : to keep compatibility, return old version ret. if (OB_FAIL(keyhash_.get(&parameter_key_wrapper, row, copy_inner_key_wrapper))) {
ret = OB_ENTRY_NOT_EXIST; if (OB_ENTRY_NOT_EXIST != ret) {
} else if (OB_ISNULL(node_ptr)) { TRANS_LOG(WARN, "get from keyhash fail", KR(ret), K(*parameter_key));
ret = OB_ERR_UNEXPECTED;
TRANS_LOG(ERROR, "node_ptr is nullptr", K(*parameter_key));
} else {
const ObStoreRowkeyWrapper parameter_key_wrapper(parameter_key->get_rowkey());
const ObStoreRowkeyWrapper *copy_inner_key_wrapper = nullptr;
if (OB_FAIL(node_ptr->get_keyhash().get(&parameter_key_wrapper, row, copy_inner_key_wrapper))) {
if (OB_ENTRY_NOT_EXIST != ret) {
TRANS_LOG(WARN, "get from keyhash fail", KR(ret), K(*parameter_key));
}
row = nullptr;
} else if (OB_ISNULL(row)) {
ret = OB_ERR_UNEXPECTED;
TRANS_LOG(ERROR, "get NULL value from keyhash", KR(ret), K(*parameter_key));
} else {
ret = returned_key->encode(copy_inner_key_wrapper->get_rowkey());
} }
row = nullptr;
} else if (OB_ISNULL(row)) {
ret = OB_ERR_UNEXPECTED;
TRANS_LOG(ERROR, "get NULL value from keyhash", KR(ret), K(*parameter_key));
} else {
ret = returned_key->encode(copy_inner_key_wrapper->get_rowkey());
} }
} }
return ret; return ret;
@ -303,33 +247,24 @@ int ObQueryEngine::ensure(const ObMemtableKey *key, ObMvccRow *value)
ret = OB_INVALID_ARGUMENT; ret = OB_INVALID_ARGUMENT;
TRANS_LOG(WARN, "query_engine ensure error, invalid param", KR(ret), KP(key), KP(value)); TRANS_LOG(WARN, "query_engine ensure error, invalid param", KR(ret), KP(key), KP(value));
} else { } else {
TableIndex *node_ptr = nullptr; ObStoreRowkeyWrapper key_wrapper(key->get_rowkey());
if (OB_UNLIKELY(OB_TABLE_NOT_EXIST == (ret = get_table_index(node_ptr)))) { if (value->is_btree_indexed()) {
ret = set_table_index(key->get_rowkey()->get_obj_cnt(), node_ptr); if (value->is_btree_tag_del()) {
} if (OB_FAIL(keybtree_.re_insert(key_wrapper, value))) {
if (OB_SUCC(ret) && OB_NOT_NULL(node_ptr)) { TRANS_LOG(WARN, "ensure keybtree fail", KR(ret), K(*key));
if (value->is_btree_indexed()) {
if (value->is_btree_tag_del()) {
ObStoreRowkeyWrapper key_wrapper(key->get_rowkey());
if (OB_FAIL(node_ptr->get_keybtree().re_insert(key_wrapper, value))) {
TRANS_LOG(WARN, "ensure keybtree fail", KR(ret), K(*key));
} else {
value->clear_btree_tag_del();
}
}
} else {
ObStoreRowkeyWrapper key_wrapper(key->get_rowkey());
if (OB_FAIL(node_ptr->get_keybtree().insert(key_wrapper, value))) {
if (OB_ENTRY_EXIST == ret) {
TRANS_LOG(ERROR, "ensure keybtree fail", KR(ret), K(*key));
ob_abort();
} else {
TRANS_LOG(WARN, "ensure keybtree fail", KR(ret), K(*key));
}
} else { } else {
value->set_btree_indexed(); value->clear_btree_tag_del();
} }
} }
} else if (OB_FAIL(keybtree_.insert(key_wrapper, value))) {
if (OB_ENTRY_EXIST == ret) {
TRANS_LOG(ERROR, "ensure keybtree fail", KR(ret), K(*key));
ob_abort();
} else {
TRANS_LOG(WARN, "ensure keybtree fail", KR(ret), K(*key));
}
} else {
value->set_btree_indexed();
} }
} }
return ret; return ret;
@ -362,14 +297,11 @@ int ObQueryEngine::purge(const ObMemtableKey *key, int64_t version)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
ObMvccRow *value = nullptr; ObMvccRow *value = nullptr;
TableIndex *node_ptr = nullptr;
ObStoreRowkeyWrapper key_wrapper(key->get_rowkey()); ObStoreRowkeyWrapper key_wrapper(key->get_rowkey());
if (IS_NOT_INIT) { if (IS_NOT_INIT) {
TRANS_LOG(WARN, "not init", "this", this); TRANS_LOG(WARN, "not init", "this", this);
ret = OB_NOT_INIT; ret = OB_NOT_INIT;
} else if (OB_FAIL(get_table_index(node_ptr))) { } else if (OB_FAIL(keybtree_.del(key_wrapper, value, version))) {
// do nothing
} else if (OB_FAIL(node_ptr->get_keybtree().del(key_wrapper, value, version))) {
if (OB_UNLIKELY(OB_ENTRY_NOT_EXIST != ret)) { if (OB_UNLIKELY(OB_ENTRY_NOT_EXIST != ret)) {
TRANS_LOG(WARN, "purge from keybtree fail", KR(ret), K(*key)); TRANS_LOG(WARN, "purge from keybtree fail", KR(ret), K(*key));
} }
@ -385,22 +317,18 @@ int ObQueryEngine::scan(const ObMemtableKey *start_key, const bool start_exclude
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
Iterator<BtreeIterator> *iter = nullptr; Iterator<BtreeIterator> *iter = nullptr;
TableIndex *node_ptr = nullptr;
if (IS_NOT_INIT) { if (IS_NOT_INIT) {
TRANS_LOG(WARN, "not init", "this", this); TRANS_LOG(WARN, "not init", "this", this);
ret = OB_NOT_INIT; ret = OB_NOT_INIT;
} else if (OB_ISNULL(iter = iter_alloc_.alloc())) { } else if (OB_ISNULL(iter = iter_alloc_.alloc())) {
TRANS_LOG(WARN, "alloc iter fail"); TRANS_LOG(WARN, "alloc iter fail");
ret = OB_ALLOCATE_MEMORY_FAILED; ret = OB_ALLOCATE_MEMORY_FAILED;
} else if (OB_FAIL(get_table_index(node_ptr))) {
// FIXME fengshuo.fs : to keep compatibility, return old version ret.
ret = OB_SUCCESS;
} else { } else {
ObStoreRowkeyWrapper scan_start_key_wrapper(start_key->get_rowkey()); ObStoreRowkeyWrapper scan_start_key_wrapper(start_key->get_rowkey());
ObStoreRowkeyWrapper scan_end_key_wrapper(end_key->get_rowkey()); ObStoreRowkeyWrapper scan_end_key_wrapper(end_key->get_rowkey());
iter->reset(); iter->reset();
const_cast<ObMemtableKey *>(iter->get_key())->encode(nullptr); const_cast<ObMemtableKey *>(iter->get_key())->encode(nullptr);
if (OB_FAIL(node_ptr->get_keybtree().set_key_range(iter->get_read_handle(), if (OB_FAIL(keybtree_.set_key_range(iter->get_read_handle(),
scan_start_key_wrapper, start_exclude, scan_start_key_wrapper, start_exclude,
scan_end_key_wrapper, end_exclude, version))) { scan_end_key_wrapper, end_exclude, version))) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
@ -443,15 +371,11 @@ int ObQueryEngine::sample_rows(Iterator<BtreeRawIterator> *iter, const ObMemtabl
physical_row_count = 0; physical_row_count = 0;
ratio = 1.5; ratio = 1.5;
const bool skip_purge_memtable = false; const bool skip_purge_memtable = false;
TableIndex *node_ptr = nullptr;
ObStoreRowkeyWrapper scan_start_key_wrapper(start_key->get_rowkey()); ObStoreRowkeyWrapper scan_start_key_wrapper(start_key->get_rowkey());
ObStoreRowkeyWrapper scan_end_key_wrapper(end_key->get_rowkey()); ObStoreRowkeyWrapper scan_end_key_wrapper(end_key->get_rowkey());
TRANS_LOG(DEBUG, "estimate row count, key range", K(*start_key), K(*end_key)); TRANS_LOG(DEBUG, "estimate row count, key range", K(*start_key), K(*end_key));
iter->reset(); iter->reset();
if (OB_FAIL(get_table_index(node_ptr))) { if (OB_FAIL(keybtree_.set_key_range(iter->get_read_handle(),
// FIXME fengshuo.fs : to keep compatibility, return old version ret.
ret = OB_ITER_END;
} else if (OB_FAIL(node_ptr->get_keybtree().set_key_range(iter->get_read_handle(),
scan_start_key_wrapper, start_exclude, scan_start_key_wrapper, start_exclude,
scan_end_key_wrapper, end_exclude, 0/*unused version*/))) { scan_end_key_wrapper, end_exclude, 0/*unused version*/))) {
TRANS_LOG(WARN, "set key range to btree scan handle failed", KR(ret)); TRANS_LOG(WARN, "set key range to btree scan handle failed", KR(ret));
@ -522,21 +446,17 @@ int ObQueryEngine::init_raw_iter_for_estimate(Iterator<BtreeRawIterator>*& iter,
const ObMemtableKey *end_key) const ObMemtableKey *end_key)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
TableIndex *node_ptr = nullptr;
if (IS_NOT_INIT) { if (IS_NOT_INIT) {
TRANS_LOG(WARN, "not init", "this", this); TRANS_LOG(WARN, "not init", "this", this);
ret = OB_NOT_INIT; ret = OB_NOT_INIT;
} else if (OB_ISNULL(iter = raw_iter_alloc_.alloc())) { } else if (OB_ISNULL(iter = raw_iter_alloc_.alloc())) {
TRANS_LOG(WARN, "alloc raw iter fail"); TRANS_LOG(WARN, "alloc raw iter fail");
ret = OB_ALLOCATE_MEMORY_FAILED; ret = OB_ALLOCATE_MEMORY_FAILED;
} else if (OB_FAIL(get_table_index(node_ptr))) {
// FIXME fengshuo.fs : to keep compatibility, return old version ret.
ret = OB_SUCCESS;
} else { } else {
ObStoreRowkeyWrapper start_key_wrapper(start_key->get_rowkey()); ObStoreRowkeyWrapper start_key_wrapper(start_key->get_rowkey());
ObStoreRowkeyWrapper end_key_wrapper(end_key->get_rowkey()); ObStoreRowkeyWrapper end_key_wrapper(end_key->get_rowkey());
iter->reset(); iter->reset();
if (OB_FAIL(node_ptr->get_keybtree().set_key_range( if (OB_FAIL(keybtree_.set_key_range(
iter->get_read_handle(), iter->get_read_handle(),
start_key_wrapper, 1, start_key_wrapper, 1,
end_key_wrapper, 1, 0/*unused version*/))) { end_key_wrapper, 1, 0/*unused version*/))) {
@ -790,109 +710,5 @@ int ObQueryEngine::estimate_row_count(const transaction::ObTransID &tx_id,
return ret; return ret;
} }
void ObQueryEngine::check_cleanout(bool &is_all_cleanout,
bool &is_all_delay_cleanout,
int64_t &count)
{
if (OB_NOT_NULL(index_)) {
index_->check_cleanout(is_all_cleanout,
is_all_delay_cleanout,
count);
}
}
void ObQueryEngine::dump2text(FILE *fd)
{
TableIndex *index = ATOMIC_LOAD(&index_);
if (OB_NOT_NULL(index) && NOT_PLACE_HOLDER(index)) {
index->dump2text(fd);
}
}
int ObQueryEngine::get_table_index(TableIndex *&return_ptr) const
{
int ret = OB_SUCCESS;
if (IS_NOT_INIT) {
TRANS_LOG(WARN, "not init", "this", this);
ret = OB_NOT_INIT;
} else {
TableIndex *p = nullptr;
while (OB_SUCC(ret) && OB_ISNULL(return_ptr)) {
if (OB_ISNULL(p = ATOMIC_LOAD(&index_))) {
// if we found a empty slot, table_id must not be in the hash.
ret = OB_TABLE_NOT_EXIST;
} else if (OB_UNLIKELY(PLACE_HOLDER == p)) {
// allocing, spin to wait.
sched_yield();
} else {
// right position
return_ptr = p;
}
}
}
return ret;
}
int ObQueryEngine::set_table_index(const int64_t obj_cnt, TableIndex *&return_ptr)
{
int ret = OB_SUCCESS;
if (IS_NOT_INIT) {
TRANS_LOG(WARN, "not init", "this", this);
ret = OB_NOT_INIT;
} else if (OB_FAIL(set_table_index_(obj_cnt, return_ptr))) {
TRANS_LOG(WARN, "set table index failed.", KR(ret));
} else {
// set table index succeed.
}
return ret;
}
int ObQueryEngine::set_table_index_(const int64_t obj_cnt, TableIndex *&return_ptr)
{
int ret = OB_SUCCESS;
return_ptr = nullptr;
TableIndex *p = nullptr;
TableIndex *new_node = nullptr;
while (OB_SUCC(ret) && OB_ISNULL(return_ptr)) {
if (OB_NOT_NULL(p = ATOMIC_LOAD(&index_))) {
// cur position has been allocated.
if (OB_UNLIKELY(PLACE_HOLDER == p)) {
// allocing, spin to wait.
sched_yield();
} else {
// table_id is equal
return_ptr = p;
}
} else if (OB_LIKELY(ATOMIC_BCAS(&index_, nullptr, PLACE_HOLDER))) {
// hold the empty slot successfully
if (OB_NOT_NULL(new_node = reinterpret_cast<TableIndex *>(
memstore_allocator_.alloc(sizeof(TableIndex))))
&& OB_NOT_NULL(new (new_node)
TableIndex(btree_allocator_, memstore_allocator_, obj_cnt))) {
if (OB_FAIL(new_node->init())) {
ret = OB_INIT_FAIL;
TRANS_LOG(ERROR, "table_index_node init failed", KR(ret), K(new_node));
new_node->~TableIndex();
memstore_allocator_.free(new_node);
new_node = nullptr;
} else {
return_ptr = new_node;
}
} else {
ret = OB_ALLOCATE_MEMORY_FAILED;
TRANS_LOG(WARN, "alloc table_index_node failed", KR(ret));
new_node = nullptr;
}
// must unlock
ATOMIC_STORE(&index_, new_node);
} else {
// can not hold that slot, try in next loop
// other thead may insert equal table_id, so do not inc i.
}
}
return ret;
}
} // namespace memtable } // namespace memtable
} // namespace oceanbase } // namespace oceanbase

View File

@ -139,47 +139,16 @@ public:
DISALLOW_COPY_AND_ASSIGN(IteratorAlloc); DISALLOW_COPY_AND_ASSIGN(IteratorAlloc);
}; };
class TableIndex
{
public:
explicit TableIndex(BtreeNodeAllocator &btree_allocator,
common::ObIAllocator &memstore_allocator,
int64_t obj_cnt)
: is_inited_(false),
keybtree_(btree_allocator),
keyhash_(memstore_allocator),
obj_cnt_(obj_cnt)
{}
~TableIndex() { destroy(); }
int init();
void destroy();
void check_cleanout(bool &is_all_cleanout,
bool &is_all_delay_cleanout,
int64_t &count);
void dump2text(FILE* fd);
int dump_keyhash(FILE *fd) const;
int dump_keybtree(FILE *fd);
int64_t hash_size() const;
int64_t hash_alloc_memory() const;
int64_t btree_size() const;
int64_t btree_alloc_memory() const;
KeyBtree &get_keybtree() { return keybtree_; }
KeyHash &get_keyhash() { return keyhash_; }
int64_t get_obj_cnt() { return obj_cnt_; }
private:
DISALLOW_COPY_AND_ASSIGN(TableIndex);
bool is_inited_;
KeyBtree keybtree_;
KeyHash keyhash_;
int64_t obj_cnt_;
};
public: public:
enum { ESTIMATE_CHILD_COUNT_THRESHOLD = 1024, MAX_RANGE_SPLIT_COUNT = 1024 * 1024}; enum { ESTIMATE_CHILD_COUNT_THRESHOLD = 1024, MAX_RANGE_SPLIT_COUNT = 1024 * 1024};
explicit ObQueryEngine(ObIAllocator &memstore_allocator) explicit ObQueryEngine(ObIAllocator &memstore_allocator)
: is_inited_(false), is_expanding_(false), tenant_id_(common::OB_SERVER_TENANT_ID), : is_inited_(false),
index_(nullptr), memstore_allocator_(memstore_allocator), is_expanding_(false),
btree_allocator_(memstore_allocator_) {} tenant_id_(common::OB_SERVER_TENANT_ID),
memstore_allocator_(memstore_allocator),
btree_allocator_(memstore_allocator_),
keybtree_(btree_allocator_),
keyhash_(memstore_allocator_) {}
~ObQueryEngine() { destroy(); } ~ObQueryEngine() { destroy(); }
int init(const uint64_t tenant_id); int init(const uint64_t tenant_id);
void destroy(); void destroy();
@ -203,46 +172,17 @@ public:
const ObMemtableKey *start_key, const int start_exclude, const ObMemtableKey *start_key, const int start_exclude,
const ObMemtableKey *end_key, const int end_exclude, const ObMemtableKey *end_key, const int end_exclude,
int64_t &logical_row_count, int64_t &physical_row_count); int64_t &logical_row_count, int64_t &physical_row_count);
int dump_keyhash(FILE *fd) const
{
TableIndex *index = ATOMIC_LOAD(&index_);
return OB_NOT_NULL(index) && NOT_PLACE_HOLDER(index) ? index->dump_keyhash(fd) : OB_SUCCESS;
}
int64_t hash_size() const
{
TableIndex *index = ATOMIC_LOAD(&index_);
return OB_NOT_NULL(index) && NOT_PLACE_HOLDER(index) ? index->hash_size() : 0;
}
int64_t hash_alloc_memory() const
{
TableIndex *index = ATOMIC_LOAD(&index_);
return OB_NOT_NULL(index) && NOT_PLACE_HOLDER(index) ? index->hash_alloc_memory() : 0;
}
int dump_keybtree(FILE *fd)
{
TableIndex *index = ATOMIC_LOAD(&index_);
return OB_NOT_NULL(index) && NOT_PLACE_HOLDER(index) ? index->dump_keybtree(fd) : OB_SUCCESS;
}
int64_t btree_size() const
{
TableIndex *index = ATOMIC_LOAD(&index_);
return OB_NOT_NULL(index) && NOT_PLACE_HOLDER(index) ? index->btree_size() : 0;
}
int64_t btree_alloc_memory() const
{
TableIndex *index = ATOMIC_LOAD(&index_);
return OB_NOT_NULL(index) && NOT_PLACE_HOLDER(index)
? index->btree_alloc_memory() + btree_allocator_.get_allocated()
: 0;
}
int dump_keyhash(FILE *fd) const;
int dump_keybtree(FILE *fd);
int64_t hash_size() const;
int64_t hash_alloc_memory() const;
int64_t btree_size() const;
int64_t btree_alloc_memory() const;
void check_cleanout(bool &is_all_cleanout, void check_cleanout(bool &is_all_cleanout,
bool &is_all_delay_cleanout, bool &is_all_delay_cleanout,
int64_t &count); int64_t &count);
void dump2text(FILE *fd); void dump2text(FILE *fd);
int get_table_index(TableIndex *&return_ptr) const;
int set_table_index(const int64_t obj_cnt, TableIndex *&return_ptr);
bool is_partition_memtable_empty(const uint64_t table_id) const;
private: private:
int sample_rows(Iterator<BtreeRawIterator> *iter, const ObMemtableKey *start_key, int sample_rows(Iterator<BtreeRawIterator> *iter, const ObMemtableKey *start_key,
const int start_exclude, const ObMemtableKey *end_key, const int end_exclude, const int start_exclude, const ObMemtableKey *end_key, const int end_exclude,
@ -251,8 +191,6 @@ private:
int init_raw_iter_for_estimate(Iterator<BtreeRawIterator>*& iter, int init_raw_iter_for_estimate(Iterator<BtreeRawIterator>*& iter,
const ObMemtableKey *start_key, const ObMemtableKey *start_key,
const ObMemtableKey *end_key); const ObMemtableKey *end_key);
int set_table_index_(const int64_t obj_cnt, TableIndex *&return_ptr);
int find_split_range_level_(const ObMemtableKey *start_key, int find_split_range_level_(const ObMemtableKey *start_key,
const ObMemtableKey *end_key, const ObMemtableKey *end_key,
const int64_t range_count, const int64_t range_count,
@ -274,15 +212,15 @@ private:
private: private:
DISALLOW_COPY_AND_ASSIGN(ObQueryEngine); DISALLOW_COPY_AND_ASSIGN(ObQueryEngine);
static TableIndex * const PLACE_HOLDER;
bool is_inited_; bool is_inited_;
bool is_expanding_; bool is_expanding_;
uint64_t tenant_id_; uint64_t tenant_id_;
TableIndex *index_;
ObIAllocator &memstore_allocator_; ObIAllocator &memstore_allocator_;
BtreeNodeAllocator btree_allocator_; BtreeNodeAllocator btree_allocator_;
IteratorAlloc<BtreeIterator> iter_alloc_; IteratorAlloc<BtreeIterator> iter_alloc_;
IteratorAlloc<BtreeRawIterator> raw_iter_alloc_; IteratorAlloc<BtreeRawIterator> raw_iter_alloc_;
KeyBtree keybtree_;
KeyHash keyhash_;
}; };
} // namespace memtable } // namespace memtable

View File

@ -2511,11 +2511,6 @@ int ObMemtable::get_active_table_ids(common::ObIArray<uint64_t> &table_ids)
return ret; return ret;
} }
bool ObMemtable::is_partition_memtable_empty(const uint64_t table_id) const
{
return query_engine_.is_partition_memtable_empty(table_id);
}
#ifdef OB_BUILD_TDE_SECURITY #ifdef OB_BUILD_TDE_SECURITY
int ObMemtable::save_encrypt_meta(const uint64_t table_id, const share::ObEncryptMeta *encrypt_meta) int ObMemtable::save_encrypt_meta(const uint64_t table_id, const share::ObEncryptMeta *encrypt_meta)
{ {

View File

@ -457,7 +457,6 @@ public:
virtual OB_INLINE int64_t get_timestamp() const override { return timestamp_; } virtual OB_INLINE int64_t get_timestamp() const override { return timestamp_; }
void inc_timestamp(const int64_t timestamp) { timestamp_ = MAX(timestamp_, timestamp + 1); } void inc_timestamp(const int64_t timestamp) { timestamp_ = MAX(timestamp_, timestamp + 1); }
int get_active_table_ids(common::ObIArray<uint64_t> &table_ids); int get_active_table_ids(common::ObIArray<uint64_t> &table_ids);
bool is_partition_memtable_empty(const uint64_t table_id) const;
blocksstable::ObDatumRange &m_get_real_range(blocksstable::ObDatumRange &real_range, blocksstable::ObDatumRange &m_get_real_range(blocksstable::ObDatumRange &real_range,
const blocksstable::ObDatumRange &range, const bool is_reverse) const; const blocksstable::ObDatumRange &range, const bool is_reverse) const;
int get_tx_table_guard(storage::ObTxTableGuard &tx_table_guard); int get_tx_table_guard(storage::ObTxTableGuard &tx_table_guard);

View File

@ -157,7 +157,10 @@ public:
{ {
} }
~ObMtArrayBase() { destroy(); } ~ObMtArrayBase() { destroy(); }
void destroy() {} void destroy() {
dir_ = nullptr;
alloc_memory_ = 0;
}
int64_t get_alloc_memory() const { return ATOMIC_LOAD(&alloc_memory_) + sizeof(*this); } int64_t get_alloc_memory() const { return ATOMIC_LOAD(&alloc_memory_) + sizeof(*this); }
// 1. caller guraantees the validity of idx // 1. caller guraantees the validity of idx
// 2. allocate dir_/seg on demand // 2. allocate dir_/seg on demand
@ -353,6 +356,10 @@ public:
{ {
arr_.destroy(); arr_.destroy();
arr_size_ = 0; arr_size_ = 0;
tail_node_.hash_ = 0xFFFFFFFFFFFFFFFF; // can be any value
tail_node_.next_ = NULL;
zero_node_.set_bucket_filled(0);
zero_node_.next_ = &tail_node_;
} }
int64_t get_arr_size() const { return ATOMIC_LOAD(&arr_size_); } int64_t get_arr_size() const { return ATOMIC_LOAD(&arr_size_); }
int64_t get_alloc_memory() const { return sizeof(*this) + arr_.get_alloc_memory() + get_arr_size() * sizeof(ObMtHashNode) - sizeof(arr_);} int64_t get_alloc_memory() const { return sizeof(*this) + arr_.get_alloc_memory() + get_arr_size() * sizeof(ObMtHashNode) - sizeof(arr_);}
@ -580,7 +587,7 @@ private:
// or searches the whole link list // or searches the whole link list
ret = common::OB_ENTRY_NOT_EXIST; ret = common::OB_ENTRY_NOT_EXIST;
} }
TRANS_LOG(DEBUG, "do_get finish", K(arr_size), K(query_key_so_hash), KP(bucket_node), TRANS_LOG(DEBUG, "do_get finish", K(ret), K(arr_size), K(query_key_so_hash), KP(bucket_node),
K(op_bucket_node), K(genealogy), KP(prev_node), KP(next_node)); K(op_bucket_node), K(genealogy), KP(prev_node), KP(next_node));
} }
return ret; return ret;

View File

@ -30,44 +30,6 @@ using namespace oceanbase::keybtree;
using namespace oceanbase::memtable; using namespace oceanbase::memtable;
using ObQueryEngineIterator = ObQueryEngine::Iterator<BtreeIterator<ObStoreRowkeyWrapper, ObMvccRow *>>; using ObQueryEngineIterator = ObQueryEngine::Iterator<BtreeIterator<ObStoreRowkeyWrapper, ObMvccRow *>>;
TEST(TestObQueryEngine, get_and_set_table_index_node)
{
// This is a concurrency scene, use multi-thread test.
constexpr uint64_t TABLE_COUNT_LIMIT = (1 << 14);
constexpr int64_t THREAD_COUNT = 20;
ObModAllocator allocator;
ObQueryEngine qe(allocator);
ObQueryEngine::TableIndex *table_index = nullptr;
uint64_t counter = 0;
int ret = OB_SUCCESS;
ret = qe.init(1);
EXPECT_EQ(OB_SUCCESS, ret);
std::thread threads[THREAD_COUNT];
for (int64_t i = 0; i < THREAD_COUNT; ++i) {
threads[i] = std::thread([&]() {
int ret = OB_SUCCESS;
ObQueryEngine::TableIndex *tmp_ptr = nullptr;
if (OB_FAIL(qe.set_table_index(i, tmp_ptr))) {
TRANS_LOG(WARN, "", KR(ret));
} else {
ATOMIC_AAF(&counter, 1);
ObQueryEngine::TableIndex *cmp_ptr = nullptr;
EXPECT_NE(nullptr, tmp_ptr);
EXPECT_EQ(OB_SUCCESS, qe.get_table_index(cmp_ptr));
EXPECT_EQ(tmp_ptr, cmp_ptr);
}
});
}
for (int64_t i = 0; i < THREAD_COUNT; ++i) {
threads[i].join();
}
EXPECT_EQ(counter, THREAD_COUNT);
}
TEST(TestObQueryEngine, smoke_test) TEST(TestObQueryEngine, smoke_test)
{ {
static const int64_t R_COUNT = 6; static const int64_t R_COUNT = 6;