Delete Table Index In QueryEngine
This commit is contained in:
@ -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(¶meter_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(¶meter_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
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Reference in New Issue
Block a user