[FEAT MERGE] OLTP performance optimization feature
This commit is contained in:
parent
9daa7428e9
commit
050e984b04
3
build.sh
3
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
|
||||
;;
|
||||
|
@ -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()
|
||||
|
1
deps/oblib/src/lib/CMakeLists.txt
vendored
1
deps/oblib/src/lib/CMakeLists.txt
vendored
@ -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
|
||||
)
|
||||
|
||||
|
7
deps/oblib/src/lib/alloc/memory_dump.cpp
vendored
7
deps/oblib/src/lib/alloc/memory_dump.cpp
vendored
@ -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);
|
||||
|
1
deps/oblib/src/lib/allocator/ob_qsync.h
vendored
1
deps/oblib/src/lib/allocator/ob_qsync.h
vendored
@ -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)
|
||||
{
|
||||
|
243
deps/oblib/src/lib/lock/ob_bucket_qsync_lock.cpp
vendored
Normal file
243
deps/oblib/src/lib/lock/ob_bucket_qsync_lock.cpp
vendored
Normal file
@ -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
|
265
deps/oblib/src/lib/lock/ob_bucket_qsync_lock.h
vendored
Normal file
265
deps/oblib/src/lib/lock/ob_bucket_qsync_lock.h
vendored
Normal file
@ -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_ */
|
33
deps/oblib/src/lib/lock/ob_qsync_lock.cpp
vendored
33
deps/oblib/src/lib/lock/ob_qsync_lock.cpp
vendored
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
2
deps/oblib/src/lib/lock/ob_qsync_lock.h
vendored
2
deps/oblib/src/lib/lock/ob_qsync_lock.h
vendored
@ -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_;
|
||||
|
@ -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;
|
||||
|
@ -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++) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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));
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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_) {
|
||||
|
@ -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)) {
|
||||
|
@ -317,12 +317,25 @@ int ObDASTabletMapper::get_non_partition_tablet_id(ObIArray<ObTabletID> &tablet_
|
||||
ObIArray<ObObjectID> &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<DASRelatedTabletMap *>(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;
|
||||
}
|
||||
|
||||
|
@ -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<DASRelatedTabletMap::MapEntry, common::ObIAllocator> 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<common::ObTabletID> &tablet_ids,
|
||||
const common::ObIArray<common::ObObjectID> &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
|
||||
|
@ -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_))) {
|
||||
|
@ -80,7 +80,7 @@ class ObCandiTabletLoc
|
||||
{
|
||||
public:
|
||||
ObCandiTabletLoc();
|
||||
virtual ~ObCandiTabletLoc();
|
||||
~ObCandiTabletLoc();
|
||||
|
||||
void reset();
|
||||
int assign(const ObCandiTabletLoc &other);
|
||||
|
@ -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<ObTabletID, 1> tablet_ids;
|
||||
ObSEArray<ObObjectID, 1> 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<DASRelatedTabletMap *>(
|
||||
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));
|
||||
|
@ -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<int64_t, 1> 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<DASRelatedTabletMap::MapEntry, common::ObIAllocator> related_list_;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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; }
|
||||
|
@ -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())) {
|
||||
|
@ -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));
|
||||
|
@ -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_);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -239,18 +239,18 @@ int ObMetaPointerMap<Key, T>::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<T> *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<T> *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;
|
||||
}
|
||||
|
@ -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<ObTablet>::reset();
|
||||
@ -182,6 +185,7 @@ int ObTabletPointer::deep_copy(char *buf, const int64_t buf_len, ObMetaPointer<O
|
||||
pvalue->memtable_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;
|
||||
|
@ -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_;
|
||||
|
@ -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<ObTabletPointer*>(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<ObTenantMetaMemStatus> &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;
|
||||
}
|
||||
|
@ -186,7 +186,6 @@ public:
|
||||
int get_meta_mem_status(common::ObIArray<ObTenantMetaMemStatus> &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<ObMetaPointer<ObTablet>> TabletValueStore;
|
||||
|
||||
struct CandidateTabletInfo final
|
||||
|
@ -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));
|
||||
|
@ -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<ObTableHandleV2>;
|
||||
|
||||
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<common::ObQSyncLock *>(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<common::ObQSyncLock *>(lock_)->rdlock();
|
||||
} else if (lock_type_ == LockType::OB_SPIN_RWLOCK) {
|
||||
ret = static_cast<common::SpinRWLock *>(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<common::ObQSyncLock *>(lock_)->rdunlock();
|
||||
} else if (lock_type_ == LockType::OB_SPIN_RWLOCK) {
|
||||
static_cast<common::SpinRWLock *>(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<common::SpinRWLock *>(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<common::ObQSyncLock *>(lock_)->wrlock();
|
||||
} else if (lock_type_ == LockType::OB_SPIN_RWLOCK) {
|
||||
ret = static_cast<common::SpinRWLock *>(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<common::ObQSyncLock *>(lock_)->wrunlock();
|
||||
} else if (lock_type_ == LockType::OB_SPIN_RWLOCK) {
|
||||
static_cast<common::SpinRWLock *>(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<MemtableMgrLock&>(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<MemtableMgrLock &>(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
|
||||
|
@ -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 {
|
||||
|
@ -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 <typename Callback = ObResourceDefaultCallback<Key,Value>>
|
||||
int get(const Key &key, ObResourceHandle<Value> &handle, Callback callback = ObResourceDefaultCallback<Key, Value>());
|
||||
@ -203,20 +203,27 @@ ObResourceMap<Key, Value>::~ObResourceMap()
|
||||
}
|
||||
|
||||
template <typename Key, typename Value>
|
||||
int ObResourceMap<Key, Value>::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<Key, Value>::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<Key, Value>::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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -75,6 +75,7 @@ private:
|
||||
|
||||
private:
|
||||
share::ObLSID ls_id_;
|
||||
common::ObQSyncLock lock_def_;
|
||||
};
|
||||
|
||||
} // namespace tablelock
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -80,12 +80,10 @@ public:
|
||||
};
|
||||
|
||||
typedef ObDList<ObTableLockOpLinkNode> ObTableLockOpList;
|
||||
typedef common::LinkHashNode<ObLockID> ObOBJLockHashNode;
|
||||
typedef common::LinkHashValue<ObLockID> ObOBJLockHashValue;
|
||||
class ObOBJLock : public ObOBJLockHashValue
|
||||
class ObOBJLock : public ObTransHashLink<ObOBJLock>
|
||||
{
|
||||
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<ObLockID, ObOBJLock, ObOBJLockAlloc> Map;
|
||||
const static int MIN_MAP_SIZE = 1 << 10;
|
||||
typedef ObTransHashMap<ObLockID, ObOBJLock, ObOBJLockAlloc, common::SpinRWLock, 1 << 10> 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<ObTableLockOp> &store_arr_;
|
||||
|
@ -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<ObTabletPointer*>(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<ObTabletPointer*>(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<ObTabletPointer*>(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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -134,6 +134,7 @@ private:
|
||||
|
||||
private:
|
||||
ObLS *ls_; //8B
|
||||
common::SpinRWLock lock_def_; //8B
|
||||
ObStorageSchemaRecorder schema_recorder_;// 136B
|
||||
};
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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_;
|
||||
|
@ -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_();
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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_;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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_);
|
||||
|
@ -140,7 +140,7 @@ const static char OB_SIMPLE_ITERATOR_LABEL_FOR_TX_ID[] = "ObTxCtxMgr";
|
||||
typedef common::ObSimpleIterator<ObTransID, OB_SIMPLE_ITERATOR_LABEL_FOR_TX_ID, 16> ObTxIDIterator;
|
||||
|
||||
// LogStream Transaction Context Manager
|
||||
class ObLSTxCtxMgr: public ObLSTxCtxMgrHashValue
|
||||
class ObLSTxCtxMgr: public ObTransHashLink<ObLSTxCtxMgr>
|
||||
{
|
||||
// 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<share::ObLSID, ObLSTxCtxMgr,
|
||||
ObLSTxCtxMgrAlloc, common::RefHandle> ObLSTxCtxMgrMap;
|
||||
typedef transaction::ObTransHashMap<share::ObLSID, ObLSTxCtxMgr,
|
||||
ObLSTxCtxMgrAlloc, common::ObQSyncLock> ObLSTxCtxMgrMap;
|
||||
|
||||
class ObTxCtxMgr
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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<ObTxCommitCallback> &
|
||||
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<ObTxCommitCallback> &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)
|
||||
|
@ -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_;
|
||||
|
||||
/*
|
||||
|
@ -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));
|
||||
|
@ -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<ObTsTenantInfo> ObTsTenantInfoNode;
|
||||
typedef common::LinkHashValue<ObTsTenantInfo> 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())
|
||||
|
||||
}
|
||||
|
@ -268,7 +268,6 @@ public:
|
||||
|
||||
void dump_2_text(FILE *fd) const;
|
||||
static void print_to_stderr(const ObTxData &tx_data);
|
||||
|
||||
|
||||
DECLARE_TO_STRING;
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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_) {
|
||||
|
@ -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 <typename T>
|
||||
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
||||
|
@ -30,6 +30,11 @@ using namespace share;
|
||||
namespace storage
|
||||
{
|
||||
|
||||
int64_t ObTenantMetaMemMgr::cal_adaptive_bucket_num()
|
||||
{
|
||||
return 1000;
|
||||
}
|
||||
|
||||
template<>
|
||||
int ObMetaPointerMap<ObTabletMapKey, ObTablet>::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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,10 @@ class ObTransTestValue : public ObTransHashLink<ObTransTestValue>
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user