From 050e984b04bdcc43f61d70c505dcde32a78f9686 Mon Sep 17 00:00:00 2001 From: obdev Date: Mon, 19 Dec 2022 02:38:04 +0000 Subject: [PATCH] [FEAT MERGE] OLTP performance optimization feature --- build.sh | 3 + cmake/Env.cmake | 18 +- deps/oblib/src/lib/CMakeLists.txt | 1 + deps/oblib/src/lib/alloc/memory_dump.cpp | 7 +- deps/oblib/src/lib/allocator/ob_qsync.h | 1 + .../src/lib/lock/ob_bucket_qsync_lock.cpp | 243 +++++++++ .../oblib/src/lib/lock/ob_bucket_qsync_lock.h | 265 ++++++++++ deps/oblib/src/lib/lock/ob_qsync_lock.cpp | 33 +- deps/oblib/src/lib/lock/ob_qsync_lock.h | 2 + .../src/lib/objectpool/ob_resource_pool.h | 3 +- .../src/rpc/obmysql/ob_2_0_protocol_utils.cpp | 2 +- src/logservice/ob_log_handler.cpp | 9 +- src/logservice/palf/log_define.h | 5 +- src/logservice/palf/log_sliding_window.h | 2 +- src/logservice/palf/palf_handle_impl.cpp | 2 +- src/objit/src/CMakeLists.txt | 2 +- src/observer/mysql/obmp_packet_sender.cpp | 2 +- src/observer/mysql/obmp_utils.cpp | 19 +- src/sql/das/ob_das_context.cpp | 4 +- src/sql/das/ob_das_location_router.cpp | 25 +- src/sql/das/ob_das_location_router.h | 23 +- src/sql/ob_sql.cpp | 12 + .../optimizer/ob_phy_table_location_info.h | 2 +- src/sql/optimizer/ob_table_location.cpp | 70 ++- src/sql/optimizer/ob_table_location.h | 27 +- src/sql/session/ob_sql_session_info.cpp | 2 + src/sql/session/ob_sql_session_info.h | 9 + src/storage/blocksstable/ob_tmp_file.cpp | 3 +- src/storage/ls/ob_ls_tablet_service.cpp | 24 +- src/storage/memtable/ob_memtable.cpp | 8 +- src/storage/memtable/ob_memtable_context.cpp | 11 +- .../memtable/ob_redo_log_generator.cpp | 20 +- src/storage/memtable/ob_redo_log_generator.h | 6 +- src/storage/meta_mem/ob_meta_pointer_map.h | 24 +- src/storage/meta_mem/ob_tablet_pointer.cpp | 20 + src/storage/meta_mem/ob_tablet_pointer.h | 5 +- .../meta_mem/ob_tenant_meta_mem_mgr.cpp | 54 +- src/storage/meta_mem/ob_tenant_meta_mem_mgr.h | 3 +- src/storage/ob_i_memtable_mgr.cpp | 10 +- src/storage/ob_i_memtable_mgr.h | 165 +++++- src/storage/ob_long_ops_monitor.cpp | 3 +- src/storage/ob_resource_map.h | 20 +- .../tablelock/ob_lock_memtable_mgr.cpp | 17 +- src/storage/tablelock/ob_lock_memtable_mgr.h | 1 + src/storage/tablelock/ob_obj_lock.cpp | 33 +- src/storage/tablelock/ob_obj_lock.h | 47 +- src/storage/tablet/ob_tablet.cpp | 44 +- src/storage/tablet/ob_tablet.h | 4 +- .../tablet/ob_tablet_binding_helper.cpp | 12 +- .../tablet/ob_tablet_create_delete_helper.cpp | 4 +- src/storage/tablet/ob_tablet_memtable_mgr.cpp | 36 +- src/storage/tablet/ob_tablet_memtable_mgr.h | 1 + src/storage/tx/ob_gts_local_cache.cpp | 29 +- src/storage/tx/ob_gts_local_cache.h | 8 +- src/storage/tx/ob_gts_source.cpp | 123 ++--- src/storage/tx/ob_gts_source.h | 12 +- src/storage/tx/ob_i_ts_source.h | 16 - src/storage/tx/ob_trans_ctx.h | 2 - src/storage/tx/ob_trans_ctx_lock.cpp | 67 +-- src/storage/tx/ob_trans_ctx_lock.h | 40 -- src/storage/tx/ob_trans_ctx_mgr_v4.cpp | 9 +- src/storage/tx/ob_trans_ctx_mgr_v4.h | 14 +- src/storage/tx/ob_trans_functor.h | 174 ++++--- src/storage/tx/ob_trans_part_ctx.cpp | 200 ++++---- src/storage/tx/ob_trans_part_ctx.h | 4 +- src/storage/tx/ob_ts_mgr.cpp | 478 ++++-------------- src/storage/tx/ob_ts_mgr.h | 132 +---- src/storage/tx/ob_tx_data_define.h | 1 - src/storage/tx/ob_tx_elr_util.cpp | 3 +- src/storage/tx/ob_tx_log.cpp | 75 ++- src/storage/tx/ob_tx_log.h | 90 +++- src/storage/tx_storage/ob_access_service.cpp | 6 +- .../tx_table/ob_tx_ctx_memtable_mgr.cpp | 7 +- src/storage/tx_table/ob_tx_ctx_memtable_mgr.h | 4 +- .../tx_table/ob_tx_data_memtable_mgr.cpp | 16 +- .../tx_table/ob_tx_data_memtable_mgr.h | 4 +- .../test_dag_net_in_dag_scheduler.cpp | 9 + unittest/storage/test_meta_pointer_map.cpp | 8 +- ...st_partition_incremental_range_spliter.cpp | 5 + unittest/storage/tx/ob_mock_tx_ctx.cpp | 1 - unittest/storage/tx/test_ob_trans_hashmap.cpp | 55 +- .../storage/tx_table/test_tx_ctx_table.cpp | 8 + 82 files changed, 1738 insertions(+), 1230 deletions(-) create mode 100644 deps/oblib/src/lib/lock/ob_bucket_qsync_lock.cpp create mode 100644 deps/oblib/src/lib/lock/ob_bucket_qsync_lock.h diff --git a/build.sh b/build.sh index e94fa2c88..40217700e 100755 --- a/build.sh +++ b/build.sh @@ -169,6 +169,9 @@ function build # build soft link for ccls ln -sf ${TOPDIR}/build_ccls/compile_commands.json ${TOPDIR}/compile_commands.json ;; + xperf) + do_build "$@" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_AUTO_FDO=ON -DENABLE_THIN_LTO=ON -DOB_USE_LLD=$LLD_OPTION + ;; xdebug_asan) do_build "$@" -DCMAKE_BUILD_TYPE=Debug -DOB_USE_LLD=$LLD_OPTION -DOB_USE_ASAN=$ASAN_OPTION ;; diff --git a/cmake/Env.cmake b/cmake/Env.cmake index 925ea1dd5..87c9c2128 100644 --- a/cmake/Env.cmake +++ b/cmake/Env.cmake @@ -48,6 +48,14 @@ if(ENABLE_AUTO_FDO) set(AUTO_FDO_OPT "-fprofile-sample-use=${CMAKE_SOURCE_DIR}/observer.prof") endif() +ob_define(THIN_LTO_OPT "") +ob_define(THIN_LTO_CONCURRENCY_LINK "") + +if(ENABLE_THIN_LTO) + set(THIN_LTO_OPT "-flto=thin") + set(THIN_LTO_CONCURRENCY_LINK "-Wl,--thinlto-jobs=16") +endif() + # should not use initial-exec for tls-model if building OBCDC. if(NOT OB_BUILD_CDC) @@ -82,11 +90,11 @@ if (OB_USE_CLANG) set(REORDER_LINK_OPT "-Wl,--no-rosegment,--build-id=sha1,--no-warn-symbol-ordering,--symbol-ordering-file,${HOTFUNC_PATH}") set(OB_LD_BIN "${DEVTOOLS_DIR}/bin/ld.lld") endif() - set(CMAKE_CXX_FLAGS "--gcc-toolchain=${GCC9} ${DEBUG_PREFIX} ${AUTO_FDO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8 ${CMAKE_ASAN_FLAG} ${CMAKE_COVERAGE_FLAG} -std=gnu++11") - set(CMAKE_C_FLAGS "--gcc-toolchain=${GCC9} ${DEBUG_PREFIX} ${AUTO_FDO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8 ${CMAKE_ASAN_FLAG} ${CMAKE_COVERAGE_FLAG}") - set(CMAKE_CXX_LINK_FLAGS "${LD_OPT} --gcc-toolchain=${GCC9} ${DEBUG_PREFIX} ${AUTO_FDO_OPT}") - set(CMAKE_SHARED_LINKER_FLAGS "${LD_OPT} -Wl,-z,noexecstack ${REORDER_LINK_OPT}") - set(CMAKE_EXE_LINKER_FLAGS "${LD_OPT} -Wl,-z,noexecstack ${REORDER_LINK_OPT} ${OB_EXE_LINKER_OPT}") + set(CMAKE_CXX_FLAGS "--gcc-toolchain=${GCC9} ${DEBUG_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8 ${CMAKE_ASAN_FLAG} ${CMAKE_COVERAGE_FLAG} -std=gnu++11") + set(CMAKE_C_FLAGS "--gcc-toolchain=${GCC9} ${DEBUG_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8 ${CMAKE_ASAN_FLAG} ${CMAKE_COVERAGE_FLAG}") + set(CMAKE_CXX_LINK_FLAGS "${LD_OPT} ${THIN_LTO_CONCURRENCY_LINK} --gcc-toolchain=${GCC9} ${DEBUG_PREFIX} ${AUTO_FDO_OPT}") + set(CMAKE_SHARED_LINKER_FLAGS "${LD_OPT} -Wl,-z,noexecstack ${THIN_LTO_CONCURRENCY_LINK} ${REORDER_LINK_OPT}") + set(CMAKE_EXE_LINKER_FLAGS "${LD_OPT} -Wl,-z,noexecstack ${THIN_LTO_CONCURRENCY_LINK} ${REORDER_LINK_OPT} ${OB_EXE_LINKER_OPT}") else() # not clang, use gcc message("gcc9 not support currently, please set OB_USE_CLANG ON and we will finish it as soon as possible") endif() diff --git a/deps/oblib/src/lib/CMakeLists.txt b/deps/oblib/src/lib/CMakeLists.txt index 7a4ed1735..14d85b964 100644 --- a/deps/oblib/src/lib/CMakeLists.txt +++ b/deps/oblib/src/lib/CMakeLists.txt @@ -114,6 +114,7 @@ ob_set_subtarget(oblib_lib lock lock/ob_thread_cond.cpp lock/ob_rwlock.cpp lock/ob_futex.cpp + lock/ob_bucket_qsync_lock.cpp lock/ob_qsync_lock.cpp ) diff --git a/deps/oblib/src/lib/alloc/memory_dump.cpp b/deps/oblib/src/lib/alloc/memory_dump.cpp index b06373532..250744bb5 100644 --- a/deps/oblib/src/lib/alloc/memory_dump.cpp +++ b/deps/oblib/src/lib/alloc/memory_dump.cpp @@ -162,10 +162,14 @@ void ObMemoryDump::destroy() int ObMemoryDump::push(void *task) { int ret = OB_SUCCESS; + const bool enable_dump = lib::is_trace_log_enabled(); if (!is_inited_) { ret = OB_NOT_INIT; } else if (NULL == task) { ret = OB_INVALID_ARGUMENT; + } else if (!enable_dump) { + // do nothing + free_task(task); } else { ret = queue_.push(task); if (OB_SIZE_OVERFLOW == ret) { @@ -181,7 +185,8 @@ void ObMemoryDump::run1() int ret = OB_SUCCESS; lib::set_thread_name("MemoryDump"); static int64_t last_dump_ts = ObTimeUtility::current_time(); - while (!has_set_stop()) { + const bool enable_dump = lib::is_trace_log_enabled(); + while (!has_set_stop() && enable_dump) { void *task = NULL; if (OB_SUCC(queue_.pop(task, 100 * 1000))) { handle(task); diff --git a/deps/oblib/src/lib/allocator/ob_qsync.h b/deps/oblib/src/lib/allocator/ob_qsync.h index f60e935e7..e0864fcc0 100644 --- a/deps/oblib/src/lib/allocator/ob_qsync.h +++ b/deps/oblib/src/lib/allocator/ob_qsync.h @@ -121,6 +121,7 @@ public: }; ObDynamicQSync(): is_inited_(false), ref_array_(NULL), ref_num_(0) {} virtual ~ObDynamicQSync() {destroy();} + bool is_inited() const { return is_inited_; } int init(const lib::ObMemAttr& mem_attr) { diff --git a/deps/oblib/src/lib/lock/ob_bucket_qsync_lock.cpp b/deps/oblib/src/lib/lock/ob_bucket_qsync_lock.cpp new file mode 100644 index 000000000..8783d25a5 --- /dev/null +++ b/deps/oblib/src/lib/lock/ob_bucket_qsync_lock.cpp @@ -0,0 +1,243 @@ +/** + * Copyright (c) 2022 OceanBase + * OceanBase CE is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#include "lib/lock/ob_bucket_qsync_lock.h" +#include "lib/lock/ob_qsync_lock.h" + +namespace oceanbase +{ +namespace common +{ +ObBucketQSyncLock::ObBucketQSyncLock() + : bucket_cnt_(0), + locks_(NULL), + is_inited_(false) +{ +} + +ObBucketQSyncLock::~ObBucketQSyncLock() +{ + destroy(); +} + +int ObBucketQSyncLock::init( + const uint64_t bucket_cnt, + const uint64_t tenant_id, + const lib::ObLabel &label) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + SHARE_LOG(WARN, "The ObBucketQSyncLock has been inited, ", K(ret)); + } else if (OB_UNLIKELY(0 == bucket_cnt) || OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) { + ret = OB_INVALID_ARGUMENT; + SHARE_LOG(WARN, "Invalid argument, ", K(bucket_cnt), K(label), K(tenant_id), K(ret)); + } else { + bucket_cnt_ = bucket_cnt; + ObMemAttr mem_attr(tenant_id, label); + void *buf = NULL; + if (OB_UNLIKELY(NULL == (buf = ob_malloc(bucket_cnt_ * sizeof(ObQSyncLock), mem_attr)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + SHARE_LOG(WARN, "Fail to allocate memory, ", K(bucket_cnt_), K(ret)); + } else { + locks_ = new (buf) ObQSyncLock[bucket_cnt_]; + + for (int64_t i = 0; OB_SUCC(ret) && i < bucket_cnt_; ++i) { + if (OB_FAIL(locks_[i].init(mem_attr))) { + SHARE_LOG(WARN, "Fail to init qsync lock", K(ret), K(bucket_cnt_), K(i)); + } + } + + if (OB_SUCC(ret)) { + is_inited_ = true; + } + } + } + + if (OB_UNLIKELY(!is_inited_)) { + destroy(); + } + return ret; +} + +void ObBucketQSyncLock::destroy() +{ + is_inited_ = false; + if (nullptr != locks_) { + for (uint64_t i = 0; i < bucket_cnt_; ++i) { + locks_[i].~ObQSyncLock(); + } + ob_free(locks_); + locks_ = NULL; + } + bucket_cnt_ = 0; +} + +int ObBucketQSyncLock::rdlock(const uint64_t bucket_idx) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + SHARE_LOG(WARN, "ObBucketQSyncLock not inited", K(ret)); + } else if(OB_UNLIKELY(bucket_idx >= bucket_cnt_)) { + ret = OB_INVALID_ARGUMENT; + SHARE_LOG(WARN, "Invalid argument, ", K(bucket_idx), K_(bucket_cnt), K(ret)); + } else if (OB_FAIL(locks_[bucket_idx].rdlock())) { + SHARE_LOG(WARN, "Fail to read lock latch, ", K(bucket_idx), K(ret)); + } + return ret; +} + +int ObBucketQSyncLock::wrlock(const uint64_t bucket_idx) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + SHARE_LOG(WARN, "ObBucketQSyncLock not inited", K(ret)); + } else if(OB_UNLIKELY(bucket_idx >= bucket_cnt_)) { + ret = OB_INVALID_ARGUMENT; + SHARE_LOG(WARN, "Invalid argument, ", K(bucket_idx), K_(bucket_cnt), K(ret)); + } else if (OB_FAIL(locks_[bucket_idx].wrlock())) { + SHARE_LOG(WARN, "Fail to write lock latch, ", K(bucket_idx), K(ret)); + } + return ret; +} + +int ObBucketQSyncLock::rdunlock(const uint64_t bucket_idx) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + SHARE_LOG(WARN, "ObBucketQSyncLock not inited", K(ret)); + } else if(OB_UNLIKELY(bucket_idx >= bucket_cnt_)) { + ret = OB_INVALID_ARGUMENT; + SHARE_LOG(WARN, "Invalid argument, ", K(bucket_idx), K_(bucket_cnt), K(ret)); + } else { + locks_[bucket_idx].rdunlock(); + } + return ret; +} + +int ObBucketQSyncLock::wrunlock(const uint64_t bucket_idx) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + SHARE_LOG(WARN, "ObBucketQSyncLock not inited", K(ret)); + } else if(OB_UNLIKELY(bucket_idx >= bucket_cnt_)) { + ret = OB_INVALID_ARGUMENT; + SHARE_LOG(WARN, "Invalid argument, ", K(bucket_idx), K_(bucket_cnt), K(ret)); + } else { + locks_[bucket_idx].wrunlock(); + } + return ret; +} + +int ObBucketQSyncLock::wrlock_all() +{ + int ret = OB_SUCCESS; + int64_t last_succ_idx = -1; + const int64_t start_ts = ObClockGenerator::getClock(); + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + SHARE_LOG(WARN, "ObBucketQSyncLock not inited", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < bucket_cnt_; ++i) { + if (OB_SUCC(locks_[i].wrlock())) { + last_succ_idx = i; + } else { + if(OB_EAGAIN != ret) { + SHARE_LOG(WARN, "failed to try wrlock", K(ret), K(i), K(bucket_cnt_)); + } + } + } + + if (OB_FAIL(ret)) { + for (int64_t i = 0; i <= last_succ_idx; ++i) { + locks_[i].wrunlock(); + } + } + } + + const int64_t cost_ts = ObClockGenerator::getClock() - start_ts; + SHARE_LOG(DEBUG, "wrlock all", K(bucket_cnt_), K(cost_ts), K(ret)); + return ret; +} + +int ObBucketQSyncLock::wrunlock_all() +{ + int ret = OB_SUCCESS; + const int64_t start_ts = ObClockGenerator::getClock(); + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + SHARE_LOG(WARN, "ObBucketQSyncLock not inited", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < bucket_cnt_; ++i) { + locks_[i].wrunlock(); + } + } + const int64_t cost_ts = ObClockGenerator::getClock() - start_ts; + SHARE_LOG(DEBUG, "unlock all", K(bucket_cnt_), K(cost_ts), K(ret)); + return ret; +} + +int ObBucketQSyncLock::try_rdlock_all() +{ + int ret = OB_SUCCESS; + int64_t last_succ_idx = -1; + const int64_t start_ts = ObClockGenerator::getClock(); + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + SHARE_LOG(WARN, "ObBucketQSyncLock not inited", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < bucket_cnt_; ++i) { + ret = locks_[i].try_rdlock(); + if (OB_SUCCESS == ret) { + last_succ_idx = i; + } else if (OB_EAGAIN != ret) { + SHARE_LOG(WARN, "failed to try wrlock", K(ret), K(i), K(bucket_cnt_)); + } + } + + if (OB_FAIL(ret)) { + for (int64_t i = 0; i <= last_succ_idx; ++i) { + locks_[i].rdunlock(); + } + } + } + const int64_t cost_ts = ObClockGenerator::getClock() - start_ts; + SHARE_LOG(DEBUG, "try lock all", K(bucket_cnt_), K(cost_ts), K(ret)); + return ret; +} + +int ObBucketQSyncLock::rdunlock_all() +{ + int ret = OB_SUCCESS; + const int64_t start_ts = ObClockGenerator::getClock(); + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + SHARE_LOG(WARN, "ObBucketQSyncLock not inited", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < bucket_cnt_; ++i) { + locks_[i].rdunlock(); + } + } + const int64_t cost_ts = ObClockGenerator::getClock() - start_ts; + SHARE_LOG(DEBUG, "unlock all", K(bucket_cnt_), K(cost_ts), K(ret)); + return ret; +} +} //namespace common +} //namespace oceanbae diff --git a/deps/oblib/src/lib/lock/ob_bucket_qsync_lock.h b/deps/oblib/src/lib/lock/ob_bucket_qsync_lock.h new file mode 100644 index 000000000..a05197b1e --- /dev/null +++ b/deps/oblib/src/lib/lock/ob_bucket_qsync_lock.h @@ -0,0 +1,265 @@ +/** + * Copyright (c) 2022 OceanBase + * OceanBase CE is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ +#ifndef OCEANBASE_SHARE_LOCK_OB_BUCKET_QSYNC_LOCK_H_ +#define OCEANBASE_SHARE_LOCK_OB_BUCKET_QSYNC_LOCK_H_ + +#include "common/ob_clock_generator.h" +#include "lib/alloc/alloc_struct.h" +#include "lib/oblog/ob_log_module.h" +#include "lib/utility/ob_macro_utils.h" +#include "lib/utility/ob_print_utils.h" + +namespace oceanbase +{ +namespace common +{ +class ObQSyncLock; + +class ObBucketQSyncLock +{ +public: + ObBucketQSyncLock(); + virtual ~ObBucketQSyncLock(); + int init( + const uint64_t bucket_cnt, + const uint64_t tenant_id = OB_SERVER_TENANT_ID, + const lib::ObLabel &label = ObModIds::BUCKET_LOCK); + void destroy(); + int rdlock(const uint64_t bucket_idx); + int wrlock(const uint64_t bucket_idx); + int rdunlock(const uint64_t bucket_idx); + int wrunlock(const uint64_t bucket_idx); + int wrlock_all(); + int wrunlock_all(); + int try_rdlock_all(); + int rdunlock_all(); + TO_STRING_KV(K_(bucket_cnt), K_(is_inited)); +private: + friend class ObMultiBucketQSyncLockGuard; + friend class ObBucketHashQSyncRLockGuard; + friend class ObBucketHashQSyncWLockGuard; + inline uint64_t get_bucket_idx(const uint64_t hash_value) const; + int try_lock_all(const bool is_write_lock); +private: + uint64_t bucket_cnt_; + ObQSyncLock *locks_; + bool is_inited_; +private: + DISALLOW_COPY_AND_ASSIGN(ObBucketQSyncLock); +}; + +uint64_t ObBucketQSyncLock::get_bucket_idx(const uint64_t hash_value) const +{ + uint64_t bucket_idx = 0; + if (0 != bucket_cnt_) { + bucket_idx = hash_value % bucket_cnt_; + } + return bucket_idx; +} + +class ObBucketQSyncRLockGuard final +{ +public: + [[nodiscard]] ObBucketQSyncRLockGuard(ObBucketQSyncLock &lock, const uint64_t bucket_index) + : lock_(lock), + index_(bucket_index), + lock_start_ts_(0), + ret_(OB_SUCCESS) + { + if (OB_UNLIKELY(OB_SUCCESS != (ret_ = lock_.rdlock(index_)))) { + SHARE_LOG(WARN, "Fail to read lock bucket, ", K_(index), K_(ret)); + } else { + lock_start_ts_ = ObClockGenerator::getClock();; + } + }; + ~ObBucketQSyncRLockGuard() + { + if (OB_LIKELY(OB_SUCCESS == ret_)) { + if (OB_UNLIKELY(OB_SUCCESS != (ret_ = lock_.rdunlock(index_)))) { + SHARE_LOG(WARN, "Fail to unlock bucket, ", K_(ret)); + } else { + const int64_t lock_end_ts = ObClockGenerator::getClock();; + if (lock_end_ts - lock_start_ts_ > 5 * 1000 * 1000) { + SHARE_LOG(INFO, "bucket lock handle cost too much time", + K_(lock_start_ts), + "cost_us", lock_end_ts - lock_start_ts_, + KCSTRING(lbt())); + } + } + } + }; + inline int get_ret() const { return ret_; } +private: + ObBucketQSyncLock &lock_; + const uint64_t index_; + int64_t lock_start_ts_; + int ret_; +private: + DISALLOW_COPY_AND_ASSIGN(ObBucketQSyncRLockGuard); +}; + +class ObBucketQSyncWLockGuard final +{ +public: + [[nodiscard]] ObBucketQSyncWLockGuard(ObBucketQSyncLock &lock, const uint64_t bucket_index) + : lock_(lock), + index_(bucket_index), + lock_start_ts_(0), + ret_(OB_SUCCESS) + { + if (OB_UNLIKELY(OB_SUCCESS != (ret_ = lock_.wrlock(index_)))) { + SHARE_LOG(WARN, "Fail to write lock bucket, ", K_(index), K_(ret)); + } else { + lock_start_ts_ = ObClockGenerator::getClock();; + } + }; + ~ObBucketQSyncWLockGuard() + { + if (OB_LIKELY(OB_SUCCESS == ret_)) { + if (OB_UNLIKELY(OB_SUCCESS != (ret_ = lock_.wrunlock(index_)))) { + SHARE_LOG(WARN, "Fail to unlock bucket, ", K_(index), K_(ret)); + } else { + const int64_t lock_end_ts = ObClockGenerator::getClock();; + if (lock_end_ts - lock_start_ts_ > 5 * 1000 * 1000) { + SHARE_LOG(INFO, "bucket lock handle cost too much time", + K_(lock_start_ts), + "cost_us", lock_end_ts - lock_start_ts_, + KCSTRING(lbt())); + } + } + } + }; + inline int get_ret() const { return ret_; } +private: + ObBucketQSyncLock &lock_; + const uint64_t index_; + int64_t lock_start_ts_; + int ret_; +private: + DISALLOW_COPY_AND_ASSIGN(ObBucketQSyncWLockGuard); +}; + +class ObBucketHashQSyncRLockGuard final +{ +public: + [[nodiscard]] ObBucketHashQSyncRLockGuard(ObBucketQSyncLock &lock, const uint64_t hash_value) + : guard_(lock, lock.get_bucket_idx(hash_value)) + { + } + ~ObBucketHashQSyncRLockGuard() {} + inline int get_ret() const { return guard_.get_ret(); } +private: + ObBucketQSyncRLockGuard guard_; + DISALLOW_COPY_AND_ASSIGN(ObBucketHashQSyncRLockGuard); +}; + +class ObBucketHashQSyncWLockGuard final +{ +public: + [[nodiscard]] ObBucketHashQSyncWLockGuard(ObBucketQSyncLock &lock, const uint64_t hash_value) + : guard_(lock, lock.get_bucket_idx(hash_value)) + { + } + ~ObBucketHashQSyncWLockGuard() {} + inline int get_ret() const { return guard_.get_ret(); } +private: + ObBucketQSyncWLockGuard guard_; + DISALLOW_COPY_AND_ASSIGN(ObBucketHashQSyncWLockGuard); +}; + +class ObBucketQSyncWLockAllGuard final +{ +public: + [[nodiscard]] ObBucketQSyncWLockAllGuard(ObBucketQSyncLock &lock) + : lock_(lock), + lock_start_ts_(0), + ret_(OB_SUCCESS) + { + if (OB_UNLIKELY(OB_SUCCESS != (ret_ = lock_.wrlock_all()))) { + SHARE_LOG(WARN, "Fail to try write lock all buckets", K_(ret)); + } else { + lock_start_ts_ = ObClockGenerator::getClock();; + } + }; + ~ObBucketQSyncWLockAllGuard() + { + if (OB_LIKELY(OB_SUCCESS == ret_)) { + if (OB_UNLIKELY(OB_SUCCESS != (ret_ = lock_.wrunlock_all()))) { + SHARE_LOG(WARN, "Fail to unlock all buckets, ", K_(ret)); + } else { + const int64_t lock_end_ts = ObClockGenerator::getClock();; + if (lock_end_ts - lock_start_ts_ > 5 * 1000 * 1000) { + STORAGE_LOG(INFO, "bucket lock handle cost too much time", + K_(lock_start_ts), + "cost_us", lock_end_ts - lock_start_ts_, + KCSTRING(lbt())); + } + } + } + }; + inline int get_ret() const { return ret_; } +private: + ObBucketQSyncLock &lock_; + int64_t lock_start_ts_; + int ret_; +private: + DISALLOW_COPY_AND_ASSIGN(ObBucketQSyncWLockAllGuard); +}; + +class ObBucketTryQSyncRLockAllGuard final +{ +public: + [[nodiscard]] ObBucketTryQSyncRLockAllGuard(ObBucketQSyncLock &lock) + : lock_(lock), + lock_start_ts_(0), + ret_(OB_SUCCESS) + { + if (OB_UNLIKELY(OB_SUCCESS != (ret_ = lock_.try_rdlock_all()))) { + if (OB_EAGAIN != ret_) { + SHARE_LOG(WARN, "Fail to try read lock all buckets", K_(ret), K(lbt())); + } else { + if (REACH_COUNT_INTERVAL(1000)) {// print one log per 1000 times. + SHARE_LOG(WARN, "fail to lock all buckets, need to try again", K_(ret), K(lbt())); + } + } + } else { + lock_start_ts_ = ObClockGenerator::getClock();; + } + }; + ~ObBucketTryQSyncRLockAllGuard() + { + if (OB_LIKELY(OB_SUCCESS == ret_)) { + if (OB_UNLIKELY(OB_SUCCESS != (ret_ = lock_.rdunlock_all()))) { + SHARE_LOG(WARN, "Fail to unlock all buckets, ", K_(ret)); + } else { + const int64_t lock_end_ts = ObClockGenerator::getClock();; + if (lock_end_ts - lock_start_ts_ > 5 * 1000 * 1000) { + STORAGE_LOG(INFO, "bucket lock handle cost too much time", + K_(lock_start_ts), + "cost_us", lock_end_ts - lock_start_ts_, + KCSTRING(lbt())); + } + } + } + }; + inline int get_ret() const { return ret_; } +private: + ObBucketQSyncLock &lock_; + int64_t lock_start_ts_; + int ret_; +private: + DISALLOW_COPY_AND_ASSIGN(ObBucketTryQSyncRLockAllGuard); +}; +} // namespace common +} // namespace oceanbase + +#endif /* OCEANBASE_SHARE_LOCK_OB_BUCKET_QSYNC_LOCK_H_ */ diff --git a/deps/oblib/src/lib/lock/ob_qsync_lock.cpp b/deps/oblib/src/lib/lock/ob_qsync_lock.cpp index 51d8d8fdf..a91f0a404 100644 --- a/deps/oblib/src/lib/lock/ob_qsync_lock.cpp +++ b/deps/oblib/src/lib/lock/ob_qsync_lock.cpp @@ -28,20 +28,15 @@ void ObQSyncLock::destroy() int ObQSyncLock::rdlock() { + int ret = common::OB_SUCCESS; + do { - if (OB_UNLIKELY(0 != ATOMIC_LOAD(&write_flag_))) { + if (common::OB_EAGAIN == (ret = try_rdlock())) { sched_yield(); - } else { - const int64_t idx = qsync_.acquire_ref(); - if (OB_UNLIKELY(0 != ATOMIC_LOAD(&write_flag_))) { - qsync_.release_ref(idx); - sched_yield(); - } else { - break; - } } - } while (true); - return common::OB_SUCCESS; + } while (common::OB_EAGAIN == ret); + + return ret; } void ObQSyncLock::rdunlock() @@ -70,5 +65,21 @@ void ObQSyncLock::wrunlock() ATOMIC_STORE(&write_flag_, 0); } +int ObQSyncLock::try_rdlock() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(0 != ATOMIC_LOAD(&write_flag_))) { + ret = OB_EAGAIN; + } else { + const int64_t idx = qsync_.acquire_ref(); + if (OB_UNLIKELY(0 != ATOMIC_LOAD(&write_flag_))) { + qsync_.release_ref(idx); + ret = OB_EAGAIN; + } else { + // success, do nothing + } + } + return ret; +} } } diff --git a/deps/oblib/src/lib/lock/ob_qsync_lock.h b/deps/oblib/src/lib/lock/ob_qsync_lock.h index 1380cbb67..708bfdaa0 100644 --- a/deps/oblib/src/lib/lock/ob_qsync_lock.h +++ b/deps/oblib/src/lib/lock/ob_qsync_lock.h @@ -26,11 +26,13 @@ public: ObQSyncLock() : write_flag_(0) {} ~ObQSyncLock() {} int init(const lib::ObMemAttr &mem_attr); + bool is_inited() const { return qsync_.is_inited(); } void destroy(); int rdlock(); void rdunlock(); int wrlock(); void wrunlock(); + int try_rdlock(); private: int64_t write_flag_ CACHE_ALIGNED; common::ObDynamicQSync qsync_; diff --git a/deps/oblib/src/lib/objectpool/ob_resource_pool.h b/deps/oblib/src/lib/objectpool/ob_resource_pool.h index 8708fa704..21164641a 100644 --- a/deps/oblib/src/lib/objectpool/ob_resource_pool.h +++ b/deps/oblib/src/lib/objectpool/ob_resource_pool.h @@ -21,6 +21,7 @@ #include "lib/container/ob_id_map.h" #include "lib/utility/utility.h" #include "lib/allocator/ob_fifo_allocator.h" +#include "ob_clock_generator.h" DEFINE_HAS_MEMBER(RP_MAX_FREE_LIST_NUM); @@ -154,7 +155,7 @@ public: ret = &(node->data); node->magic = ALLOC_MAGIC_NUM; } - const int64_t cur_ts = ObTimeUtility::fast_current_time(); + const int64_t cur_ts = ObClockGenerator::getClock(); if (cur_ts - last_check_ts_ > CHECK_INTERVAL && ATOMIC_BCAS(&updating_, 0, 1)) { int64_t n = 0; diff --git a/deps/oblib/src/rpc/obmysql/ob_2_0_protocol_utils.cpp b/deps/oblib/src/rpc/obmysql/ob_2_0_protocol_utils.cpp index fbe4e7c05..7781dc89a 100644 --- a/deps/oblib/src/rpc/obmysql/ob_2_0_protocol_utils.cpp +++ b/deps/oblib/src/rpc/obmysql/ob_2_0_protocol_utils.cpp @@ -310,7 +310,7 @@ int ObProto20Utils::encode_new_extra_info(char *buffer, int64_t length, int64_t ret = OB_SIZE_OVERFLOW; OB_LOG(WARN,"buffer size overflow", K(ret), K(pos), K(length)); } else { - MEMSET(buffer+pos, 0x00, length-pos); + //MEMSET(buffer+pos, 0x00, length-pos); pos += 4; for (int64_t i = 0; OB_SUCC(ret) && i < extra_info->count(); i++) { diff --git a/src/logservice/ob_log_handler.cpp b/src/logservice/ob_log_handler.cpp index bc68ca6f0..5cc940eca 100644 --- a/src/logservice/ob_log_handler.cpp +++ b/src/logservice/ob_log_handler.cpp @@ -205,14 +205,14 @@ int ObLogHandler::append(const void *buffer, PalfAppendOptions opts; opts.need_nonblock = need_nonblock; opts.need_check_proposal_id = true; - const int64_t begin_ts = common::ObTimeUtility::current_time(); + ObTimeGuard tg("ObLogHandler::append", 100000); while (true) { // generate opts opts.proposal_id = ATOMIC_LOAD(&proposal_id_); do { RLockGuard guard(lock_); CriticalGuard(ls_qs_); - cb->set_append_start_ts(ObTimeUtility::fast_current_time()); + cb->set_append_start_ts(ObClockGenerator::getClock()); if (IS_NOT_INIT) { ret = OB_NOT_INIT; } else if (is_in_stop_state_ || is_offline_) { @@ -224,7 +224,7 @@ int ObLogHandler::append(const void *buffer, CLOG_LOG(WARN, "palf_handle_ append failed", K(ret), KPC(this)); } } else { - cb->set_append_finish_ts(ObTimeUtility::fast_current_time()); + cb->set_append_finish_ts(ObClockGenerator::getClock()); cb->__set_lsn(lsn); cb->__set_scn(scn); ret = apply_status_->push_append_cb(cb); @@ -249,8 +249,7 @@ int ObLogHandler::append(const void *buffer, break; } } - const int64_t cost_ts = common::ObTimeUtility::current_time() - begin_ts; - append_cost_stat_.stat(cost_ts); + append_cost_stat_.stat(tg.get_diff()); return ret; } diff --git a/src/logservice/palf/log_define.h b/src/logservice/palf/log_define.h index 3f66fb222..64898e808 100644 --- a/src/logservice/palf/log_define.h +++ b/src/logservice/palf/log_define.h @@ -19,6 +19,7 @@ #include "lib/utility/ob_print_utils.h" // databuff_printf #include "lib/container/ob_fixed_array.h" // ObFixedArray #include "share/ob_force_print_log.h" // force_print +#include "common/ob_clock_generator.h" namespace oceanbase { @@ -258,9 +259,9 @@ struct TimeoutChecker inline bool palf_reach_time_interval(const int64_t interval, int64_t &warn_time) { bool bool_ret = false; - if ((common::ObTimeUtility::current_time() - warn_time >= interval) || + if ((ObClockGenerator::getClock() - warn_time >= interval) || common::OB_INVALID_TIMESTAMP == warn_time) { - warn_time = common::ObTimeUtility::current_time(); + warn_time = ObClockGenerator::getClock(); bool_ret = true; } return bool_ret; diff --git a/src/logservice/palf/log_sliding_window.h b/src/logservice/palf/log_sliding_window.h index 04cc0d722..def33a95e 100644 --- a/src/logservice/palf/log_sliding_window.h +++ b/src/logservice/palf/log_sliding_window.h @@ -345,7 +345,7 @@ public: static const int64_t TMP_HEADER_SER_BUF_LEN = 256; // log header序列化的临时buffer大小 static const int64_t APPEND_CNT_ARRAY_SIZE = 32; // append次数统计数组的size static const uint64_t APPEND_CNT_ARRAY_MASK = APPEND_CNT_ARRAY_SIZE - 1; - static const int64_t APPEND_CNT_LB_FOR_PERIOD_FREEZE = 130000; // 切为PERIOD_FREEZE_MODE的append count下界 + static const int64_t APPEND_CNT_LB_FOR_PERIOD_FREEZE = 140000; // 切为PERIOD_FREEZE_MODE的append count下界 private: struct LogTaskGuard { diff --git a/src/logservice/palf/palf_handle_impl.cpp b/src/logservice/palf/palf_handle_impl.cpp index 894159592..2ab01d1fe 100644 --- a/src/logservice/palf/palf_handle_impl.cpp +++ b/src/logservice/palf/palf_handle_impl.cpp @@ -359,7 +359,7 @@ int PalfHandleImpl::submit_log( SCN &scn) { int ret = OB_SUCCESS; - const int64_t curr_ts_us = common::ObTimeUtility::current_time(); + const int64_t curr_ts_us = ObClockGenerator::getClock(); if (IS_NOT_INIT) { ret = OB_NOT_INIT; PALF_LOG(WARN, "PalfHandleImpl is not inited", K(ret)); diff --git a/src/objit/src/CMakeLists.txt b/src/objit/src/CMakeLists.txt index d33b0aab6..1e4c367dc 100644 --- a/src/objit/src/CMakeLists.txt +++ b/src/objit/src/CMakeLists.txt @@ -7,7 +7,7 @@ target_include_directories(objit_base INTERFACE # GLOB all source files according to its suffix. file(GLOB_RECURSE objit_SRC "*.h" "*.cpp" "${CMAKE_CURRENT_SROUCE_DIR}/../include/*.h") -set(CMAKE_CXX_STANDARD 14) +add_definitions(-std=gnu++14) add_library(objit_objects OBJECT ${objit_SRC}) target_link_libraries(objit_objects PRIVATE oblib_base_base objit_base) diff --git a/src/observer/mysql/obmp_packet_sender.cpp b/src/observer/mysql/obmp_packet_sender.cpp index a55b98f86..49ba9b875 100644 --- a/src/observer/mysql/obmp_packet_sender.cpp +++ b/src/observer/mysql/obmp_packet_sender.cpp @@ -537,7 +537,7 @@ int ObMPPacketSender::send_ok_packet(ObSQLSessionInfo &session, ObOKPParam &ok_p if (OB_SUCC(ret)) { if (!ok_param.take_trace_id_to_client_) { - const int64_t elapsed_time = ObTimeUtility::current_time() - query_receive_ts_; + const int64_t elapsed_time = ObClockGenerator::getClock() - query_receive_ts_; bool is_slow = (elapsed_time > GCONF.trace_log_slow_query_watermark); ok_param.take_trace_id_to_client_ = is_slow; } diff --git a/src/observer/mysql/obmp_utils.cpp b/src/observer/mysql/obmp_utils.cpp index e3e4c66ff..89e49024d 100644 --- a/src/observer/mysql/obmp_utils.cpp +++ b/src/observer/mysql/obmp_utils.cpp @@ -341,7 +341,15 @@ int ObMPUtils::init_flt_info(Ob20ExtraInfo extra_info, session)); extra_info.get_full_link_trace().reset(); } - OZ(init_flt_log_framework(session, is_client_support_flt)); + + if (session.get_control_info().is_valid()){ + OZ(init_flt_log_framework(session, is_client_support_flt)); + } else { + FLT_SET_TRACE_LEVEL(0); + FLT_SET_AUTO_FLUSH(false); + session.set_auto_flush_trace(false); + session.set_trace_enable(false); + } return ret; } @@ -357,12 +365,10 @@ int ObMPUtils::append_flt_extra_info(common::ObIAllocator &allocator, int size = 0; FLTQueryInfo query_info; - omt::ObTenantConfigGuard tenant_config(TENANT_CONF(sess.get_effective_tenant_id())); - // reserver memory for control info // if sys config in control info and sys parameter has modified, resend this control info. if (sess.get_control_info().is_valid_sys_config() - && !((sess.get_control_info().print_sample_pct_ == ((double)(tenant_config->_print_sample_ppm))/1000000) + && !((sess.get_control_info().print_sample_pct_ == ((double)(sess.get_tenant_print_sample_ppm()))/1000000) && (sess.get_control_info().slow_query_thres_ == GCONF.trace_log_slow_query_watermark))) { sess.set_send_control_info(false); } @@ -394,7 +400,7 @@ int ObMPUtils::append_flt_extra_info(common::ObIAllocator &allocator, if (!con.is_valid()) { con.reset(); } - con.print_sample_pct_ = ((double)(tenant_config->_print_sample_ppm))/1000000; + con.print_sample_pct_ = ((double)(sess.get_tenant_print_sample_ppm()))/1000000; con.slow_query_thres_ = GCONF.trace_log_slow_query_watermark; sess.set_flt_control_info(con); @@ -575,8 +581,7 @@ int ObMPUtils::init_flt_log_framework(sql::ObSQLSessionInfo &sess, bool is_clien FLTControlInfo con = sess.get_control_info(); if (con.is_valid()) { // init trace enable - omt::ObTenantConfigGuard tenant_config(TENANT_CONF(sess.get_effective_tenant_id())); - con.print_sample_pct_ = ((double)(tenant_config->_print_sample_ppm))/1000000; + con.print_sample_pct_ = ((double)(sess.get_tenant_print_sample_ppm()))/1000000; ObRandom r; double rand_num = 1.0 * (r.rand(0, RAND_MAX)/RAND_MAX); if (rand_num < con.sample_pct_) { diff --git a/src/sql/das/ob_das_context.cpp b/src/sql/das/ob_das_context.cpp index c2e81b855..2c7977c11 100644 --- a/src/sql/das/ob_das_context.cpp +++ b/src/sql/das/ob_das_context.cpp @@ -77,7 +77,9 @@ int ObDASCtx::get_das_tablet_mapper(const uint64_t ref_table_id, real_table_id = share::schema::ObSchemaUtils::get_real_table_mappings_tid(ref_table_id); } const uint64_t tenant_id = MTL_ID(); - if (!is_vt) { + if (tablet_mapper.is_non_partition_optimized()) { + // table ids has calced for no partition entity table, continue + } else if (!is_vt) { if (schema_guard_ == nullptr) { void *buf = allocator_.alloc(sizeof(ObSchemaGetterGuard)); if (OB_ISNULL(buf)) { diff --git a/src/sql/das/ob_das_location_router.cpp b/src/sql/das/ob_das_location_router.cpp index c88340f6b..414a730c3 100644 --- a/src/sql/das/ob_das_location_router.cpp +++ b/src/sql/das/ob_das_location_router.cpp @@ -317,12 +317,25 @@ int ObDASTabletMapper::get_non_partition_tablet_id(ObIArray &tablet_ ObIArray &out_part_ids) { int ret = OB_SUCCESS; - ObNewRange range; - // here need whole range, for virtual table calc tablet and object id - range.set_whole_range(); - OZ(get_tablet_and_object_id(PARTITION_LEVEL_ZERO, OB_INVALID_ID, - range, tablet_ids, out_part_ids)); - + if (is_non_partition_optimized_) { + if (OB_FAIL(tablet_ids.push_back(tablet_id_))) { + LOG_WARN("failed to push back tablet ids", K(ret)); + } else if (OB_FAIL(out_part_ids.push_back(object_id_))) { + LOG_WARN("failed to push back partition ids", K(ret)); + } else { + DASRelatedTabletMap *map = static_cast(related_info_.related_map_); + if (OB_NOT_NULL(map) && OB_NOT_NULL(related_list_) + && OB_FAIL(map->get_list().assign(*related_list_))) { + LOG_WARN("failed to assign related map list", K(ret)); + } + } + } else { + ObNewRange range; + // here need whole range, for virtual table calc tablet and object id + range.set_whole_range(); + OZ(get_tablet_and_object_id(PARTITION_LEVEL_ZERO, OB_INVALID_ID, + range, tablet_ids, out_part_ids)); + } return ret; } diff --git a/src/sql/das/ob_das_location_router.h b/src/sql/das/ob_das_location_router.h index 4166be4ae..97aece716 100644 --- a/src/sql/das/ob_das_location_router.h +++ b/src/sql/das/ob_das_location_router.h @@ -68,6 +68,7 @@ private: class DASRelatedTabletMap : public share::schema::IRelatedTabletMap { friend class ObDASCtx; +public: struct MapEntry { OB_UNIS_VERSION(1); @@ -99,6 +100,7 @@ public: common::ObTableID related_table_id, Value &val); void clear() { list_.clear(); } + RelatedTabletList &get_list() { return list_; } TO_STRING_KV(K_(list)); private: //There are usually not many tablets for a query. @@ -111,11 +113,16 @@ private: class ObDASTabletMapper { friend class ObDASCtx; + typedef common::ObList RelatedTabletList; public: ObDASTabletMapper() : table_schema_(nullptr), vt_svr_pair_(nullptr), - related_info_() + related_info_(), + is_non_partition_optimized_(false), + tablet_id_(ObTabletID::INVALID_TABLET_ID), + object_id_(OB_INVALID_ID), + related_list_(nullptr) { } @@ -193,6 +200,16 @@ public: const common::ObTableID &dst_table_id, common::ObObjectID &dst_object_id); share::schema::RelatedTableInfo &get_related_table_info() { return related_info_; } + bool is_non_partition_optimized() const { return is_non_partition_optimized_; } + void set_non_partitioned_table_ids(const common::ObTabletID &tablet_id, + const common::ObObjectID &object_id, + const RelatedTabletList *related_list) + { + tablet_id_ = tablet_id; + object_id_ = object_id; + related_list_ = related_list; + is_non_partition_optimized_ = true; + } private: int mock_vtable_related_tablet_id_map(const common::ObIArray &tablet_ids, const common::ObIArray &out_part_ids); @@ -202,6 +219,10 @@ private: const share::schema::ObTableSchema *table_schema_; const VirtualSvrPair *vt_svr_pair_; share::schema::RelatedTableInfo related_info_; + bool is_non_partition_optimized_; + ObTabletID tablet_id_; + ObObjectID object_id_; + const RelatedTabletList *related_list_; }; class ObDASLocationRouter diff --git a/src/sql/ob_sql.cpp b/src/sql/ob_sql.cpp index 065b53344..d1d385a2d 100644 --- a/src/sql/ob_sql.cpp +++ b/src/sql/ob_sql.cpp @@ -2774,6 +2774,18 @@ int ObSql::code_generate( } // for end } } + if (OB_SUCC(ret)) { + for (int64_t i = 0; OB_SUCC(ret) && i < tbl_part_infos.count(); i++) { + ObTableLocation &tl = tbl_part_infos.at(i)->get_table_location(); + if (tl.is_partitioned() || is_virtual_table(tl.get_loc_meta().ref_table_id_)) { + continue; + } else if (OB_FAIL(tl.calc_not_partitioned_table_ids(result.get_exec_context()))) { + LOG_WARN("failed to calc not partitioned table ids", K(ret)); + } else { + tl.set_is_non_partition_optimized(true); + } + } + } // set table location for phy_plan if (OB_SUCC(ret)) { if (OB_FAIL(phy_plan->set_table_locations(tbl_part_infos, *sql_ctx.schema_guard_))) { diff --git a/src/sql/optimizer/ob_phy_table_location_info.h b/src/sql/optimizer/ob_phy_table_location_info.h index 81a031f46..d67a83e34 100644 --- a/src/sql/optimizer/ob_phy_table_location_info.h +++ b/src/sql/optimizer/ob_phy_table_location_info.h @@ -80,7 +80,7 @@ class ObCandiTabletLoc { public: ObCandiTabletLoc(); - virtual ~ObCandiTabletLoc(); + ~ObCandiTabletLoc(); void reset(); int assign(const ObCandiTabletLoc &other); diff --git a/src/sql/optimizer/ob_table_location.cpp b/src/sql/optimizer/ob_table_location.cpp index 5a79618c3..4b2e2d278 100644 --- a/src/sql/optimizer/ob_table_location.cpp +++ b/src/sql/optimizer/ob_table_location.cpp @@ -678,7 +678,8 @@ ObTableLocation::ObTableLocation(const ObTableLocation &other) : gen_col_node_(NULL), subcalc_node_(NULL), sub_gen_col_node_(NULL), - part_projector_(allocator_) + part_projector_(allocator_), + related_list_(allocator_) { *this = other; } @@ -718,6 +719,9 @@ int ObTableLocation::assign(const ObTableLocation &other) is_link_ = other.is_link_; is_part_range_get_ = other.is_part_range_get_; is_subpart_range_get_ = other.is_subpart_range_get_; + is_non_partition_optimized_ = other.is_non_partition_optimized_; + tablet_id_ = other.tablet_id_; + object_id_ = other.object_id_; if (OB_FAIL(loc_meta_.assign(other.loc_meta_))) { LOG_WARN("assign loc meta failed", K(ret), K(other.loc_meta_)); } @@ -786,6 +790,9 @@ int ObTableLocation::assign(const ObTableLocation &other) if (OB_SUCC(ret) && OB_NOT_NULL(other.se_sub_gen_col_expr_)) { OZ(other.se_sub_gen_col_expr_->deep_copy(allocator_, se_sub_gen_col_expr_)); } + if (OB_SUCC(ret) && OB_FAIL(related_list_.assign(other.related_list_))) { + LOG_WARN("assign related list failed", K(ret)); + } } if (OB_FAIL(ret)) { inited_ = false; @@ -837,6 +844,10 @@ void ObTableLocation::reset() is_link_ = false; is_part_range_get_ = false; is_subpart_range_get_ = false; + is_non_partition_optimized_ = false; + tablet_id_.reset(); + object_id_ = OB_INVALID_ID; + related_list_.reset(); } int ObTableLocation::init(share::schema::ObSchemaGetterGuard &schema_guard, const ObDMLStmt &stmt, @@ -1163,6 +1174,32 @@ int ObTableLocation::init_table_location_with_column_ids(ObSqlSchemaGuard &schem return ret; } +int ObTableLocation::calc_not_partitioned_table_ids(ObExecContext &exec_ctx) +{ + int ret = OB_SUCCESS; + ObSEArray tablet_ids; + ObSEArray partition_ids; + ObDASTabletMapper tablet_mapper; + if (OB_FAIL(exec_ctx.get_das_ctx().get_das_tablet_mapper( + loc_meta_.ref_table_id_, tablet_mapper, &loc_meta_.related_table_ids_))) { + LOG_WARN("fail to get das tablet mapper", K(ret)); + } else if (OB_FAIL(tablet_mapper.get_non_partition_tablet_id(tablet_ids, partition_ids))) { + LOG_WARN("fail to get non partition tablet id", K(ret)); + } else if (!(1 == tablet_ids.count() && 1 == partition_ids.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get tablet ids or partition ids size more than 1", K(ret)); + } else { + tablet_id_ = tablet_ids.at(0); + object_id_ = partition_ids.at(0); + DASRelatedTabletMap *related_map = static_cast( + tablet_mapper.get_related_table_info().related_map_); + if (OB_NOT_NULL(related_map)) { + related_list_.assign(related_map->get_list()); + } + } + return ret; +} + int ObTableLocation::init( const ObTableSchema *table_schema, const ObDMLStmt &stmt, @@ -1339,8 +1376,11 @@ int ObTableLocation::calculate_partition_ids_by_rowkey(ObSQLSessionInfo &session sql_schema_guard.set_schema_guard(&schema_guard); exec_ctx.set_my_session(&session_info); ObDASTabletMapper tablet_mapper; - if (OB_FAIL(exec_ctx.get_das_ctx().get_das_tablet_mapper(table_id, tablet_mapper, - &loc_meta_.related_table_ids_))) { + if (is_non_partition_optimized_ && table_id == loc_meta_.ref_table_id_) { + tablet_mapper.set_non_partitioned_table_ids(tablet_id_, object_id_, &related_list_); + } + if (OB_FAIL(exec_ctx.get_das_ctx().get_das_tablet_mapper( + table_id, tablet_mapper, &loc_meta_.related_table_ids_))) { LOG_WARN("fail to get das tablet mapper", K(ret)); } else if (OB_UNLIKELY(is_virtual_table(table_id))) { ret = OB_NOT_SUPPORTED; @@ -1388,6 +1428,9 @@ int ObTableLocation::calculate_tablet_id_by_row(ObExecContext &exec_ctx, { int ret = OB_SUCCESS; ObDASTabletMapper tablet_mapper; + if (is_non_partition_optimized_ && table_id == loc_meta_.ref_table_id_) { + tablet_mapper.set_non_partitioned_table_ids(tablet_id_, object_id_, &related_list_); + } if (OB_FAIL(exec_ctx.get_das_ctx().get_das_tablet_mapper(table_id, tablet_mapper, &loc_meta_.related_table_ids_))) { LOG_WARN("fail to get das tablet mapper", K(ret)); @@ -1439,6 +1482,9 @@ int ObTableLocation::calculate_tablet_ids(ObExecContext &exec_ctx, // skip dblink table tablet_ids.push_back(ObTabletID(0)); partition_ids.push_back(0); + } else if (is_non_partition_optimized_ + && FALSE_IT(tablet_mapper.set_non_partitioned_table_ids( + tablet_id_, object_id_, &related_list_))) { } else if (OB_FAIL(exec_ctx.get_das_ctx().get_das_tablet_mapper( loc_meta_.ref_table_id_, tablet_mapper, &loc_meta_.related_table_ids_))) { LOG_WARN("fail to get das tablet mapper", K(ret)); @@ -4031,6 +4077,9 @@ int ObTableLocation::replace_ref_table_id(const uint64_t ref_table_id, ObExecCon LOG_DEBUG("set log op infos", K(ref_table_id), K(loc_meta_)); //replace the partition hint ids with local index object id ObDASTabletMapper tablet_mapper; + if (is_non_partition_optimized_) { + tablet_mapper.set_non_partitioned_table_ids(tablet_id_, object_id_, &related_list_); + } if (OB_FAIL(DAS_CTX(exec_ctx).get_das_tablet_mapper(loc_meta_.ref_table_id_, tablet_mapper))) { LOG_WARN("get das tablet mapper failed", K(ret)); } @@ -4505,6 +4554,10 @@ OB_DEF_SERIALIZE(ObTableLocation) is_part_range_get_, is_subpart_range_get_); } + OB_UNIS_ENCODE(is_non_partition_optimized_); + OB_UNIS_ENCODE(tablet_id_); + OB_UNIS_ENCODE(object_id_); + OB_UNIS_ENCODE(related_list_); return ret; } @@ -4577,6 +4630,10 @@ OB_DEF_SERIALIZE_SIZE(ObTableLocation) LST_DO_CODE(OB_UNIS_ADD_LEN, is_part_range_get_, is_subpart_range_get_); + OB_UNIS_ADD_LEN(is_non_partition_optimized_); + OB_UNIS_ADD_LEN(tablet_id_); + OB_UNIS_ADD_LEN(object_id_); + OB_UNIS_ADD_LEN(related_list_); return len; } @@ -4727,6 +4784,10 @@ OB_DEF_DESERIALIZE(ObTableLocation) is_part_range_get_, is_subpart_range_get_); } + OB_UNIS_DECODE(is_non_partition_optimized_); + OB_UNIS_DECODE(tablet_id_); + OB_UNIS_DECODE(object_id_); + OB_UNIS_DECODE(related_list_); return ret; } @@ -4749,6 +4810,9 @@ int ObTableLocation::get_partition_ids_by_range(ObExecContext &exec_ctx, if (OB_UNLIKELY(!inited_)) { ret = OB_NOT_INIT; LOG_WARN("ObTableLocation not inited", K(ret)); + } else if (is_non_partition_optimized_ + && FALSE_IT(tablet_mapper.set_non_partitioned_table_ids( + tablet_id_, object_id_, &related_list_))) { } else if (OB_FAIL(exec_ctx.get_das_ctx().get_das_tablet_mapper( loc_meta_.ref_table_id_, tablet_mapper, &loc_meta_.related_table_ids_))) { LOG_WARN("fail to get das tablet mapper", K(ret)); diff --git a/src/sql/optimizer/ob_table_location.h b/src/sql/optimizer/ob_table_location.h index 87c0fe340..8432afe63 100644 --- a/src/sql/optimizer/ob_table_location.h +++ b/src/sql/optimizer/ob_table_location.h @@ -25,6 +25,7 @@ #include "sql/engine/px/ob_granule_util.h" #include "sql/resolver/dml/ob_dml_stmt.h" #include "lib/hash/ob_pointer_hashmap.h" +#include "sql/das/ob_das_location_router.h" //#include "sql/resolver/ddl/ob_alter_table_stmt.h" namespace oceanbase @@ -41,6 +42,7 @@ class ObColumnRefRawExpr; class ObExprEqualCheckContext; class ObDASTabletMapper; class ObDASCtx; +class DASRelatedTabletMap; typedef common::ObSEArray RowkeyArray; class ObPartIdRowMapManager { @@ -491,7 +493,11 @@ public: is_valid_temporal_subpart_range_(false), is_link_(false), is_part_range_get_(false), - is_subpart_range_get_(false) + is_subpart_range_get_(false), + is_non_partition_optimized_(false), + tablet_id_(ObTabletID::INVALID_TABLET_ID), + object_id_(OB_INVALID_ID), + related_list_(allocator_) { } @@ -535,7 +541,11 @@ public: is_valid_temporal_subpart_range_(false), is_link_(false), is_part_range_get_(false), - is_subpart_range_get_(false) + is_subpart_range_get_(false), + is_non_partition_optimized_(false), + tablet_id_(ObTabletID::INVALID_TABLET_ID), + object_id_(OB_INVALID_ID), + related_list_(allocator_) { } virtual ~ObTableLocation() { reset(); } @@ -665,6 +675,12 @@ public: bool is_partitioned() const { return is_partitioned_; } + void set_is_non_partition_optimized(bool is_non_partition_optimized) { + is_non_partition_optimized_ = is_non_partition_optimized; + } + + bool is_non_partition_optimized() const { return is_non_partition_optimized_; } + share::schema::ObPartitionLevel get_part_level() const { return part_level_; } const stmt::StmtType &get_stmt_type() const { return stmt_type_; } @@ -742,6 +758,8 @@ public: const bool is_dml_table = true, bool is_link = false); + int calc_not_partitioned_table_ids(ObExecContext &exec_ctx); + TO_STRING_KV(K_(loc_meta), K_(part_projector), K_(has_dynamic_exec_param), @@ -1131,6 +1149,11 @@ private: bool is_link_; //used to identify whether the table is a link_table bool is_part_range_get_; bool is_subpart_range_get_; + + bool is_non_partition_optimized_; + ObTabletID tablet_id_; + ObObjectID object_id_; + common::ObList related_list_; }; } diff --git a/src/sql/session/ob_sql_session_info.cpp b/src/sql/session/ob_sql_session_info.cpp index 52dce6161..4a3d3b598 100644 --- a/src/sql/session/ob_sql_session_info.cpp +++ b/src/sql/session/ob_sql_session_info.cpp @@ -2331,6 +2331,8 @@ void ObSQLSessionInfo::ObCachedTenantConfigInfo::refresh() } // 6. enable extended SQL syntax in the MySQL mode enable_sql_extension_ = tenant_config->enable_sql_extension; + // 7. print_sample_ppm_ for flt + ATOMIC_STORE(&print_sample_ppm_, tenant_config->_print_sample_ppm); } //timezone的更新频率非常低,放到后台驱动 (void)session_->update_timezone_info(); diff --git a/src/sql/session/ob_sql_session_info.h b/src/sql/session/ob_sql_session_info.h index 9efda5e15..936f9f77b 100644 --- a/src/sql/session/ob_sql_session_info.h +++ b/src/sql/session/ob_sql_session_info.h @@ -466,6 +466,7 @@ public: enable_bloom_filter_(true), at_type_(ObAuditTrailType::NONE), sort_area_size_(128*1024*1024), + print_sample_ppm_(0), last_check_ec_ts_(0), session_(session) { @@ -478,6 +479,7 @@ public: bool get_enable_sql_extension() const { return enable_sql_extension_; } ObAuditTrailType get_at_type() const { return at_type_; } int64_t get_sort_area_size() const { return ATOMIC_LOAD(&sort_area_size_); } + int64_t get_print_sample_ppm() const { return ATOMIC_LOAD(&print_sample_ppm_); } private: //租户级别配置项缓存session 上,避免每次获取都需要刷新 bool is_external_consistent_; @@ -487,6 +489,8 @@ public: bool enable_bloom_filter_; ObAuditTrailType at_type_; int64_t sort_area_size_; + // for record sys config print_sample_ppm + int64_t print_sample_ppm_; int64_t last_check_ec_ts_; ObSQLSessionInfo *session_; }; @@ -919,6 +923,11 @@ public: cached_tenant_config_info_.refresh(); return cached_tenant_config_info_.get_sort_area_size(); } + int64_t get_tenant_print_sample_ppm() + { + cached_tenant_config_info_.refresh(); + return cached_tenant_config_info_.get_print_sample_ppm(); + } int get_tmp_table_size(uint64_t &size); int ps_use_stream_result_set(bool &use_stream); void set_proxy_version(uint64_t v) { proxy_version_ = v; } diff --git a/src/storage/blocksstable/ob_tmp_file.cpp b/src/storage/blocksstable/ob_tmp_file.cpp index 4147dcfc9..1467c55f8 100644 --- a/src/storage/blocksstable/ob_tmp_file.cpp +++ b/src/storage/blocksstable/ob_tmp_file.cpp @@ -1114,7 +1114,8 @@ int ObTmpFileManager::init() if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; STORAGE_LOG(WARN, "ObTmpFileManager has not been inited", K(ret)); - } else if (OB_FAIL(files_.init(DEFAULT_BUCKET_NUM, ObModIds::OB_TMP_FILE_MANAGER, + } else if (OB_FAIL(files_.init(DEFAULT_BUCKET_NUM, OB_SERVER_TENANT_ID, + ObModIds::OB_TMP_FILE_MANAGER, TOTAL_LIMIT, HOLD_LIMIT, BLOCK_SIZE))) { STORAGE_LOG(WARN, "fail to init map for temporary files", K(ret)); } else if (OB_FAIL(OB_TMP_FILE_STORE.init())) { diff --git a/src/storage/ls/ob_ls_tablet_service.cpp b/src/storage/ls/ob_ls_tablet_service.cpp index 5f67f718e..001fc6577 100644 --- a/src/storage/ls/ob_ls_tablet_service.cpp +++ b/src/storage/ls/ob_ls_tablet_service.cpp @@ -1556,7 +1556,7 @@ int ObLSTabletService::get_tablet_with_timeout( ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(tablet_id), K(get_timeout_us)); } else if (OB_FAIL(ObTabletCreateDeleteHelper::check_and_get_tablet(key, handle, get_timeout_us))) { - while (OB_ALLOCATE_MEMORY_FAILED == ret && ObTimeUtility::current_time() < retry_timeout_us) { + while (OB_ALLOCATE_MEMORY_FAILED == ret && ObClockGenerator::getClock() < retry_timeout_us) { ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, handle, get_timeout_us); } if (OB_ALLOCATE_MEMORY_FAILED == ret) { @@ -2421,7 +2421,7 @@ int ObLSTabletService::update_rows( LOG_DEBUG("get_dml_update_row", KP(row_iter), K(old_tbl_row), K(new_tbl_row)); bool duplicate = false; ++got_row_count; - cur_time = ObTimeUtility::current_time(); + cur_time = ObClockGenerator::getClock(); if ((0 == (0x1FF & got_row_count)) && (cur_time > dml_param.timeout_)) { //checking timeout cost too much, so check every 512 rows ret = OB_TIMEOUT; @@ -2556,7 +2556,7 @@ int ObLSTabletService::put_rows( int64_t cur_time = 0; while (OB_SUCC(ret) && OB_SUCC(row_iter->get_next_row(row))) { - cur_time = ObTimeUtility::current_time(); + cur_time = ObClockGenerator::getClock(); tbl_row.row_val_ = *row; if (cur_time > dml_param.timeout_) { ret = OB_TIMEOUT; @@ -2622,7 +2622,7 @@ int ObLSTabletService::delete_rows( // delete table rows int64_t cur_time = 0; while (OB_SUCC(ret) && OB_SUCC(row_iter->get_next_row(row))) { - cur_time = ObTimeUtility::current_time(); + cur_time = ObClockGenerator::getClock(); if (cur_time > run_ctx.dml_param_.timeout_) { ret = OB_TIMEOUT; LOG_WARN("query timeout", K(cur_time), K(run_ctx.dml_param_), K(ret)); @@ -2705,7 +2705,7 @@ int ObLSTabletService::lock_rows( bool is_exists = true; if (ObTimeUtility::current_time() > dml_param.timeout_) { ret = OB_TIMEOUT; - int64_t cur_time = ObTimeUtility::current_time(); + int64_t cur_time = ObClockGenerator::getClock(); LOG_WARN("query timeout", K(cur_time), K(dml_param), K(ret)); } else if (GCONF.enable_defensive_check() && OB_FAIL(check_old_row_legitimacy(tablet_handle, run_ctx, *row))) { @@ -2773,7 +2773,7 @@ int ObLSTabletService::lock_row( ObTablet::get_lock_wait_timeout(abs_lock_timeout, dml_param.timeout_); if (ObTimeUtility::current_time() > dml_param.timeout_) { ret = OB_TIMEOUT; - int64_t cur_time = ObTimeUtility::current_time(); + int64_t cur_time = ObClockGenerator::getClock(); LOG_WARN("query timeout", K(cur_time), K(dml_param), K(ret)); } else if (OB_FAIL(tablet_handle.get_obj()->lock_row(run_ctx.relative_table_, ctx, row))) { if (OB_TRY_LOCK_ROW_CONFLICT != ret) { @@ -3201,6 +3201,14 @@ int ObLSTabletService::need_check_old_row_legitimacy(ObDMLRunningCtx &run_ctx, //batch stmt execution dependency defensive check to check //if the same row was modified multiple times need_check = true; + ret = E(EventTable::EN_INS_MULTI_VALUES_BATCH_OPT) OB_SUCCESS; + // no need to check old row, just for bmsql performance optimization + // TODO yuchen.ywc https://aone.alibaba-inc.com/project/81079/task/45910845 + if (OB_SUCCESS != ret) { + LOG_INFO("error sim when current statement is batch update", K(ret), K(is_udf)); + need_check = false; + ret = OB_SUCCESS; + } } else if (GCONF.enable_defensive_check()) { need_check = true; if (data_table.is_index_table() && !data_table.can_read_index()) { @@ -3375,9 +3383,9 @@ int ObLSTabletService::insert_rows_to_tablet( const ObDMLBaseParam &dml_param = run_ctx.dml_param_; ObRelativeTable &data_table = run_ctx.relative_table_; if (OB_FAIL(ret)) { - } else if (ObTimeUtility::current_time() > dml_param.timeout_) { + } else if (ObClockGenerator::getClock() > dml_param.timeout_) { ret = OB_TIMEOUT; - int64_t cur_time = ObTimeUtility::current_time(); + int64_t cur_time = ObClockGenerator::getClock(); LOG_WARN("query timeout", K(cur_time), K(dml_param), K(ret)); } else if (OB_FAIL(construct_table_rows(rows, tbl_rows, row_count))) { LOG_WARN("fail to construct table rows", K(ret)); diff --git a/src/storage/memtable/ob_memtable.cpp b/src/storage/memtable/ob_memtable.cpp index 1eea602ef..f5926149e 100644 --- a/src/storage/memtable/ob_memtable.cpp +++ b/src/storage/memtable/ob_memtable.cpp @@ -652,7 +652,7 @@ int ObMemtable::exist( ObQueryFlag query_flag; query_flag.read_latest_ = true; query_flag.prewarm_ = false; - get_begin(ctx.mvcc_acc_ctx_); + //get_begin(ctx.mvcc_acc_ctx_); if (IS_NOT_INIT) { ret = OB_NOT_INIT; TRANS_LOG(WARN, "not init", K(*this), K(ret)); @@ -693,7 +693,7 @@ int ObMemtable::exist( TRANS_LOG(DEBUG, "Check memtable exist rowkey, ", K(table_id), K(rowkey), K(is_exist), K(has_found)); } - get_end(ctx.mvcc_acc_ctx_, ret); + //get_end(ctx.mvcc_acc_ctx_, ret); return ret; } @@ -2276,7 +2276,7 @@ int ObMemtable::set_(ObStoreCtx &ctx, ObMemtableKey mtk; auto *mem_ctx = ctx.mvcc_acc_ctx_.get_mem_ctx(); - set_begin(ctx.mvcc_acc_ctx_); + //set_begin(ctx.mvcc_acc_ctx_); if (OB_FAIL(tmp_key.assign(new_row.row_val_.cells_, read_info.get_schema_rowkey_count()))) { @@ -2361,7 +2361,7 @@ int ObMemtable::set_(ObStoreCtx &ctx, "store_ctx", ctx); } - set_end(ctx.mvcc_acc_ctx_, ret); + //set_end(ctx.mvcc_acc_ctx_, ret); if (OB_SUCC(ret)) { set_max_schema_version(ctx.table_version_); } diff --git a/src/storage/memtable/ob_memtable_context.cpp b/src/storage/memtable/ob_memtable_context.cpp index 34e943a7a..20d12467a 100644 --- a/src/storage/memtable/ob_memtable_context.cpp +++ b/src/storage/memtable/ob_memtable_context.cpp @@ -649,11 +649,14 @@ int ObMemtableCtx::fill_redo_log(char *buf, } } } - if (OB_SUCCESS != ret && OB_EAGAIN != ret && OB_ENTRY_NOT_EXIST != ret - && OB_ERR_TOO_BIG_ROWSIZE != ret) { + if (OB_SUCCESS != ret && OB_EAGAIN != ret && OB_ENTRY_NOT_EXIST != ret) { TRANS_LOG(WARN, "fill_redo_log fail", "ret", ret, "trans_id", - NULL == ctx_ ? "" : S(ctx_->get_trans_id()), "buf", buf, "buf_len", buf_len, "buf_pos", - buf_pos); + NULL == ctx_ ? "" : S(ctx_->get_trans_id()), + "buf", buf, + "buf_len", buf_len, + "buf_pos", buf_pos, + "pending_log_size", trans_mgr_.get_pending_log_size(), + K(*this)); } return ret; diff --git a/src/storage/memtable/ob_redo_log_generator.cpp b/src/storage/memtable/ob_redo_log_generator.cpp index 8e3c5dca4..ff3d75832 100644 --- a/src/storage/memtable/ob_redo_log_generator.cpp +++ b/src/storage/memtable/ob_redo_log_generator.cpp @@ -94,10 +94,11 @@ int ObRedoLogGenerator::fill_redo_log(char *buf, } else if (iter->is_logging_blocked()) { ret = (data_node_count == 0) ? OB_BLOCK_FROZEN : OB_EAGAIN; } else { + bool fake_fill = false; if (MutatorType::MUTATOR_ROW == iter->get_mutator_type()) { - ret = fill_row_redo(cursor, mmw, redo, log_for_lock_node); + ret = fill_row_redo(cursor, mmw, redo, log_for_lock_node, fake_fill); } else if (MutatorType::MUTATOR_TABLE_LOCK == iter->get_mutator_type()) { - ret = fill_table_lock_redo(cursor, mmw, table_lock_redo, log_for_lock_node); + ret = fill_table_lock_redo(cursor, mmw, table_lock_redo, log_for_lock_node, fake_fill); } else { ret = OB_ERR_UNEXPECTED; TRANS_LOG(ERROR, "mutator row type not expected.", K(ret)); @@ -126,7 +127,9 @@ int ObRedoLogGenerator::fill_redo_log(char *buf, } callbacks.end_ = cursor; - data_node_count++; + if (!fake_fill) { + data_node_count++; + } data_size += iter->get_data_size(); max_seq_no = max(max_seq_no, iter->get_seq_no()); } @@ -271,12 +274,12 @@ void ObRedoLogGenerator::sync_log_fail(const ObCallbackScope &callbacks) int ObRedoLogGenerator::fill_row_redo(ObITransCallbackIterator &cursor, ObMutatorWriter &mmw, RedoDataNode &redo, - const bool log_for_lock_node) + const bool log_for_lock_node, + bool &fake_fill) { int ret = OB_SUCCESS; ObMvccRowCallback *riter = (ObMvccRowCallback *)*cursor; - bool fake_fill = false; if (blocksstable::ObDmlFlag::DF_LOCK == riter->get_dml_flag()) { if (!log_for_lock_node) { @@ -314,16 +317,17 @@ int ObRedoLogGenerator::fill_row_redo(ObITransCallbackIterator &cursor, int ObRedoLogGenerator::fill_table_lock_redo(ObITransCallbackIterator &cursor, ObMutatorWriter &mmw, TableLockRedoDataNode &redo, - const bool log_for_lock_node) + const bool log_for_lock_node, + bool &fake_fill) { int ret = OB_SUCCESS; ObOBJLockCallback *titer = (ObOBJLockCallback *)*cursor; if (!log_for_lock_node && !titer->must_log()) { - // do nothing + fake_fill = true; } else if (OB_FAIL(titer->get_redo(redo))) { TRANS_LOG(ERROR, "get_redo failed.", K(ret)); - } else if (OB_FAIL(mmw.append_table_lock_kv(mem_ctx_->get_max_table_version(), + } else if (OB_FAIL(mmw.append_table_lock_kv(mem_ctx_->get_max_table_version(), redo))) { if (OB_BUF_NOT_ENOUGH != ret) { TRANS_LOG(WARN, "fill table lock redo fail", K(ret)); diff --git a/src/storage/memtable/ob_redo_log_generator.h b/src/storage/memtable/ob_redo_log_generator.h index 77e59db95..de96561f3 100644 --- a/src/storage/memtable/ob_redo_log_generator.h +++ b/src/storage/memtable/ob_redo_log_generator.h @@ -85,11 +85,13 @@ private: int fill_row_redo(ObITransCallbackIterator &cursor, ObMutatorWriter &mmw, RedoDataNode &redo, - const bool log_for_lock_node); + const bool log_for_lock_node, + bool &fake_fill); int fill_table_lock_redo(ObITransCallbackIterator &cursor, ObMutatorWriter &mmw, TableLockRedoDataNode &redo, - const bool log_for_lock_node); + const bool log_for_lock_node, + bool &fake_fill); bool check_dup_tablet_(const ObITransCallback * callback_ptr) const; private: DISALLOW_COPY_AND_ASSIGN(ObRedoLogGenerator); diff --git a/src/storage/meta_mem/ob_meta_pointer_map.h b/src/storage/meta_mem/ob_meta_pointer_map.h index a2e516202..ed7024157 100644 --- a/src/storage/meta_mem/ob_meta_pointer_map.h +++ b/src/storage/meta_mem/ob_meta_pointer_map.h @@ -239,18 +239,18 @@ int ObMetaPointerMap::erase(const Key &key) ret = common::OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "invalid argument", K(ret), K(key)); } else { - common::ObBucketHashWLockGuard lock_guard(ResourceMap::bucket_lock_, ResourceMap::hash_func_(key)); - if (OB_FAIL(ResourceMap::map_.get_refactored(key, ptr))) { - STORAGE_LOG(WARN, "fail to get from map", K(ret)); - } else if (OB_FAIL(ResourceMap::map_.erase_refactored(key))) { - STORAGE_LOG(WARN, "fail to erase from map", K(ret)); - } else { - ObMetaPointer *value = ptr->get_value_ptr(); - value->reset_obj(); - if (OB_FAIL(ResourceMap::dec_handle_ref(ptr))) { - STORAGE_LOG(WARN, "fail to dec handle ref", K(ret)); - } - } + common::ObBucketHashWLockGuard lock_guard(ResourceMap::bucket_lock_, ResourceMap::hash_func_(key)); + if (OB_FAIL(ResourceMap::map_.get_refactored(key, ptr))) { + STORAGE_LOG(WARN, "fail to get from map", K(ret)); + } else if (OB_FAIL(ResourceMap::map_.erase_refactored(key))) { + STORAGE_LOG(WARN, "fail to erase from map", K(ret)); + } else { + ObMetaPointer *value = ptr->get_value_ptr(); + value->reset_obj(); + if (OB_FAIL(ResourceMap::dec_handle_ref(ptr))) { + STORAGE_LOG(WARN, "fail to dec handle ref", K(ret)); + } + } } return ret; } diff --git a/src/storage/meta_mem/ob_tablet_pointer.cpp b/src/storage/meta_mem/ob_tablet_pointer.cpp index d63cbeb43..5c74ffe0f 100644 --- a/src/storage/meta_mem/ob_tablet_pointer.cpp +++ b/src/storage/meta_mem/ob_tablet_pointer.cpp @@ -38,6 +38,7 @@ ObTabletPointer::ObTabletPointer() memtable_mgr_handle_(), ddl_info_(), tx_data_(), + redefined_schema_version_(OB_INVALID_VERSION), cond_(), msd_lock_(), ddl_kv_mgr_lock_() @@ -52,6 +53,7 @@ ObTabletPointer::ObTabletPointer( memtable_mgr_handle_(memtable_mgr_handle), ddl_info_(), tx_data_(), + redefined_schema_version_(OB_INVALID_VERSION), cond_(), msd_lock_(ObLatchIds::TABLET_MULTI_SOURCE_DATA_LOCK), ddl_kv_mgr_lock_() @@ -73,6 +75,7 @@ void ObTabletPointer::reset() memtable_mgr_handle_.reset(); ddl_info_.reset(); tx_data_.reset(); + redefined_schema_version_ = OB_INVALID_VERSION; cond_.destroy(); ObMetaPointer::reset(); @@ -182,6 +185,7 @@ int ObTabletPointer::deep_copy(char *buf, const int64_t buf_len, ObMetaPointermemtable_mgr_handle_ = memtable_mgr_handle_; pvalue->ddl_info_ = ddl_info_; pvalue->tx_data_ = tx_data_; + pvalue->redefined_schema_version_ = redefined_schema_version_; value = pvalue; // NOTICE: cond and rw lock cannot be copied } else { @@ -207,6 +211,22 @@ int ObTabletPointer::get_tx_data(ObTabletTxMultiSourceDataUnit &tx_data) const return ret; } +int ObTabletPointer::set_redefined_schema_version(const int64_t schema_version) +{ + int ret = OB_SUCCESS; + TCWLockGuard guard(msd_lock_); + redefined_schema_version_ = schema_version; + return ret; +} + +int ObTabletPointer::get_redefined_schema_version(int64_t &schema_version) const +{ + int ret = OB_SUCCESS; + TCRLockGuard guard(msd_lock_); + schema_version = redefined_schema_version_; + return ret; +} + int ObTabletPointer::create_ddl_kv_mgr(const share::ObLSID &ls_id, const ObTabletID &tablet_id, ObDDLKvMgrHandle &ddl_kv_mgr_handle) { int ret = OB_SUCCESS; diff --git a/src/storage/meta_mem/ob_tablet_pointer.h b/src/storage/meta_mem/ob_tablet_pointer.h index 0d9f3d44e..9079250c0 100644 --- a/src/storage/meta_mem/ob_tablet_pointer.h +++ b/src/storage/meta_mem/ob_tablet_pointer.h @@ -52,10 +52,12 @@ public: virtual int64_t get_deep_copy_size() const override; INHERIT_TO_STRING_KV("ObMetaPointer", ObMetaPointer, K_(ls_handle), K_(ddl_kv_mgr_handle), - K_(memtable_mgr_handle), K_(ddl_info)); + K_(memtable_mgr_handle), K_(ddl_info), K_(redefined_schema_version)); public: int set_tx_data(const ObTabletTxMultiSourceDataUnit &tx_data); int get_tx_data(ObTabletTxMultiSourceDataUnit &tx_data) const; + int set_redefined_schema_version(const int64_t schema_version); + int get_redefined_schema_version(int64_t &schema_version) const; int create_ddl_kv_mgr(const share::ObLSID &ls_id, const ObTabletID &tablet_id, ObDDLKvMgrHandle &ddl_kv_mgr_handle); void get_ddl_kv_mgr(ObDDLKvMgrHandle &ddl_kv_mgr_handle); int set_ddl_kv_mgr(const ObDDLKvMgrHandle &ddl_kv_mgr_handle); @@ -69,6 +71,7 @@ private: ObMemtableMgrHandle memtable_mgr_handle_; ObTabletDDLInfo ddl_info_; ObTabletTxMultiSourceDataUnit tx_data_; + int64_t redefined_schema_version_; common::ObThreadCond cond_; mutable common::TCRWLock msd_lock_; lib::ObMutex ddl_kv_mgr_lock_; diff --git a/src/storage/meta_mem/ob_tenant_meta_mem_mgr.cpp b/src/storage/meta_mem/ob_tenant_meta_mem_mgr.cpp index 66419e2f9..e0765eff4 100644 --- a/src/storage/meta_mem/ob_tenant_meta_mem_mgr.cpp +++ b/src/storage/meta_mem/ob_tenant_meta_mem_mgr.cpp @@ -131,22 +131,19 @@ int ObTenantMetaMemMgr::init() { int ret = OB_SUCCESS; lib::ObMemAttr mem_attr(tenant_id_, "MetaAllocator", ObCtxIds::META_OBJ_CTX_ID); - const int64_t mem_limit = get_tenant_memory_limit(tenant_id_); - const int64_t min_bkt_cnt = DEFAULT_BUCKET_NUM; - const int64_t max_bkt_cnt = 10000000L; - const int64_t tablet_bucket_num = std::min(std::max((mem_limit / (1024 * 1024 * 1024)) * 50000, min_bkt_cnt), max_bkt_cnt); - const int64_t bucket_num = common::hash::cal_next_prime(tablet_bucket_num); + const int64_t bucket_num = cal_adaptive_bucket_num(); if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; LOG_WARN("ObTenantMetaMemMgr has been initialized", K(ret)); - } else if (OB_FAIL(bucket_lock_.init(bucket_num, ObLatchIds::BLOCK_MANAGER_LOCK))) { + } else if (OB_FAIL(bucket_lock_.init(bucket_num, ObLatchIds::BLOCK_MANAGER_LOCK, "T3MBucket", + tenant_id_))) { LOG_WARN("fail to init bucket lock", K(ret)); } else if (OB_FAIL(allocator_.init(lib::ObMallocAllocator::get_instance(), OB_MALLOC_NORMAL_BLOCK_SIZE, mem_attr))) { LOG_WARN("fail to init tenant fifo allocator", K(ret)); - } else if (OB_FAIL(tablet_map_.init(bucket_num, "TabletMap", TOTAL_LIMIT, HOLD_LIMIT, + } else if (OB_FAIL(tablet_map_.init(bucket_num, tenant_id_, "TabletMap", TOTAL_LIMIT, HOLD_LIMIT, common::OB_MALLOC_NORMAL_BLOCK_SIZE))) { - LOG_WARN("fail to initialize tablet map", K(ret)); + LOG_WARN("fail to initialize tablet map", K(ret), K(bucket_num)); } else if (OB_FAIL(last_min_minor_sstable_set_.create(DEFAULT_MINOR_SSTABLE_SET_COUNT))) { LOG_WARN("fail to create last min minor sstable set", K(ret)); } else if (pinned_tablet_set_.create(DEFAULT_BUCKET_NUM)) { @@ -1012,32 +1009,6 @@ int ObTenantMetaMemMgr::get_tablet_pointer_tx_data( return ret; } -int ObTenantMetaMemMgr::set_tablet_pointer_tx_data( - const ObTabletMapKey &key, - const ObTabletTxMultiSourceDataUnit &tx_data) -{ - int ret = OB_SUCCESS; - ObTabletPointerHandle ptr_handle(tablet_map_); - 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(key, ptr_handle))) { - LOG_WARN("failed to get ptr handle", K(ret), K(key)); - } else { - ObTabletPointer *tablet_ptr = static_cast(ptr_handle.get_resource_ptr()); - if (OB_ISNULL(tablet_ptr)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet ptr is NULL", K(ret), K(ptr_handle)); - } else if (OB_FAIL(tablet_ptr->set_tx_data(tx_data))) { - LOG_WARN("failed to set tx data in tablet pointer", K(ret), K(key), K(tx_data)); - } - } - return ret; -} - int ObTenantMetaMemMgr::get_tablet_ddl_kv_mgr( const ObTabletMapKey &key, ObDDLKvMgrHandle &ddl_kv_mgr_handle) @@ -1068,6 +1039,17 @@ int ObTenantMetaMemMgr::get_tablet_ddl_kv_mgr( return ret; } +int64_t ObTenantMetaMemMgr::cal_adaptive_bucket_num() +{ + const int64_t mem_limit = get_tenant_memory_limit(tenant_id_); + const int64_t min_bkt_cnt = DEFAULT_BUCKET_NUM; + const int64_t max_bkt_cnt = 1000000L; + const int64_t tablet_bucket_num = std::min(std::max((mem_limit / (1024 * 1024 * 1024)) * 50000, min_bkt_cnt), max_bkt_cnt); + const int64_t bucket_num = common::hash::cal_next_prime(tablet_bucket_num); + LOG_INFO("cal adaptive bucket num", K(mem_limit), K(min_bkt_cnt), K(max_bkt_cnt), K(tablet_bucket_num), K(bucket_num)); + return bucket_num; +} + int ObTenantMetaMemMgr::get_meta_mem_status(common::ObIArray &info) const { int ret = OB_SUCCESS; @@ -1154,8 +1136,8 @@ int ObTenantMetaMemMgr::compare_and_swap_tablet( } if (OB_FAIL(ret)) { - } else if (OB_FAIL(new_handle.get_obj()->set_tx_data_in_tablet_pointer())) { - LOG_WARN("failed to set tx data in tablet pointer", K(ret), K(key)); + } else if (OB_FAIL(new_handle.get_obj()->update_msd_cache_on_pointer())) { + LOG_WARN("failed to update msd cache in tablet pointer", K(ret), K(key)); } return ret; } diff --git a/src/storage/meta_mem/ob_tenant_meta_mem_mgr.h b/src/storage/meta_mem/ob_tenant_meta_mem_mgr.h index 5cecbba03..9fbb46210 100644 --- a/src/storage/meta_mem/ob_tenant_meta_mem_mgr.h +++ b/src/storage/meta_mem/ob_tenant_meta_mem_mgr.h @@ -186,7 +186,6 @@ public: int get_meta_mem_status(common::ObIArray &info) const; int get_tablet_pointer_tx_data(const ObTabletMapKey &key, ObTabletTxMultiSourceDataUnit &tx_data); - int set_tablet_pointer_tx_data(const ObTabletMapKey &key, const ObTabletTxMultiSourceDataUnit &tx_data); int insert_pinned_tablet(const ObTabletMapKey &key); int erase_pinned_tablet(const ObTabletMapKey &key); int get_tablet_ddl_kv_mgr(const ObTabletMapKey &key, ObDDLKvMgrHandle &ddl_kv_mgr_handle); @@ -201,6 +200,8 @@ public: TO_STRING_KV(K_(tenant_id), K_(is_inited)); private: + int64_t cal_adaptive_bucket_num(); + typedef ObResourceValueStore> TabletValueStore; struct CandidateTabletInfo final diff --git a/src/storage/ob_i_memtable_mgr.cpp b/src/storage/ob_i_memtable_mgr.cpp index d0bf42112..e50d1475a 100644 --- a/src/storage/ob_i_memtable_mgr.cpp +++ b/src/storage/ob_i_memtable_mgr.cpp @@ -29,7 +29,7 @@ namespace storage int ObIMemtableMgr::get_active_memtable(ObTableHandleV2 &handle) const { int ret = OB_SUCCESS; - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); if (OB_UNLIKELY(memtable_tail_ <= 0)) { ret = OB_ENTRY_NOT_EXIST; STORAGE_LOG(WARN, "There is no memtable in MemtableMgr", K(ret), K(memtable_tail_)); @@ -46,7 +46,7 @@ int ObIMemtableMgr::get_first_nonempty_memtable(ObTableHandleV2 &handle) const { int ret = OB_SUCCESS; bool is_exist = false; - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); for (int64_t i = memtable_head_; OB_SUCC(ret) && i < memtable_tail_; ++i) { ObTableHandleV2 tmp_handle; @@ -86,7 +86,7 @@ int ObIMemtableMgr::get_all_memtables(ObTableHdlArray &handles) { int ret = OB_SUCCESS; // TODO(handora.qc): oblatchid - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); for (int64_t i = memtable_head_; OB_SUCC(ret) && i < memtable_tail_; ++i) { ObTableHandleV2 handle; if (OB_FAIL(get_ith_memtable(i, handle))) { @@ -135,7 +135,7 @@ int ObIMemtableMgr::get_newest_snapshot_version(SCN &snapshot_version) int ObIMemtableMgr::release_memtables(const SCN &scn) { - SpinWLockGuard lock_guard(lock_); + MemMgrWLockGuard lock_guard(lock_); int ret = OB_SUCCESS; if (IS_NOT_INIT) { @@ -174,7 +174,7 @@ int ObIMemtableMgr::release_memtables() { int ret = OB_SUCCESS; const bool force_release = true; - SpinWLockGuard lock_guard(lock_); + MemMgrWLockGuard lock_guard(lock_); if (IS_NOT_INIT) { ret = OB_NOT_INIT; STORAGE_LOG(WARN, "not inited", K(ret)); diff --git a/src/storage/ob_i_memtable_mgr.h b/src/storage/ob_i_memtable_mgr.h index 33d60491c..ea35fe48f 100644 --- a/src/storage/ob_i_memtable_mgr.h +++ b/src/storage/ob_i_memtable_mgr.h @@ -13,6 +13,8 @@ #ifndef OCEANBASE_STORAGE_OB_I_MEMTABLE_MGR #define OCEANBASE_STORAGE_OB_I_MEMTABLE_MGR +#include "lib/lock/ob_spin_rwlock.h" +#include "lib/lock/ob_qsync_lock.h" #include "storage/ob_i_table.h" #include "storage/memtable/ob_multi_source_data.h" #include "storage/ob_storage_schema_recorder.h" @@ -35,11 +37,164 @@ class ObFreezer; using ObTableHdlArray = common::ObIArray; +enum LockType +{ + OB_LOCK_UNKNOWN = 0, + OB_SPIN_RWLOCK, + OB_QSYNC_LOCK, + OB_LOCK_MAX +}; + +class MemtableMgrLock +{ +public: + MemtableMgrLock(const LockType lock_type, void *lock) : lock_type_(lock_type), lock_(lock) {} + ~MemtableMgrLock() { reset(); } + void reset() + { + lock_type_ = LockType::OB_LOCK_UNKNOWN; + lock_ = NULL; + } + + bool is_valid() const + { + return NULL != lock_ + && (lock_type_ > OB_LOCK_UNKNOWN && lock_type_ < OB_LOCK_MAX) + && (OB_QSYNC_LOCK == lock_type_ ? static_cast(lock_)->is_inited() : true); + } + + int rdlock() + { + int ret = OB_SUCCESS; + + if (!is_valid()) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(ERROR, "unexpected lock or lock_type", K(ret), K_(lock_type), KP_(lock)); + } else if (lock_type_ == OB_QSYNC_LOCK) { + ret = static_cast(lock_)->rdlock(); + } else if (lock_type_ == LockType::OB_SPIN_RWLOCK) { + ret = static_cast(lock_)->rdlock(); + } else { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(ERROR, "unexpected lock_type", K(ret), K_(lock_type)); + } + return ret; + } + + void rdunlock() + { + if (lock_type_ == OB_QSYNC_LOCK) { + static_cast(lock_)->rdunlock(); + } else if (lock_type_ == LockType::OB_SPIN_RWLOCK) { + static_cast(lock_)->unlock(); + } else { + STORAGE_LOG(ERROR, "unexpected lock_type", K_(lock_type)); + } + } + + int try_wrlock() + { + int ret = OB_SUCCESS; + + if (!is_valid()) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(ERROR, "unexpected lock or lock_type", K(ret), K_(lock_type), KP_(lock)); + } else if (lock_type_ == LockType::OB_SPIN_RWLOCK) { + ret = static_cast(lock_)->try_wrlock(); + } else { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(ERROR, "unexpected lock_type", K(ret), K_(lock_type)); + } + return ret; + } + + int wrlock() + { + int ret = OB_SUCCESS; + + if (!is_valid()) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(ERROR, "unexpected lock or lock_type", K(ret), K_(lock_type), KP_(lock)); + } else if (lock_type_ == OB_QSYNC_LOCK) { + ret = static_cast(lock_)->wrlock(); + } else if (lock_type_ == LockType::OB_SPIN_RWLOCK) { + ret = static_cast(lock_)->wrlock(); + } else { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(ERROR, "unexpected lock_type", K(ret), K_(lock_type)); + } + return ret; + } + + void wrunlock() + { + if (lock_type_ == OB_QSYNC_LOCK) { + static_cast(lock_)->wrunlock(); + } else if (lock_type_ == LockType::OB_SPIN_RWLOCK) { + static_cast(lock_)->unlock(); + } else { + STORAGE_LOG(ERROR, "unexpected lock_type", K_(lock_type)); + } + } + +private: + LockType lock_type_; + void *lock_; +}; + +class MemMgrRLockGuard +{ +public: + explicit MemMgrRLockGuard(const MemtableMgrLock &lock) + : lock_(const_cast(lock)), ret_(OB_SUCCESS) + { + if (OB_UNLIKELY(OB_SUCCESS != (ret_ = lock_.rdlock()))) { + COMMON_LOG(WARN, "Fail to read lock, ", K_(ret)); + } + } + ~MemMgrRLockGuard() + { + if (OB_LIKELY(OB_SUCCESS == ret_)) { + lock_.rdunlock(); + } + } + inline int get_ret() const { return ret_; } +private: + MemtableMgrLock &lock_; + int ret_; +private: + DISALLOW_COPY_AND_ASSIGN(MemMgrRLockGuard); +}; + +class MemMgrWLockGuard +{ +public: + explicit MemMgrWLockGuard(const MemtableMgrLock &lock) + : lock_(const_cast(lock)), ret_(OB_SUCCESS) + { + if (OB_UNLIKELY(OB_SUCCESS != (ret_ = lock_.wrlock()))) { + COMMON_LOG(WARN, "Fail to write lock, ", K_(ret)); + } + } + ~MemMgrWLockGuard() + { + if (OB_LIKELY(OB_SUCCESS == ret_)) { + lock_.wrunlock(); + } + } + inline int get_ret() const { return ret_; } +private: + MemtableMgrLock &lock_; + int ret_; +private: + DISALLOW_COPY_AND_ASSIGN(MemMgrWLockGuard); +}; + class ObIMemtableMgr { public: - ObIMemtableMgr() + ObIMemtableMgr(const LockType lock_type, void *lock) : is_inited_(false), ref_cnt_(0), tablet_id_(), @@ -48,7 +203,7 @@ public: memtable_head_(0), memtable_tail_(0), t3m_(nullptr), - lock_(common::ObLatchIds::TABLET_MEMTABLE_LOCK) + lock_(lock_type, lock) { memset(tables_, 0, sizeof(tables_)); } @@ -61,6 +216,7 @@ public: logservice::ObLogHandler *log_handler, ObFreezer *freezer, ObTenantMetaMemMgr *t3m); + virtual int create_memtable(const share::SCN clog_checkpoint_scn, const int64_t schema_version, const bool for_replay = false) @@ -101,7 +257,7 @@ public: bool has_memtable() { - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); return has_memtable_(); } @@ -151,7 +307,6 @@ protected: const share::ObLSID &ls_id, ObFreezer *freezer, ObTenantMetaMemMgr *t3m) = 0; - protected: bool is_inited_; volatile int64_t ref_cnt_; @@ -163,7 +318,7 @@ protected: int64_t memtable_tail_; ObTenantMetaMemMgr *t3m_; memtable::ObIMemtable *tables_[MAX_MEMSTORE_CNT]; - mutable common::SpinRWLock lock_; + mutable MemtableMgrLock lock_; }; class ObMemtableMgrHandle final diff --git a/src/storage/ob_long_ops_monitor.cpp b/src/storage/ob_long_ops_monitor.cpp index f3146339f..28d50d141 100644 --- a/src/storage/ob_long_ops_monitor.cpp +++ b/src/storage/ob_long_ops_monitor.cpp @@ -406,7 +406,8 @@ int ObLongOpsMonitor::init() if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; LOG_WARN("ObLongOpsMonitor has been inited twice", K(ret)); - } else if (OB_FAIL(map_.init(DEFAULT_BUCKET_NUM, ObModIds::OB_SSTABLE_LONG_OPS_MONITOR, + } else if (OB_FAIL(map_.init(DEFAULT_BUCKET_NUM, OB_SERVER_TENANT_ID, + ObModIds::OB_SSTABLE_LONG_OPS_MONITOR, TOTAL_LIMIT, HOLD_LIMIT, PAGE_SIZE))) { LOG_WARN("fail to init map", K(ret)); } else { diff --git a/src/storage/ob_resource_map.h b/src/storage/ob_resource_map.h index e70e3d36c..7bcf53afd 100644 --- a/src/storage/ob_resource_map.h +++ b/src/storage/ob_resource_map.h @@ -160,7 +160,7 @@ class ObResourceMap public: ObResourceMap(); virtual ~ObResourceMap(); - int init(const int64_t bucket_num, const char *label, + int init(const int64_t bucket_num, const uint64_t tenant_id, const char *label, const int64_t total_limit, const int64_t hold_limit, const int64_t page_size); template > int get(const Key &key, ObResourceHandle &handle, Callback callback = ObResourceDefaultCallback()); @@ -203,20 +203,27 @@ ObResourceMap::~ObResourceMap() } template -int ObResourceMap::init(const int64_t bucket_num, const char *label, - const int64_t total_limit, const int64_t hold_limit, const int64_t page_size) +int ObResourceMap::init( + const int64_t bucket_num, + const uint64_t tenant_id, + const char *label, + const int64_t total_limit, + const int64_t hold_limit, + const int64_t page_size) { int ret = common::OB_SUCCESS; const int64_t bkt_num = common::hash::cal_next_prime(bucket_num); if (OB_UNLIKELY(is_inited_)) { ret = common::OB_INIT_TWICE; STORAGE_LOG(WARN, "ObResourceMap has already been inited", K(ret)); - } else if (OB_UNLIKELY(bucket_num <= 0 || total_limit <= 0 || hold_limit <= 0 || page_size <= 0)) { + } else if (OB_UNLIKELY(bucket_num <= 0 || total_limit <= 0 || hold_limit <= 0 || page_size <= 0 + || OB_INVALID_TENANT_ID == tenant_id)) { ret = common::OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "invalid argument", K(ret), K(bucket_num), K(total_limit), K(hold_limit), K(page_size)); + STORAGE_LOG(WARN, "invalid argument", K(ret), K(bucket_num), K(total_limit), K(hold_limit), + K(page_size), K(tenant_id)); } else if (OB_FAIL(bucket_lock_.init(bkt_num))) { STORAGE_LOG(WARN, "fail to init bucket lock", K(ret), K(bkt_num)); - } else if (OB_FAIL(map_.create(bkt_num, label))) { + } else if (OB_FAIL(map_.create(bkt_num, label, label, tenant_id))) { STORAGE_LOG(WARN, "fail to create map", K(ret)); } else if (OB_UNLIKELY(bkt_num != map_.bucket_count())) { ret = OB_ERR_UNEXPECTED; @@ -227,6 +234,7 @@ int ObResourceMap::init(const int64_t bucket_num, const char *label, } else { allocator_.set_label(label); is_inited_ = true; + STORAGE_LOG(INFO, "init resource map success", K(ret), K(tenant_id), K(bkt_num)); } return ret; } diff --git a/src/storage/tablelock/ob_lock_memtable_mgr.cpp b/src/storage/tablelock/ob_lock_memtable_mgr.cpp index 02beaadea..0f17a0b04 100644 --- a/src/storage/tablelock/ob_lock_memtable_mgr.cpp +++ b/src/storage/tablelock/ob_lock_memtable_mgr.cpp @@ -28,8 +28,14 @@ namespace transaction namespace tablelock { -ObLockMemtableMgr::ObLockMemtableMgr() -{} +ObLockMemtableMgr::ObLockMemtableMgr() : ObIMemtableMgr(LockType::OB_QSYNC_LOCK, &lock_def_) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(lock_def_.init(lib::ObMemAttr(MTL_ID(), "LockMemtableMgr")))) { + LOG_WARN("lock memtable mgr lock init error", K(ret), "tenant_id", MTL_ID()); + } + UNUSED(ret); +} int ObLockMemtableMgr::init( const common::ObTabletID &tablet_id, @@ -47,6 +53,9 @@ int ObLockMemtableMgr::init( OB_ISNULL(t3m)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(ls_id), KP(freezer), KP(t3m)); + } else if (!lock_def_.is_inited()) { + ret = OB_NOT_INIT; + LOG_WARN("lock memtable mgr lock not init", K(ret), K(tablet_id), K(ls_id)); } else { ls_id_ = ls_id; freezer_ = freezer; @@ -65,7 +74,7 @@ void ObLockMemtableMgr::destroy() void ObLockMemtableMgr::reset() { - SpinWLockGuard lock_guard(lock_); + MemMgrWLockGuard lock_guard(lock_); reset_tables(); freezer_ = NULL; is_inited_ = false; @@ -86,7 +95,7 @@ int ObLockMemtableMgr::create_memtable(const SCN clog_checkpoint_scn, ObLockMemtable *memtable = nullptr; ObLSTxService *ls_tx_svr = nullptr; - SpinWLockGuard lock_guard(lock_); + MemMgrWLockGuard lock_guard(lock_); table_key.table_type_ = ObITable::LOCK_MEMTABLE; table_key.tablet_id_ = LS_LOCK_TABLET; diff --git a/src/storage/tablelock/ob_lock_memtable_mgr.h b/src/storage/tablelock/ob_lock_memtable_mgr.h index c9f7e4aef..8a79c1e10 100644 --- a/src/storage/tablelock/ob_lock_memtable_mgr.h +++ b/src/storage/tablelock/ob_lock_memtable_mgr.h @@ -75,6 +75,7 @@ private: private: share::ObLSID ls_id_; + common::ObQSyncLock lock_def_; }; } // namespace tablelock diff --git a/src/storage/tablelock/ob_obj_lock.cpp b/src/storage/tablelock/ob_obj_lock.cpp index 70cc5ea29..bf4cad98b 100644 --- a/src/storage/tablelock/ob_obj_lock.cpp +++ b/src/storage/tablelock/ob_obj_lock.cpp @@ -91,7 +91,7 @@ int ObTableLockOpLinkNode::get_table_lock_store_info(ObTableLockOp &info) return ret; } -ObOBJLock::ObOBJLock() +ObOBJLock::ObOBJLock(const ObLockID &lock_id) : lock_id_(lock_id) { is_deleted_ = false; row_share_ = 0; @@ -667,15 +667,14 @@ int ObOBJLock::get_table_lock_store_info( } bool ObOBJLockMap::GetTableLockStoreInfoFunctor::operator() ( - const ObLockID &lock_id, ObOBJLock *obj_lock) { int ret = common::OB_SUCCESS; bool bool_ret = false; - if (!lock_id.is_valid() || OB_ISNULL(obj_lock)) { + if (OB_ISNULL(obj_lock)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(lock_id), "map", OB_P(obj_lock)); + LOG_WARN("invalid argument", K(ret), "map", OB_P(obj_lock)); } else if (OB_FAIL(obj_lock->get_table_lock_store_info(store_arr_, freeze_scn_))) { LOG_WARN("get table lock store info failed", K(ret)); } @@ -747,15 +746,14 @@ int ObOBJLockMap::get_lock_op_iter(const ObLockID &lock_id, } bool ObOBJLockMap::GetMinCommittedDDLLogtsFunctor::operator() ( - const ObLockID &lock_id, ObOBJLock *obj_lock) { int ret = common::OB_SUCCESS; bool bool_ret = false; - if (!lock_id.is_valid() || OB_ISNULL(obj_lock)) { + if (OB_ISNULL(obj_lock)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(lock_id), "map", OB_P(obj_lock)); + LOG_WARN("invalid argument", K(ret), "map", OB_P(obj_lock)); } else { min_committed_scn_ = std::min(min_committed_scn_, obj_lock->get_min_ddl_lock_committed_scn(flushed_scn_)); @@ -1625,17 +1623,17 @@ void ObOBJLock::drop_op_list_if_empty_( } } -ObOBJLock *ObOBJLockFactory::alloc(const uint64_t tenant_id) +ObOBJLock *ObOBJLockFactory::alloc(const uint64_t tenant_id, const ObLockID &lock_id) { int ret = OB_SUCCESS; void *ptr = NULL; ObOBJLock* obj_lock = NULL; ObMemAttr attr(tenant_id, OB_TABLE_LOCK_NODE); - if (!is_valid_tenant_id(tenant_id)) { + if (!is_valid_tenant_id(tenant_id) || !lock_id.is_valid()) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid tenant_id", K(ret), K(tenant_id)); + LOG_WARN("invalid tenant_id", K(ret), K(tenant_id), K(lock_id)); } else if (NULL != (ptr = ob_malloc(sizeof(ObOBJLock), attr))) { - obj_lock = new(ptr) ObOBJLock; + obj_lock = new(ptr) ObOBJLock(lock_id); (void)ATOMIC_FAA(&alloc_count_, 1); } LOG_DEBUG( "alloc allock_count", K(alloc_count_), K(ptr)); @@ -1670,7 +1668,7 @@ int ObOBJLockMap::init() if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; LOG_WARN("ObOBJLockMap has been inited already", K(ret)); - } else if (OB_FAIL(lock_map_.init(OB_TABLE_LOCK_MAP_ELEMENT))) { + } else if (OB_FAIL(lock_map_.init(lib::ObMemAttr(MTL_ID(), "ObOBJLockMap")))) { LOG_WARN("ObOBJLockMap create lock map failed", K(ret)); } else { is_inited_ = true; @@ -1727,11 +1725,12 @@ int ObOBJLockMap::get_or_create_obj_lock_with_ref_( do { if (OB_FAIL(lock_map_.get(lock_id, obj_lock))) { if (ret == OB_ENTRY_NOT_EXIST) { - if (OB_ISNULL(obj_lock = ObOBJLockFactory::alloc(tenant_id))) { + if (OB_ISNULL(obj_lock = ObOBJLockFactory::alloc(tenant_id, lock_id))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("failed to alllocate ObOBJLock ", K(ret)); - } else if (OB_FAIL(lock_map_.insert_and_get(lock_id, - obj_lock))) { + } else if (OB_FAIL(lock_map_.insert_and_get(obj_lock->get_lock_id(), + obj_lock, + NULL))) { ObOBJLockFactory::release(obj_lock); obj_lock = nullptr; if (ret != OB_ENTRY_EXIST) { @@ -1920,7 +1919,7 @@ int ObOBJLockMap::remove_lock(const ObLockID &lock_id) WRLockGuard guard(obj_lock->rwlock_); obj_lock->set_deleted(); obj_lock->reset_without_lock(allocator_); - if (OB_FAIL(lock_map_.del(lock_id))) { + if (OB_FAIL(lock_map_.del(lock_id, obj_lock))) { if (ret != OB_ENTRY_NOT_EXIST) { LOG_WARN("remove lock owner list map failed. ", K(ret), K(lock_id)); } else { @@ -2084,7 +2083,7 @@ void ObOBJLockMap::drop_obj_lock_if_empty_( } else if (obj_lock != recheck_ptr) { LOG_WARN("the obj lock at map is not me, do nothing", K(lock_id), KP(obj_lock), KP(recheck_ptr)); - } else if (OB_FAIL(lock_map_.del(lock_id))) { + } else if (OB_FAIL(lock_map_.del(lock_id, obj_lock))) { LOG_WARN("remove obj lock from map failed. ", K(ret), K(lock_id)); } } diff --git a/src/storage/tablelock/ob_obj_lock.h b/src/storage/tablelock/ob_obj_lock.h index 124f3125b..4a48279ff 100644 --- a/src/storage/tablelock/ob_obj_lock.h +++ b/src/storage/tablelock/ob_obj_lock.h @@ -80,12 +80,10 @@ public: }; typedef ObDList ObTableLockOpList; -typedef common::LinkHashNode ObOBJLockHashNode; -typedef common::LinkHashValue ObOBJLockHashValue; -class ObOBJLock : public ObOBJLockHashValue +class ObOBJLock : public ObTransHashLink { public: - ObOBJLock(); + ObOBJLock(const ObLockID &lock_id); int lock( const ObLockParam ¶m, storage::ObStoreCtx &ctx, @@ -133,6 +131,10 @@ public: int get_lock_op_iter( const ObLockID &lock_id, ObLockOpIterator &iter) const; + const ObLockID &get_lock_id() const { return lock_id_; } + void set_lock_id(const ObLockID &lock_id) { lock_id_ = lock_id; } + bool contain(const ObLockID &lock_id) { return lock_id_ == lock_id; } + TO_STRING_KV(K_(lock_id), K_(is_deleted), K_(row_share), K_(row_exclusive)); private: void print_() const; void reset_(ObMalloc &allocator); @@ -263,12 +265,13 @@ private: ObTableLockOpList *map_[TABLE_LOCK_MODE_COUNT]; int64_t row_share_; int64_t row_exclusive_; + ObLockID lock_id_; }; class ObOBJLockFactory { public: - static ObOBJLock *alloc(const uint64_t tenant_id); + static ObOBJLock *alloc(const uint64_t tenant_id, const ObLockID &lock_id); static void release(ObOBJLock *e); static int64_t alloc_count_; static int64_t release_count_; @@ -289,27 +292,14 @@ public: p = NULL; } } - static ObOBJLockHashNode* alloc_node(ObOBJLock* p) - { - UNUSED(p); - return op_alloc(ObOBJLockHashNode); - } - static void free_node(ObOBJLockHashNode* node) - { - if (NULL != node) { - op_free(node); - node = NULL; - } - } }; class ObOBJLockMap { - typedef common::ObLinkHashMap Map; - const static int MIN_MAP_SIZE = 1 << 10; + typedef ObTransHashMap Map; public: ObOBJLockMap() : - lock_map_(MIN_MAP_SIZE), + lock_map_(), allocator_(), is_inited_(false) {} @@ -362,13 +352,13 @@ private: : err_code_(OB_SUCCESS), iter_(iter) {} - bool operator()(const ObLockID &lock_id, ObOBJLock *obj_lock) + bool operator()(ObOBJLock *obj_lock) { int ret = OB_SUCCESS; UNUSED(obj_lock); bool need_continue = true; - if (OB_FAIL(iter_.push(lock_id))) { - TABLELOCK_LOG(WARN, "push lock id into iterator failed", K(ret), K(lock_id)); + if (OB_FAIL(iter_.push(obj_lock->get_lock_id()))) { + TABLELOCK_LOG(WARN, "push lock id into iterator failed", "lock_id", obj_lock->get_lock_id(), K(ret)); need_continue = false; err_code_ = ret; } @@ -382,10 +372,10 @@ private: class PrintLockFunctor { public: - bool operator()(const ObLockID &lock_id, ObOBJLock *obj_lock) + bool operator()(ObOBJLock *obj_lock) { bool bool_ret = true; - TABLELOCK_LOG(INFO, "LockID: ", K(lock_id)); + TABLELOCK_LOG(INFO, "LockID: ", "lock_id", obj_lock->get_lock_id()); obj_lock->print(); return bool_ret; } @@ -395,9 +385,8 @@ private: public: explicit ResetLockFunctor(ObMalloc &allocator) : allocator_(allocator) {} - bool operator()(const ObLockID &lock_id, ObOBJLock *obj_lock) + bool operator()(ObOBJLock *obj_lock) { - UNUSED(lock_id); bool bool_ret = true; obj_lock->reset(allocator_); return bool_ret; @@ -411,7 +400,7 @@ private: explicit GetMinCommittedDDLLogtsFunctor(share::SCN &flushed_scn) : min_committed_scn_(share::SCN::max_scn()), flushed_scn_(flushed_scn) {} - bool operator()(const ObLockID &lock_id, ObOBJLock *obj_lock); + bool operator()(ObOBJLock *obj_lock); share::SCN get_min_committed_scn() { return min_committed_scn_; } private: @@ -425,7 +414,7 @@ private: share::SCN freeze_scn) : store_arr_(store_arr), freeze_scn_(freeze_scn) {} - bool operator()(const ObLockID &lock_id, ObOBJLock *obj_lock); + bool operator()(ObOBJLock *obj_lock); private: ObIArray &store_arr_; diff --git a/src/storage/tablet/ob_tablet.cpp b/src/storage/tablet/ob_tablet.cpp index 05dbb8270..40d0aa8cf 100644 --- a/src/storage/tablet/ob_tablet.cpp +++ b/src/storage/tablet/ob_tablet.cpp @@ -2860,27 +2860,65 @@ int ObTablet::set_tx_data_in_tablet_pointer(const ObTabletTxMultiSourceDataUnit { int ret = OB_SUCCESS; const ObTabletMapKey key(tablet_meta_.ls_id_, tablet_meta_.tablet_id_); - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + ObTabletPointer *tablet_ptr = static_cast(pointer_hdl_.get_resource_ptr()); - if (OB_FAIL(t3m->set_tablet_pointer_tx_data(key, tx_data))) { + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(tablet_ptr->set_tx_data(tx_data))) { LOG_WARN("failed to set tx data in tablet pointer", K(ret), K(key), K(tx_data)); } return ret; } -int ObTablet::set_tx_data_in_tablet_pointer() +int ObTablet::update_msd_cache_on_pointer() { int ret = OB_SUCCESS; const ObLSID &ls_id = tablet_meta_.ls_id_; const ObTabletID &tablet_id = tablet_meta_.tablet_id_; ObTabletTxMultiSourceDataUnit &tx_data = tablet_meta_.tx_data_; + ObTabletBindingInfo info; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(get_ddl_data(info))) { + LOG_WARN("failed to get ddl data", K(ret), K(ls_id)); } else if (OB_FAIL(set_tx_data_in_tablet_pointer(tx_data))) { LOG_WARN("failed to set tx data in tablet pointer", K(ret), K(ls_id), K(tablet_id), K(tx_data)); + } else if (OB_FAIL(set_redefined_schema_version_in_tablet_pointer(info.schema_version_))) { + LOG_WARN("failed to set redefined schema version in tablet pointer", K(ret), K(ls_id), K(tablet_id), K(info)); + } + + return ret; +} + +int ObTablet::get_redefined_schema_version_in_tablet_pointer(int64_t &schema_version) const +{ + int ret = OB_SUCCESS; + ObTabletPointer *tablet_ptr = static_cast(pointer_hdl_.get_resource_ptr()); + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(tablet_ptr->get_redefined_schema_version(schema_version))) { + LOG_WARN("failed to get redefined schema version from pointer", K(ret)); + } + + return ret; +} + +int ObTablet::set_redefined_schema_version_in_tablet_pointer(const int64_t schema_version) +{ + int ret = OB_SUCCESS; + ObTabletPointer *tablet_ptr = static_cast(pointer_hdl_.get_resource_ptr()); + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(tablet_ptr->set_redefined_schema_version(schema_version))) { + LOG_WARN("failed to set redefined schema version in tablet pointer", K(ret), K(schema_version)); } return ret; diff --git a/src/storage/tablet/ob_tablet.h b/src/storage/tablet/ob_tablet.h index 0340f690e..837394121 100644 --- a/src/storage/tablet/ob_tablet.h +++ b/src/storage/tablet/ob_tablet.h @@ -358,7 +358,9 @@ public: const bool for_replay, const memtable::MemtableRefOp ref_op = memtable::MemtableRefOp::NONE, const bool is_callback = false); - int set_tx_data_in_tablet_pointer(); + int update_msd_cache_on_pointer(); + int get_redefined_schema_version_in_tablet_pointer(int64_t &schema_version) const; + int set_redefined_schema_version_in_tablet_pointer(const int64_t schema_version); int set_memtable_clog_checkpoint_scn( const ObMigrationTabletParam *tablet_meta); diff --git a/src/storage/tablet/ob_tablet_binding_helper.cpp b/src/storage/tablet/ob_tablet_binding_helper.cpp index 53a90ebec..2cc9dacb4 100644 --- a/src/storage/tablet/ob_tablet_binding_helper.cpp +++ b/src/storage/tablet/ob_tablet_binding_helper.cpp @@ -670,6 +670,8 @@ int ObTabletBindingHelper::modify_tablet_binding_for_unbind( info.schema_version_ = arg.schema_version_; if (OB_FAIL(tablet->set_multi_data_for_commit(info, scn, for_replay, MemtableRefOp::NONE))) { LOG_WARN("failed to save tablet binding info", K(ret)); + } else if (OB_FAIL(tablet->set_redefined_schema_version_in_tablet_pointer(info.schema_version_))) { + LOG_WARN("failed to set redefined schema version in tablet pointer", K(ret)); } } } @@ -693,14 +695,12 @@ int ObTabletBindingHelper::check_schema_version(ObTabletHandle &handle, const in { int ret = OB_SUCCESS; ObTablet *tablet = handle.get_obj(); - TCRWLock &lock = tablet->get_rw_lock(); - TCRLockGuard guard(lock); - ObTabletBindingInfo info; - if (OB_FAIL(tablet->get_ddl_data(info))) { + int64_t redefined_schema_version = OB_INVALID_VERSION; + if (OB_FAIL(tablet->get_redefined_schema_version_in_tablet_pointer(redefined_schema_version))) { LOG_WARN("failed to get tablet binding info", K(ret)); - } else if (OB_UNLIKELY(schema_version < info.schema_version_)) { + } else if (OB_UNLIKELY(schema_version < redefined_schema_version)) { ret = OB_SCHEMA_EAGAIN; - LOG_WARN("use stale schema before ddl", K(ret), K(tablet->get_tablet_meta().tablet_id_), K(info.schema_version_), K(schema_version)); + LOG_WARN("use stale schema before ddl", K(ret), K(tablet->get_tablet_meta().tablet_id_), K(redefined_schema_version), K(schema_version)); } return ret; } diff --git a/src/storage/tablet/ob_tablet_create_delete_helper.cpp b/src/storage/tablet/ob_tablet_create_delete_helper.cpp index 945cefb79..146df6513 100644 --- a/src/storage/tablet/ob_tablet_create_delete_helper.cpp +++ b/src/storage/tablet/ob_tablet_create_delete_helper.cpp @@ -1349,7 +1349,7 @@ int ObTabletCreateDeleteHelper::get_tablet( static const int64_t SLEEP_TIME_US = 10; ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); ObTabletHandle tablet_handle; - const int64_t begin_time = ObTimeUtility::current_time(); + const int64_t begin_time = ObClockGenerator::getClock(); int64_t current_time = 0; while (OB_SUCC(ret)) { @@ -1360,7 +1360,7 @@ int ObTabletCreateDeleteHelper::get_tablet( ret = OB_TABLET_NOT_EXIST; LOG_DEBUG("tablet does not exist", K(ret), K(key)); } else if (OB_ITEM_NOT_SETTED == ret) { - current_time = ObTimeUtility::current_time(); + current_time = ObClockGenerator::getClock(); if (current_time - begin_time > timeout_us) { ret = OB_TABLET_NOT_EXIST; LOG_WARN("continuously meet item not set error", K(ret), K(begin_time), K(current_time), K(timeout_us)); diff --git a/src/storage/tablet/ob_tablet_memtable_mgr.cpp b/src/storage/tablet/ob_tablet_memtable_mgr.cpp index c876ba7ef..2f879ebd1 100644 --- a/src/storage/tablet/ob_tablet_memtable_mgr.cpp +++ b/src/storage/tablet/ob_tablet_memtable_mgr.cpp @@ -33,11 +33,13 @@ namespace storage { ObTabletMemtableMgr::ObTabletMemtableMgr() - : ls_(NULL), + : ObIMemtableMgr(LockType::OB_SPIN_RWLOCK, &lock_def_), + ls_(NULL), + lock_def_(common::ObLatchIds::TABLET_MEMTABLE_LOCK), schema_recorder_() { #if defined(__x86_64__) - static_assert(sizeof(ObTabletMemtableMgr) <= 352, "The size of ObTabletMemtableMgr will affect the meta memory manager, and the necessity of adding new fields needs to be considered."); + static_assert(sizeof(ObTabletMemtableMgr) <= 370, "The size of ObTabletMemtableMgr will affect the meta memory manager, and the necessity of adding new fields needs to be considered."); #endif } @@ -48,7 +50,7 @@ ObTabletMemtableMgr::~ObTabletMemtableMgr() void ObTabletMemtableMgr::destroy() { - SpinWLockGuard lock_guard(lock_); + MemMgrWLockGuard lock_guard(lock_); // release memtable memtable::ObIMemtable *imemtable = nullptr; int ret = OB_SUCCESS; @@ -146,7 +148,7 @@ int ObTabletMemtableMgr::create_memtable(const SCN clog_checkpoint_scn, { ObTimeGuard time_guard("ObTabletMemtableMgr::create_memtable", 10 * 1000); // Write lock - SpinWLockGuard lock_guard(lock_); + MemMgrWLockGuard lock_guard(lock_); time_guard.click("lock"); int ret = OB_SUCCESS; @@ -269,7 +271,7 @@ bool ObTabletMemtableMgr::has_active_memtable() ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); } else { - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); if (NULL != get_active_memtable_()) { bool_ret = true; } @@ -279,14 +281,14 @@ bool ObTabletMemtableMgr::has_active_memtable() int64_t ObTabletMemtableMgr::get_memtable_count() const { - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); return get_memtable_count_(); } int ObTabletMemtableMgr::get_boundary_memtable(ObTableHandleV2 &handle) { int ret = OB_SUCCESS; - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); memtable::ObIMemtable *memtable = nullptr; handle.reset(); @@ -307,7 +309,7 @@ int ObTabletMemtableMgr::get_boundary_memtable(ObTableHandleV2 &handle) int ObTabletMemtableMgr::get_active_memtable(ObTableHandleV2 &handle) const { int ret = OB_SUCCESS; - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); handle.reset(); if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; @@ -344,7 +346,7 @@ int ObTabletMemtableMgr::get_active_memtable_(ObTableHandleV2 &handle) const ObMemtable *ObTabletMemtableMgr::get_last_frozen_memtable() const { int ret = OB_SUCCESS; - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); memtable::ObMemtable *memtable = nullptr; if (OB_UNLIKELY(!is_inited_)) { @@ -476,7 +478,7 @@ int ObTabletMemtableMgr::get_memtable_for_replay(SCN replay_scn, ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); } else { - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); int64_t i = 0; for (i = memtable_tail_ - 1; OB_SUCC(ret) && i >= memtable_head_; --i) { if (OB_FAIL(get_ith_memtable(i, handle))) { @@ -520,7 +522,7 @@ int ObTabletMemtableMgr::get_memtables( ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); } else { - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); if (reset_handle) { handle.reset(); } @@ -548,7 +550,7 @@ int ObTabletMemtableMgr::get_memtables_nolock(ObTableHdlArray &handle) int ObTabletMemtableMgr::get_all_memtables(ObTableHdlArray &handle) { int ret = OB_SUCCESS; - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); @@ -598,7 +600,7 @@ int ObTabletMemtableMgr::get_first_frozen_memtable(ObTableHandleV2 &handle) cons { int ret = OB_SUCCESS; memtable::ObMemtable *memtable = NULL; - SpinRLockGuard guard(lock_); + MemMgrRLockGuard guard(lock_); if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; @@ -750,7 +752,7 @@ int64_t ObTabletMemtableMgr::to_string(char *buf, const int64_t buf_len) const J_COLON(); pos += ObIMemtableMgr::to_string(buf + pos, buf_len - pos); J_COMMA(); - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); J_OBJ_START(); J_ARRAY_START(); for (int64_t i = memtable_head_; i < memtable_tail_; ++i) { @@ -810,7 +812,7 @@ int ObTabletMemtableMgr::get_memtables_v2( ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); } else { - SpinRLockGuard guard(lock_); + MemMgrRLockGuard guard(lock_); if (reset_handle) { handle.reset(); } @@ -867,7 +869,7 @@ int ObTabletMemtableMgr::get_multi_source_data_unit( ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), KP(multi_source_data_unit)); } else { - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); if (!has_memtable_()) { ret = OB_ENTRY_NOT_EXIST; @@ -910,7 +912,7 @@ int ObTabletMemtableMgr::get_memtable_for_multi_source_data_unit( ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); } else { - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); if (!has_memtable_()) { ret = OB_ENTRY_NOT_EXIST; diff --git a/src/storage/tablet/ob_tablet_memtable_mgr.h b/src/storage/tablet/ob_tablet_memtable_mgr.h index db0b00a57..135b855ad 100644 --- a/src/storage/tablet/ob_tablet_memtable_mgr.h +++ b/src/storage/tablet/ob_tablet_memtable_mgr.h @@ -134,6 +134,7 @@ private: private: ObLS *ls_; //8B + common::SpinRWLock lock_def_; //8B ObStorageSchemaRecorder schema_recorder_;// 136B }; } diff --git a/src/storage/tx/ob_gts_local_cache.cpp b/src/storage/tx/ob_gts_local_cache.cpp index d72325483..ca93f3396 100644 --- a/src/storage/tx/ob_gts_local_cache.cpp +++ b/src/storage/tx/ob_gts_local_cache.cpp @@ -25,7 +25,6 @@ void ObGTSLocalCache::reset() { srr_.reset(); gts_ = 0; - barrier_ts_ = 0; latest_srr_.reset(); receive_gts_ts_.reset(); } @@ -48,7 +47,7 @@ int ObGTSLocalCache::update_gts(const MonotonicTs srr, //The update sequence must be receive_gts_ts first, then gts, then srr (void)atomic_update(&receive_gts_ts_.mts_, receive_gts_ts.mts_); (void)atomic_update(>s_, gts); - update = (atomic_update(&srr_.mts_, srr.mts_) && (ATOMIC_LOAD(&barrier_ts_) <= gts)); + update = atomic_update(&srr_.mts_, srr.mts_); } return ret; @@ -57,8 +56,7 @@ int ObGTSLocalCache::update_gts(const MonotonicTs srr, // While updating srr and gts, it is also necessary to check whether gts crosses the barrier ts int ObGTSLocalCache::update_gts_and_check_barrier(const MonotonicTs srr, const int64_t gts, - const MonotonicTs receive_gts_ts, - bool &is_cross_barrier) + const MonotonicTs receive_gts_ts) { int ret = OB_SUCCESS; @@ -71,7 +69,6 @@ int ObGTSLocalCache::update_gts_and_check_barrier(const MonotonicTs srr, (void)atomic_update(&receive_gts_ts_.mts_, receive_gts_ts.mts_); (void)atomic_update(>s_, gts); (void)atomic_update(&srr_.mts_, srr.mts_); - is_cross_barrier = (ATOMIC_LOAD(&barrier_ts_) <= gts); } return ret; @@ -85,7 +82,7 @@ int ObGTSLocalCache::update_gts(const int64_t gts, bool &update) ret = OB_INVALID_ARGUMENT; TRANS_LOG(WARN, "invalid argument", KR(ret), K(gts)); } else { - update = (atomic_update(>s_, gts) && (ATOMIC_LOAD(&barrier_ts_) <= gts)); + update = atomic_update(>s_, gts); } return ret; @@ -95,8 +92,7 @@ int ObGTSLocalCache::get_gts(int64_t >s) const { int ret = OB_SUCCESS; const int64_t tmp_gts = ATOMIC_LOAD(>s_); - const int64_t barrier_ts = ATOMIC_LOAD(&barrier_ts_); - if (OB_UNLIKELY(barrier_ts > tmp_gts) || OB_UNLIKELY(0 == tmp_gts)) { + if (OB_UNLIKELY(0 == tmp_gts)) { ret = OB_EAGAIN; } else { //Here should not add 1 @@ -120,8 +116,7 @@ int ObGTSLocalCache::get_gts(const MonotonicTs stc, // Must get gts first, then receive_gts_ts const int64_t tmp_gts = ATOMIC_LOAD(>s_); const int64_t tmp_receive_gts_ts = ATOMIC_LOAD(&receive_gts_ts_.mts_); - const int64_t barrier_ts = ATOMIC_LOAD(&barrier_ts_); - if (barrier_ts > tmp_gts || 0 == tmp_gts) { + if (0 == tmp_gts) { ret = OB_EAGAIN; need_send_rpc = true; } else if (stc.mts_ > srr) { @@ -164,19 +159,5 @@ int ObGTSLocalCache::update_latest_srr(const MonotonicTs latest_srr) return ret; } -int ObGTSLocalCache::update_base_ts(const int64_t base_ts) -{ - int ret = OB_SUCCESS; - - if (OB_UNLIKELY(base_ts < 0) || base_ts >= INT64_MAX/2) { - ret = OB_INVALID_ARGUMENT; - TRANS_LOG(WARN, "invalid argument", KR(ret), K(base_ts)); - } else { - (void)atomic_update(&barrier_ts_, base_ts); - } - - return ret; -} - } // transaction } // oceanbase diff --git a/src/storage/tx/ob_gts_local_cache.h b/src/storage/tx/ob_gts_local_cache.h index e45c1e5cd..b9c224919 100644 --- a/src/storage/tx/ob_gts_local_cache.h +++ b/src/storage/tx/ob_gts_local_cache.h @@ -37,8 +37,7 @@ public: bool &update); int update_gts_and_check_barrier(const MonotonicTs srr, const int64_t gts, - const MonotonicTs receive_gts_ts, - bool &is_cross_barrier); + const MonotonicTs receive_gts_ts); int update_gts(const int64_t gts, bool &update); int get_gts(int64_t >s) const; MonotonicTs get_latest_srr() const { return MonotonicTs(ATOMIC_LOAD(&latest_srr_.mts_)); } @@ -46,16 +45,13 @@ public: int get_gts(const MonotonicTs stc, int64_t >s, MonotonicTs &receive_gts_ts, bool &need_send_rpc) const; int get_srr_and_gts_safe(MonotonicTs &srr, int64_t >s, MonotonicTs &receive_gts_ts) const; int update_latest_srr(const MonotonicTs latest_srr); - int update_base_ts(const int64_t base_ts); - TO_STRING_KV(K_(srr), K_(gts), K_(barrier_ts), K_(latest_srr)); + TO_STRING_KV(K_(srr), K_(gts), K_(latest_srr)); private: // send rpc request timestamp MonotonicTs srr_; // The latest local gts value is always less than or equal to the gts leader int64_t gts_; - // next timestamp - int64_t barrier_ts_; MonotonicTs latest_srr_; // receive gts MonotonicTs receive_gts_ts_; diff --git a/src/storage/tx/ob_gts_source.cpp b/src/storage/tx/ob_gts_source.cpp index fba73a476..c48c8db36 100644 --- a/src/storage/tx/ob_gts_source.cpp +++ b/src/storage/tx/ob_gts_source.cpp @@ -200,7 +200,6 @@ int ObGtsSource::get_gts(const MonotonicTs stc, int tmp_ret = OB_SUCCESS; int64_t tmp_gts = 0; bool need_send_rpc = false; - ObAddr leader; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; @@ -220,18 +219,18 @@ int ObGtsSource::get_gts(const MonotonicTs stc, TRANS_LOG(DEBUG, "query_gts", KR(ret), K(need_send_rpc), K(stc), K(gts_local_cache_.get_latest_srr())); // When getting gts, if the global timestamp service is locally, get gts directly - if (OB_SUCCESS != (tmp_ret = get_gts_leader_(leader))) { - TRANS_LOG(WARN, "get gts leader fail", K(tmp_ret), K_(tenant_id)); + if (!gts_cache_leader_.is_valid() && OB_SUCCESS != (tmp_ret = refresh_gts_cache_leader_())) { + TRANS_LOG(WARN, "refresh gts leader fail", K(tmp_ret), K_(tenant_id)); (void)refresh_gts_location_(); - } else if (leader == server_) { + } else if (gts_cache_leader_ == server_) { MTL_SWITCH(tenant_id_) { ret = OB_EAGAIN; // When getting gts, if the global timestamp service is locally, get gts directly // Here the error code is overwritten by the result of the local call - if (OB_SUCCESS != (tmp_ret = get_gts_from_local_timestamp_service_(leader, gts, receive_gts_ts))) { + if (OB_SUCCESS != (tmp_ret = get_gts_from_local_timestamp_service_(gts, receive_gts_ts))) { if (OB_EAGAIN != tmp_ret) { if (EXECUTE_COUNT_PER_SEC(16)) { - TRANS_LOG(WARN, "get_gts_from_local_timestamp_service fail", K(leader), K_(server), K(tmp_ret)); + TRANS_LOG(WARN, "get_gts_from_local_timestamp_service fail", K_(gts_cache_leader), K_(server), K(tmp_ret)); } refresh_gts_location(); } @@ -245,11 +244,11 @@ int ObGtsSource::get_gts(const MonotonicTs stc, } else { // If not in local, refresh gts if (need_send_rpc) { - if (OB_SUCCESS != (tmp_ret = query_gts_(leader))) { - TRANS_LOG(WARN, "query gts fail", K(tmp_ret), K(leader)); + if (OB_SUCCESS != (tmp_ret = query_gts_(gts_cache_leader_))) { + TRANS_LOG(WARN, "query gts fail", K(tmp_ret), K_(gts_cache_leader)); } } - TRANS_LOG(DEBUG, "after query gts", KR(tmp_ret), K(leader), K(need_send_rpc)); + TRANS_LOG(DEBUG, "after query gts", KR(tmp_ret), K_(gts_cache_leader), K(need_send_rpc)); } // If ret is not OB_SUCCESS, it means that an asynchronous task needs to be added to wait for the subsequent gts value if (OB_FAIL(ret) && NULL != task) { @@ -275,8 +274,7 @@ int ObGtsSource::get_gts(const MonotonicTs stc, } // Get the timestamp from the local timestamp service -int ObGtsSource::get_gts_from_local_timestamp_service_(ObAddr &leader, - int64_t >s, +int ObGtsSource::get_gts_from_local_timestamp_service_(int64_t >s, MonotonicTs &receive_gts_ts) { int ret = OB_SUCCESS; @@ -286,44 +284,34 @@ int ObGtsSource::get_gts_from_local_timestamp_service_(ObAddr &leader, ObTimestampAccess *timestamp_access = MTL(ObTimestampAccess *); if (OB_ISNULL(timestamp_access)) { ret = OB_ERR_UNEXPECTED; - TRANS_LOG(ERROR, "timestamp access is null", KR(ret), KP(timestamp_access), K_(tenant_id), K(leader)); + TRANS_LOG(ERROR, "timestamp access is null", KR(ret), KP(timestamp_access), K_(tenant_id)); } else if (OB_FAIL(timestamp_access->get_number(ObTimeUtility::current_time_ns(), tmp_gts))) { if (EXECUTE_COUNT_PER_SEC(100)) { - TRANS_LOG(WARN, "global_timestamp_service get gts fail", K(leader), K(tmp_gts), KR(ret)); + TRANS_LOG(WARN, "global_timestamp_service get gts fail", K(tmp_gts), KR(ret)); } if (OB_NOT_MASTER == ret) { gts_cache_leader_.reset(); } } else { - if (leader.is_valid()) { - gts_cache_leader_ = leader; - } const MonotonicTs tmp_receive_gts_ts = MonotonicTs::current_time(); - bool is_cross_barrier = false; if (OB_FAIL(gts_local_cache_.update_gts_and_check_barrier(srr, tmp_gts, - tmp_receive_gts_ts, - is_cross_barrier))) { - TRANS_LOG(WARN, "update gts fail", K(srr), K(gts), K(receive_gts_ts), - K(is_cross_barrier), KR(ret)); - } else if (is_cross_barrier) { + tmp_receive_gts_ts))) { + TRANS_LOG(WARN, "update gts fail", K(srr), K(gts), K(receive_gts_ts), KR(ret)); + } else { // get gts success, need to overwrite the OB_EAGAIN error code to OB_SUCCESS gts = tmp_gts; receive_gts_ts = tmp_receive_gts_ts; - ret = OB_SUCCESS; - } else { - ret = OB_EAGAIN; } } return ret; } -int ObGtsSource::get_gts_from_local_timestamp_service_(ObAddr &leader, - int64_t >s) +int ObGtsSource::get_gts_from_local_timestamp_service_(int64_t >s) { MonotonicTs unused_receive_gts_ts; - return get_gts_from_local_timestamp_service_(leader, gts, unused_receive_gts_ts); + return get_gts_from_local_timestamp_service_(gts, unused_receive_gts_ts); } int ObGtsSource::get_srr(MonotonicTs &srr) @@ -388,7 +376,6 @@ int ObGtsSource::wait_gts_elapse(const int64_t ts, ObTsCbTask *task, bool &need_ } else { int64_t gts = 0; bool tmp_need_wait = false; - ObAddr leader; int tmp_ret = OB_SUCCESS; if (OB_FAIL(gts_local_cache_.get_gts(gts))) { if (OB_UNLIKELY(OB_EAGAIN != ret)) { @@ -405,14 +392,14 @@ int ObGtsSource::wait_gts_elapse(const int64_t ts, ObTsCbTask *task, bool &need_ } if (OB_SUCCESS == ret && tmp_need_wait) { // When getting gts, if the global timestamp service is locally, get gts directly - if (OB_SUCCESS != (tmp_ret = get_gts_leader_(leader))) { - TRANS_LOG(WARN, "get gts leader fail", K(tmp_ret), K_(tenant_id)); + if (!gts_cache_leader_.is_valid() && OB_SUCCESS != (tmp_ret = refresh_gts_cache_leader_())) { + TRANS_LOG(WARN, "refresh gts leader fail", K(tmp_ret), K_(tenant_id)); (void)refresh_gts_location_(); - } else if (leader == server_) { + } else if (gts_cache_leader_ == server_) { // When getting gts, if the global timestamp service is locally, get gts directly - if (OB_SUCCESS != (tmp_ret = get_gts_from_local_timestamp_service_(leader, gts))) { + if (OB_SUCCESS != (tmp_ret = get_gts_from_local_timestamp_service_(gts))) { if (OB_EAGAIN != tmp_ret && EXECUTE_COUNT_PER_SEC(100)) { - TRANS_LOG(WARN, "get_gts_from_local_timestamp_service fail", K(leader), K_(server), K(tmp_ret)); + TRANS_LOG(WARN, "get_gts_from_local_timestamp_service fail", K_(gts_cache_leader), K_(server), K(tmp_ret)); } } else if (ts <= gts) { tmp_need_wait = false; @@ -465,7 +452,6 @@ int ObGtsSource::wait_gts_elapse(const int64_t ts) TRANS_LOG(WARN, "invalid argument", KR(ret), K(ts)); } else { int64_t gts = 0; - ObAddr leader; if (OB_FAIL(gts_local_cache_.get_gts(gts))) { if (OB_UNLIKELY(OB_EAGAIN != ret)) { TRANS_LOG(WARN, "get gts failed", K(ret)); @@ -479,14 +465,14 @@ int ObGtsSource::wait_gts_elapse(const int64_t ts) if (OB_FAIL(ret)) { int tmp_ret = OB_SUCCESS; // When getting gts, if the global timestamp service is locally, get gts directly - if (OB_SUCCESS != (tmp_ret = get_gts_leader_(leader))) { + if (!gts_cache_leader_.is_valid() && OB_SUCCESS != (tmp_ret = refresh_gts_cache_leader_())) { TRANS_LOG(WARN, "get gts leader fail", K(tmp_ret), K_(tenant_id)); (void)refresh_gts_location_(); - } else if (leader == server_) { + } else if (gts_cache_leader_ == server_) { // When getting gts, if the global timestamp service is locally, get gts directly - if (OB_SUCCESS != (tmp_ret = get_gts_from_local_timestamp_service_(leader, gts))) { + if (OB_SUCCESS != (tmp_ret = get_gts_from_local_timestamp_service_(gts))) { if (OB_EAGAIN != tmp_ret) { - TRANS_LOG(WARN, "get_gts_from_local_timestamp_service fail", K(leader), K_(server), K(tmp_ret)); + TRANS_LOG(WARN, "get_gts_from_local_timestamp_service fail", K_(gts_cache_leader), K_(server), K(tmp_ret)); } } else if (ts <= gts) { ret = OB_SUCCESS; @@ -495,7 +481,7 @@ int ObGtsSource::wait_gts_elapse(const int64_t ts) } } else { // If the leader is not in local, gts needs to be refreshed - if (OB_SUCCESS != (tmp_ret = query_gts_(leader))) { + if (OB_SUCCESS != (tmp_ret = query_gts_(gts_cache_leader_))) { TRANS_LOG(WARN, "refresh gts failed", K(tmp_ret)); } } @@ -522,46 +508,7 @@ int ObGtsSource::refresh_gts(const bool need_refresh) return ret; } -int ObGtsSource::update_base_ts(const int64_t base_ts) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(0 > base_ts)) { - ret = OB_INVALID_ARGUMENT; - TRANS_LOG(WARN, "invalid argument", KR(ret), K(base_ts)); - } else if (OB_FAIL(gts_local_cache_.update_base_ts(base_ts))) { - TRANS_LOG(WARN, "update base ts failed", KR(ret), K(base_ts)); - } else { - } - if (OB_UNLIKELY(OB_SUCCESS != ret)) { - TRANS_LOG(WARN, "update base ts failed", K(ret), K_(tenant_id), K(base_ts), - K_(gts_local_cache)); - } else { - TRANS_LOG(INFO, "update base ts success", K_(tenant_id), K(base_ts), - K_(gts_local_cache)); - } - return ret; -} - -int ObGtsSource::get_base_ts(int64_t &base_ts) -{ - int ret = OB_SUCCESS; - int64_t tmp_base_ts = 0; - if (OB_UNLIKELY(!is_inited_)) { - TRANS_LOG(WARN, "not inited"); - ret = OB_NOT_INIT; - } else if (OB_FAIL(gts_local_cache_.get_gts(tmp_base_ts))) { - } else { - base_ts = tmp_base_ts; - } - if (OB_UNLIKELY(OB_SUCCESS != ret)) { - TRANS_LOG(WARN, "get base ts failed", K(ret), K_(tenant_id)); - } else { - TRANS_LOG(INFO, "get base ts success", K_(tenant_id), K(base_ts)); - } - return ret; -} - -int ObGtsSource::get_gts_leader_(ObAddr &leader) +int ObGtsSource::refresh_gts_cache_leader_() { int ret = OB_SUCCESS; const int64_t cluster_id = GCONF.cluster_id; @@ -572,19 +519,15 @@ int ObGtsSource::get_gts_leader_(ObAddr &leader) return ret; } #endif - if (gts_cache_leader_.is_valid()) { - leader = gts_cache_leader_; - } else if (OB_FAIL(location_adapter_->nonblock_get_leader(cluster_id, tenant_id_, GTS_LS, leader))) { + if (OB_FAIL(location_adapter_->nonblock_get_leader(cluster_id, tenant_id_, GTS_LS, gts_cache_leader_))) { if (EXECUTE_COUNT_PER_SEC(16)) { TRANS_LOG(WARN, "gts nonblock get leader failed", K(ret), K_(tenant_id), K(GTS_LS)); } - } else { - gts_cache_leader_ = leader; } - if (OB_SUCC(ret) && !leader.is_valid()) { + if (OB_SUCC(ret) && !gts_cache_leader_.is_valid()) { ret = OB_LS_LOCATION_LEADER_NOT_EXIST; if (EXECUTE_COUNT_PER_SEC(16)) { - TRANS_LOG(WARN, "gts cache leader is invalid", KR(ret), K(leader), K(*this)); + TRANS_LOG(WARN, "gts cache leader is invalid", KR(ret), K_(gts_cache_leader), K(*this)); } } @@ -606,7 +549,6 @@ int ObGtsSource::query_gts_(const ObAddr &leader) (void)refresh_gts_location_(); } else { gts_statistics_.inc_gts_rpc_cnt(); - ObTransStatistic::get_instance().add_gts_rpc_count(tenant_id_, 1); TRANS_LOG(DEBUG, "post gts request success", K(srr), K_(gts_local_cache)); } return ret; @@ -630,16 +572,15 @@ int ObGtsSource::refresh_gts_location_() int ObGtsSource::refresh_gts_(const bool need_refresh) { int ret = OB_SUCCESS; - ObAddr leader; bool need_refresh_gts_location = need_refresh; - if (OB_FAIL(get_gts_leader_(leader))) { + if (!gts_cache_leader_.is_valid() && OB_FAIL(refresh_gts_cache_leader_())) { if (EXECUTE_COUNT_PER_SEC(16)) { TRANS_LOG(WARN, "get gts leader failed", KR(ret), K_(tenant_id)); } need_refresh_gts_location = true; } else { - ret = query_gts_(leader); + ret = query_gts_(gts_cache_leader_); } if (need_refresh_gts_location) { (void)refresh_gts_location_(); diff --git a/src/storage/tx/ob_gts_source.h b/src/storage/tx/ob_gts_source.h index a45b147d9..890e19604 100644 --- a/src/storage/tx/ob_gts_source.h +++ b/src/storage/tx/ob_gts_source.h @@ -66,7 +66,7 @@ private: int64_t try_wait_gts_elapse_cnt_; }; -class ObGtsSource : public ObITsSource +class ObGtsSource { public: ObGtsSource() : log_interval_(3 * 1000 * 1000), refresh_location_interval_(100 * 1000) { reset(); } @@ -90,22 +90,18 @@ public: int wait_gts_elapse(const int64_t ts, ObTsCbTask *task, bool &need_wait); int wait_gts_elapse(const int64_t ts); int refresh_gts(const bool need_refresh); - int update_base_ts(const int64_t base_ts); - int get_base_ts(int64_t &base_ts); bool is_external_consistent() { return true; } int refresh_gts_location() { return refresh_gts_location_(); } TO_STRING_KV(K_(tenant_id), K_(gts_local_cache), K_(server), K_(gts_cache_leader)); private: - int get_gts_leader_(common::ObAddr &leader); + int refresh_gts_cache_leader_(); int refresh_gts_location_(); int refresh_gts_(const bool need_refresh); int query_gts_(const common::ObAddr &leader); void statistics_(); - int get_gts_from_local_timestamp_service_(common::ObAddr &leader, - int64_t >s, + int get_gts_from_local_timestamp_service_(int64_t >s, MonotonicTs &receive_gts_ts); - int get_gts_from_local_timestamp_service_(common::ObAddr &leader, - int64_t >s); + int get_gts_from_local_timestamp_service_(int64_t >s); public: static const int64_t GET_GTS_QUEUE_COUNT = 1; static const int64_t WAIT_GTS_QUEUE_COUNT = 1; diff --git a/src/storage/tx/ob_i_ts_source.h b/src/storage/tx/ob_i_ts_source.h index 0a352903b..8b0ad8cb8 100644 --- a/src/storage/tx/ob_i_ts_source.h +++ b/src/storage/tx/ob_i_ts_source.h @@ -54,22 +54,6 @@ private: bool need_inc_; }; -class ObITsSource -{ -public: - virtual int update_gts(const int64_t gts, bool &update) = 0; - virtual int get_gts(const MonotonicTs stc, ObTsCbTask *task, int64_t >s, MonotonicTs &receive_gts_ts) = 0; - virtual int get_gts(ObTsCbTask *task, int64_t >s) = 0; - virtual int wait_gts_elapse(const int64_t gts, ObTsCbTask *task, bool &need_wait) = 0; - virtual int wait_gts_elapse(const int64_t gts) = 0; - virtual int refresh_gts(const bool need_refresh) = 0; - virtual int update_base_ts(const int64_t base_ts) = 0; - virtual int get_base_ts(int64_t &base_ts) = 0; - virtual bool is_external_consistent() = 0; -public: - VIRTUAL_TO_STRING_KV("", ""); -}; - } }//end of namespace oceanbase diff --git a/src/storage/tx/ob_trans_ctx.h b/src/storage/tx/ob_trans_ctx.h index 54acef2f6..1eb5714cc 100644 --- a/src/storage/tx/ob_trans_ctx.h +++ b/src/storage/tx/ob_trans_ctx.h @@ -269,8 +269,6 @@ protected: bool has_pending_callback_; // whether the trans can release locks early bool can_elr_; - // del part ctx from hashmap after unlock to avoid deadlock between foreach/remove_if and del - bool need_del_ctx_; // inc opid before ctx unlocked int64_t opid_; diff --git a/src/storage/tx/ob_trans_ctx_lock.cpp b/src/storage/tx/ob_trans_ctx_lock.cpp index 05b05c698..e426cd0ae 100644 --- a/src/storage/tx/ob_trans_ctx_lock.cpp +++ b/src/storage/tx/ob_trans_ctx_lock.cpp @@ -13,6 +13,7 @@ #include "ob_trans_ctx_lock.h" #include "ob_trans_ctx.h" #include "ob_trans_service.h" +#include "common/ob_clock_generator.h" namespace oceanbase { @@ -58,18 +59,14 @@ void CtxLock::after_unlock(CtxLockArg &arg) int CtxLock::lock() { int ret = lock_.wrlock(common::ObLatchIds::TRANS_CTX_LOCK); - if (OB_SUCCESS == ret) { - lock_start_ts_ = ObTimeUtility::fast_current_time(); - } + lock_start_ts_ = ObClockGenerator::getClock(); return ret; } int CtxLock::lock(const int64_t timeout_us) { int ret = lock_.wrlock(common::ObLatchIds::TRANS_CTX_LOCK, ObTimeUtility::current_time() + timeout_us); - if (OB_SUCCESS == ret) { - lock_start_ts_ = ObTimeUtility::fast_current_time(); - } + lock_start_ts_ = ObClockGenerator::getClock(); return ret; } @@ -77,7 +74,7 @@ int CtxLock::try_lock() { int ret = lock_.try_wrlock(common::ObLatchIds::TRANS_CTX_LOCK); if (OB_SUCCESS == ret) { - lock_start_ts_ = ObTimeUtility::fast_current_time(); + lock_start_ts_ = ObClockGenerator::getClock(); } return ret; } @@ -87,7 +84,7 @@ void CtxLock::unlock() CtxLockArg arg; before_unlock(arg); lock_.unlock(); - const int64_t lock_ts = ObTimeUtility::current_time() - lock_start_ts_; + const int64_t lock_ts = ObClockGenerator::getClock() - lock_start_ts_; if (lock_start_ts_ > 0 && lock_ts > WARN_LOCK_TS) { lock_start_ts_ = 0; TRANS_LOG(WARN, "ctx lock too much time", K(arg.trans_id_), K(lock_ts), K(lbt())); @@ -115,59 +112,5 @@ void CtxLockGuard::reset() } } -void TransTableSeqLock::write_lock() -{ - seq_++; - MEM_BARRIER(); -} - -void TransTableSeqLock::write_unlock() -{ - MEM_BARRIER(); - if (seq_ & 1L) { - seq_++; - } -} - -uint64_t TransTableSeqLock::read_begin() -{ - uint64_t seq = ATOMIC_LOAD(&seq_); - MEM_BARRIER(); - return seq; -} - -bool TransTableSeqLock::read_retry(const uint64_t seq) -{ - MEM_BARRIER(); - if (ATOMIC_LOAD(&seq_) != seq) { - return true; - } - return seq & 1L; -} - -CtxTransTableLockGuard::~CtxTransTableLockGuard() -{ - reset(); -} - -void CtxTransTableLockGuard::set(CtxLock &lock, TransTableSeqLock &seqlock) -{ - reset(); - - CtxLockGuard::set(lock); - lock_ = &seqlock; - lock_->write_lock(); -} - -void CtxTransTableLockGuard::reset() -{ - if (lock_) { - lock_->write_unlock(); - lock_ = NULL; - } - CtxLockGuard::reset(); -} - - } // transaction } // oceanbase diff --git a/src/storage/tx/ob_trans_ctx_lock.h b/src/storage/tx/ob_trans_ctx_lock.h index 483d49d7e..c6b1004e7 100644 --- a/src/storage/tx/ob_trans_ctx_lock.h +++ b/src/storage/tx/ob_trans_ctx_lock.h @@ -44,14 +44,12 @@ class CtxLockArg public: CtxLockArg() : trans_id_(), task_list_(), commit_cb_(), has_pending_callback_(false), - need_del_ctx_(false), p_mt_ctx_(NULL) {} public: ObTransID trans_id_; LocalTaskList task_list_; ObTxCommitCallback commit_cb_; bool has_pending_callback_; - bool need_del_ctx_; // It is used to wake up lock queue after submitting the log for elr transaction memtable::ObIMemtableCtx *p_mt_ctx_; }; @@ -110,44 +108,6 @@ private: CtxLock *lock_; }; -class TransTableSeqLock -{ -public: - TransTableSeqLock() : seq_(0) {} - ~TransTableSeqLock() {} - - void write_lock(); - void write_unlock(); - uint64_t read_begin(); - bool read_retry(uint64_t seq); - - DISABLE_COPY_ASSIGN(TransTableSeqLock); -private: - uint64_t seq_; -}; - -class CtxTransTableLockGuard : public CtxLockGuard -{ -public: - CtxTransTableLockGuard() : CtxLockGuard(), lock_(NULL) {} - explicit CtxTransTableLockGuard(CtxLock &lock, - TransTableSeqLock &seqlock, - const bool need_lock = true) - : CtxLockGuard(lock, need_lock), lock_(&seqlock) - { - lock_->write_lock(); - } - - ~CtxTransTableLockGuard(); - - void set(CtxLock &lock, TransTableSeqLock &seqlock); - void reset(); - - DISABLE_COPY_ASSIGN(CtxTransTableLockGuard); -private: - TransTableSeqLock *lock_; -}; - } // transaction } // oceanbase diff --git a/src/storage/tx/ob_trans_ctx_mgr_v4.cpp b/src/storage/tx/ob_trans_ctx_mgr_v4.cpp index a02948255..4ee73042c 100644 --- a/src/storage/tx/ob_trans_ctx_mgr_v4.cpp +++ b/src/storage/tx/ob_trans_ctx_mgr_v4.cpp @@ -470,7 +470,6 @@ int ObLSTxCtxMgr::get_tx_ctx_(const ObTransID &tx_id, const bool for_replay, ObP const int64_t MAX_LOOP_COUNT = 100; int64_t count = 0; int64_t gts = 0; - MonotonicTs unused_ts = MonotonicTs::current_time(); if (IS_NOT_INIT) { TRANS_LOG(WARN, "ObLSTxCtxMgr not inited"); @@ -1507,8 +1506,8 @@ int ObTxCtxMgr::init(const int64_t tenant_id, if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; TRANS_LOG(WARN, "ObTxCtxMgr inited twice", K(*this)); - } else if (OB_FAIL(ls_tx_ctx_mgr_map_.init(ObModIds::OB_HASH_BUCKET_PARTITION_TRANS_CTX))) { - TRANS_LOG(WARN, "ls_tx_ctx_mgr_map_ init error", KR(ret)); + } else if (OB_FAIL(ls_tx_ctx_mgr_map_.init(lib::ObMemAttr(tenant_id, "TxCtxMgr")))) { + TRANS_LOG(WARN, "ls_tx_ctx_mgr_map_ init error", KR(ret), K(tenant_id)); } else if (OB_ISNULL(ts_mgr)) { ret = OB_ERR_UNEXPECTED; TRANS_LOG(WARN, "ts mgr is null"); @@ -2072,7 +2071,7 @@ int ObTxCtxMgr::create_ls(const int64_t tenant_id, TRANS_LOG(WARN, "ls tx service init failed", K(ret), K(ls_id)); ObLSTxCtxMgrFactory::release(ls_tx_ctx_mgr); ls_tx_ctx_mgr = NULL; - } else if (OB_FAIL(ls_tx_ctx_mgr_map_.insert_and_get(ls_id, ls_tx_ctx_mgr))) { + } else if (OB_FAIL(ls_tx_ctx_mgr_map_.insert_and_get(ls_id, ls_tx_ctx_mgr, NULL))) { TRANS_LOG(WARN, "ls_tx_ctx_mgr_map_ insert error", KR(ret), K(ls_id)); ObLSTxCtxMgrFactory::release(ls_tx_ctx_mgr); ls_tx_ctx_mgr = NULL; @@ -2153,7 +2152,7 @@ int ObTxCtxMgr::remove_ls(const ObLSID &ls_id, const bool graceful) // if ls_id has been removed, OB_SUCCESS is returned. if (OB_SUCC(get_ls_tx_ctx_mgr(ls_id, ls_tx_ctx_mgr))) { // remove ls_id transaction context from map - if (OB_FAIL(ls_tx_ctx_mgr_map_.del(ls_id))) { + if (OB_FAIL(ls_tx_ctx_mgr_map_.del(ls_id, ls_tx_ctx_mgr))) { TRANS_LOG(WARN, "remove ls error", KR(ret), K(ls_id)); } else { ATOMIC_INC(&ls_release_cnt_); diff --git a/src/storage/tx/ob_trans_ctx_mgr_v4.h b/src/storage/tx/ob_trans_ctx_mgr_v4.h index aaf904d21..8764fe109 100644 --- a/src/storage/tx/ob_trans_ctx_mgr_v4.h +++ b/src/storage/tx/ob_trans_ctx_mgr_v4.h @@ -140,7 +140,7 @@ const static char OB_SIMPLE_ITERATOR_LABEL_FOR_TX_ID[] = "ObTxCtxMgr"; typedef common::ObSimpleIterator ObTxIDIterator; // LogStream Transaction Context Manager -class ObLSTxCtxMgr: public ObLSTxCtxMgrHashValue +class ObLSTxCtxMgr: public ObTransHashLink { // ut friend class unittest::TestTxCtxTable; @@ -319,6 +319,12 @@ public: // @param [in] fd int dump_single_tx_data_2_text(const int64_t tx_id, FILE *fd); + // check this ObLSTxCtxMgr contains the specified ObLSID + bool contain(const share::ObLSID &ls_id) + { + return ls_id_ == ls_id; + } + public: // Increase this ObLSTxCtxMgr's total_tx_ctx_count void inc_total_tx_ctx_count() { (void)ATOMIC_AAF(&total_tx_ctx_count_, 1); } @@ -487,7 +493,7 @@ public: K_(aggre_rec_scn), K_(prev_aggre_rec_scn), "uref", - (!is_inited_ ? -1 : get_uref())); + (!is_inited_ ? -1 : get_ref())); private: DISALLOW_COPY_AND_ASSIGN(ObLSTxCtxMgr); @@ -779,8 +785,8 @@ public: } }; -typedef common::ObLinkHashMap ObLSTxCtxMgrMap; +typedef transaction::ObTransHashMap ObLSTxCtxMgrMap; class ObTxCtxMgr { diff --git a/src/storage/tx/ob_trans_functor.h b/src/storage/tx/ob_trans_functor.h index 8a3441ce4..a9aaaaa20 100644 --- a/src/storage/tx/ob_trans_functor.h +++ b/src/storage/tx/ob_trans_functor.h @@ -361,19 +361,26 @@ class StopLSFunctor public: StopLSFunctor() {} ~StopLSFunctor() {} - bool operator()(const share::ObLSID &ls_id, ObLSTxCtxMgr *ls_tx_ctx_mgr) + bool operator()(ObLSTxCtxMgr *ls_tx_ctx_mgr) { int tmp_ret = common::OB_SUCCESS; bool bool_ret = false; const bool graceful = false; - if (!ls_id.is_valid() || OB_ISNULL(ls_tx_ctx_mgr)) { - TRANS_LOG(WARN, "invalid argument", K(ls_id), KP(ls_tx_ctx_mgr)); + if (OB_ISNULL(ls_tx_ctx_mgr)) { + TRANS_LOG(WARN, "invalid argument", KP(ls_tx_ctx_mgr)); tmp_ret = OB_INVALID_ARGUMENT; - } else if (OB_TMP_FAIL(ls_tx_ctx_mgr->stop(graceful))) { - TRANS_LOG(WARN, "ObLSTxCtxMgr stop error", K(tmp_ret), K(ls_id)); } else { - bool_ret = true; + const share::ObLSID &ls_id = ls_tx_ctx_mgr->get_ls_id(); + + if (!ls_id.is_valid()) { + TRANS_LOG(WARN, "invalid ls id", K(ls_id), KP(ls_tx_ctx_mgr)); + tmp_ret = OB_INVALID_ARGUMENT; + } else if (OB_TMP_FAIL(ls_tx_ctx_mgr->stop(graceful))) { + TRANS_LOG(WARN, "ObLSTxCtxMgr stop error", K(tmp_ret), K(ls_id)); + } else { + bool_ret = true; + } } return bool_ret; @@ -385,23 +392,30 @@ class WaitLSFunctor public: explicit WaitLSFunctor(int64_t &retry_count) : retry_count_(retry_count) {} ~WaitLSFunctor() {} - bool operator()(const share::ObLSID &ls_id, ObLSTxCtxMgr *ls_tx_ctx_mgr) + bool operator()(ObLSTxCtxMgr *ls_tx_ctx_mgr) { int tmp_ret = common::OB_SUCCESS; bool bool_ret = true; - if (!ls_id.is_valid() || OB_ISNULL(ls_tx_ctx_mgr)) { - TRANS_LOG(WARN, "invalid argument", K(ls_id), KP(ls_tx_ctx_mgr)); + if (OB_ISNULL(ls_tx_ctx_mgr)) { + TRANS_LOG(WARN, "invalid argument", KP(ls_tx_ctx_mgr)); tmp_ret = OB_INVALID_ARGUMENT; - } else if (!ls_tx_ctx_mgr->is_stopped()) { - TRANS_LOG(WARN, "ls_id has not been stopped", K(ls_id)); - tmp_ret = OB_PARTITION_IS_NOT_STOPPED; - } else if (ls_tx_ctx_mgr->get_tx_ctx_count() > 0) { - // if there are unfinished transactions at the ls_id, - // increase retry_count by 1 - ++retry_count_; } else { - // do nothing + const share::ObLSID &ls_id = ls_tx_ctx_mgr->get_ls_id(); + + if (!ls_id.is_valid()) { + TRANS_LOG(WARN, "invalid ls id", K(ls_id), KP(ls_tx_ctx_mgr)); + tmp_ret = OB_INVALID_ARGUMENT; + } else if (!ls_tx_ctx_mgr->is_stopped()) { + TRANS_LOG(WARN, "ls_id has not been stopped", K(ls_id)); + tmp_ret = OB_PARTITION_IS_NOT_STOPPED; + } else if (ls_tx_ctx_mgr->get_tx_ctx_count() > 0) { + // if there are unfinished transactions at the ls_id, + // increase retry_count by 1 + ++retry_count_; + } else { + // do nothing + } } if (common::OB_SUCCESS != tmp_ret) { @@ -419,22 +433,29 @@ class RemoveLSFunctor public: RemoveLSFunctor() {} ~RemoveLSFunctor() {} - bool operator()(const share::ObLSID &ls_id, ObLSTxCtxMgr *ls_tx_ctx_mgr) + bool operator()(ObLSTxCtxMgr *ls_tx_ctx_mgr) { int tmp_ret = common::OB_SUCCESS; bool bool_ret = false; - if (!ls_id.is_valid() || OB_ISNULL(ls_tx_ctx_mgr)) { - TRANS_LOG(WARN, "invalid argument", K(ls_id), KP(ls_tx_ctx_mgr)); + if (OB_ISNULL(ls_tx_ctx_mgr)) { + TRANS_LOG(WARN, "invalid argument", KP(ls_tx_ctx_mgr)); tmp_ret = OB_INVALID_ARGUMENT; - } else if (!ls_tx_ctx_mgr->is_stopped()) { - TRANS_LOG(WARN, "ls_tx_ctx_mgr has not been stopped", K(ls_id)); - tmp_ret = OB_PARTITION_IS_NOT_STOPPED; } else { - // Release all ctx memory on the ls_id - ls_tx_ctx_mgr->destroy(); - ls_tx_ctx_mgr = NULL; - bool_ret = true; + const share::ObLSID &ls_id = ls_tx_ctx_mgr->get_ls_id(); + + if (!ls_id.is_valid()) { + TRANS_LOG(WARN, "invalid ls id", K(ls_id), KP(ls_tx_ctx_mgr)); + tmp_ret = OB_INVALID_ARGUMENT; + } else if (!ls_tx_ctx_mgr->is_stopped()) { + TRANS_LOG(WARN, "ls_tx_ctx_mgr has not been stopped", K(ls_id)); + tmp_ret = OB_PARTITION_IS_NOT_STOPPED; + } else { + // Release all ctx memory on the ls_id + ls_tx_ctx_mgr->destroy(); + ls_tx_ctx_mgr = NULL; + bool_ret = true; + } } UNUSED(tmp_ret); return bool_ret; @@ -445,18 +466,25 @@ class IterateLSIDFunctor { public: explicit IterateLSIDFunctor(ObLSIDIterator &ls_id_iter) : ls_id_iter_(ls_id_iter) {} - bool operator()(const share::ObLSID &ls_id, ObLSTxCtxMgr *ls_tx_ctx_mgr) + bool operator()(ObLSTxCtxMgr *ls_tx_ctx_mgr) { int tmp_ret = common::OB_SUCCESS; bool bool_ret = false; - if (!ls_id.is_valid() || OB_ISNULL(ls_tx_ctx_mgr)) { - TRANS_LOG(WARN, "invalid argument", K(ls_id), KP(ls_tx_ctx_mgr)); + if (OB_ISNULL(ls_tx_ctx_mgr)) { + TRANS_LOG(WARN, "invalid argument", KP(ls_tx_ctx_mgr)); tmp_ret = OB_INVALID_ARGUMENT; - } else if (OB_TMP_FAIL(ls_id_iter_.push(ls_id))) { - TRANS_LOG(WARN, "ObLSIDIterator push ls_id error", K(tmp_ret), K(ls_id)); } else { - bool_ret = true; + const share::ObLSID &ls_id = ls_tx_ctx_mgr->get_ls_id(); + + if (!ls_id.is_valid()) { + TRANS_LOG(WARN, "invalid ls id", K(ls_id), KP(ls_tx_ctx_mgr)); + tmp_ret = OB_INVALID_ARGUMENT; + } else if (OB_TMP_FAIL(ls_id_iter_.push(ls_id))) { + TRANS_LOG(WARN, "ObLSIDIterator push ls_id error", K(tmp_ret), K(ls_id)); + } else { + bool_ret = true; + } } return bool_ret; } @@ -469,34 +497,42 @@ class IterateLSTxCtxMgrStatFunctor public: IterateLSTxCtxMgrStatFunctor(const ObAddr &addr, ObTxCtxMgrStatIterator &tx_ctx_mgr_stat_iter) : tx_ctx_mgr_stat_iter_(tx_ctx_mgr_stat_iter), addr_(addr) {} - bool operator()(const share::ObLSID &ls_id, ObLSTxCtxMgr *ls_tx_ctx_mgr) + bool operator()(ObLSTxCtxMgr *ls_tx_ctx_mgr) { int tmp_ret = common::OB_SUCCESS; bool bool_ret = false; ObLSTxCtxMgrStat ls_tx_ctx_mgr_stat; - if (!ls_id.is_valid() || OB_ISNULL(ls_tx_ctx_mgr)) { - TRANS_LOG(WARN, "invalid argument", K(ls_id), KP(ls_tx_ctx_mgr)); + if (OB_ISNULL(ls_tx_ctx_mgr)) { + TRANS_LOG(WARN, "invalid argument", KP(ls_tx_ctx_mgr)); tmp_ret = OB_INVALID_ARGUMENT; } else { - uint64_t mgr_state = ls_tx_ctx_mgr->get_state_(); - tmp_ret = ls_tx_ctx_mgr_stat.init(addr_, - ls_tx_ctx_mgr->ls_id_, - ls_tx_ctx_mgr->is_master_(mgr_state), - ls_tx_ctx_mgr->is_stopped_(mgr_state), - mgr_state, - ObLSTxCtxMgr::State::state_str(mgr_state), - ls_tx_ctx_mgr->total_tx_ctx_count_, - (int64_t)(&(*ls_tx_ctx_mgr))); - if (OB_SUCCESS != tmp_ret) { - TRANS_LOG(WARN, "ObLSTxCtxMgrStat init error", K_(addr), "ls_tx_ctx_mgr", *ls_tx_ctx_mgr); - } else if (OB_TMP_FAIL(tx_ctx_mgr_stat_iter_.push(ls_tx_ctx_mgr_stat))) { - TRANS_LOG(WARN, "ObTxCtxMgrStatIterator push error", - K(tmp_ret), K(ls_id), "ls_tx_ctx_mgr", *ls_tx_ctx_mgr); + const share::ObLSID &ls_id = ls_tx_ctx_mgr->get_ls_id(); + + if (!ls_id.is_valid()) { + TRANS_LOG(WARN, "invalid ls id", K(ls_id), KP(ls_tx_ctx_mgr)); + tmp_ret = OB_INVALID_ARGUMENT; } else { - bool_ret = true; + uint64_t mgr_state = ls_tx_ctx_mgr->get_state_(); + tmp_ret = ls_tx_ctx_mgr_stat.init(addr_, + ls_tx_ctx_mgr->ls_id_, + ls_tx_ctx_mgr->is_master_(mgr_state), + ls_tx_ctx_mgr->is_stopped_(mgr_state), + mgr_state, + ObLSTxCtxMgr::State::state_str(mgr_state), + ls_tx_ctx_mgr->total_tx_ctx_count_, + (int64_t)(&(*ls_tx_ctx_mgr))); + if (OB_SUCCESS != tmp_ret) { + TRANS_LOG(WARN, "ObLSTxCtxMgrStat init error", K_(addr), "ls_tx_ctx_mgr", *ls_tx_ctx_mgr); + } else if (OB_TMP_FAIL(tx_ctx_mgr_stat_iter_.push(ls_tx_ctx_mgr_stat))) { + TRANS_LOG(WARN, "ObTxCtxMgrStatIterator push error", + K(tmp_ret), K(ls_id), "ls_tx_ctx_mgr", *ls_tx_ctx_mgr); + } else { + bool_ret = true; + } } } + return bool_ret; } private: @@ -656,18 +692,25 @@ class IterateAllLSTxStatFunctor { public: explicit IterateAllLSTxStatFunctor(ObTxStatIterator &tx_stat_iter): tx_stat_iter_(tx_stat_iter) {} - bool operator()(const share::ObLSID &ls_id, ObLSTxCtxMgr *ls_tx_ctx_mgr) + bool operator()(ObLSTxCtxMgr *ls_tx_ctx_mgr) { int tmp_ret = common::OB_SUCCESS; bool bool_ret = false; - if (!ls_id.is_valid() || OB_ISNULL(ls_tx_ctx_mgr)) { - TRANS_LOG(WARN, "invalid argument", K(ls_id), KP(ls_tx_ctx_mgr)); + if (OB_ISNULL(ls_tx_ctx_mgr)) { + TRANS_LOG(WARN, "invalid argument", KP(ls_tx_ctx_mgr)); tmp_ret = OB_INVALID_ARGUMENT; - } else if (OB_TMP_FAIL(ls_tx_ctx_mgr->iterate_tx_ctx_stat(tx_stat_iter_))) { - TRANS_LOG(WARN, "iterate_tx_ctx_stat error", K(tmp_ret), K(ls_id)); } else { - bool_ret = true; + const share::ObLSID &ls_id = ls_tx_ctx_mgr->get_ls_id(); + + if (!ls_id.is_valid()) { + TRANS_LOG(WARN, "invalid ls id", K(ls_id), KP(ls_tx_ctx_mgr)); + tmp_ret = OB_INVALID_ARGUMENT; + } else if (OB_TMP_FAIL(ls_tx_ctx_mgr->iterate_tx_ctx_stat(tx_stat_iter_))) { + TRANS_LOG(WARN, "iterate_tx_ctx_stat error", K(tmp_ret), K(ls_id)); + } else { + bool_ret = true; + } } return bool_ret; } @@ -955,18 +998,25 @@ class PrintAllLSTxCtxFunctor public: PrintAllLSTxCtxFunctor() {} ~PrintAllLSTxCtxFunctor() {} - bool operator()(const share::ObLSID &ls_id, ObLSTxCtxMgr *ls_tx_ctx_mgr) + bool operator()(ObLSTxCtxMgr *ls_tx_ctx_mgr) { int tmp_ret = common::OB_SUCCESS; bool bool_ret = false; const bool verbose = true; - if (!ls_id.is_valid() || OB_ISNULL(ls_tx_ctx_mgr)) { - TRANS_LOG(WARN, "invalid argument", K(ls_id), KP(ls_tx_ctx_mgr)); + if (OB_ISNULL(ls_tx_ctx_mgr)) { + TRANS_LOG(WARN, "invalid argument", KP(ls_tx_ctx_mgr)); tmp_ret = OB_INVALID_ARGUMENT; } else { - ls_tx_ctx_mgr->print_all_tx_ctx(ObLSTxCtxMgr::MAX_HASH_ITEM_PRINT, verbose); - bool_ret = true; + const share::ObLSID &ls_id = ls_tx_ctx_mgr->get_ls_id(); + + if (!ls_id.is_valid()) { + TRANS_LOG(WARN, "invalid ls id", K(ls_id), KP(ls_tx_ctx_mgr)); + tmp_ret = OB_INVALID_ARGUMENT; + } else { + ls_tx_ctx_mgr->print_all_tx_ctx(ObLSTxCtxMgr::MAX_HASH_ITEM_PRINT, verbose); + bool_ret = true; + } } UNUSED(tmp_ret); return bool_ret; diff --git a/src/storage/tx/ob_trans_part_ctx.cpp b/src/storage/tx/ob_trans_part_ctx.cpp index fb80c280d..95b6bf0dd 100644 --- a/src/storage/tx/ob_trans_part_ctx.cpp +++ b/src/storage/tx/ob_trans_part_ctx.cpp @@ -69,7 +69,7 @@ int ObPartTransCtx::init(const uint64_t tenant_id, { int ret = OB_SUCCESS; - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); // default init : just reset immediately default_init_(); @@ -332,7 +332,10 @@ void ObPartTransCtx::reset_log_cbs_() int ObPartTransCtx::start_trans() { int ret = OB_SUCCESS; - const int64_t left_time = trans_expired_time_ - ObClockGenerator::getRealClock(); + // first register task timeout = 10s, + // no need to unregister/register task when sp transaction commit + int64_t default_timeout_us = 10000000; + const int64_t left_time = trans_expired_time_ - ObClockGenerator::getClock(); if (IS_NOT_INIT) { TRANS_LOG(WARN, "ObPartTransCtx not inited"); @@ -349,14 +352,15 @@ int ObPartTransCtx::start_trans() TRANS_LOG(WARN, "transaction is timeout", K(ret), K_(trans_expired_time), KPC(this)); } else { part_trans_action_ = ObPartTransAction::START; - (void)unregister_timeout_task_(); - if (OB_FAIL(register_timeout_task_(left_time))) { - TRANS_LOG(WARN, "register timeout task error", KR(ret), "context", *this); + if (left_time > 0 && left_time < default_timeout_us) { + (void)unregister_timeout_task_(); + if (OB_FAIL(register_timeout_task_(left_time))) { + TRANS_LOG(WARN, "register timeout task error", KR(ret), "context", *this); + } } } if (OB_FAIL(ret)) { set_exiting_(); - (void)unregister_timeout_task_(); } TRANS_LOG(DEBUG, "start trans", K(ret), K(trans_id_), "ctx_ref", get_ref()); REC_TRANS_TRACE_EXT2(tlog_, start_trans, OB_ID(ret), ret, OB_ID(left_time), left_time, OB_ID(ctx_ref), @@ -419,7 +423,7 @@ int ObPartTransCtx::handle_timeout(const int64_t delay) bool commit_expired = now > stmt_expired_time_; common::ObTimeGuard timeguard("part_handle_timeout", 10 * 1000); if (OB_SUCC(lock_.lock(5000000 /*5 seconds*/))) { - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_, false); + CtxLockGuard guard(lock_, false); timeguard.click(); if (IS_NOT_INIT) { TRANS_LOG(WARN, "ObPartTransCtx not inited"); @@ -548,7 +552,7 @@ int ObPartTransCtx::kill(const KillTransArg &arg, ObIArray & int cb_param = OB_TRANS_UNKNOWN; common::ObTimeGuard timeguard("part_kill", 10 * 1000); - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); if (IS_NOT_INIT) { TRANS_LOG(WARN, "ObPartTransCtx not inited"); @@ -680,11 +684,6 @@ int ObPartTransCtx::commit(const ObLSArray &parts, } else if (OB_FAIL(set_app_trace_info_(app_trace_info))) { TRANS_LOG(WARN, "set app trace info error", K(ret), K(app_trace_info), KPC(this)); } else if (FALSE_IT(stmt_expired_time_ = expire_ts)) { - } else if (OB_FAIL(unregister_timeout_task_())) { - TRANS_LOG(WARN, "unregister timeout handler error", K(ret), KPC(this)); - } else if (OB_FAIL(register_timeout_task_(ObServerConfig::get_instance().trx_2pc_retry_interval - + trans_id_.hash() % USEC_PER_SEC))) { - TRANS_LOG(WARN, "register timeout handler error", K(ret), KPC(this)); } else { if (commit_time.is_valid()) { set_stc_(commit_time); @@ -904,7 +903,7 @@ int ObPartTransCtx::replay_start_working_log(const SCN start_working_ts) { int ret = OB_SUCCESS; - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); exec_info_.data_complete_ = false; start_working_log_ts_ = start_working_ts; if (!has_persisted_log_()) { @@ -936,7 +935,7 @@ int ObPartTransCtx::gts_callback_interrupted(const int errcode) bool need_revert_ctx = false; { - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); if (IS_NOT_INIT) { ret = OB_NOT_INIT; TRANS_LOG(ERROR, "ObPartTransCtx not inited", K(ret)); @@ -964,7 +963,7 @@ int ObPartTransCtx::get_gts_callback(const MonotonicTs srr, bool need_revert_ctx = false; { // TRANS_LOG(INFO, "get_gts_callback begin", K(*this)); - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); if (IS_NOT_INIT) { ret = OB_NOT_INIT; TRANS_LOG(WARN, "ObPartTransCtx not inited", K(ret)); @@ -1027,7 +1026,7 @@ int ObPartTransCtx::gts_elapse_callback(const MonotonicTs srr, const SCN >s) int ret = OB_SUCCESS; bool need_revert_ctx = false; { - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); if (IS_NOT_INIT) { ret = OB_NOT_INIT; TRANS_LOG(WARN, "ObPartTransCtx not inited", K(ret)); @@ -1231,7 +1230,7 @@ int ObPartTransCtx::check_scheduler_status() { int ret = OB_SUCCESS; if (OB_SUCCESS == lock_.try_lock()) { - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_, false); + CtxLockGuard guard(lock_, false); // 1. check the status of scheduler on rs bool is_alive = true; bool need_check_scheduler = need_to_ask_scheduler_status_(); @@ -1268,6 +1267,10 @@ int ObPartTransCtx::check_scheduler_status() // ignore msg postting result last_ask_scheduler_status_ts_ = ObClockGenerator::getClock(); } + + if (is_committing_()) { + (void)check_and_register_timeout_task_(); + } } return OB_SUCCESS; } @@ -1275,7 +1278,7 @@ int ObPartTransCtx::check_scheduler_status() int ObPartTransCtx::recover_tx_ctx_table_info(const ObTxCtxTableInfo &ctx_info) { int ret = OB_SUCCESS; - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); if (!ctx_info.is_valid()) { ret = OB_INVALID_ARGUMENT; @@ -1446,7 +1449,7 @@ int ObPartTransCtx::remove_callback_for_uncommited_txn(ObMemtable *mt) int ObPartTransCtx::submit_redo_log(const bool is_freeze) { int ret = OB_SUCCESS; - const int64_t start = ObTimeUtility::fast_current_time(); + ObTimeGuard tg("submit_redo_log", 100000); bool try_submit = false; bool is_tx_committing = false; bool final_log_submitting = false; @@ -1454,6 +1457,7 @@ int ObPartTransCtx::submit_redo_log(const bool is_freeze) if (is_freeze) { // spin lock CtxLockGuard guard(lock_); + tg.click(); ATOMIC_STORE(&is_submitting_redo_log_for_freeze_, true); is_tx_committing = ObTxState::INIT != get_downstream_state(); @@ -1466,10 +1470,11 @@ int ObPartTransCtx::submit_redo_log(const bool is_freeze) } try_submit = true; } + tg.click(); ATOMIC_STORE(&is_submitting_redo_log_for_freeze_, false); if (try_submit) { REC_TRANS_TRACE_EXT2(tlog_, submit_instant_log, Y(ret), OB_ID(arg2), is_freeze, - OB_ID(used), ObTimeUtility::fast_current_time() - start, + OB_ID(used), tg.get_diff(), OB_ID(ctx_ref), get_ref()); } } else if (OB_FAIL(lock_.try_lock())) { @@ -1482,6 +1487,7 @@ int ObPartTransCtx::submit_redo_log(const bool is_freeze) } else { CtxLockGuard guard(lock_, false); + tg.click(); if (mt_ctx_.pending_log_size_too_large()) { is_tx_committing = ObTxState::INIT != get_downstream_state(); @@ -1493,9 +1499,10 @@ int ObPartTransCtx::submit_redo_log(const bool is_freeze) try_submit = true; } } + tg.click(); if (try_submit) { REC_TRANS_TRACE_EXT2(tlog_, submit_instant_log, Y(ret), OB_ID(arg2), is_freeze, - OB_ID(used), ObTimeUtility::fast_current_time() - start, + OB_ID(used), tg.get_diff(), OB_ID(ctx_ref), get_ref()); } } @@ -1626,22 +1633,15 @@ int ObPartTransCtx::tx_end_(const bool commit) int ObPartTransCtx::on_dist_end_(const bool commit) { int ret = OB_SUCCESS; - - int64_t start_us, end_us; - start_us = end_us = 0; // Distributed transactions need to wait for the commit log majority successfully before // unlocking. If you want to know the reason, it is in the ::do_dist_commit - start_us = ObTimeUtility::fast_current_time(); if (OB_FAIL(tx_end_(commit))) { TRANS_LOG(WARN, "trans end error", KR(ret), K(commit), "context", *this); - } else if (FALSE_IT(end_us = ObTimeUtility::fast_current_time())) { } else if (commit) { // reset the early lock release stat after the txn commits elr_handler_.reset_elr_state(); } - ObTransStatistic::get_instance().add_trans_mt_end_count(tenant_id_, 1); - ObTransStatistic::get_instance().add_trans_mt_end_time(tenant_id_, end_us - start_us); TRANS_LOG(DEBUG, "trans end", K(ret), K(trans_id_), K(commit), K(commit_version)); return ret; @@ -1949,6 +1949,22 @@ int ObPartTransCtx::common_on_success_(ObTxLogCb *log_cb) return ret; } +void ObPartTransCtx::check_and_register_timeout_task_() +{ + int64_t tmp_ret = OB_SUCCESS; + + if (!timeout_task_.is_running() + && !timeout_task_.is_registered() + && !is_follower_() + && !is_exiting_) { + const int64_t timeout_left = is_committing_() ? trans_2pc_timeout_ + : MIN(MAX_TRANS_2PC_TIMEOUT_US, MAX(trans_expired_time_ - ObClockGenerator::getClock(), 1000 * 1000)); + if (OB_SUCCESS != (tmp_ret = register_timeout_task_(timeout_left))) { + TRANS_LOG(WARN, "register timeout task failed", KR(tmp_ret), KPC(this)); + } + } +} + int ObPartTransCtx::try_submit_next_log_() { int ret = OB_SUCCESS; @@ -1973,6 +1989,10 @@ int ObPartTransCtx::try_submit_next_log_() } } } + + // ignore retcode + (void)check_and_register_timeout_task_(); + return ret; } @@ -2202,8 +2222,7 @@ int ObPartTransCtx::fill_redo_log_(char *buf, ObRedoLogSubmitHelper &helper) { int ret = OB_SUCCESS; - const bool log_for_lock_node = true; - // !(is_local_tx_() && (part_trans_action_ == ObPartTransAction::COMMIT)); + const bool log_for_lock_node = !(is_local_tx_() && (part_trans_action_ == ObPartTransAction::COMMIT)); if (OB_UNLIKELY(NULL == buf || buf_len < 0 || pos < 0 || buf_len < pos)) { ret = OB_INVALID_ARGUMENT; @@ -2284,6 +2303,7 @@ int ObPartTransCtx::submit_redo_log_(ObTxLogBlock &log_block, need_undo_log = true; } } else if (OB_ENTRY_NOT_EXIST == ret || OB_BLOCK_FROZEN == ret) { + TRANS_LOG(INFO, "no redo log to be flushed", KR(ret), K(*this)); // rewrite ret ret = (OB_ENTRY_NOT_EXIST == ret) ? OB_SUCCESS : ret; has_redo = false; @@ -2294,7 +2314,8 @@ int ObPartTransCtx::submit_redo_log_(ObTxLogBlock &log_block, } need_continue = false; } else if (OB_ERR_TOO_BIG_ROWSIZE == ret) { - TRANS_LOG(ERROR, "too big row size", K(ret), K(*this)); + TRANS_LOG(WARN, "encounter too big row size error," + "maybe local mutator buf is for optimization", K(ret), K(*this)); return_log_cb_(log_cb); log_cb = NULL; } else { @@ -2453,8 +2474,13 @@ int ObPartTransCtx::submit_redo_commit_info_log_(ObTxLogBlock &log_block, TRANS_LOG(WARN, "get log cb failed", KR(ret), K(*this)); } } else if (log_block.get_cb_arg_array().count() == 0) { - ret = OB_ERR_UNEXPECTED; - TRANS_LOG(ERROR, "cb arg array is empty", K(ret), K(log_block)); + if (log_block.is_use_local_buf()) { + ret = OB_EAGAIN; + TRANS_LOG(WARN, "local buf not enough, need retry", KR(ret), K(log_block), K(*this)); + } else { + ret = OB_ERR_UNEXPECTED; + TRANS_LOG(ERROR, "cb arg array is empty", K(ret), K(log_block)); + } return_log_cb_(log_cb); log_cb = NULL; // acquire ctx ref before submit log @@ -2722,18 +2748,36 @@ int ObPartTransCtx::submit_commit_log_() ObRedoLogSubmitHelper helper; ObTxBufferNodeArray multi_source_data; ObTxLogBlockHeader log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_); + const bool local_tx = is_local_tx_(); - if (OB_FAIL(log_block.init(replay_hint, log_block_header))) { - TRANS_LOG(WARN, "init log block failed", KR(ret), K(*this)); - } else if (OB_FAIL(gen_final_mds_array_(multi_source_data))) { + if (OB_FAIL(gen_final_mds_array_(multi_source_data))) { TRANS_LOG(WARN, "gen total multi source data failed", KR(ret), K(*this)); - } else if (is_local_tx_()) { - if (!sub_state_.is_info_log_submitted()) { - prev_lsn.reset(); - if (OB_FAIL(submit_multi_data_source_(log_block))) { - TRANS_LOG(WARN, "submit multi source data failed", KR(ret), K(*this)); - } else if (OB_FAIL(submit_redo_commit_info_log_(log_block, has_redo, helper))) { - TRANS_LOG(WARN, "submit redo commit state log failed", KR(ret), K(*this)); + } else { + bool use_local_block_buf = local_tx + && multi_source_data.count() == 0 + && mt_ctx_.get_pending_log_size() < ObTxAdaptiveLogBuf::DEFAULT_MIN_LOG_BUF_SIZE / 4; // 512B + if (OB_FAIL(log_block.init(replay_hint, log_block_header, use_local_block_buf))) { + TRANS_LOG(WARN, "init log block failed", KR(ret), K(*this)); + } else if (local_tx) { + if (!sub_state_.is_info_log_submitted()) { + prev_lsn.reset(); + if (OB_FAIL(submit_multi_data_source_(log_block))) { + TRANS_LOG(WARN, "submit multi source data failed", KR(ret), K(*this)); + } else if (OB_SUCC(submit_redo_commit_info_log_(log_block, has_redo, helper))) { + // do nothing + } else if (use_local_block_buf) { + // realloc log buf and retry submit log + log_block.reset(); + if (OB_FAIL(log_block.init(replay_hint, log_block_header, false /*use_local_block_buf*/))) { + TRANS_LOG(WARN, "init log block failed", KR(ret), K(*this)); + } else if (OB_FAIL(submit_redo_commit_info_log_(log_block, has_redo, helper))) { + TRANS_LOG(WARN, "submit redo commit state log failed", KR(ret), K(*this)); + } else { + // do nothing + } + } else { + TRANS_LOG(WARN, "submit redo commit state log failed", KR(ret), K(*this)); + } } } } @@ -2742,7 +2786,7 @@ int ObPartTransCtx::submit_commit_log_() const uint64_t checksum = (exec_info_.need_checksum_ && !is_incomplete_replay_ctx_ ? mt_ctx_.calc_checksum_all() : 0); SCN log_commit_version; - if (!is_local_tx_()) { + if (!local_tx) { log_commit_version = ctx_tx_data_.get_commit_version(); if (OB_FAIL(get_prev_log_lsn_(log_block, ObTxLogType::TX_PREPARE_LOG, prev_lsn))) { TRANS_LOG(WARN, "get prev log lsn failed", K(ret), K(*this)); @@ -3421,7 +3465,7 @@ int ObPartTransCtx::submit_log(const ObTwoPhaseCommitLogType &log_type) int ObPartTransCtx::try_submit_next_log() { - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); return try_submit_next_log_(); } @@ -3518,7 +3562,7 @@ int ObPartTransCtx::push_repalying_log_ts(const SCN log_ts_ns) { int ret = OB_SUCCESS; - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); if (log_ts_ns < exec_info_.max_applying_log_ts_) { TRANS_LOG(WARN, @@ -3536,7 +3580,7 @@ int ObPartTransCtx::push_replayed_log_ts(SCN log_ts_ns, const palf::LSN &offset) { int ret = OB_SUCCESS; - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); if (exec_info_.max_applied_log_ts_ < log_ts_ns) { exec_info_.max_applied_log_ts_ = log_ts_ns; @@ -3664,7 +3708,7 @@ int ObPartTransCtx::validate_replay_log_entry_no(bool first_created_ctx, { int ret = OB_SUCCESS; - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); if (first_created_ctx) { @@ -3739,7 +3783,7 @@ int ObPartTransCtx::replay_redo_in_ctx(const ObTxRedoLog &redo_log, lib::Worker::CompatMode mode = lib::Worker::CompatMode::INVALID; bool need_replay = true; - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); if (OB_FAIL(check_replay_avaliable_(offset, timestamp, part_log_no, need_replay))) { TRANS_LOG(WARN, "check replay available failed", KR(ret), K(offset), K(timestamp), K(*this)); @@ -3994,7 +4038,7 @@ int ObPartTransCtx::replay_prepare(const ObTxPrepareLog &prepare_log, // const int64_t start = ObTimeUtility::fast_current_time(); bool need_replay = true; - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); if (OB_FAIL(check_replay_avaliable_(offset, timestamp, part_log_no, need_replay))) { TRANS_LOG(WARN, "check replay available failed", KR(ret), K(offset), K(timestamp), K(*this)); @@ -4065,7 +4109,7 @@ int ObPartTransCtx::replay_commit(const ObTxCommitLog &commit_log, const SCN commit_version = commit_log.get_commit_version(); bool need_replay = true; - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); // TODO replace participants_ with prepare_log_info_arr_ for transfer if (OB_FAIL(check_replay_avaliable_(offset, timestamp, part_log_no, need_replay))) { @@ -4168,7 +4212,7 @@ int ObPartTransCtx::replay_clear(const ObTxClearLog &clear_log, common::ObTimeGuard timeguard("replay_clear", 10 * 1000); // const int64_t start = ObTimeUtility::fast_current_time(); bool need_replay = true; - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); if (OB_FAIL(check_replay_avaliable_(offset, timestamp, part_log_no, need_replay))) { TRANS_LOG(WARN, "check replay available failed", KR(ret), K(offset), K(timestamp), K(*this)); @@ -4242,7 +4286,7 @@ int ObPartTransCtx::replay_abort(const ObTxAbortLog &abort_log, // const int64_t start = ObTimeUtility::fast_current_time(); bool need_replay = false; - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); if (OB_FAIL(check_replay_avaliable_(offset, timestamp, part_log_no, need_replay))) { TRANS_LOG(WARN, "check replay available failed", KR(ret), K(offset), K(timestamp), K(*this)); @@ -4453,7 +4497,7 @@ int ObPartTransCtx::switch_to_leader(const SCN &start_working_ts) int ret = OB_SUCCESS; common::ObTimeGuard timeguard("switch to leader", 10 * 1000); - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); TxCtxStateHelper state_helper(role_state_); timeguard.click(); if (IS_NOT_INIT) { @@ -4553,7 +4597,7 @@ int ObPartTransCtx::switch_to_follower_forcedly(ObIArray &cb { int ret = OB_SUCCESS; common::ObTimeGuard timeguard("switch_to_follower_forcely", 10 * 1000); - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); TxCtxStateHelper state_helper(role_state_); if (IS_NOT_INIT) { @@ -5307,7 +5351,7 @@ int ObPartTransCtx::del_retain_ctx() bool need_del = false; { - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); if (RetainCause::UNKOWN == get_retain_cause()) { ret = OB_ERR_UNEXPECTED; @@ -5542,7 +5586,7 @@ int ObPartTransCtx::supplement_undo_actions_if_exist_() int ObPartTransCtx::check_status() { - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); return check_status_(); } @@ -5603,7 +5647,7 @@ int ObPartTransCtx::start_access(const ObTxDesc &tx_desc, const int64_t data_scn) { int ret = OB_SUCCESS; - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); if (OB_FAIL(check_status_())) { } else if (tx_desc.op_sn_ < last_op_sn_) { ret = OB_TRANS_SQL_SEQUENCE_ILLEGAL; @@ -5643,7 +5687,7 @@ int ObPartTransCtx::start_access(const ObTxDesc &tx_desc, int ObPartTransCtx::end_access() { int ret = OB_SUCCESS; - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); --pending_write_; mt_ctx_.dec_ref(); mt_ctx_.revert_callback_list(); @@ -5686,7 +5730,7 @@ int ObPartTransCtx::rollback_to_savepoint(const int64_t op_sn, { int ret = OB_SUCCESS; bool need_write_log = false; - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); if (OB_FAIL(check_status_())) { } else if(!busy_cbs_.is_empty()) { ret = OB_NEED_RETRY; @@ -5829,7 +5873,7 @@ int ObPartTransCtx::abort(const int reason) { UNUSED(reason); int ret = OB_SUCCESS; - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); if (OB_UNLIKELY(is_follower_())) { ret = OB_NOT_MASTER; TRANS_LOG(WARN, "not master", KR(ret), KPC(this)); @@ -5857,7 +5901,7 @@ int ObPartTransCtx::abort(const int reason) int ObPartTransCtx::tx_keepalive_response_(const int64_t status) { int ret = OB_SUCCESS; - CtxTransTableLockGuard guard(lock_, trans_table_seqlock_); + CtxLockGuard guard(lock_); if (OB_TRANS_CTX_NOT_EXIST == status && can_be_recycled_()) { if (REACH_TIME_INTERVAL(5 * 1000 * 1000)) { @@ -6021,13 +6065,7 @@ int ObPartTransCtx::do_force_kill_tx_() int ObPartTransCtx::on_local_commit_tx_() { int ret = OB_SUCCESS; - bool need_wait = false; - - int64_t start_us, end_us; - - start_us = end_us = 0; - common::ObTimeGuard tg("part_ctx::on_local_commit", 100 * 1000); if (!sub_state_.is_gts_waiting()) { @@ -6037,15 +6075,15 @@ int ObPartTransCtx::on_local_commit_tx_() } else if (OB_FAIL(wait_gts_elapse_commit_version_(need_wait))) { TRANS_LOG(WARN, "wait gts elapse commit version failed", KR(ret), KPC(this)); } else if (FALSE_IT(tg.click())) { - } else if (FALSE_IT(start_us = ObTimeUtility::fast_current_time())) { } else if (OB_FAIL(tx_end_(true /*commit*/))) { TRANS_LOG(WARN, "trans end error", KR(ret), "context", *this); - } else if (FALSE_IT(end_us = ObTimeUtility::fast_current_time())) { } else if (FALSE_IT(elr_handler_.reset_elr_state())) { } else if (OB_FAIL(trans_clear_())) { TRANS_LOG(WARN, "local tx clear error", KR(ret), K(*this)); - } else if (OB_FAIL(notify_data_source_(NotifyType::ON_COMMIT, ctx_tx_data_.get_end_log_ts(), - false, exec_info_.multi_data_source_))) { + } else if (OB_FAIL(notify_data_source_(NotifyType::ON_COMMIT, + ctx_tx_data_.get_end_log_ts(), + false, + exec_info_.multi_data_source_))) { TRANS_LOG(WARN, "notify data source failed", KR(ret), K(*this)); } else if (FALSE_IT(set_durable_state_(ObTxState::COMMIT))) { @@ -6070,9 +6108,6 @@ int ObPartTransCtx::on_local_commit_tx_() TRANS_LOG(INFO, "on local commit cost too much time", K(ret), K(need_wait), K(tg), K(*this)); } - ObTransStatistic::get_instance().add_trans_mt_end_count(tenant_id_, 1); - ObTransStatistic::get_instance().add_trans_mt_end_time(tenant_id_, end_us - start_us); - return ret; } @@ -6080,18 +6115,10 @@ int ObPartTransCtx::on_local_abort_tx_() { int ret = OB_SUCCESS; - int64_t start_us, end_us; - - start_us = end_us = 0; - ObTxBufferNodeArray tmp_array; - if (OB_FALSE_IT(start_us = ObTimeUtility::fast_current_time())) { - - } else if (OB_FAIL(tx_end_(false /*commit*/))) { + if (OB_FAIL(tx_end_(false /*commit*/))) { TRANS_LOG(WARN, "trans end error", KR(ret), K(commit_version), "context", *this); - } else if (FALSE_IT(end_us = ObTimeUtility::fast_current_time())) { - } else if (OB_FAIL(trans_clear_())) { TRANS_LOG(WARN, "local tx clear error", KR(ret), K(*this)); } else if (OB_FAIL(gen_total_mds_array_(tmp_array))) { @@ -6111,9 +6138,6 @@ int ObPartTransCtx::on_local_abort_tx_() set_exiting_(); } - ObTransStatistic::get_instance().add_trans_mt_end_count(tenant_id_, 1); - ObTransStatistic::get_instance().add_trans_mt_end_time(tenant_id_, end_us - start_us); - return ret; } int ObPartTransCtx::dump_2_text(FILE *fd) diff --git a/src/storage/tx/ob_trans_part_ctx.h b/src/storage/tx/ob_trans_part_ctx.h index 27426cb24..f7ef4b2e3 100644 --- a/src/storage/tx/ob_trans_part_ctx.h +++ b/src/storage/tx/ob_trans_part_ctx.h @@ -80,7 +80,7 @@ enum namespace transaction { -const static int64_t OB_TX_MAX_LOG_CBS = 32; +const static int64_t OB_TX_MAX_LOG_CBS = 3; const static int64_t RESERVE_LOG_CALLBACK_COUNT_FOR_FREEZING = 1; // participant transaction context @@ -257,6 +257,7 @@ private: int common_on_success_(ObTxLogCb * log_cb); int on_success_ops_(ObTxLogCb * log_cb); + void check_and_register_timeout_task_(); // bool need_commit_barrier(); @@ -681,7 +682,6 @@ private: int64_t last_ask_scheduler_status_ts_; int64_t cur_query_start_time_; - mutable TransTableSeqLock trans_table_seqlock_; ObCLogEncryptInfo clog_encrypt_info_; /* diff --git a/src/storage/tx/ob_ts_mgr.cpp b/src/storage/tx/ob_ts_mgr.cpp index 4cf7ac23a..4d85497a8 100644 --- a/src/storage/tx/ob_ts_mgr.cpp +++ b/src/storage/tx/ob_ts_mgr.cpp @@ -37,22 +37,10 @@ using namespace obrpc; namespace transaction { -ObTsSourceGuard::~ObTsSourceGuard() +ObTsSourceInfo::ObTsSourceInfo() : is_inited_(false), + tenant_id_(OB_INVALID_TENANT_ID), + last_access_ts_(0) { - if (NULL != ts_source_ && NULL != ts_source_info_) { - ts_source_info_->revert_ts_source_(*this); - } -} - -ObTsSourceInfo::ObTsSourceInfo() : is_inited_(false), is_valid_(false), - tenant_id_(OB_INVALID_TENANT_ID), last_check_switch_ts_(0), - last_obtain_switch_ts_(0), - check_switch_interval_(DEFAULT_CHECK_SWITCH_INTERVAL_US), - cur_ts_type_(TS_SOURCE_GTS), last_access_ts_(0) -{ - for (int64_t i = 0; i < MAX_TS_SOURCE; i++) { - ts_source_[i] = NULL; - } } int ObTsSourceInfo::init(const uint64_t tenant_id) @@ -61,16 +49,11 @@ int ObTsSourceInfo::init(const uint64_t tenant_id) if (!is_valid_tenant_id(tenant_id)) { ret = OB_INVALID_ARGUMENT; TRANS_LOG(WARN, "invalid argument", KR(ret), K(tenant_id)); - } else if (OB_FAIL(rwlock_.init(lib::ObMemAttr(tenant_id, "TsSourceInfo")))) { - TRANS_LOG(WARN, "ObQSyncLock init fail", KR(ret), K(tenant_id)); } else { - is_valid_ = true; tenant_id_ = tenant_id; last_access_ts_ = ObClockGenerator::getClock(); - last_obtain_switch_ts_ = ObClockGenerator::getClock(); - ts_source_[TS_SOURCE_GTS] = >s_source_; is_inited_ = true; - TRANS_LOG(INFO, "ts source info init success", K(tenant_id), K_(cur_ts_type)); + TRANS_LOG(INFO, "ts source info init success", K(tenant_id)); } return ret; } @@ -85,84 +68,6 @@ void ObTsSourceInfo::destroy() } } -int ObTsSourceInfo::get_ts_source(const uint64_t tenant_id, ObTsSourceGuard &guard, bool &is_valid) -{ - int ret = OB_SUCCESS; - rwlock_.rdlock(); - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - TRANS_LOG(WARN, "not init", K(ret)); - } else if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id)) || OB_UNLIKELY(tenant_id_ != tenant_id)) { - ret = OB_INVALID_ARGUMENT; - TRANS_LOG(WARN, "invalid argument", KR(ret), K(tenant_id), K(tenant_id_)); - } else { - int cur_ts_type = cur_ts_type_; - is_valid = is_valid_; - guard.set(this, ts_source_[cur_ts_type], cur_ts_type); - } - if (OB_FAIL(ret)) { - rwlock_.rdunlock(); - } - return ret; -} - -int ObTsSourceInfo::check_and_switch_ts_source(const uint64_t tenant_id) -{ - int ret = OB_SUCCESS; - const int64_t now = ObClockGenerator::getClock(); - // new ts type must be set TS_SOURCE_UNKNOWN - int64_t new_ts_type = TS_SOURCE_UNKNOWN; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - TRANS_LOG(WARN, "not init", K(ret)); - } else if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id)) || OB_UNLIKELY(tenant_id_ != tenant_id)) { - ret = OB_INVALID_ARGUMENT; - TRANS_LOG(WARN, "invalid argument", KR(ret), K(tenant_id), K(tenant_id_)); - } else if (now - last_check_switch_ts_ < check_switch_interval_) { - // do nothing - } else { - last_check_switch_ts_ = now; - // ignore tmp_ret - if (OB_FAIL(ObTsMgr::get_cur_ts_type(tenant_id, new_ts_type))) { - TRANS_LOG(WARN, "get cur ts type failed", K(ret), K(tenant_id)); - check_switch_interval_ += DEFAULT_CHECK_SWITCH_INTERVAL_US; - if (check_switch_interval_ > MAX_CHECK_SWITCH_INTERVAL_US) { - check_switch_interval_ = MAX_CHECK_SWITCH_INTERVAL_US; - } - } else { - check_switch_interval_ = DEFAULT_CHECK_SWITCH_INTERVAL_US; - last_obtain_switch_ts_ = now; - if (OB_UNLIKELY(cur_ts_type_ != new_ts_type)) { - rwlock_.wrlock(); - if (TS_SOURCE_UNKNOWN != new_ts_type - && cur_ts_type_ != new_ts_type) { - if (OB_FAIL(switch_ts_source_(tenant_id, new_ts_type))) { - TRANS_LOG(ERROR, "switch ts source failed", K(ret), K(new_ts_type)); - } - } - rwlock_.wrunlock(); - } - } - } - return ret; -} - -int ObTsSourceInfo::set_invalid() -{ - int ret = OB_SUCCESS; - rwlock_.wrlock(); - if (is_valid_) { - const int64_t task_count = gts_source_.get_task_count(); - if (0 == task_count) { - is_valid_ = false; - } else { - ret = OB_EAGAIN; - } - } - rwlock_.wrunlock(); - return ret; -} - int ObTsSourceInfo::check_if_tenant_has_been_dropped(const uint64_t tenant_id, bool &has_dropped) { int ret = OB_SUCCESS; @@ -188,57 +93,13 @@ int ObTsSourceInfo::check_if_tenant_has_been_dropped(const uint64_t tenant_id, b int ObTsSourceInfo::gts_callback_interrupted(const int errcode) { int ret = OB_SUCCESS; - rwlock_.wrlock(); const int64_t task_count = gts_source_.get_task_count(); if (0 != task_count) { ret = gts_source_.gts_callback_interrupted(errcode); } - rwlock_.wrunlock(); return ret; } -int ObTsSourceInfo::switch_ts_source(const uint64_t tenant_id, const int ts_type) -{ - return switch_ts_source_(tenant_id, ts_type); -} - -int ObTsSourceInfo::switch_ts_source_(const uint64_t tenant_id, const int ts_type) -{ - int ret = OB_SUCCESS; - int64_t base_ts = 0; - const int old_ts_type = cur_ts_type_; - if (ts_type == cur_ts_type_) { - TRANS_LOG(INFO, "timestamp source not changed", K(ts_type)); - } else { - ObITsSource *cur_source = ts_source_[cur_ts_type_]; - ObITsSource *next_source = ts_source_[ts_type]; - if (NULL == cur_source || NULL == next_source) { - ret = OB_ERR_UNEXPECTED; - TRANS_LOG(ERROR, "unexpected error, ts source is NULL", - KR(ret), KP(cur_source), KP(next_source)); - } else if (OB_FAIL(cur_source->get_base_ts(base_ts))) { - TRANS_LOG(ERROR, "get base ts from current ts source failed", KR(ret)); - } else if (OB_FAIL(next_source->update_base_ts(base_ts + 1))) { - TRANS_LOG(ERROR, "set base ts to next ts source failed", KR(ret)); - } else { - cur_ts_type_ = ts_type; - } - if (OB_SUCCESS != ret) { - TRANS_LOG(WARN, "switch ts source failed", KR(ret), K(tenant_id), K(old_ts_type), K(ts_type)); - } else { - TRANS_LOG(INFO, "switch ts source success", - K(tenant_id), K(old_ts_type), K(ts_type), K(base_ts)); - } - } - return ret; -} - -void ObTsSourceInfo::revert_ts_source_(ObTsSourceGuard &guard) -{ - UNUSED(guard); - rwlock_.rdunlock(); -} - ObTsSourceInfoGuard::~ObTsSourceInfoGuard() { if (NULL != ts_source_info_ && NULL != mgr_) { @@ -620,14 +481,11 @@ int ObTsMgr::delete_tenant_(const uint64_t tenant_id) do { ObTsSourceInfo *ts_source_info = NULL; ObTsSourceInfoGuard info_guard; - ObTsSourceGuard source_guard; if (OB_FAIL(get_ts_source_info_opt_(tenant_id, info_guard, false, false))) { TRANS_LOG(WARN, "get ts source info failed", K(ret), K(tenant_id)); } else if (OB_ISNULL(ts_source_info = info_guard.get_ts_source_info())) { ret = OB_ERR_UNEXPECTED; TRANS_LOG(WARN, "ts source info is NULL", KR(ret), K(tenant_id)); - } else if (OB_FAIL(ts_source_info->set_invalid())) { - TRANS_LOG(WARN, "set tenant gts invalid failed", KR(ret), K(tenant_id)); } else { TRANS_LOG(INFO, "set tenant gts invalid success", K(tenant_id)); } @@ -664,7 +522,6 @@ int ObTsMgr::remove_dropped_tenant_(const uint64_t tenant_id) ObTsTenantInfo tenant_info(tenant_id); ObTsSourceInfo *ts_source_info = NULL; ObTsSourceInfoGuard info_guard; - ObTsSourceGuard source_guard; if (OB_FAIL(get_ts_source_info_opt_(tenant_id, info_guard, false, false))) { TRANS_LOG(WARN, "get ts source info failed", K(ret), K(tenant_id)); } else if (OB_ISNULL(ts_source_info = info_guard.get_ts_source_info())) { @@ -694,32 +551,22 @@ int ObTsMgr::update_gts(const uint64_t tenant_id, const int64_t gts, bool &updat ret = OB_INVALID_ARGUMENT; TRANS_LOG(WARN, "invalid argument", KR(ret), K(tenant_id), K(gts)); } else { - do { - bool is_valid = false; - ObTsSourceInfo *ts_source_info = NULL; - ObITsSource *ts_source = NULL; - ObTsSourceInfoGuard info_guard; - ObTsSourceGuard source_guard; - if (OB_FAIL(get_ts_source_info_opt_(tenant_id, info_guard, true, true))) { - TRANS_LOG(WARN, "get ts source info failed", K(ret), K(tenant_id)); - } else if (OB_ISNULL(ts_source_info = info_guard.get_ts_source_info())) { + ObTsSourceInfo *ts_source_info = NULL; + ObGtsSource *ts_source = NULL; + ObTsSourceInfoGuard info_guard; + if (OB_FAIL(get_ts_source_info_opt_(tenant_id, info_guard, true, true))) { + TRANS_LOG(WARN, "get ts source info failed", K(ret), K(tenant_id)); + } else if (OB_ISNULL(ts_source_info = info_guard.get_ts_source_info())) { + ret = OB_ERR_UNEXPECTED; + TRANS_LOG(WARN, "ts source info is NULL", K(ret), K(tenant_id)); + } else { + if (OB_ISNULL(ts_source = ts_source_info->get_gts_source())) { ret = OB_ERR_UNEXPECTED; - TRANS_LOG(WARN, "ts source info is NULL", K(ret), K(tenant_id)); - } else if (OB_FAIL(ts_source_info->get_ts_source(tenant_id, source_guard, is_valid))) { - TRANS_LOG(WARN, "get ts source failed", K(ret), K(tenant_id)); - } else if (is_valid) { - if (OB_ISNULL(ts_source = source_guard.get_ts_source())) { - ret = OB_ERR_UNEXPECTED; - TRANS_LOG(WARN, "ts source is NULL", K(ret)); - } else if (OB_FAIL(ts_source->update_gts(gts, update))) { - TRANS_LOG(WARN, "update gts cache failed", K(ret), K(tenant_id), K(gts)); - } else { - break; - } - } else { - PAUSE(); + TRANS_LOG(WARN, "ts source is NULL", K(ret)); + } else if (OB_FAIL(ts_source->update_gts(gts, update))) { + TRANS_LOG(WARN, "update gts cache failed", K(ret), K(tenant_id), K(gts)); } - } while (OB_SUCCESS == ret); + } } return ret; @@ -739,32 +586,24 @@ int ObTsMgr::get_gts(const uint64_t tenant_id, ObTsCbTask *task, SCN &scn) ret = OB_INVALID_ARGUMENT; TRANS_LOG(WARN, "invalid argument", KR(ret), K(tenant_id), KP(task)); } else { - do { - bool is_valid = false; - ObTsSourceInfo *ts_source_info = NULL; - ObITsSource *ts_source = NULL; - ObTsSourceInfoGuard info_guard; - ObTsSourceGuard source_guard; - if (OB_FAIL(get_ts_source_info_opt_(tenant_id, info_guard, true, true))) { - TRANS_LOG(WARN, "get ts source info failed", K(ret), K(tenant_id)); - } else if (OB_ISNULL(ts_source_info = info_guard.get_ts_source_info())) { + ObTsSourceInfo *ts_source_info = NULL; + ObGtsSource *ts_source = NULL; + ObTsSourceInfoGuard info_guard; + if (OB_FAIL(get_ts_source_info_opt_(tenant_id, info_guard, true, true))) { + TRANS_LOG(WARN, "get ts source info failed", K(ret), K(tenant_id)); + } else if (OB_ISNULL(ts_source_info = info_guard.get_ts_source_info())) { + ret = OB_ERR_UNEXPECTED; + TRANS_LOG(WARN, "ts source info is NULL", K(ret), K(tenant_id)); + } else { + if (OB_ISNULL(ts_source = ts_source_info->get_gts_source())) { ret = OB_ERR_UNEXPECTED; - TRANS_LOG(WARN, "ts source info is NULL", K(ret), K(tenant_id)); - } else if (OB_FAIL(ts_source_info->get_ts_source(tenant_id, source_guard, is_valid))) { - TRANS_LOG(WARN, "get ts source failed", K(ret), K(tenant_id)); - } else if (is_valid) { - if (OB_ISNULL(ts_source = source_guard.get_ts_source())) { - ret = OB_ERR_UNEXPECTED; - TRANS_LOG(WARN, "ts source is NULL", K(ret)); - } else if (OB_FAIL(ts_source->get_gts(task, gts))) { - if (OB_EAGAIN != ret) { - TRANS_LOG(WARN, "get gts error", K(ret), K(tenant_id), KP(task)); - } - } else { - break; + TRANS_LOG(WARN, "ts source is NULL", K(ret)); + } else if (OB_FAIL(ts_source->get_gts(task, gts))) { + if (OB_EAGAIN != ret) { + TRANS_LOG(WARN, "get gts error", K(ret), K(tenant_id), KP(task)); } } - } while (OB_SUCCESS == ret); + } } if (OB_SUCC(ret)) { @@ -795,34 +634,24 @@ int ObTsMgr::get_gts(const uint64_t tenant_id, ret = OB_INVALID_ARGUMENT; TRANS_LOG(WARN, "invalid argument", KR(ret), K(tenant_id), K(stc), KP(task)); } else { - do { - bool is_valid = false; - ObTsSourceInfo *ts_source_info = NULL; - ObITsSource *ts_source = NULL; - ObTsSourceInfoGuard info_guard; - ObTsSourceGuard source_guard; - if (OB_FAIL(get_ts_source_info_opt_(tenant_id, info_guard, true, true))) { - TRANS_LOG(WARN, "get ts source info failed", K(ret), K(tenant_id)); - } else if (OB_ISNULL(ts_source_info = info_guard.get_ts_source_info())) { + ObTsSourceInfo *ts_source_info = NULL; + ObGtsSource *ts_source = NULL; + ObTsSourceInfoGuard info_guard; + if (OB_FAIL(get_ts_source_info_opt_(tenant_id, info_guard, true, true))) { + TRANS_LOG(WARN, "get ts source info failed", K(ret), K(tenant_id)); + } else if (OB_ISNULL(ts_source_info = info_guard.get_ts_source_info())) { + ret = OB_ERR_UNEXPECTED; + TRANS_LOG(WARN, "ts source info is NULL", K(ret), K(tenant_id)); + } else { + if (OB_ISNULL(ts_source = ts_source_info->get_gts_source())) { ret = OB_ERR_UNEXPECTED; - TRANS_LOG(WARN, "ts source info is NULL", K(ret), K(tenant_id)); - } else if (OB_FAIL(ts_source_info->get_ts_source(tenant_id, source_guard, is_valid))) { - TRANS_LOG(WARN, "get ts source failed", K(ret), K(tenant_id)); - } else if (is_valid) { - if (OB_ISNULL(ts_source = source_guard.get_ts_source())) { - ret = OB_ERR_UNEXPECTED; - TRANS_LOG(WARN, "ts source is NULL", K(ret)); - } else if (OB_FAIL(ts_source->get_gts(stc, task, gts, receive_gts_ts))) { - if (OB_EAGAIN != ret) { - TRANS_LOG(WARN, "get gts error", K(ret), K(tenant_id), K(stc), KP(task)); - } - } else { - break; + TRANS_LOG(WARN, "ts source is NULL", K(ret)); + } else if (OB_FAIL(ts_source->get_gts(stc, task, gts, receive_gts_ts))) { + if (OB_EAGAIN != ret) { + TRANS_LOG(WARN, "get gts error", K(ret), K(tenant_id), K(stc), KP(task)); } - } else { - PAUSE(); } - } while (OB_SUCCESS == ret); + } } if (OB_SUCC(ret)) { @@ -855,12 +684,10 @@ int ObTsMgr::get_ts_sync(const uint64_t tenant_id, TRANS_LOG(WARN, "invalid argument", K(ret), K(tenant_id), K(timeout_us)); } else { do { - bool is_valid = false; - int64_t ts = 0; ObTsSourceInfo *ts_source_info = NULL; - ObITsSource *ts_source = NULL; + ObGtsSource *ts_source = NULL; ObTsSourceInfoGuard info_guard; - ObTsSourceGuard source_guard; + int64_t ts = 0; if (OB_UNLIKELY(ObTimeUtility::current_time() >= start + timeout_us)) { ret = OB_TIMEOUT; } else if (OB_FAIL(get_ts_source_info_opt_(tenant_id, info_guard, true, true))) { @@ -868,10 +695,8 @@ int ObTsMgr::get_ts_sync(const uint64_t tenant_id, } else if (OB_ISNULL(ts_source_info = info_guard.get_ts_source_info())) { ret = OB_ERR_UNEXPECTED; TRANS_LOG(WARN, "ts source info is NULL", K(ret), K(tenant_id)); - } else if (OB_FAIL(ts_source_info->get_ts_source(tenant_id, source_guard, is_valid))) { - TRANS_LOG(WARN, "get ts source failed", K(ret), K(tenant_id)); - } else if (is_valid) { - if (OB_ISNULL(ts_source = source_guard.get_ts_source())) { + } else { + if (OB_ISNULL(ts_source = ts_source_info->get_gts_source())) { ret = OB_ERR_UNEXPECTED; TRANS_LOG(WARN, "ts source is NULL", K(ret)); } else if (OB_FAIL(ts_source->get_gts(stc, NULL, ts, receive_gts_ts))) { @@ -889,8 +714,6 @@ int ObTsMgr::get_ts_sync(const uint64_t tenant_id, is_external_consistent = ts_source->is_external_consistent(); break; } - } else { - PAUSE(); } } while (OB_SUCCESS == ret); } @@ -898,57 +721,6 @@ int ObTsMgr::get_ts_sync(const uint64_t tenant_id, return ret; } -int ObTsMgr::update_base_ts(const int64_t base_ts) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - TRANS_LOG(WARN, "ObTsMgr is not inited", K(ret)); - } else if (OB_UNLIKELY(!is_running_)) { - ret = OB_NOT_RUNNING; - TRANS_LOG(WARN, "ObTsMgr is not running", K(ret)); - } else if (OB_UNLIKELY(0 > base_ts)) { - ret = OB_INVALID_ARGUMENT; - TRANS_LOG(WARN, "invalid argument", KR(ret), K(base_ts)); - } else { - UpdateBaseTs functor(base_ts); - if (OB_FAIL(ts_source_info_map_.for_each(functor))) { - TRANS_LOG(WARN, "iterate all ts source info failed", KR(ret)); - } - } - if (OB_SUCCESS != ret) { - TRANS_LOG(ERROR, "update base ts failed", KR(ret), K(base_ts)); - } else { - TRANS_LOG(INFO, "update base ts success", K(base_ts)); - } - return ret; -} - -int ObTsMgr::get_base_ts(int64_t &base_ts) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - TRANS_LOG(WARN, "ObTsMgr is not inited", K(ret)); - } else if (OB_UNLIKELY(!is_running_)) { - ret = OB_NOT_RUNNING; - TRANS_LOG(WARN, "ObTsMgr is not running", KR(ret)); - } else { - GetBaseTs functor; - if (OB_FAIL(ts_source_info_map_.for_each(functor))) { - TRANS_LOG(WARN, "iterate all ts source info failed", KR(ret)); - } else { - base_ts = functor.get_base_ts(); - } - } - if (OB_SUCCESS != ret) { - TRANS_LOG(ERROR, "get base ts failed", KR(ret)); - } else { - TRANS_LOG(INFO, "get base ts success", K(base_ts)); - } - return ret; -} - bool ObTsMgr::is_external_consistent(const uint64_t tenant_id) { int ret = OB_SUCCESS; @@ -964,31 +736,22 @@ bool ObTsMgr::is_external_consistent(const uint64_t tenant_id) ret = OB_INVALID_ARGUMENT; TRANS_LOG(WARN, "invalid argument", KR(ret), K(tenant_id)); } else { - do { - bool is_valid = false; - ObTsSourceInfo *ts_source_info = NULL; - ObITsSource *ts_source = NULL; - ObTsSourceInfoGuard info_guard; - ObTsSourceGuard source_guard; - if (OB_FAIL(get_ts_source_info_opt_(tenant_id, info_guard, true, true))) { - TRANS_LOG(WARN, "get ts source info failed", K(ret), K(tenant_id)); - } else if (OB_ISNULL(ts_source_info = info_guard.get_ts_source_info())) { + ObTsSourceInfo *ts_source_info = NULL; + ObGtsSource *ts_source = NULL; + ObTsSourceInfoGuard info_guard; + if (OB_FAIL(get_ts_source_info_opt_(tenant_id, info_guard, true, true))) { + TRANS_LOG(WARN, "get ts source info failed", K(ret), K(tenant_id)); + } else if (OB_ISNULL(ts_source_info = info_guard.get_ts_source_info())) { + ret = OB_ERR_UNEXPECTED; + TRANS_LOG(WARN, "ts source info is NULL", K(ret), K(tenant_id)); + } else { + if (OB_ISNULL(ts_source = ts_source_info->get_gts_source())) { ret = OB_ERR_UNEXPECTED; - TRANS_LOG(WARN, "ts source info is NULL", K(ret), K(tenant_id)); - } else if (OB_FAIL(ts_source_info->get_ts_source(tenant_id, source_guard, is_valid))) { - TRANS_LOG(WARN, "get ts source failed", K(ret), K(tenant_id)); - } else if (is_valid) { - if (OB_ISNULL(ts_source = source_guard.get_ts_source())) { - ret = OB_ERR_UNEXPECTED; - TRANS_LOG(WARN, "ts source is NULL", K(ret), K(tenant_id)); - } else { - bool_ret = ts_source->is_external_consistent(); - break; - } + TRANS_LOG(WARN, "ts source is NULL", K(ret), K(tenant_id)); } else { - PAUSE(); + bool_ret = ts_source->is_external_consistent(); } - } while (OB_SUCCESS == ret); + } } return bool_ret; @@ -997,7 +760,6 @@ bool ObTsMgr::is_external_consistent(const uint64_t tenant_id) int ObTsMgr::wait_gts_elapse(const uint64_t tenant_id, const SCN &scn, ObTsCbTask *task, bool &need_wait) { - const int64_t start = ObTimeUtility::fast_current_time(); int ret = OB_SUCCESS; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; @@ -1005,44 +767,30 @@ int ObTsMgr::wait_gts_elapse(const uint64_t tenant_id, const SCN &scn, } else if (OB_UNLIKELY(!is_running_)) { ret = OB_NOT_RUNNING; TRANS_LOG(WARN, "ObTsMgr not running", K(ret)); - } else if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id)) || OB_UNLIKELY(!scn.is_valid()) || OB_ISNULL(task)) { + } else if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id)) + || OB_UNLIKELY(!scn.is_valid()) + || OB_ISNULL(task)) { ret = OB_INVALID_ARGUMENT; TRANS_LOG(WARN, "invalid argument", KR(ret), K(tenant_id), K(scn), KP(task)); } else { - do { - bool is_valid = false; - const int64_t ts = scn.get_val_for_gts(); - ObTsSourceInfo *ts_source_info = NULL; - ObITsSource *ts_source = NULL; - ObTsSourceInfoGuard info_guard; - ObTsSourceGuard source_guard; - if (OB_FAIL(get_ts_source_info_opt_(tenant_id, info_guard, true, true))) { - TRANS_LOG(WARN, "get ts source info failed", K(ret), K(tenant_id)); - } else if (OB_ISNULL(ts_source_info = info_guard.get_ts_source_info())) { + ObTsSourceInfo *ts_source_info = NULL; + ObGtsSource *ts_source = NULL; + ObTsSourceInfoGuard info_guard; + const int64_t ts = scn.get_val_for_gts(); + if (OB_FAIL(get_ts_source_info_opt_(tenant_id, info_guard, true, true))) { + TRANS_LOG(WARN, "get ts source info failed", K(ret), K(tenant_id)); + } else if (OB_ISNULL(ts_source_info = info_guard.get_ts_source_info())) { + ret = OB_ERR_UNEXPECTED; + TRANS_LOG(WARN, "ts source info is NULL", K(ret), K(tenant_id)); + } else { + if (OB_ISNULL(ts_source = ts_source_info->get_gts_source())) { ret = OB_ERR_UNEXPECTED; - TRANS_LOG(WARN, "ts source info is NULL", K(ret), K(tenant_id)); - } else if (OB_FAIL(ts_source_info->get_ts_source(tenant_id, source_guard, is_valid))) { - TRANS_LOG(WARN, "get ts source failed", K(ret), K(tenant_id)); - } else if (is_valid) { - if (OB_ISNULL(ts_source = source_guard.get_ts_source())) { - ret = OB_ERR_UNEXPECTED; - TRANS_LOG(WARN, "ts source is NULL", K(ret)); - } else if (OB_FAIL(ts_source->wait_gts_elapse(ts, task, need_wait))) { - TRANS_LOG(WARN, "wait gts elapse failed", K(ret), K(ts), KP(task)); - } else { - break; - } - } else { - PAUSE(); + TRANS_LOG(WARN, "ts source is NULL", K(ret)); + } else if (OB_FAIL(ts_source->wait_gts_elapse(ts, task, need_wait))) { + TRANS_LOG(WARN, "wait gts elapse failed", K(ret), K(ts), KP(task)); } - } while (OB_SUCCESS == ret); + } } - ObTransStatistic::get_instance().add_gts_wait_elapse_total_count(tenant_id, 1); - if (OB_SUCC(ret)) { - const int64_t end = ObTimeUtility::fast_current_time(); - ObTransStatistic::get_instance().add_gts_wait_elapse_total_time(tenant_id, end - start); - } - TRANS_LOG(DEBUG, "ObTsMgr::wait_gts_elapse", KR(ret), KP(task), K(need_wait)); return ret; } @@ -1060,56 +808,30 @@ int ObTsMgr::wait_gts_elapse(const uint64_t tenant_id, const SCN &scn) ret = OB_INVALID_ARGUMENT; TRANS_LOG(WARN, "invalid argument", KR(ret), K(tenant_id), K(scn)); } else { - do { - bool is_valid = false; - const int64_t ts = scn.get_val_for_gts(); - ObTsSourceInfo *ts_source_info = NULL; - ObITsSource *ts_source = NULL; - ObTsSourceInfoGuard info_guard; - ObTsSourceGuard source_guard; - if (OB_FAIL(get_ts_source_info_opt_(tenant_id, info_guard, true, true))) { - TRANS_LOG(WARN, "get ts source info failed", K(ret), K(tenant_id)); - } else if (OB_ISNULL(ts_source_info = info_guard.get_ts_source_info())) { + ObTsSourceInfo *ts_source_info = NULL; + ObGtsSource *ts_source = NULL; + ObTsSourceInfoGuard info_guard; + const int64_t ts = scn.get_val_for_gts(); + if (OB_FAIL(get_ts_source_info_opt_(tenant_id, info_guard, true, true))) { + TRANS_LOG(WARN, "get ts source info failed", K(ret), K(tenant_id)); + } else if (OB_ISNULL(ts_source_info = info_guard.get_ts_source_info())) { + ret = OB_ERR_UNEXPECTED; + TRANS_LOG(WARN, "ts source info is NULL", K(ret), K(tenant_id)); + } else { + if (OB_ISNULL(ts_source = ts_source_info->get_gts_source())) { ret = OB_ERR_UNEXPECTED; - TRANS_LOG(WARN, "ts source info is NULL", K(ret), K(tenant_id)); - } else if (OB_FAIL(ts_source_info->get_ts_source(tenant_id, source_guard, is_valid))) { - TRANS_LOG(WARN, "get ts source failed", K(ret), K(tenant_id)); - } else if (is_valid) { - if (OB_ISNULL(ts_source = source_guard.get_ts_source())) { - ret = OB_ERR_UNEXPECTED; - TRANS_LOG(WARN, "ts source is NULL", K(ret)); - } else if (OB_FAIL(ts_source->wait_gts_elapse(ts))) { - if (OB_EAGAIN != ret) { - TRANS_LOG(WARN, "wait gts elapse fail", K(ret), K(ts), K(tenant_id)); - } - } else { - break; + TRANS_LOG(WARN, "ts source is NULL", K(ret)); + } else if (OB_FAIL(ts_source->wait_gts_elapse(ts))) { + if (OB_EAGAIN != ret) { + TRANS_LOG(WARN, "wait gts elapse fail", K(ret), K(ts), K(tenant_id)); } - } else { - PAUSE(); } - } while (OB_SUCCESS == ret); + } } - ObTransStatistic::get_instance().add_gts_try_wait_elapse_total_count(tenant_id, 1); return ret; } -int ObTsMgr::get_cur_ts_type(const uint64_t tenant_id, int64_t &cur_ts_type) -{ - int ret = OB_SUCCESS; - if (OB_ISNULL(GCTX.omt_)) { - ret = OB_ERR_UNEXPECTED; - TRANS_LOG(WARN, "failed to get multi tenant from GCTX", K(ret)); - } else if (!GCTX.omt_->has_tenant(tenant_id)) { - ret = OB_TENANT_NOT_IN_SERVER; - TRANS_LOG(WARN, "tenant not in server", K(ret), K(tenant_id)); - } else { - cur_ts_type = TS_SOURCE_GTS; - } - return ret; -} - ObTsMgr *&ObTsMgr::get_instance_inner() { static ObTsMgr instance; @@ -1225,8 +947,6 @@ int ObTsMgr::add_tenant_(const uint64_t tenant_id) TRANS_LOG(WARN, "gts_source init error", KR(ret)); } else if (OB_FAIL(ts_source_info->init(tenant_id))) { TRANS_LOG(WARN, "ts source init failed", KR(ret)); - } else if (OB_FAIL(ts_source_info->switch_ts_source(tenant_id, TS_SOURCE_GTS))) { - TRANS_LOG(WARN, "switch ts source failed", K(ret)); } else if (OB_FAIL(ts_source_info_map_.insert_and_get(tenant_info, ts_source_info))) { if (OB_ENTRY_EXIST != ret) { TRANS_LOG(WARN, "wait queue hashmap insert error", KR(ret), KP(ts_source_info)); diff --git a/src/storage/tx/ob_ts_mgr.h b/src/storage/tx/ob_ts_mgr.h index 2f8a3f380..8e2c2fbb0 100644 --- a/src/storage/tx/ob_ts_mgr.h +++ b/src/storage/tx/ob_ts_mgr.h @@ -60,7 +60,6 @@ class SCN; namespace transaction { class ObLocationAdapter; -class ObITsSource; class ObGtsRequestRpc; class ObIGlobalTimestampService; @@ -82,9 +81,6 @@ class ObITsMgr { public: virtual int update_gts(const uint64_t tenant_id, const int64_t gts, bool &update) = 0; - /* - virtual int update_local_trans_version(const uint64_t tenant_id, const int64_t version, bool &update) = 0; - */ virtual int get_gts(const uint64_t tenant_id, const MonotonicTs stc, ObTsCbTask *task, @@ -93,54 +89,18 @@ public: virtual int get_gts(const uint64_t tenant_id, ObTsCbTask *task, share::SCN &scn) = 0; virtual int get_ts_sync(const uint64_t tenant_id, const int64_t timeout_ts, share::SCN &scn, bool &is_external_consistent) = 0; - /* - virtual int get_local_trans_version(const uint64_t tenant_id, - const MonotonicTs stc, - ObTsCbTask *task, - int64_t >s, - MonotonicTs &receive_gts_ts) = 0; - virtual int get_local_trans_version(const uint64_t tenant_id, - ObTsCbTask *task, - int64_t >s) = 0; - */ virtual int wait_gts_elapse(const uint64_t tenant_id, const share::SCN &scn, ObTsCbTask *task, bool &need_wait) = 0; virtual int wait_gts_elapse(const uint64_t tenant_id, const share::SCN &scn) = 0; - virtual int update_base_ts(const int64_t base_ts) = 0; - virtual int get_base_ts(int64_t &base_ts) = 0; virtual bool is_external_consistent(const uint64_t tenant_id) = 0; public: VIRTUAL_TO_STRING_KV("", ""); }; -class ObTsSourceInfo; -class ObTsSourceGuard -{ -public: - ObTsSourceGuard() : ts_source_(NULL), ts_source_info_(NULL), ts_type_(0) {} - ~ObTsSourceGuard(); - void set(ObTsSourceInfo *info, ObITsSource *ts_source, const int ts_type) - { - ts_source_info_ = info; - ts_source_ = ts_source; - ts_type_ = ts_type; - } - void set_ts_source(ObITsSource *ts_source) { ts_source_ = ts_source; } - void set_ts_source_info(ObTsSourceInfo *ts_source_info) { ts_source_info_ = ts_source_info; } - ObITsSource *get_ts_source() { return ts_source_; } - void set_ts_type(int ts_type) { ts_type_ = ts_type; } - int get_ts_type() { return ts_type_; } -private: - ObITsSource *ts_source_; - ObTsSourceInfo *ts_source_info_; - int ts_type_; -}; - typedef common::LinkHashNode ObTsTenantInfoNode; typedef common::LinkHashValue ObTsTenantInfoValue; class ObTsSourceInfo : public ObTsTenantInfoValue { - friend class ObTsSourceGuard; public: ObTsSourceInfo(); ~ObTsSourceInfo() { destroy(); } @@ -149,33 +109,15 @@ public: public: uint64_t get_tenant_id() const { return tenant_id_; } ObGtsSource *get_gts_source() { return >s_source_; } - int get_ts_source(const uint64_t tenant_id, ObTsSourceGuard &guard, bool &is_valid); - int check_and_switch_ts_source(const uint64_t tenant_id); void update_last_access_ts() { last_access_ts_ = common::ObClockGenerator::getClock(); } int64_t get_last_access_ts() const { return last_access_ts_; } - int64_t get_last_obtain_switch_ts() const { return last_obtain_switch_ts_; } - int set_invalid(); int check_if_tenant_has_been_dropped(const uint64_t tenant_id, bool &has_dropped); int gts_callback_interrupted(const int errcode); - int switch_ts_source(const uint64_t tenant_id, const int ts_type); -private: - int switch_ts_source_(const uint64_t tenant_id, const int ts_type); - void revert_ts_source_(ObTsSourceGuard &guard); -private: - static const int64_t DEFAULT_CHECK_SWITCH_INTERVAL_US = 100 * 1000; - static const int64_t MAX_CHECK_SWITCH_INTERVAL_US = 3 * 1000 * 1000; private: bool is_inited_; - bool is_valid_; uint64_t tenant_id_; - int64_t last_check_switch_ts_; - int64_t last_obtain_switch_ts_; - int64_t check_switch_interval_; - ObITsSource *ts_source_[MAX_TS_SOURCE]; - int cur_ts_type_; + int64_t last_access_ts_; ObGtsSource gts_source_; - mutable common::ObQSyncLock rwlock_; - int64_t last_access_ts_ CACHE_ALIGNED; }; class ObTsSourceInfoAlloc @@ -216,8 +158,6 @@ public: if (OB_ISNULL(ts_source_info)) { ret = common::OB_ERR_UNEXPECTED; TRANS_LOG(ERROR, "ts source info is null", KR(ret)); - } else if (OB_FAIL(ts_source_info->check_and_switch_ts_source(gts_tenant_info.get_value()))) { - TRANS_LOG(WARN, "check and switch ts source failed", KR(ret), K(gts_tenant_info)); } else if (NULL == (gts_source = (ts_source_info->get_gts_source()))) { ret = common::OB_ERR_UNEXPECTED; TRANS_LOG(ERROR, "gts cache queue is null", KR(ret), K(gts_tenant_info)); @@ -255,8 +195,6 @@ public: TRANS_LOG(ERROR, "ts source info is null", KR(ret)); } else if (now - ts_source_info->get_last_access_ts() < obsolete_time_) { // do nothing - } else if (now - ts_source_info->get_last_obtain_switch_ts() < obsolete_time_) { - // do nothing } else if (OB_FAIL(array_.push_back(gts_tenant_info.get_value()))) { TRANS_LOG(WARN, "push back tenant failed", K(ret), K(gts_tenant_info)); } else { @@ -347,10 +285,6 @@ public: int delete_tenant(const uint64_t tenant_id); public: int update_gts(const uint64_t tenant_id, const int64_t gts, bool &update); - /* - int update_local_trans_version(const uint64_t tenant_id, const int64_t version, bool &update); - */ - //根据stc获取合适的gts值,如果条件不满足需要注册gts task,等异步回调 int get_gts(const uint64_t tenant_id, const MonotonicTs stc, @@ -363,23 +297,10 @@ public: int get_gts(const uint64_t tenant_id, ObTsCbTask *task, share::SCN &scn); int get_ts_sync(const uint64_t tenant_id, const int64_t timeout_ts, share::SCN &scn, bool &is_external_consistent); - /* - int get_local_trans_version(const uint64_t tenant_id, - const MonotonicTs stc, - ObTsCbTask *task, - int64_t >s, - MonotonicTs &receive_gts_ts); - int get_local_trans_version(const uint64_t tenant_id, - ObTsCbTask *task, - int64_t >s); - */ int wait_gts_elapse(const uint64_t tenant_id, const share::SCN &scn, ObTsCbTask *task, bool &need_wait); int wait_gts_elapse(const uint64_t tenant_id, const share::SCN &scn); - int update_base_ts(const int64_t base_ts); - int get_base_ts(int64_t &base_ts); bool is_external_consistent(const uint64_t tenant_id); - static int get_cur_ts_type(const uint64_t tenant_id, int64_t &cur_ts_type); int refresh_gts_location(const uint64_t tenant_id); public: TO_STRING_KV("ts_source", "GTS"); @@ -412,57 +333,6 @@ private: ObTsSourceInfo *ts_source_infos_[TS_SOURCE_INFO_CACHE_NUM]; }; -class GetBaseTs -{ -public: - GetBaseTs() : base_ts_(0) {} - bool operator()(const ObTsTenantInfo &tenant, ObTsSourceInfo *ts_source_info) - { - UNUSED(tenant); - int ret = common::OB_SUCCESS; - bool bool_ret = false; - int64_t ts = 0; - if (NULL == ts_source_info) { - ret = common::OB_INVALID_ARGUMENT; - } else { - ObGtsSource *gts_source = ts_source_info->get_gts_source(); - if (OB_FAIL(gts_source->get_base_ts(ts))) { - } else { - base_ts_ = (ts > base_ts_ ? ts : base_ts_); - bool_ret = true; - } - } - return bool_ret; - } - int64_t get_base_ts() const { return base_ts_; } -private: - int64_t base_ts_; -}; - -class UpdateBaseTs -{ -public: - UpdateBaseTs(const int64_t base_ts) : base_ts_(base_ts) {} - bool operator()(const ObTsTenantInfo &tenant, ObTsSourceInfo *ts_source_info) - { - UNUSED(tenant); - int ret = common::OB_SUCCESS; - bool bool_ret = false; - if (NULL == ts_source_info) { - ret = common::OB_INVALID_ARGUMENT; - } else { - ObGtsSource *gts_source = ts_source_info->get_gts_source(); - if (OB_FAIL(gts_source->update_base_ts(base_ts_))) { - } else { - bool_ret = true; - } - } - return bool_ret; - } -private: - int64_t base_ts_; -}; - #define OB_TS_MGR (::oceanbase::transaction::ObTsMgr::get_instance()) } diff --git a/src/storage/tx/ob_tx_data_define.h b/src/storage/tx/ob_tx_data_define.h index 6185061ed..f862c9d79 100644 --- a/src/storage/tx/ob_tx_data_define.h +++ b/src/storage/tx/ob_tx_data_define.h @@ -268,7 +268,6 @@ public: void dump_2_text(FILE *fd) const; static void print_to_stderr(const ObTxData &tx_data); - DECLARE_TO_STRING; diff --git a/src/storage/tx/ob_tx_elr_util.cpp b/src/storage/tx/ob_tx_elr_util.cpp index 0055c5ddf..e96f630cf 100644 --- a/src/storage/tx/ob_tx_elr_util.cpp +++ b/src/storage/tx/ob_tx_elr_util.cpp @@ -34,12 +34,13 @@ int ObTxELRUtil::check_and_update_tx_elr_info(ObTxDesc &tx, const bool can_elr) void ObTxELRUtil::refresh_elr_tenant_config_() { - bool need_refresh = ObClockGenerator::getClock()- last_refresh_ts_ > REFRESH_INTERVAL; + bool need_refresh = ObClockGenerator::getClock() - last_refresh_ts_ > REFRESH_INTERVAL; if (OB_UNLIKELY(need_refresh)) { omt::ObTenantConfigGuard tenant_config(TENANT_CONF(MTL_ID())); if (OB_LIKELY(tenant_config.is_valid())) { can_tenant_elr_ = tenant_config->enable_early_lock_release; + last_refresh_ts_ = ObClockGenerator::getClock(); } if (REACH_TIME_INTERVAL(10000000 /* 10s */)) { TRANS_LOG(INFO, "refresh tenant config success", "tenant_id", MTL_ID(), K(*this)); diff --git a/src/storage/tx/ob_tx_log.cpp b/src/storage/tx/ob_tx_log.cpp index ed2cb43ed..f759bdf93 100644 --- a/src/storage/tx/ob_tx_log.cpp +++ b/src/storage/tx/ob_tx_log.cpp @@ -920,11 +920,8 @@ const int32_t ObTxLogBlock::DEFAULT_BIG_ROW_BLOCK_SIZE = void ObTxLogBlock::reset() { - if (nullptr != fill_buf_) { - ClogBufFactory::release(fill_buf_); - } + fill_buf_.reset(); replay_buf_ = nullptr; - fill_buf_ = nullptr; len_ = pos_ = 0; cur_log_type_ = ObTxLogType::UNKNOWN; cb_arg_array_.reset(); @@ -941,22 +938,27 @@ void ObTxLogBlock::reuse(const int64_t replay_hint, const ObTxLogBlockHeader &bl } } -ObTxLogBlock::ObTxLogBlock() : fill_buf_(nullptr), replay_buf_(nullptr) +ObTxLogBlock::ObTxLogBlock() : replay_buf_(nullptr), + len_(0), + pos_(0), + cur_log_type_(ObTxLogType::UNKNOWN), + cb_arg_array_() { - reset(); + // do nothing } -int ObTxLogBlock::init(const int64_t replay_hint, const ObTxLogBlockHeader &block_header) +int ObTxLogBlock::init(const int64_t replay_hint, + const ObTxLogBlockHeader &block_header, + const bool use_local_buf) { int ret = OB_SUCCESS; - if (OB_NOT_NULL(replay_buf_) || OB_NOT_NULL(fill_buf_) || !block_header.is_valid()) { + if (OB_NOT_NULL(replay_buf_) || !block_header.is_valid()) { ret = OB_INVALID_ARGUMENT; TRANS_LOG(ERROR, "invalid argument", K(replay_hint), K(*this), K(block_header)); - } else if (OB_ISNULL(fill_buf_ = ClogBufFactory::alloc())) { - ret = OB_ALLOCATE_MEMORY_FAILED; - TRANS_LOG(ERROR, "alloc clog buffer error", KR(ret)); + } else if (OB_FAIL(fill_buf_.init(use_local_buf))) { + TRANS_LOG(WARN, "fill log buffer init error", K(ret), K(replay_hint), K(block_header), K(use_local_buf)); } else { - len_ = fill_buf_->get_size(); + len_ = fill_buf_.get_length(); pos_ = 0; if (OB_FAIL(serialize_log_block_header_(replay_hint, block_header))) { ret = OB_SERIALIZE_ERROR; @@ -972,8 +974,9 @@ int ObTxLogBlock::init_with_header(const char *buf, ObTxLogBlockHeader &block_header) { int ret = OB_SUCCESS; - if (OB_NOT_NULL(replay_buf_) || OB_NOT_NULL(fill_buf_) - || OB_ISNULL(buf) || size <= 0) { + if (OB_NOT_NULL(replay_buf_) + || OB_ISNULL(buf) + || size <= 0) { ret = OB_INVALID_ARGUMENT; TRANS_LOG(ERROR, "invalid argument", K(buf), K(size), K(*this)); } else { @@ -991,8 +994,7 @@ int ObTxLogBlock::init_with_header(const char *buf, int ObTxLogBlock::init(const char *buf, const int64_t &size, int skip_pos, ObTxLogBlockHeader &block_header) { int ret = OB_SUCCESS; - if (OB_NOT_NULL(replay_buf_) || OB_NOT_NULL(fill_buf_) - || OB_ISNULL(buf) || size <= 0) { + if (OB_ISNULL(buf) || size <= 0) { ret = OB_INVALID_ARGUMENT; TRANS_LOG(ERROR, "invalid argument", K(buf), K(size), K(*this)); } else { @@ -1015,21 +1017,22 @@ int ObTxLogBlock::rewrite_barrier_log_block(int64_t replay_hint, char *serialize_buf = nullptr; logservice::ObLogBaseHeader header(logservice::ObLogBaseType::TRANS_SERVICE_LOG_BASE_TYPE, barrier_type, replay_hint); - if (OB_ISNULL(fill_buf_) || OB_NOT_NULL(replay_buf_)) { + if (OB_ISNULL(fill_buf_.get_buf())) { ret = OB_INVALID_ARGUMENT; } else { - serialize_buf = fill_buf_->get_buf(); + serialize_buf = fill_buf_.get_buf(); } if (OB_FAIL(ret)) { // do nothing } else if (OB_ISNULL(serialize_buf)) { ret = OB_ERR_UNEXPECTED; - TRANS_LOG(WARN, "unexpected empty serialize_buf", KP(serialize_buf), K(*this)); + TRANS_LOG(WARN, "unexpected empty serialize_buf", K(*this)); } else if (OB_FAIL(header.serialize(serialize_buf, len_, tmp_pos))) { TRANS_LOG(WARN, "serialize log base header error", K(ret)); } + return ret; } @@ -1040,10 +1043,10 @@ int ObTxLogBlock::serialize_log_block_header_(const int64_t replay_hint, char *serialize_buf = nullptr; logservice::ObLogBaseHeader header(logservice::ObLogBaseType::TRANS_SERVICE_LOG_BASE_TYPE, logservice::ObReplayBarrierType::NO_NEED_BARRIER, replay_hint); - if (OB_ISNULL(fill_buf_) || OB_NOT_NULL(replay_buf_) || pos_ != 0) { + if (OB_ISNULL(fill_buf_.get_buf()) || pos_ != 0) { ret = OB_INVALID_ARGUMENT; } else { - serialize_buf = fill_buf_->get_buf(); + serialize_buf = fill_buf_.get_buf(); } if (OB_FAIL(ret)) { @@ -1053,11 +1056,10 @@ int ObTxLogBlock::serialize_log_block_header_(const int64_t replay_hint, TRANS_LOG(WARN, "unexpected empty serialize_buf", K(*this)); } else if (OB_FAIL(header.serialize(serialize_buf, len_, pos_))) { TRANS_LOG(WARN, "serialize log base header error", K(ret)); - // } else if (OB_FAIL(block_header.before_serialize())) { - // TRANS_LOG(WARN, "block header before serialize failed", K(ret)); } else if (OB_FAIL(block_header.serialize(serialize_buf, len_, pos_))) { TRANS_LOG(WARN, "serialize block header error", K(ret)); } + return ret; } @@ -1065,7 +1067,7 @@ int ObTxLogBlock::deserialize_log_block_header_(int64_t &replay_hint, ObTxLogBlo { int ret = OB_SUCCESS; logservice::ObLogBaseHeader header; - if (OB_ISNULL(replay_buf_) || OB_NOT_NULL(fill_buf_) || pos_ != 0) { + if (OB_ISNULL(replay_buf_) || pos_ != 0) { ret = OB_INVALID_ARGUMENT; } else if (OB_FAIL(header.deserialize(replay_buf_, len_, pos_))) { TRANS_LOG(WARN, "deserialize log base header error", K(ret),K(len_),K(pos_)); @@ -1077,20 +1079,10 @@ int ObTxLogBlock::deserialize_log_block_header_(int64_t &replay_hint, ObTxLogBlo return ret; } -ObTxLogBlock::~ObTxLogBlock() -{ - reset(); - // if (nullptr != fill_buf_) { - // ClogBufFactory::release(fill_buf_); - // } - // fill_buf_ = nullptr; - // replay_buf_ = nullptr; -} - int ObTxLogBlock::get_next_log(ObTxLogHeader &header) { int ret = OB_SUCCESS; - if (OB_ISNULL(replay_buf_) || OB_NOT_NULL(fill_buf_)) { + if (OB_ISNULL(replay_buf_)) { ret = OB_INVALID_ARGUMENT; TRANS_LOG(ERROR, "invalid argument", K(*this)); } else if (OB_SUCC(update_next_log_pos_())) { @@ -1104,20 +1096,11 @@ int ObTxLogBlock::get_next_log(ObTxLogHeader &header) return ret; } -char *ObTxLogBlock::get_buf() -{ - char *tmp_buf = nullptr; - if (OB_NOT_NULL(fill_buf_)) { - tmp_buf = fill_buf_->get_buf(); - } - return tmp_buf; -} - int ObTxLogBlock::prepare_mutator_buf(ObTxRedoLog &redo) { int ret = OB_SUCCESS; char *tmp_buf = get_buf(); - if (OB_ISNULL(tmp_buf) || OB_NOT_NULL(replay_buf_)) { + if (OB_ISNULL(tmp_buf)) { ret = OB_INVALID_ARGUMENT; TRANS_LOG(ERROR, "invalid argument", K(*this)); } else if (ObTxLogType::TX_REDO_LOG == cur_log_type_) { @@ -1142,7 +1125,7 @@ int ObTxLogBlock::finish_mutator_buf(ObTxRedoLog &redo, const int64_t &mutator_s int64_t tmp_pos = pos_; char * tmp_buf = get_buf(); ObTxLogHeader header(ObTxLogType::TX_REDO_LOG); - if (OB_ISNULL(tmp_buf) || OB_NOT_NULL(replay_buf_)) { + if (OB_ISNULL(tmp_buf)) { ret = OB_INVALID_ARGUMENT; TRANS_LOG(ERROR, "invalid argument", K(*this)); } else if (ObTxLogType::TX_REDO_LOG != cur_log_type_) { diff --git a/src/storage/tx/ob_tx_log.h b/src/storage/tx/ob_tx_log.h index f4407ed14..03d732162 100644 --- a/src/storage/tx/ob_tx_log.h +++ b/src/storage/tx/ob_tx_log.h @@ -910,6 +910,66 @@ private: ObTransID tx_id_; }; +class ObTxAdaptiveLogBuf +{ +public: + ObTxAdaptiveLogBuf() : buf_(NULL), use_default_buf_(false) + { + default_buf_[0]='\0'; + } + ~ObTxAdaptiveLogBuf() { reset(); } + int init(const bool use_local_buf) + { + int ret = OB_SUCCESS; + + if (use_local_buf) { + // for performance optimization + use_default_buf_ = true; + } else { + if (OB_ISNULL(buf_ = ClogBufFactory::alloc())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + TRANS_LOG(ERROR, "alloc clog buffer error", KR(ret)); + } else { + use_default_buf_ = false; + } + } + + return ret; + } + void reset() + { + if (NULL != buf_) { + ClogBufFactory::release(buf_); + buf_ = NULL; + } + default_buf_[0]='\0'; + use_default_buf_ = false; + } + char *get_buf() + { + char *buf = NULL; + + if (use_default_buf_) { + buf = default_buf_; + } else if (NULL != buf_) { + buf = buf_->get_buf(); + } + return buf; + } + int64_t get_length() const + { + return use_default_buf_ ? DEFAULT_MIN_LOG_BUF_SIZE : common::OB_MAX_LOG_ALLOWED_SIZE; + } + bool is_use_local_buf() const { return use_default_buf_; } + TO_STRING_KV(KP_(buf), K_(use_default_buf)); +public: + static const int64_t DEFAULT_MIN_LOG_BUF_SIZE = 2048; +private: + ClogBuf *buf_; + char default_buf_[DEFAULT_MIN_LOG_BUF_SIZE]; + bool use_default_buf_; +}; + class ObTxLogBlock { public: @@ -921,17 +981,18 @@ public: ObTxLogBlock(); void reset(); void reuse(const int64_t replay_hint, const ObTxLogBlockHeader &block_header); - int init(const int64_t replay_hint, const ObTxLogBlockHeader &block_header); // init before fill - int init_with_header( - const char *buf, - const int64_t &size, - int64_t &replay_hint, - ObTxLogBlockHeader &block_header); // init before replay , unused , only for test + int init(const int64_t replay_hint, + const ObTxLogBlockHeader &block_header, + const bool use_local_buf = false); + int init_with_header(const char *buf, + const int64_t &size, + int64_t &replay_hint, + ObTxLogBlockHeader &block_header); int init(const char *buf, const int64_t &size, int skip_pos, ObTxLogBlockHeader &block_header); // init before replay - ~ObTxLogBlock(); + ~ObTxLogBlock() { reset(); } int get_next_log(ObTxLogHeader &header); const ObTxCbArgArray &get_cb_arg_array() const { return cb_arg_array_; } template @@ -948,7 +1009,8 @@ public: int rewrite_barrier_log_block(int64_t replay_hint, const enum logservice::ObReplayBarrierType barrier_type); - TO_STRING_KV(KP(fill_buf_), + bool is_use_local_buf() const { return fill_buf_.is_use_local_buf(); } + TO_STRING_KV(K(fill_buf_), KP(replay_buf_), K(len_), K(pos_), @@ -957,7 +1019,7 @@ public: public: // get fill buf for submit log - char *get_buf(); + char *get_buf() { return fill_buf_.get_buf(); } const int64_t &get_size() { return pos_; } private: int serialize_log_block_header_(const int64_t replay_hint, const ObTxLogBlockHeader &block_header); @@ -966,7 +1028,7 @@ private: // DESERIALIZE_HEADER in ob_unify_serialize.h) DISALLOW_COPY_AND_ASSIGN(ObTxLogBlock); - ClogBuf *fill_buf_; + ObTxAdaptiveLogBuf fill_buf_; const char *replay_buf_; int64_t len_; int64_t pos_; @@ -979,7 +1041,7 @@ int ObTxLogBlock::deserialize_log_body(T &tx_log_body) { int ret = OB_SUCCESS; int64_t tmp_pos = pos_; - if (OB_ISNULL(replay_buf_) || OB_NOT_NULL(fill_buf_)) { + if (OB_ISNULL(replay_buf_)) { ret = OB_INVALID_ARGUMENT; TRANS_LOG(ERROR, "invalid argument", K(*this)); } else if (T::LOG_TYPE != cur_log_type_) { @@ -1000,7 +1062,7 @@ int ObTxLogBlock::add_new_log(T &tx_log_body) int ret = OB_SUCCESS; int64_t tmp_pos = pos_; ObTxLogHeader header(T::LOG_TYPE); - if (OB_NOT_NULL(replay_buf_) || (OB_ISNULL(fill_buf_))) { + if ((OB_ISNULL(fill_buf_.get_buf()))) { ret = OB_INVALID_ARGUMENT; TRANS_LOG(ERROR, "invalid argument", K(*this)); } else if (T::LOG_TYPE == ObTxLogType::TX_REDO_LOG) { @@ -1013,9 +1075,9 @@ int ObTxLogBlock::add_new_log(T &tx_log_body) } else if (ObTxLogType::TX_REDO_LOG == cur_log_type_) { ret = OB_EAGAIN; TRANS_LOG(WARN, "MutatorBuf is using"); - } else if (OB_FAIL(header.serialize(fill_buf_->get_buf(), len_, tmp_pos))) { + } else if (OB_FAIL(header.serialize(fill_buf_.get_buf(), len_, tmp_pos))) { TRANS_LOG(WARN, "serialize log header error", K(ret), K(header), K(*this)); - } else if (OB_FAIL(tx_log_body.serialize(fill_buf_->get_buf(), len_, tmp_pos))) { + } else if (OB_FAIL(tx_log_body.serialize(fill_buf_.get_buf(), len_, tmp_pos))) { TRANS_LOG(WARN, "serialize tx_log_body error", K(ret), K(tx_log_body), K(*this)); } else { // do nothing diff --git a/src/storage/tx_storage/ob_access_service.cpp b/src/storage/tx_storage/ob_access_service.cpp index 0fc143bae..0f55aee20 100644 --- a/src/storage/tx_storage/ob_access_service.cpp +++ b/src/storage/tx_storage/ob_access_service.cpp @@ -1137,7 +1137,10 @@ int ObAccessService::audit_tablet_opt_dml_stat( const int64_t affected_rows) { int ret = OB_SUCCESS; - if (OB_ISNULL(dml_param.table_param_)) { + static __thread int64_t last_access_ts = 0; + if (!GCONF.enable_defensive_check() && ObClockGenerator::getClock() - last_access_ts < 1000000) { + // do nothing + } else if (OB_ISNULL(dml_param.table_param_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret), K(dml_param.table_param_)); } else if (dml_stat_type == ObOptDmlStatType::TABLET_OPT_INSERT_STAT || @@ -1159,6 +1162,7 @@ int ObAccessService::audit_tablet_opt_dml_stat( } else { LOG_TRACE("succeed to update dml stat local cache", K(dml_stat)); } + last_access_ts = ObClockGenerator::getClock(); } return ret; } diff --git a/src/storage/tx_table/ob_tx_ctx_memtable_mgr.cpp b/src/storage/tx_table/ob_tx_ctx_memtable_mgr.cpp index 97bbd9354..7d8ac2649 100644 --- a/src/storage/tx_table/ob_tx_ctx_memtable_mgr.cpp +++ b/src/storage/tx_table/ob_tx_ctx_memtable_mgr.cpp @@ -40,7 +40,6 @@ int ObTxCtxMemtableMgr::init(const common::ObTabletID &tablet_id, t3m_ = t3m; table_type_ = ObITable::TableType::TX_CTX_MEMTABLE; is_inited_ = true; - LOG_INFO("tx ctx memtable mgr init successfully", K(ls_id), K(tablet_id), K(this)); return ret; @@ -53,7 +52,7 @@ void ObTxCtxMemtableMgr::destroy() void ObTxCtxMemtableMgr::reset() { - SpinWLockGuard lock_guard(lock_); + MemMgrWLockGuard lock_guard(lock_); reset_tables(); freezer_ = NULL; is_inited_ = false; @@ -74,7 +73,7 @@ int ObTxCtxMemtableMgr::create_memtable(const SCN last_replay_scn, ObTxCtxMemtable *tx_ctx_memtable = nullptr; ObLSTxService *ls_tx_svr = nullptr; - SpinWLockGuard lock_guard(lock_); + MemMgrWLockGuard lock_guard(lock_); table_key.table_type_ = ObITable::TX_CTX_MEMTABLE; table_key.tablet_id_ = ObTabletID(ObTabletID::LS_TX_CTX_TABLET_ID); @@ -136,7 +135,7 @@ int64_t ObTxCtxMemtableMgr::to_string(char *buf, const int64_t buf_len) const if (OB_ISNULL(buf) || buf_len <= 0) { } else { - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); J_OBJ_START(); J_ARRAY_START(); for (int64_t i = memtable_head_; i < memtable_tail_; ++i) { diff --git a/src/storage/tx_table/ob_tx_ctx_memtable_mgr.h b/src/storage/tx_table/ob_tx_ctx_memtable_mgr.h index ef032d91d..7a882bd4e 100644 --- a/src/storage/tx_table/ob_tx_ctx_memtable_mgr.h +++ b/src/storage/tx_table/ob_tx_ctx_memtable_mgr.h @@ -42,7 +42,7 @@ namespace storage class ObTxCtxMemtableMgr : public ObIMemtableMgr { public: - ObTxCtxMemtableMgr() {} + ObTxCtxMemtableMgr() : ObIMemtableMgr(LockType::OB_SPIN_RWLOCK, &lock_def_) {} ~ObTxCtxMemtableMgr() {} void reset(); @@ -71,7 +71,7 @@ protected: int unregister_from_common_checkpoint_(const ObTxCtxMemtable *memtable); private: share::ObLSID ls_id_; - + common::SpinRWLock lock_def_; }; } // namespace storage diff --git a/src/storage/tx_table/ob_tx_data_memtable_mgr.cpp b/src/storage/tx_table/ob_tx_data_memtable_mgr.cpp index 7cd88e1fa..6b389aab7 100644 --- a/src/storage/tx_table/ob_tx_data_memtable_mgr.cpp +++ b/src/storage/tx_table/ob_tx_data_memtable_mgr.cpp @@ -77,7 +77,7 @@ int ObTxDataMemtableMgr::init(const common::ObTabletID &tablet_id, void ObTxDataMemtableMgr::destroy() { - SpinWLockGuard guard(lock_); + MemMgrWLockGuard guard(lock_); reset_tables(); ls_id_ = 0; tablet_id_ = 0; @@ -139,7 +139,7 @@ int ObTxDataMemtableMgr::create_memtable(const SCN clog_checkpoint_scn, ret = OB_ERR_NULL_VALUE; STORAGE_LOG(WARN, "slice_allocator_ has not been set."); } else { - SpinWLockGuard lock_guard(lock_); + MemMgrWLockGuard lock_guard(lock_); if (OB_FAIL(create_memtable_(clog_checkpoint_scn, schema_version))) { STORAGE_LOG(WARN, "create memtable fail.", KR(ret)); } else { @@ -201,7 +201,7 @@ int ObTxDataMemtableMgr::freeze() ret = OB_ERR_NULL_VALUE; STORAGE_LOG(WARN, "slice_allocator_ has not been set.", KR(ret), KP(slice_allocator_)); } else { - SpinWLockGuard lock_guard(lock_); + MemMgrWLockGuard lock_guard(lock_); if (OB_FAIL(freeze_())) { STORAGE_LOG(WARN, "freeze tx data memtable fail.", KR(ret)); } else { @@ -280,7 +280,7 @@ int ObTxDataMemtableMgr::freeze_() int ObTxDataMemtableMgr::get_active_memtable(ObTableHandleV2 &handle) const { int ret = OB_SUCCESS; - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); if (0 == memtable_tail_) { ret = OB_EAGAIN; STORAGE_LOG(INFO, "tx data memtable is not created yet. try agagin.", K(ret), K(memtable_tail_)); @@ -318,7 +318,7 @@ int ObTxDataMemtableMgr::get_all_memtables_(ObTableHdlArray &handles) int ObTxDataMemtableMgr::get_all_memtables(ObTableHdlArray &handles) { int ret = OB_SUCCESS; - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); if (OB_FAIL(get_all_memtables_(handles))) { handles.reset(); STORAGE_LOG(WARN, "get all memtables failed.", KR(ret)); @@ -329,7 +329,7 @@ int ObTxDataMemtableMgr::get_all_memtables(ObTableHdlArray &handles) int ObTxDataMemtableMgr::get_all_memtables_with_range(ObTableHdlArray &handles, int64_t &memtable_head, int64_t &memtable_tail) { int ret = OB_SUCCESS; - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); if (OB_FAIL(get_all_memtables_(handles))) { handles.reset(); STORAGE_LOG(WARN, "get all memtables failed.", KR(ret)); @@ -343,7 +343,7 @@ int ObTxDataMemtableMgr::get_all_memtables_with_range(ObTableHdlArray &handles, int ObTxDataMemtableMgr::get_all_memtables_for_write(ObTxDataMemtableWriteGuard &write_guard) { int ret = OB_SUCCESS; - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); for (int64_t i = memtable_head_; OB_SUCC(ret) && i < memtable_tail_; ++i) { int64_t real_idx = get_memtable_idx(i); write_guard.handles_[i - memtable_head_].reset(); @@ -461,7 +461,7 @@ bool ObTxDataMemtableMgr::is_flushing() const int ObTxDataMemtableMgr::get_memtable_range(int64_t &memtable_head, int64_t &memtable_tail) { int ret = OB_SUCCESS; - SpinRLockGuard lock_guard(lock_); + MemMgrRLockGuard lock_guard(lock_); memtable_head = memtable_head_; memtable_tail = memtable_tail_; return ret; diff --git a/src/storage/tx_table/ob_tx_data_memtable_mgr.h b/src/storage/tx_table/ob_tx_data_memtable_mgr.h index df088b90f..33c072ff0 100644 --- a/src/storage/tx_table/ob_tx_data_memtable_mgr.h +++ b/src/storage/tx_table/ob_tx_data_memtable_mgr.h @@ -37,7 +37,8 @@ private: public: // ObTxDataMemtableMgr ObTxDataMemtableMgr() - : is_freezing_(false), + : ObIMemtableMgr(LockType::OB_SPIN_RWLOCK, &lock_def_), + is_freezing_(false), ls_id_(0), tx_data_table_(nullptr), ls_tablet_svr_(nullptr), @@ -136,6 +137,7 @@ private: // ObTxDataMemtableMgr ObTxDataTable *tx_data_table_; ObLSTabletService *ls_tablet_svr_; SliceAllocator *slice_allocator_; + common::SpinRWLock lock_def_; }; class TxDataMemtableMgrFreezeGuard diff --git a/unittest/share/scheduler/test_dag_net_in_dag_scheduler.cpp b/unittest/share/scheduler/test_dag_net_in_dag_scheduler.cpp index 415ebb949..08a72bd95 100644 --- a/unittest/share/scheduler/test_dag_net_in_dag_scheduler.cpp +++ b/unittest/share/scheduler/test_dag_net_in_dag_scheduler.cpp @@ -49,6 +49,15 @@ namespace oceanbase using namespace common; using namespace share; using namespace omt; + +namespace storage +{ +int64_t ObTenantMetaMemMgr::cal_adaptive_bucket_num() +{ + return 1000; +} +} + namespace unittest { diff --git a/unittest/storage/test_meta_pointer_map.cpp b/unittest/storage/test_meta_pointer_map.cpp index 2e9fe10f9..199da4712 100644 --- a/unittest/storage/test_meta_pointer_map.cpp +++ b/unittest/storage/test_meta_pointer_map.cpp @@ -30,6 +30,11 @@ using namespace share; namespace storage { +int64_t ObTenantMetaMemMgr::cal_adaptive_bucket_num() +{ + return 1000; +} + template<> int ObMetaPointerMap::load_meta_obj( const ObTabletMapKey &key, @@ -67,7 +72,8 @@ TestMetaPointerMap::TestMetaPointerMap() void TestMetaPointerMap::SetUp() { - int ret = tablet_map_.init(100000000L, "TabletMap", 15 * 1024L * 1024L * 1024L, 8 * 1024L * 1024L, + int ret = tablet_map_.init(1000L, OB_SERVER_TENANT_ID, + "TabletMap", 15 * 1024L * 1024L * 1024L, 8 * 1024L * 1024L, common::OB_MALLOC_NORMAL_BLOCK_SIZE); ASSERT_EQ(common::OB_SUCCESS, ret); diff --git a/unittest/storage/test_partition_incremental_range_spliter.cpp b/unittest/storage/test_partition_incremental_range_spliter.cpp index 80a3b1976..700c33966 100644 --- a/unittest/storage/test_partition_incremental_range_spliter.cpp +++ b/unittest/storage/test_partition_incremental_range_spliter.cpp @@ -29,6 +29,11 @@ namespace storage using namespace blocksstable; using namespace common; +int64_t ObTenantMetaMemMgr::cal_adaptive_bucket_num() +{ + return 1000; +} + static int get_number(const char *str, const char *&endpos, int64_t &num) { int ret = OB_SUCCESS; diff --git a/unittest/storage/tx/ob_mock_tx_ctx.cpp b/unittest/storage/tx/ob_mock_tx_ctx.cpp index a7879dea1..f6026ef2c 100644 --- a/unittest/storage/tx/ob_mock_tx_ctx.cpp +++ b/unittest/storage/tx/ob_mock_tx_ctx.cpp @@ -100,7 +100,6 @@ int MockObTxCtx::init(const ObLSID &ls_id, // self end ObPartTransCtx::addr_.parse_from_cstring("127.0.0.1:3001"); ObPartTransCtx::addr_.set_port(3001 + (int32_t)ls_id.id()); - need_del_ctx_ = false; is_inited_ = true; } diff --git a/unittest/storage/tx/test_ob_trans_hashmap.cpp b/unittest/storage/tx/test_ob_trans_hashmap.cpp index 710db1dc5..173b9f1a3 100644 --- a/unittest/storage/tx/test_ob_trans_hashmap.cpp +++ b/unittest/storage/tx/test_ob_trans_hashmap.cpp @@ -44,6 +44,10 @@ class ObTransTestValue : public ObTransHashLink { public: ObTransTestValue() {} + ~ObTransTestValue() + { + TRANS_LOG(INFO, "ObTransTestValue destroyed"); + } int init(const ObTransID &trans_id) { int ret = OB_SUCCESS; @@ -54,9 +58,13 @@ public: } return ret; } + void reset() + { + TRANS_LOG(INFO, "ObTransTestValue reset", K(lbt())); + } bool contain(const ObTransID &trans_id) { return trans_id_ == trans_id; } const ObTransID &get_trans_id() const { return trans_id_; } - TO_STRING_KV(K_(trans_id)); + TO_STRING_KV(K_(trans_id), "ref", get_ref()); private: ObTransID trans_id_; }; @@ -84,7 +92,7 @@ public: ForeachFunctor(TestHashMap *map) : map_(map) {} bool operator() (ObTransTestValue *val) { - TRANS_LOG(INFO, "currnet val info,", "trans_id", val->get_trans_id()); + TRANS_LOG(INFO, "currnet val info,", K(*val)); if (NULL != map_) { map_->del(val->get_trans_id(), val); } @@ -97,11 +105,17 @@ private: class RemoveFunctor { public: - bool operator() (const ObTransTestValue *val) + RemoveFunctor(TestHashMap *map) : map_(map) {} + bool operator() (ObTransTestValue *val) { - TRANS_LOG(INFO, "currnet val info will be removed ", "trans_id", val->get_trans_id()); + TRANS_LOG(INFO, "currnet val info will be removed ", K(*val)); + if (NULL != map_) { + map_->del(val->get_trans_id(), val); + } return true; } +private: + TestHashMap *map_; }; TEST_F(TestObTrans, hashmap_init_invalid) @@ -119,6 +133,7 @@ TEST_F(TestObTrans, hashmap_init_invalid) ObTransTestValue *val0 = NULL; EXPECT_EQ(OB_SUCCESS, map.alloc_value(val0)); EXPECT_EQ(OB_INVALID_ARGUMENT, val0->init(trans_id0)); + EXPECT_EQ(0, val0->get_ref()); map.free_value(val0); TRANS_LOG(INFO, "case2"); @@ -130,12 +145,16 @@ TEST_F(TestObTrans, hashmap_init_invalid) // 2.1 insert ObTransTestValue *v = NULL; EXPECT_EQ(OB_SUCCESS, map.insert_and_get(trans_id1, val1, &v)); + EXPECT_EQ(2, val1->get_ref()); + EXPECT_EQ(NULL, v); map.revert(val1); + EXPECT_EQ(1, val1->get_ref()); // 2.2 check ObTransTestValue *tmp = NULL; EXPECT_EQ(OB_SUCCESS, map.get(trans_id1, tmp)); EXPECT_EQ(tmp, val1); map.revert(tmp); + EXPECT_EQ(1, val1->get_ref()); TRANS_LOG(INFO, "case3"); // 3 entry exist @@ -143,7 +162,11 @@ TEST_F(TestObTrans, hashmap_init_invalid) ObTransTestValue *val2 = NULL; EXPECT_EQ(OB_SUCCESS, map.alloc_value(val2)); EXPECT_EQ(OB_SUCCESS, val2->init(trans_id2)); - EXPECT_EQ(OB_ENTRY_EXIST, map.insert_and_get(trans_id2, val2, &v)); + EXPECT_EQ(0, val2->get_ref()); + EXPECT_EQ(OB_ENTRY_EXIST, map.insert_and_get(trans_id2, val2, &v)); + EXPECT_EQ(2, val1->get_ref()); + EXPECT_EQ(0, val2->get_ref()); + map.revert(v); map.free_value(val2); TRANS_LOG(INFO, "case4"); @@ -153,6 +176,7 @@ TEST_F(TestObTrans, hashmap_init_invalid) EXPECT_EQ(OB_SUCCESS, val3->init(trans_id3)); EXPECT_EQ(OB_SUCCESS, map.insert_and_get(trans_id3, val3, &v)); map.revert(val3); + EXPECT_EQ(1, val3->get_ref()); TRANS_LOG(INFO, "case5"); EXPECT_EQ(2, map.count()); @@ -161,7 +185,26 @@ TEST_F(TestObTrans, hashmap_init_invalid) // 4 foreach / remove if ForeachFunctor foreach_fn(&map); map.for_each(foreach_fn); - RemoveFunctor remove_if_fn; + EXPECT_EQ(0, map.count()); + + TRANS_LOG(INFO, "case7"); + ObTransID trans_id4 = ObTransID(400); + ObTransTestValue *val4 = NULL; + EXPECT_EQ(OB_SUCCESS, map.alloc_value(val4)); + EXPECT_EQ(OB_SUCCESS, val4->init(trans_id4)); + EXPECT_EQ(OB_SUCCESS, map.insert_and_get(trans_id4, val4, &v)); + map.revert(val4); + + ObTransID trans_id5 = ObTransID(500); + ObTransTestValue *val5 = NULL; + EXPECT_EQ(OB_SUCCESS, map.alloc_value(val5)); + EXPECT_EQ(OB_SUCCESS, val5->init(trans_id5)); + EXPECT_EQ(OB_SUCCESS, map.insert_and_get(trans_id5, val5, &v)); + map.revert(val5); + + EXPECT_EQ(1, val4->get_ref()); + EXPECT_EQ(1, val5->get_ref()); + RemoveFunctor remove_if_fn(&map); map.remove_if(remove_if_fn); EXPECT_EQ(0, map.count()); } diff --git a/unittest/storage/tx_table/test_tx_ctx_table.cpp b/unittest/storage/tx_table/test_tx_ctx_table.cpp index bb0742951..13e56ce29 100644 --- a/unittest/storage/tx_table/test_tx_ctx_table.cpp +++ b/unittest/storage/tx_table/test_tx_ctx_table.cpp @@ -35,6 +35,14 @@ using namespace storage; using namespace blocksstable; using namespace share; +namespace storage +{ +int64_t ObTenantMetaMemMgr::cal_adaptive_bucket_num() +{ + return 1000; +} +} + namespace unittest {